cucumber-cucumber-expressions 16.1.2 → 17.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +37 -0
  3. data/.rubocop_todo.yml +443 -0
  4. data/Gemfile +2 -1
  5. data/Rakefile +4 -17
  6. data/VERSION +1 -1
  7. data/cucumber-cucumber-expressions.gemspec +22 -17
  8. data/lib/cucumber/cucumber_expressions/argument.rb +7 -3
  9. data/lib/cucumber/cucumber_expressions/ast.rb +24 -59
  10. data/lib/cucumber/cucumber_expressions/combinatorial_generated_expression_factory.rb +6 -13
  11. data/lib/cucumber/cucumber_expressions/cucumber_expression.rb +17 -19
  12. data/lib/cucumber/cucumber_expressions/cucumber_expression_generator.rb +11 -15
  13. data/lib/cucumber/cucumber_expressions/cucumber_expression_parser.rb +37 -53
  14. data/lib/cucumber/cucumber_expressions/cucumber_expression_tokenizer.rb +13 -18
  15. data/lib/cucumber/cucumber_expressions/errors.rb +121 -103
  16. data/lib/cucumber/cucumber_expressions/expression_factory.rb +2 -0
  17. data/lib/cucumber/cucumber_expressions/generated_expression.rb +2 -0
  18. data/lib/cucumber/cucumber_expressions/group.rb +2 -0
  19. data/lib/cucumber/cucumber_expressions/group_builder.rb +3 -1
  20. data/lib/cucumber/cucumber_expressions/parameter_type.rb +14 -26
  21. data/lib/cucumber/cucumber_expressions/parameter_type_matcher.rb +9 -7
  22. data/lib/cucumber/cucumber_expressions/parameter_type_registry.rb +27 -22
  23. data/lib/cucumber/cucumber_expressions/regular_expression.rb +3 -2
  24. data/lib/cucumber/cucumber_expressions/tree_regexp.rb +8 -7
  25. data/spec/cucumber/cucumber_expressions/argument_spec.rb +4 -2
  26. data/spec/cucumber/cucumber_expressions/combinatorial_generated_expression_factory_spec.rb +41 -0
  27. data/spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb +106 -103
  28. data/spec/cucumber/cucumber_expressions/cucumber_expression_parser_spec.rb +3 -1
  29. data/spec/cucumber/cucumber_expressions/cucumber_expression_spec.rb +90 -93
  30. data/spec/cucumber/cucumber_expressions/cucumber_expression_tokenizer_spec.rb +4 -2
  31. data/spec/cucumber/cucumber_expressions/cucumber_expression_transformation_spec.rb +4 -2
  32. data/spec/cucumber/cucumber_expressions/custom_parameter_type_spec.rb +80 -61
  33. data/spec/cucumber/cucumber_expressions/expression_factory_spec.rb +3 -1
  34. data/spec/cucumber/cucumber_expressions/parameter_type_registry_spec.rb +44 -49
  35. data/spec/cucumber/cucumber_expressions/parameter_type_spec.rb +5 -2
  36. data/spec/cucumber/cucumber_expressions/regular_expression_spec.rb +39 -30
  37. data/spec/cucumber/cucumber_expressions/tree_regexp_spec.rb +49 -49
  38. metadata +80 -25
  39. data/.rspec +0 -1
  40. data/scripts/update-gemspec +0 -32
  41. data/spec/capture_warnings.rb +0 -74
  42. data/spec/cucumber/cucumber_expressions/combinatorial_generated_expression_factory_test.rb +0 -43
@@ -1,24 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/cucumber_expressions/ast'
2
4
 
3
5
  module Cucumber
4
6
  module CucumberExpressions
5
7
  class CucumberExpressionError < StandardError
