<commit_before>require 'cucumber/core_ext/proc'

module Cucumber
  class Executor
    attr_reader :failed
    attr_accessor :formatters

    def line=(line)
      @line = line
    end

    def initialize(step_mother)
      @world_proc = lambda do
        Object.new
      end
      @before_scenario_procs = []
      @after_scenario_procs = []
      @after_step_procs = []
      @step_mother = step_mother

      @visited_scenarios = {}
      @regular_scenario_cache = {}
    end

    def register_world_proc(&proc)
      @world_proc = proc
    end

    def register_before_scenario_proc(&proc)
      proc.extend(CoreExt::CallIn)
      @before_scenario_procs << proc
    end

    def register_after_scenario_proc(&proc)
      proc.extend(CoreExt::CallIn)
      @after_scenario_procs << proc
    end

    def register_after_step_proc(&proc)
      proc.extend(CoreExt::CallIn)
      @after_step_procs << proc
    end

    def visit_features(features)
      raise "Line number can only be specified when there is 1 feature. There were #{features.length}." if @line && features.length != 1
      formatters.visit_features(features)
      features.accept(self)
      formatters.dump
    end

    def visit_feature(feature)
      formatters.visit_feature(feature)
      feature.accept(self)
      @visited_scenarios = {}
      @regular_scenario_cache = {}
    end

    def visit_header(header)
      formatters.header_executing(header)
    end

    def visit_row_scenario(scenario)
      visit_scenario(@regular_scenario_cache[scenario.name], force_accept=true) if executing_unprepared_row_scenario?(scenario)
      visit_scenario(scenario)
    end

    def visit_regular_scenario(scenario)
      @regular_scenario_cache[scenario.name] = scenario
      visit_scenario(scenario)
    end

    def visit_scenario(scenario, force_accept = false)
      if accept?(scenario) || force_accept
        @visited_scenarios[scenario.name] = true

        @error = nil
        @pending = nil

        @world = @world_proc.call
        @world.extend(Spec::Matchers) if defined?(Spec::Matchers)
        define_step_call_methods(@world)

        formatters.scenario_executing(scenario)
        @before_scenario_procs.each{|p| p.call_in(@world, *[])}
        scenario.accept(self)
        @after_scenario_procs.each{|p| p.call_in(@world, *[])}
        formatters.scenario_executed(scenario)
      end
    end

    def accept?(scenario)
      @line.nil? || scenario.at_line?(@line)
    end

    def visit_row_step(step)
      visit_step(step)
    end

    def visit_regular_step(step)
      visit_step(step)
    end

    def visit_step(step)
      unless @pending || @error
        begin
          regexp, args, proc = step.regexp_args_proc(@step_mother)
          formatters.step_executing(step, regexp, args)
          step.execute_in(@world, regexp, args, proc)
          @after_step_procs.each{|p| p.call_in(@world, *[])}
          formatters.step_passed(step, regexp, args)
        rescue Pending
          record_pending_step(step, regexp, args)
        rescue => e
          @failed = true
          @error = step.error = e
          formatters.step_failed(step, regexp, args)
        end<commit_msg>Refactoring to get rid of selector argument<commit_after>require 'cucumber/core_ext/proc'

module Cucumber
  class Executor
    attr_reader :failed
    attr_accessor :formatters

    def line=(line)
      @line = line
    end

    def initialize(step_mother)
      @world_proc = lambda do
        Object.new
      end
      @before_scenario_procs = []
      @after_scenario_procs = []
      @after_step_procs = []
      @step_mother = step_mother

      @visited_scenarios = {}
      @regular_scenario_cache = {}
    end

    def register_world_proc(&proc)
      @world_proc = proc
    end

    def register_before_scenario_proc(&proc)
      proc.extend(CoreExt::CallIn)
      @before_scenario_procs << proc
    end

    def register_after_scenario_proc(&proc)
      proc.extend(CoreExt::CallIn)
      @after_scenario_procs << proc
    end

    def register_after_step_proc(&proc)
      proc.extend(CoreExt::CallIn)
      @after_step_procs << proc
    end

    def visit_features(features)
      raise "Line number can only be specified when there is 1 feature. There were #{features.length}." if @line && features.length != 1
      formatters.visit_features(features)
      features.accept(self)
      formatters.dump
    end

    def visit_feature(feature)
      formatters.visit_feature(feature)
      feature.accept(self)
      @visited_scenarios = {}
      @regular_scenario_cache = {}
    end

    def visit_header(header)
      formatters.header_executing(header)
    end

    def visit_row_scenario(scenario)
      execute_scenario(@regular_scenario_cache[scenario.name]) if executing_unprepared_row_scenario?(scenario)
      visit_scenario(scenario)
    end

    def visit_regular_scenario(scenario)
      @regular_scenario_cache[scenario.name] = scenario
      visit_scenario(scenario)
    end

    def visit_scenario(scenario)
      if accept?(scenario)
        @visited_scenarios[scenario.name] = true
        execute_scenario(scenario)
      end
    end

    def execute_scenario(scenario)
      @error = nil
      @pending = nil

      @world = @world_proc.call
      @world.extend(Spec::Matchers) if defined?(Spec::Matchers)
      define_step_call_methods(@world)

      formatters.scenario_executing(scenario)
      @before_scenario_procs.each{|p| p.call_in(@world, *[])}
      scenario.accept(self)
      @after_scenario_procs.each{|p| p.call_in(@world, *[])}
      formatters.scenario_executed(scenario)
    end
    
    def accept?(scenario)
      @line.nil? || scenario.at_line?(@line)
    end

    def visit_row_step(step)
      visit_step(step)
    end

    def visit_regular_step(step)
      visit_step(step)
    end

    def visit_step(step)
      unless @pending || @error
        begin
          regexp, args, proc = step.regexp_args_proc(@step_mother)
          formatters.step_executing(step, regexp, args)
          step.execute_in(@world, regexp, args, proc)
          @after_step_procs.each{|p| p.call_in(@world, *[])}
          formatters.step_passed(step, regexp, args)
        rescue Pending
          record_pending_step(step, regexp, args)
        rescue => e
          @failed = true
          @error = step.error = e
          formatters.step_failed(step, regexp, args)
        end
{'fraction_non_alphanumeric': 0.09404780503046399, 'fraction_numerical': 0.0006249023590064052, 'mean_word_length': 2.7904085257548847, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 5, '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': '4004601', 'n_tokens_mistral': 2076, 'n_tokens_neox': 2034, 'n_words': 369}