1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
require 'cucumber/cucumber_expressions/parameter_type_matcher'
require 'cucumber/cucumber_expressions/generated_expression'
require 'cucumber/cucumber_expressions/combinatorial_generated_expression_factory'
module Cucumber
module CucumberExpressions
class CucumberExpressionGenerator
def initialize(parameter_type_registry)
@parameter_type_registry = parameter_type_registry
end
def generate_expression(text)
generate_expressions(text)[0]
end
def generate_expressions(text)
parameter_type_combinations = []
parameter_type_matchers = create_parameter_type_matchers(text)
expression_template = ""
pos = 0
loop do
matching_parameter_type_matchers = []
parameter_type_matchers.each do |parameter_type_matcher|
advanced_parameter_type_matcher = parameter_type_matcher.advance_to(pos)
if advanced_parameter_type_matcher.find
matching_parameter_type_matchers.push(advanced_parameter_type_matcher)
end
end
if matching_parameter_type_matchers.any?
matching_parameter_type_matchers = matching_parameter_type_matchers.sort
best_parameter_type_matcher = matching_parameter_type_matchers[0]
best_parameter_type_matchers = matching_parameter_type_matchers.select do |m|
(m <=> best_parameter_type_matcher).zero?
end
# Build a list of parameter types without duplicates. The reason there
# might be duplicates is that some parameter types have more than one regexp,
# which means multiple ParameterTypeMatcher objects will have a reference to the
# same ParameterType.
# We're sorting the list so prefer_for_regexp_match parameter types are listed first.
# Users are most likely to want these, so they should be listed at the top.
parameter_types = []
best_parameter_type_matchers.each do |parameter_type_matcher|
unless parameter_types.include?(parameter_type_matcher.parameter_type)
parameter_types.push(parameter_type_matcher.parameter_type)
end
end
parameter_types.sort!
parameter_type_combinations.push(parameter_types)
expression_template += escape(text.slice(pos...best_parameter_type_matcher.start))
expression_template += "{%s}"
pos = best_parameter_type_matcher.start + best_parameter_type_matcher.group.length
else
break
end
if pos >= text.length
break
end
end
expression_template += escape(text.slice(pos..-1))
CombinatorialGeneratedExpressionFactory.new(
expression_template,
parameter_type_combinations
).generate_expressions
end
private
def create_parameter_type_matchers(text)
parameter_matchers = []
@parameter_type_registry.parameter_types.each do |parameter_type|
if parameter_type.use_for_snippets?
parameter_matchers += create_parameter_type_matchers2(parameter_type, text)
end
end
parameter_matchers
end
def create_parameter_type_matchers2(parameter_type, text)
result = []
regexps = parameter_type.regexps
regexps.each do |regexp|
regexp = Regexp.new("(#{regexp})")
result.push(ParameterTypeMatcher.new(parameter_type, regexp, text, 0))
end
result
end
def escape(s)
s.gsub(/%/, '%%')
.gsub(/\(/, '\\(')
.gsub(/\{/, '\\{')
.gsub(/\//, '\\/')
end
end
end
end
|