6
-
7
- def build_message(
8
- index,
9
- expression,
10
- pointer,
11
- problem,
12
- solution
13
- )
14
- m = <<-EOF
15
- This Cucumber Expression has a problem at column #{index + 1}:
16
-
17
- #{expression}
18
- #{pointer}
19
- #{problem}.
20
- #{solution}
21
- EOF
8
+ def build_message(index, expression, pointer, problem, solution)
9
+ m = <<~ERROR
10
+ This Cucumber Expression has a problem at column #{index + 1}:
11
+
12
+ #{expression}
13
+ #{pointer}
14
+ #{problem}.
15
+ #{solution}
16
+ ERROR
22
17
  m.strip
23
18
  end
24
19
 
@@ -40,86 +35,100 @@ This Cucumber Expression has a problem at column #{index + 1}:
40
35
 
41
36
  class AlternativeMayNotExclusivelyContainOptionals < CucumberExpressionError
42
37
  def initialize(node, expression)
43
- super(build_message(
44
- node.start,
45
- expression,
46
- point_at_located(node),
47
- 'An alternative may not exclusively contain optionals',
48
- "If you did not mean to use an optional you can use '\\(' to escape the the '('"
49
- ))
38
+ super(
39
+ build_message(
40
+ node.start,
41
+ expression,
42
+ point_at_located(node),
43
+ 'An alternative may not exclusively contain optionals',
44
+ "If you did not mean to use an optional you can use '\\(' to escape the '('"
45
+ )
46
+ )
50
47
  end
51
48
  end
52
49
 
53
50
  class AlternativeMayNotBeEmpty < CucumberExpressionError
54
51
  def initialize(node, expression)
55
- super(build_message(
56
- node.start,
57
- expression,
58
- point_at_located(node),
59
- 'Alternative may not be empty',
60
- "If you did not mean to use an alternative you can use '\\/' to escape the the '/'"
61
- ))
52
+ super(
53
+ build_message(
54
+ node.start,
55
+ expression,
56
+ point_at_located(node),
57
+ 'Alternative may not be empty',
58
+ "If you did not mean to use an alternative you can use '\\/' to escape the '/'"
59
+ )
60
+ )
62
61
  end
63
62
  end
64
63
 
65
64
  class CantEscape < CucumberExpressionError
66
65
  def initialize(expression, index)
67
- super(build_message(
68
- index,
69
- expression,
70
- point_at(index),
71
- "Only the characters '{', '}', '(', ')', '\\', '/' and whitespace can be escaped",
72
- "If you did mean to use an '\\' you can use '\\\\' to escape it"
73
- ))
66
+ super(
67
+ build_message(
68
+ index,
69
+ expression,
70
+ point_at(index),
71
+ "Only the characters '{', '}', '(', ')', '\\', '/' and whitespace can be escaped",
72
+ "If you did mean to use an '\\' you can use '\\\\' to escape it"
73
+ )
74
+ )
74
75
  end
75
76
  end
76
77
 
77
78
  class OptionalMayNotBeEmpty < CucumberExpressionError
78
79
  def initialize(node, expression)
79
- super(build_message(
80
- node.start,
81
- expression,
82
- point_at_located(node),
83
- 'An optional must contain some text',
84
- "If you did not mean to use an optional you can use '\\(' to escape the the '('"
85
- ))
80
+ super(
81
+ build_message(
82
+ node.start,
83
+ expression,
84
+ point_at_located(node),
85
+ 'An optional must contain some text',
86
+ "If you did not mean to use an optional you can use '\\(' to escape the '('"
87
+ )
88
+ )
86
89
  end
87
90
  end
88
91
 
89
92
  class ParameterIsNotAllowedInOptional < CucumberExpressionError
90
93
  def initialize(node, expression)
91
- super(build_message(
92
- node.start,
93
- expression,
94
- point_at_located(node),
95
- 'An optional may not contain a parameter type',
96
- "If you did not mean to use an parameter type you can use '\\{' to escape the the '{'"
97
- ))
94
+ super(
95
+ build_message(
96
+ node.start,
97
+ expression,
98
+ point_at_located(node),
99
+ 'An optional may not contain a parameter type',
100
+ "If you did not mean to use an parameter type you can use '\\{' to escape the '{'"
101
+ )
102
+ )
98
103
  end
99
104
  end
100
105
 
