<commit_before>require 'enumerator'

module Jasmine
  class SpecBuilder
    attr_accessor :suites

    def initialize(config)
      @config = config
      @spec_files = config.spec_files
      @runner = config
      @spec_ids = []
    end

    def start
      guess_example_locations

      @runner.start
      load_suite_info
      wait_for_suites_to_finish_running
    end

    def stop
      @runner.stop
    end

    def script_path
      File.expand_path(__FILE__)
    end

    def guess_example_locations
      @example_locations = {}

      example_name_parts = []
      previous_indent_level = 0
      @config.spec_files_full_paths.each do |filename|
        line_number = 1
        File.open(filename, "rb") do |file|
          file.readlines.each do |line|
            match = /^(\s*)(describe|it)\s*\(\s*["'](.*)["']\s*,\s*function/.match(line)
            if (match)
              indent_level = match[1].length / 2
              example_name = match[3]
              example_name_parts[indent_level] = example_name

              full_example_name = example_name_parts.slice(0, indent_level + 1).join(" ")
              @example_locations[full_example_name] = "#{filename}:#{line_number}: in `it'"
            end
            line_number += 1
          end
        end
      end
    end

    def load_suite_info
      started = Time.now
      while !eval_js('return jsApiReporter && jsApiReporter.started') do
        raise "couldn't connect to Jasmine after 60 seconds" if (started + 60 < Time.now)
        sleep 0.1
      end

      @suites = eval_js("var result = jsApiReporter.suites(); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }")
    end

    def results_for(spec_id)
      @spec_results ||= load_results
      @spec_results[spec_id.to_s]
    end

    def load_results
      @spec_results = {}
      @spec_ids.each_slice(50) do |slice|
        @spec_results.merge!(eval_js("var result = jsApiReporter.resultsForSpecs(#{json_generate(slice)}); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }"))
      end
      @spec_results
    end

    def wait_for_suites_to_finish_running
      puts "Waiting for suite to finish in browser ..."
      while !eval_js('return jsApiReporter.finished') do
        sleep 0.1
      end
    end

    def declare_suites
      me = self
      suites.each do |suite|
        declare_suite(self, suite)
      end
    end

    def declare_suite(parent, suite)
      me = self
      parent.describe suite["name"] do
        suite["children"].each do |suite_or_spec|
          type = suite_or_spec["type"]
          if type == "suite"
            me.declare_suite(self, suite_or_spec)
          elsif type == "spec"
            me.declare_spec(self, suite_or_spec)
          else
            raise "unknown type #{type} for #{suite_or_spec.inspect}"
          end
        end
      end<commit_msg>add some status feedback so we don't time out on travis, the exec_js call takes some time to return so it really doesn't run every 100 millis<commit_after>require 'enumerator'

module Jasmine
  class SpecBuilder
    attr_accessor :suites

    def initialize(config)
      @config = config
      @spec_files = config.spec_files
      @runner = config
      @spec_ids = []
    end

    def start
      guess_example_locations

      @runner.start
      load_suite_info
      wait_for_suites_to_finish_running
    end

    def stop
      @runner.stop
    end

    def script_path
      File.expand_path(__FILE__)
    end

    def guess_example_locations
      @example_locations = {}

      example_name_parts = []
      previous_indent_level = 0
      @config.spec_files_full_paths.each do |filename|
        line_number = 1
        File.open(filename, "rb") do |file|
          file.readlines.each do |line|
            match = /^(\s*)(describe|it)\s*\(\s*["'](.*)["']\s*,\s*function/.match(line)
            if (match)
              indent_level = match[1].length / 2
              example_name = match[3]
              example_name_parts[indent_level] = example_name

              full_example_name = example_name_parts.slice(0, indent_level + 1).join(" ")
              @example_locations[full_example_name] = "#{filename}:#{line_number}: in `it'"
            end
            line_number += 1
          end
        end
      end
    end

    def load_suite_info
      started = Time.now
      while !eval_js('return jsApiReporter && jsApiReporter.started') do
        raise "couldn't connect to Jasmine after 60 seconds" if (started + 60 < Time.now)
        sleep 0.1
      end

      @suites = eval_js("var result = jsApiReporter.suites(); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }")
    end

    def results_for(spec_id)
      @spec_results ||= load_results
      @spec_results[spec_id.to_s]
    end

    def load_results
      @spec_results = {}
      @spec_ids.each_slice(50) do |slice|
        @spec_results.merge!(eval_js("var result = jsApiReporter.resultsForSpecs(#{json_generate(slice)}); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }"))
      end
      @spec_results
    end

    def wait_for_suites_to_finish_running
      puts "Waiting for suite to finish in browser ..."
      while !eval_js('return jsApiReporter.finished') do
        print '.'
        sleep 0.1
      end
    end

    def declare_suites
      me = self
      suites.each do |suite|
        declare_suite(self, suite)
      end
    end

    def declare_suite(parent, suite)
      me = self
      parent.describe suite["name"] do
        suite["children"].each do |suite_or_spec|
          type = suite_or_spec["type"]
          if type == "suite"
            me.declare_suite(self, suite_or_spec)
          elsif type == "spec"
            me.declare_spec(self, suite_or_spec)
          else
            raise "unknown type #{type} for #{suite_or_spec.inspect}"
          end
        end
      end
{'fraction_non_alphanumeric': 0.09894806048652202, 'fraction_numerical': 0.00641025641025641, 'mean_word_length': 2.2644849785407724, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4909471', 'n_tokens_mistral': 1922, 'n_tokens_neox': 1844, 'n_words': 430}