Sha256: 39e986147062a5b79cc514812764b7246566646d7454a03a451959f0b8318be9

Contents?: true

Size: 1.99 KB

Versions: 16

Compression:

Stored size: 1.99 KB

Contents

# frozen_string_literal: true

module Cucumber
  module StepMatchSearch
    def self.new(search, configuration)
      CachesStepMatch.new(
        AssertUnambiguousMatch.new(
          configuration.guess? ? AttemptToGuessAmbiguousMatch.new(search) : search,
          configuration
        )
      )
    end

    class AssertUnambiguousMatch
      def initialize(search, configuration)
        @search = search
        @configuration = configuration
      end

      def call(step_name)
        result = @search.call(step_name)
        raise Cucumber::Ambiguous.new(step_name, result, @configuration.guess?) if result.length > 1

        result
      end
    end

    class AttemptToGuessAmbiguousMatch
      def initialize(search)
        @search = search
      end

      def call(step_name)
        best_matches(step_name, @search.call(step_name))
      end

      private

      def best_matches(_step_name, step_matches) # :nodoc:
        no_groups      = step_matches.select { |step_match| step_match.args.empty? }
        max_arg_length = step_matches.map { |step_match| step_match.args.length }.max
        top_groups     = step_matches.select { |step_match| step_match.args.length == max_arg_length }

        if no_groups.any?
          longest_regexp_length = no_groups.map(&:text_length).max
          no_groups.select { |step_match| step_match.text_length == longest_regexp_length }
        elsif top_groups.any?
          shortest_capture_length = top_groups.map { |step_match| step_match.args.inject(0) { |sum, c| sum + c.to_s.length } }.min
          top_groups.select { |step_match| step_match.args.inject(0) { |sum, c| sum + c.to_s.length } == shortest_capture_length }
        else
          top_groups
        end
      end
    end

    require 'delegate'
    class CachesStepMatch < SimpleDelegator
      def call(step_name) # :nodoc:
        @match_cache ||= {}

        matches = @match_cache[step_name]
        return matches if matches

        @match_cache[step_name] = super(step_name)
      end
    end
  end
end

Version data entries

16 entries across 16 versions & 3 rubygems

Version Path
cucumber-9.2.1 lib/cucumber/step_match_search.rb
cucumber-9.2.0 lib/cucumber/step_match_search.rb
cucumber-9.1.2 lib/cucumber/step_match_search.rb
cucumber-9.1.1 lib/cucumber/step_match_search.rb
honeybadger-5.4.0 vendor/bundle/ruby/3.2.0/gems/cucumber-9.1.0/lib/cucumber/step_match_search.rb
cucumber-9.1.0 lib/cucumber/step_match_search.rb
honeybadger-5.3.0 vendor/bundle/ruby/3.2.0/gems/cucumber-9.0.2/lib/cucumber/step_match_search.rb
cucumber-9.0.2 lib/cucumber/step_match_search.rb
cucumber-9.0.1 lib/cucumber/step_match_search.rb
cucumber-9.0.0 lib/cucumber/step_match_search.rb
rubypitaya-3.12.5 ./lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/cucumber-8.0.0/lib/cucumber/step_match_search.rb
rubypitaya-3.12.4 ./lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/cucumber-8.0.0/lib/cucumber/step_match_search.rb
rubypitaya-3.12.3 ./lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/cucumber-8.0.0/lib/cucumber/step_match_search.rb
rubypitaya-3.12.2 ./lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/cucumber-8.0.0/lib/cucumber/step_match_search.rb
cucumber-8.0.0 lib/cucumber/step_match_search.rb
cucumber-8.0.0.rc.1 lib/cucumber/step_match_search.rb