101
106
  class OptionalIsNotAllowedInOptional < CucumberExpressionError
102
107
  def initialize(node, expression)
103
- super(build_message(
104
- node.start,
105
- expression,
106
- point_at_located(node),
107
- 'An optional may not contain an other optional',
108
- "If you did not mean to use an optional type you can use '\\(' to escape the the '('. For more complicated expressions consider using a regular expression instead."
109
- ))
108
+ super(
109
+ build_message(
110
+ node.start,
111
+ expression,
112
+ point_at_located(node),
113
+ 'An optional may not contain an other optional',
114
+ "If you did not mean to use an optional type you can use '\\(' to escape the '('. For more complicated expressions consider using a regular expression instead."
115
+ )
116
+ )
110
117
  end
111
118
  end
112
119
 
113
120
  class TheEndOfLineCannotBeEscaped < CucumberExpressionError
114
121
  def initialize(expression)
115
122
  index = expression.codepoints.length - 1
116
- super(build_message(
117
- index,
118
- expression,
119
- point_at(index),
120
- 'The end of line can not be escaped',
121
- "You can use '\\\\' to escape the the '\\'"
122
- ))
123
+ super(
124
+ build_message(
125
+ index,
126
+ expression,
127
+ point_at(index),
128
+ 'The end of line can not be escaped',
129
+ "You can use '\\\\' to escape the '\\'"
130
+ )
131
+ )
123
132
  end
124
133
  end
125
134
 
@@ -128,45 +137,50 @@ This Cucumber Expression has a problem at column #{index + 1}:
128
137
  begin_symbol = Token::symbol_of(begin_token)
129
138
  end_symbol = Token::symbol_of(end_token)
130
139
  purpose = Token::purpose_of(begin_token)
131
- super(build_message(
132
- current.start,
133
- expression,
134
- point_at_located(current),
135
- "The '#{begin_symbol}' does not have a matching '#{end_symbol}'",
136
- "If you did not intend to use #{purpose} you can use '\\#{begin_symbol}' to escape the #{purpose}"
137
- ))
140
+
141
+ super(
142
+ build_message(
143
+ current.start,
144
+ expression,
145
+ point_at_located(current),
146
+ "The '#{begin_symbol}' does not have a matching '#{end_symbol}'",
147
+ "If you did not intend to use #{purpose} you can use '\\#{begin_symbol}' to escape the #{purpose}"
148
+ )
149
+ )
138
150
  end
139
151
  end
140
152
 
141
153
  class AlternationNotAllowedInOptional < CucumberExpressionError
142
154
  def initialize(expression, current)
143
- super(build_message(
144
- current.start,
145
- expression,
146
- point_at_located(current),
147
- "An alternation can not be used inside an optional",
148
- "You can use '\\/' to escape the the '/'"
149
- ))
155
+ super(
156
+ build_message(
157
+ current.start,
158
+ expression,
159
+ point_at_located(current),
160
+ 'An alternation can not be used inside an optional',
161
+ "If you did not mean to use an alternation you can use '\\/' to escape the '/'. Otherwise rephrase your expression or consider using a regular expression instead."
162
+ )
163
+ )
150
164
  end
151
165
  end
152
166
 
153
167
  class InvalidParameterTypeName < CucumberExpressionError
154
168
  def initialize(type_name)
155
- super("Illegal character in parameter name {#{type_name}}. " +
156
- "Parameter names may not contain '{', '}', '(', ')', '\\' or '/'")
169
+ super("Illegal character in parameter name {#{type_name}}. Parameter names may not contain '{', '}', '(', ')', '\\' or '/'")
157
170
  end
158
171
  end
159
172
 
160
-
161
173
  class InvalidParameterTypeNameInNode < CucumberExpressionError
162
174
  def initialize(expression, token)
163
- super(build_message(
164
- token.start,
165
- expression,
166
- point_at_located(token),
167
- "Parameter names may not contain '{', '}', '(', ')', '\\' or '/'",
168
- "Did you mean to use a regular expression?"
169
- ))
175
+ super(
176
+ build_message(
177
+ token.start,
178
+ expression,
179
+ point_at_located(token),
180
+ "Parameter names may not contain '{', '}', '(', ')', '\\' or '/'",
181
+ 'Did you mean to use a regular expression?'
182
+ )
183
+ )
170
184
  end
171
185
  end
172
186
 
@@ -174,30 +188,34 @@ This Cucumber Expression has a problem at column #{index + 1}:
174
188
  attr_reader :undefined_parameter_type_name
175
189
 
176
190
  def initialize(node, expression, undefined_parameter_type_name)
177
- super(build_message(node.start,
178
- expression,
179
- point_at_located(node),
180
- "Undefined parameter type '#{undefined_parameter_type_name}'",
181
- "Please register a ParameterType for '#{undefined_parameter_type_name}'"))
191
+ super(
192
+ build_message(
193
+ node.start,
194
+ expression,
195
+ point_at_located(node),
196
+ "Undefined parameter type '#{undefined_parameter_type_name}'",
197
+ "Please register a ParameterType for '#{undefined_parameter_type_name}'"
198
+ )
199
+ )
182
200
  @undefined_parameter_type_name = undefined_parameter_type_name
183
201
  end
184
202
  end
185
203
 
186
204
  class AmbiguousParameterTypeError < CucumberExpressionError
187
205
  def initialize(parameter_type_regexp, expression_regexp, parameter_types, generated_expressions)
188
- super(<<-EOM)
189
- Your Regular Expression /#{expression_regexp.source}/
190
- matches multiple parameter types with regexp /#{parameter_type_regexp}/:
191
- #{parameter_type_names(parameter_types)}
206
+ super(<<~ERROR)
207
+ Your Regular Expression /#{expression_regexp.source}/
208
+ matches multiple parameter types with regexp /#{parameter_type_regexp}/:
209
+ #{parameter_type_names(parameter_types)}
192
210
 
193
- I couldn't decide which one to use. You have two options:
211
+ I couldn't decide which one to use. You have two options:
194
212
 
195
- 1) Use a Cucumber Expression instead of a Regular Expression. Try one of these:
196
- #{expressions(generated_expressions)}
213
+ 1) Use a Cucumber Expression instead of a Regular Expression. Try one of these:
214
+ #{expressions(generated_expressions)}
197
215
 
198
- 2) Make one of the parameter types preferential and continue to use a Regular Expression.
216
+ 2) Make one of the parameter types preferential and continue to use a Regular Expression.
199
217
 
200
- EOM
218
+ ERROR
201
219
  end
202
220
 
203
221
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/cucumber_expressions/errors'
2
4
  require 'cucumber/cucumber_expressions/cucumber_expression'
3
5
  require 'cucumber/cucumber_expressions/regular_expression'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cucumber
2
4
  module CucumberExpressions
3
5
  class GeneratedExpression
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cucumber
2
4
  module CucumberExpressions
3
5
  class Group
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/cucumber_expressions/group'
2
4
 
3
5
  module Cucumber
@@ -16,7 +18,7 @@ module Cucumber
16
18
 
17
19
  def build(match, group_indices)
18
20
  group_index = group_indices.next
19
- children = @group_builders.map {|gb| gb.build(match, group_indices)}
21
+ children = @group_builders.map { |gb| gb.build(match, group_indices) }
20
22
  Group.new(match[group_index], match.offset(group_index)[0], match.offset(group_index)[1], children)
21
23
  end
22
24
 
@@ -1,34 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/cucumber_expressions/errors'
2
4
 
3
5
  module Cucumber
4
6
  module CucumberExpressions
5
7
  class ParameterType
6
- ILLEGAL_PARAMETER_NAME_PATTERN = /([\[\]()$.|?*+])/
7
- UNESCAPE_PATTERN = /(\\([\[$.|?*+\]]))/
8
+ ILLEGAL_PARAMETER_NAME_PATTERN = /([\[\]()$.|?*+])/.freeze
9
+ UNESCAPE_PATTERN = /(\\([\[$.|?*+\]]))/.freeze
8
10
 
9
- attr_reader :name, :type, :regexps
11
+ attr_reader :name, :type, :transformer, :use_for_snippets, :prefer_for_regexp_match, :regexps
10
12
 
11
13
  def self.check_parameter_type_name(type_name)
12
- unless is_valid_parameter_type_name(type_name)
13
- raise CucumberExpressionError.new("Illegal character in parameter name {#{type_name}}. Parameter names may not contain '[]()$.|?*+'")
14
- end
14
+ raise CucumberExpressionError.new("Illegal character in parameter name {#{type_name}}. Parameter names may not contain '[]()$.|?*+'") unless is_valid_parameter_type_name(type_name)
15
15
  end
16
16
 
17
17
  def self.is_valid_parameter_type_name(type_name)
18
- unescaped_type_name = type_name.gsub(UNESCAPE_PATTERN) do
19
- $2
20
- end
18
+ unescaped_type_name = type_name.gsub(UNESCAPE_PATTERN) { Regexp.last_match(2) }
21
19
  !(ILLEGAL_PARAMETER_NAME_PATTERN =~ unescaped_type_name)
22
20
  end
23
21
 
24
- def prefer_for_regexp_match?
25
- @prefer_for_regexp_match
26
- end
27
-
28
- def use_for_snippets?
29
- @use_for_snippets
30
- end
31
-
32
22
  # Create a new Parameter
33
23
  #
34
24
  # @param name the name of the parameter type
@@ -55,14 +45,14 @@ module Cucumber
55
45
  end
56
46
 
57
47
  def <=>(other)
58
- return -1 if prefer_for_regexp_match? && !other.prefer_for_regexp_match?
59
- return 1 if other.prefer_for_regexp_match? && !prefer_for_regexp_match?
48
+ return -1 if prefer_for_regexp_match && !other.prefer_for_regexp_match
49
+ return 1 if other.prefer_for_regexp_match && !prefer_for_regexp_match
50
+
60
51
  return name <=> other.name
61
52
  end
62
53
 
63
54
  private
64
55
 
65
-
66
56
  def string_array(regexps)
67
57
  array = regexps.is_a?(Array) ? regexps : [regexps]
68
58
  array.map { |regexp| regexp.is_a?(String) ? regexp : regexp_source(regexp) }
@@ -70,14 +60,12 @@ module Cucumber
70
60
 
71
61
  def regexp_source(regexp)
72
62
  [
73
- 'EXTENDED',
74
- 'IGNORECASE',
75
- 'MULTILINE'
63
+ 'EXTENDED',
64
+ 'IGNORECASE',
65
+ 'MULTILINE'
76
66
  ].each do |option_name|
77
67
  option = Regexp.const_get(option_name)
78
- if regexp.options & option != 0
79
- raise CucumberExpressionError.new("ParameterType Regexps can't use option Regexp::#{option_name}")
80
- end
68
+ raise CucumberExpressionError.new("ParameterType Regexps can't use option Regexp::#{option_name}") if regexp.options & option != 0
81
69
  end
82
70
  regexp.source
83
71
  end
@@ -1,20 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cucumber
2
4
  module CucumberExpressions
3
5
  class ParameterTypeMatcher
4
6
  attr_reader :parameter_type
5
7
 
6
- def initialize(parameter_type, regexp, text, match_position=0)
8
+ def initialize(parameter_type, regexp, text, match_position = 0)
7
9
  @parameter_type, @regexp, @text = parameter_type, regexp, text
8
10
  @match = @regexp.match(@text, match_position)
9
11
  end
10
12
 
11
13
  def advance_to(new_match_position)
12
- (new_match_position...@text.length).each {|advancedPos|
13
- matcher = self.class.new(parameter_type, @regexp, @text, advancedPos)
14
- if matcher.find && matcher.full_word?
15
- return matcher
16
- end
17
- }
14
+ (new_match_position...@text.length).each do |advanced_position|
15
+ matcher = self.class.new(parameter_type, @regexp, @text, advanced_position)
16
+ return matcher if matcher.find && matcher.full_word?
17
+ end
18
18
 
19
19
  self.class.new(parameter_type, @regexp, @text, @text.length)
20
20
  end
@@ -38,8 +38,10 @@ module Cucumber
38
38
  def <=>(other)
39
39
  pos_comparison = start <=> other.start
40
40
  return pos_comparison if pos_comparison != 0
41
+
41
42
  length_comparison = other.group.length <=> group.length
42
43
  return length_comparison if length_comparison != 0
44
+
43
45
  0
44
46
  end
45
47
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/cucumber_expressions/parameter_type'
2
4
  require 'cucumber/cucumber_expressions/errors'
3
5
  require 'cucumber/cucumber_expressions/cucumber_expression_generator'
@@ -6,27 +8,27 @@ require 'bigdecimal'
6
8
  module Cucumber
7
9
  module CucumberExpressions
8
10
  class ParameterTypeRegistry
9
- INTEGER_REGEXPS = [/-?\d+/, /\d+/]
10
- FLOAT_REGEXP = /(?=.*\d.*)[-+]?\d*(?:\.(?=\d.*))?\d*(?:\d+[E][-+]?\d+)?/
11
- WORD_REGEXP = /[^\s]+/
12
- STRING_REGEXP = /"([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'/
13
- ANONYMOUS_REGEXP = /.*/
11
+ INTEGER_REGEXPS = [/-?\d+/, /\d+/].freeze
12
+ FLOAT_REGEXP = /(?=.*\d.*)[-+]?\d*(?:\.(?=\d.*))?\d*(?:\d+[E][-+]?\d+)?/.freeze
13
+ WORD_REGEXP = /[^\s]+/.freeze
14
+ STRING_REGEXP = /"([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'/.freeze
15
+ ANONYMOUS_REGEXP = /.*/.freeze
14
16
 
15
17
  def initialize
16
18
  @parameter_type_by_name = {}
17
- @parameter_types_by_regexp = Hash.new {|hash, regexp| hash[regexp] = []}
19
+ @parameter_types_by_regexp = Hash.new { |hash, regexp| hash[regexp] = [] }
18
20
 
19
- define_parameter_type(ParameterType.new('int', INTEGER_REGEXPS, Integer, lambda {|s = nil| s && s.to_i}, true, true))
20
- define_parameter_type(ParameterType.new('float', FLOAT_REGEXP, Float, lambda {|s = nil| s && s.to_f}, true, false))
21
- define_parameter_type(ParameterType.new('word', WORD_REGEXP, String, lambda {|s = nil| s}, false, false))
22
- define_parameter_type(ParameterType.new('string', STRING_REGEXP, String, lambda { |s1, s2| arg = s1 != nil ? s1 : s2; arg.gsub(/\\"/, '"').gsub(/\\'/, "'")}, true, false))
23
- define_parameter_type(ParameterType.new('', ANONYMOUS_REGEXP, String, lambda {|s = nil| s}, false, true))
24
- define_parameter_type(ParameterType.new('bigdecimal', FLOAT_REGEXP, BigDecimal, lambda {|s = nil| BigDecimal(s)}, false, false))
25
- define_parameter_type(ParameterType.new('biginteger', INTEGER_REGEXPS, Integer, lambda {|s = nil| s && s.to_i}, false, false))
26
- define_parameter_type(ParameterType.new('byte', INTEGER_REGEXPS, Integer, lambda {|s = nil| s && s.to_i}, false, false))
27
- define_parameter_type(ParameterType.new('short', INTEGER_REGEXPS, Integer, lambda {|s = nil| s && s.to_i}, false, false))
28
- define_parameter_type(ParameterType.new('long', INTEGER_REGEXPS, Integer, lambda {|s = nil| s && s.to_i}, false, false))
29
- define_parameter_type(ParameterType.new('double', FLOAT_REGEXP, Float, lambda {|s = nil| s && s.to_f}, false, false))
21
+ define_parameter_type(ParameterType.new('int', INTEGER_REGEXPS, Integer, ->(s = nil) { s && s.to_i }, true, true))
22
+ define_parameter_type(ParameterType.new('float', FLOAT_REGEXP, Float, ->(s = nil) { s && s.to_f }, true, false))
23
+ define_parameter_type(ParameterType.new('word', WORD_REGEXP, String, ->(s = nil) { s }, false, false))
24
+ define_parameter_type(ParameterType.new('string', STRING_REGEXP, String, ->(s1, s2) { arg = s1 != nil ? s1 : s2; arg.gsub('\\"', '"').gsub("\\'", "'") }, true, false))
25
+ define_parameter_type(ParameterType.new('', ANONYMOUS_REGEXP, String, ->(s = nil) { s }, false, true))
26
+ define_parameter_type(ParameterType.new('bigdecimal', FLOAT_REGEXP, BigDecimal, ->(s = nil) { BigDecimal(s) }, false, false))
27
+ define_parameter_type(ParameterType.new('biginteger', INTEGER_REGEXPS, Integer, ->(s = nil) { s && s.to_i }, false, false))
28
+ define_parameter_type(ParameterType.new('byte', INTEGER_REGEXPS, Integer, ->(s = nil) { s && s.to_i }, false, false))
29
+ define_parameter_type(ParameterType.new('short', INTEGER_REGEXPS, Integer, ->(s = nil) { s && s.to_i }, false, false))
30
+ define_parameter_type(ParameterType.new('long', INTEGER_REGEXPS, Integer, ->(s = nil) { s && s.to_i }, false, false))
31
+ define_parameter_type(ParameterType.new('double', FLOAT_REGEXP, Float, ->(s = nil) { s && s.to_f }, false, false))
30
32
  end
31
33
 
32
34
  def lookup_by_type_name(name)
@@ -36,7 +38,8 @@ module Cucumber
36
38
  def lookup_by_regexp(parameter_type_regexp, expression_regexp, text)
37
39
  parameter_types = @parameter_types_by_regexp[parameter_type_regexp]
38
40
  return nil if parameter_types.nil?
39
- if parameter_types.length > 1 && !parameter_types[0].prefer_for_regexp_match?
41
+
42
+ if parameter_types.length > 1 && !parameter_types[0].prefer_for_regexp_match
40
43
  # We don't do this check on insertion because we only want to restrict
41
44
  # ambiguity when we look up by Regexp. Users of CucumberExpression should
42
45
  # not be restricted.
@@ -54,7 +57,7 @@ module Cucumber
54
57
  if parameter_type.name != nil
55
58
  if @parameter_type_by_name.has_key?(parameter_type.name)
56
59
  if parameter_type.name.length == 0
57
- raise CucumberExpressionError.new("The anonymous parameter type has already been defined")
60
+ raise CucumberExpressionError.new('The anonymous parameter type has already been defined')
58
61
  else
59
62
  raise CucumberExpressionError.new("There is already a parameter with name #{parameter_type.name}")
60
63
  end
@@ -64,14 +67,16 @@ module Cucumber
64
67
 
65
68
  parameter_type.regexps.each do |parameter_type_regexp|
66
69
  parameter_types = @parameter_types_by_regexp[parameter_type_regexp]
67
- if parameter_types.any? && parameter_types[0].prefer_for_regexp_match? && parameter_type.prefer_for_regexp_match?
68
- raise CucumberExpressionError.new("There can only be one preferential parameter type per regexp. The regexp /#{parameter_type_regexp}/ is used for two preferential parameter types, {#{parameter_types[0].name}} and {#{parameter_type.name}}")
70
+ if parameter_types.any? && parameter_types[0].prefer_for_regexp_match && parameter_type.prefer_for_regexp_match
71
+ raise CucumberExpressionError.new(
72
+ "There can only be one preferential parameter type per regexp. The regexp /#{parameter_type_regexp}/ is used for two: {#{parameter_types[0].name}} and {#{parameter_type.name}}"
73
+ )
69
74
  end
75
+
70
76
  parameter_types.push(parameter_type)
71
77
  parameter_types.sort!
72
78
  end
73
79
  end
74
-
75
80
  end
76
81
  end
77
82
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/cucumber_expressions/argument'
2
4
  require 'cucumber/cucumber_expressions/parameter_type'
3
5
  require 'cucumber/cucumber_expressions/tree_regexp'
@@ -5,7 +7,6 @@ require 'cucumber/cucumber_expressions/tree_regexp'
5
7
  module Cucumber
6
8
  module CucumberExpressions
7
9
  class RegularExpression
8
-
9
10
  def initialize(expression_regexp, parameter_type_registry)
10
11
  @expression_regexp = expression_regexp
11
12
  @parameter_type_registry = parameter_type_registry
@@ -23,7 +24,7 @@ module Cucumber
23
24
  nil,
24
25
  parameter_type_regexp,
25
26
  String,
26
- lambda {|*s| s[0]},
27
+ ->(*s) { s[0] },
27
28
  false,
28
29
  false
29
30
  )
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/cucumber_expressions/group_builder'
2
4
  require 'cucumber/cucumber_expressions/errors'
3
5
 
@@ -14,18 +16,19 @@ module Cucumber
14
16
  def match(s)
15
17
  match = @regexp.match(s)
16
18
  return nil if match.nil?
19
+
17
20
  group_indices = (0..match.length).to_a.to_enum
18
21
  @group_builder.build(match, group_indices)
19
22
  end
20
23
 
21
24
  private def is_non_capturing(source, i)
22
25
  # Regex is valid. Bounds check not required.
23
- if source[i+1] != '?'
26
+ if source[i + 1] != '?'
24
27
  # (X)
25
28
  return false
26
29
  end
27
30
 
28
- if source[i+2] != '<'
31
+ if source[i + 2] != '<'
29
32
  # (?:X)
30
33
  # (?idmsuxU-idmsuxU)
31
34
  # (?idmsux-idmsux:X)
@@ -35,14 +38,14 @@ module Cucumber
35
38
  return true
36
39
  end
37
40
 
38
- if source[i+3] == '=' || source[i+3] == '!'
41
+ if source[i + 3] == '=' || source[i + 3] == '!'
39
42
  # (?<=X)
40
43
  # (?<!X)
41
44
  return true
42
45
  end
43
46
 
44
47
  # (?<name>X)
45
- raise CucumberExpressionError.new("Named capture groups are not supported. See https://github.com/cucumber/cucumber/issues/329")
48
+ raise CucumberExpressionError.new('Named capture groups are not supported. See https://github.com/cucumber/cucumber/issues/329')
46
49
  end
47
50
 
48
51
  private def create_group_builder(regexp)
@@ -60,9 +63,7 @@ module Cucumber
60
63
  group_start_stack.push(i)
61
64
  group_builder = GroupBuilder.new
62
65
  non_capturing = is_non_capturing(source, i)
63
- if non_capturing
64
- group_builder.set_non_capturing!
65
- end
66
+ group_builder.set_non_capturing! if non_capturing
66
67
  stack.push(group_builder)
67
68
  elsif c == ')' && !escaping && !char_class
68
69
  gb = stack.pop
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cucumber/cucumber_expressions/argument'
2
4
  require 'cucumber/cucumber_expressions/tree_regexp'
3
5
  require 'cucumber/cucumber_expressions/parameter_type_registry'
@@ -8,9 +10,9 @@ module Cucumber
8
10
  it 'exposes parameter_type' do
9
11
  tree_regexp = TreeRegexp.new(/three (.*) mice/)
10
12
  parameter_type_registry = ParameterTypeRegistry.new
11
- arguments = Argument.build(tree_regexp, "three blind mice", [parameter_type_registry.lookup_by_type_name("string")])
13
+ arguments = described_class.build(tree_regexp, 'three blind mice', [parameter_type_registry.lookup_by_type_name('string')])
12
14
  argument = arguments[0]
13
- expect(argument.parameter_type.name).to eq("string")
15
+ expect(argument.parameter_type.name).to eq('string')
14
16
  end
15
17
  end
16
18
  end