cucumber-cucumber-expressions 16.1.2 → 17.0.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +27 -0
- data/.rubocop_todo.yml +524 -0
- data/Gemfile +2 -1
- data/Rakefile +4 -17
- data/VERSION +1 -1
- data/cucumber-cucumber-expressions.gemspec +11 -9
- data/lib/cucumber/cucumber_expressions/argument.rb +6 -3
- data/lib/cucumber/cucumber_expressions/ast.rb +24 -59
- data/lib/cucumber/cucumber_expressions/combinatorial_generated_expression_factory.rb +6 -13
- data/lib/cucumber/cucumber_expressions/cucumber_expression.rb +9 -11
- data/lib/cucumber/cucumber_expressions/cucumber_expression_generator.rb +7 -11
- data/lib/cucumber/cucumber_expressions/cucumber_expression_parser.rb +37 -53
- data/lib/cucumber/cucumber_expressions/cucumber_expression_tokenizer.rb +13 -18
- data/lib/cucumber/cucumber_expressions/errors.rb +119 -101
- data/lib/cucumber/cucumber_expressions/expression_factory.rb +2 -0
- data/lib/cucumber/cucumber_expressions/generated_expression.rb +2 -0
- data/lib/cucumber/cucumber_expressions/group.rb +2 -0
- data/lib/cucumber/cucumber_expressions/group_builder.rb +2 -0
- data/lib/cucumber/cucumber_expressions/parameter_type.rb +13 -23
- data/lib/cucumber/cucumber_expressions/parameter_type_matcher.rb +8 -6
- data/lib/cucumber/cucumber_expressions/parameter_type_registry.rb +23 -20
- data/lib/cucumber/cucumber_expressions/regular_expression.rb +3 -2
- data/lib/cucumber/cucumber_expressions/tree_regexp.rb +5 -4
- data/spec/cucumber/cucumber_expressions/argument_spec.rb +4 -2
- data/spec/cucumber/cucumber_expressions/combinatorial_generated_expression_factory_test.rb +7 -6
- data/spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb +104 -101
- data/spec/cucumber/cucumber_expressions/cucumber_expression_parser_spec.rb +2 -0
- data/spec/cucumber/cucumber_expressions/cucumber_expression_spec.rb +84 -87
- data/spec/cucumber/cucumber_expressions/cucumber_expression_tokenizer_spec.rb +3 -1
- data/spec/cucumber/cucumber_expressions/cucumber_expression_transformation_spec.rb +2 -0
- data/spec/cucumber/cucumber_expressions/custom_parameter_type_spec.rb +79 -60
- data/spec/cucumber/cucumber_expressions/expression_factory_spec.rb +2 -0
- data/spec/cucumber/cucumber_expressions/parameter_type_registry_spec.rb +43 -48
- data/spec/cucumber/cucumber_expressions/parameter_type_spec.rb +3 -1
- data/spec/cucumber/cucumber_expressions/regular_expression_spec.rb +37 -28
- data/spec/cucumber/cucumber_expressions/tree_regexp_spec.rb +23 -22
- metadata +21 -9
- data/.rspec +0 -1
- data/scripts/update-gemspec +0 -32
- data/spec/capture_warnings.rb +0 -74
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cucumber/cucumber_expressions/cucumber_expression'
|
2
4
|
require 'cucumber/cucumber_expressions/regular_expression'
|
3
5
|
require 'cucumber/cucumber_expressions/parameter_type_registry'
|
@@ -40,54 +42,56 @@ module Cucumber
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
describe
|
45
|
+
describe 'Custom parameter type' do
|
44
46
|
before do
|
45
47
|
parameter_type_registry = ParameterTypeRegistry.new
|
46
|
-
parameter_type_registry.define_parameter_type(
|
48
|
+
parameter_type_registry.define_parameter_type(
|
49
|
+
ParameterType.new(
|
47
50
|
'color', # name
|
48
51
|
/red|blue|yellow/, # regexp
|
49
52
|
Color, # type
|
50
|
-
|
53
|
+
->(s) { Color.new(s)}, # transform
|
51
54
|
true, # use_for_snippets
|
52
55
|
false # prefer_for_regexp_match
|
53
|
-
|
56
|
+
)
|
57
|
+
)
|
54
58
|
@parameter_type_registry = parameter_type_registry
|
55
59
|
end
|
56
60
|
|
57
|
-
it
|
61
|
+
it 'throws exception for illegal character in parameter name' do
|
58
62
|
expect do
|
59
63
|
ParameterType.new(
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
'[string]',
|
65
|
+
/.*/,
|
66
|
+
String,
|
67
|
+
->(s) { s},
|
68
|
+
true,
|
69
|
+
false
|
66
70
|
)
|
67
71
|
end.to raise_error("Illegal character in parameter name {[string]}. Parameter names may not contain '[]()$.|?*+'")
|
68
72
|
end
|
69
73
|
|
70
74
|
describe CucumberExpression do
|
71
|
-
it
|
72
|
-
expression = CucumberExpression.new(
|
73
|
-
transformed_argument_value = expression.match(
|
75
|
+
it 'matches parameters with custom parameter type' do
|
76
|
+
expression = CucumberExpression.new('I have a {color} ball', @parameter_type_registry)
|
77
|
+
transformed_argument_value = expression.match('I have a red ball')[0].value(nil)
|
78
|
+
|
74
79
|
expect(transformed_argument_value).to eq(Color.new('red'))
|
75
80
|
end
|
76
81
|
|
77
|
-
it
|
78
|
-
@parameter_type_registry.define_parameter_type(
|
82
|
+
it 'matches parameters with multiple capture groups' do
|
83
|
+
@parameter_type_registry.define_parameter_type(
|
84
|
+
ParameterType.new(
|
79
85
|
'coordinate',
|
80
86
|
/(\d+),\s*(\d+),\s*(\d+)/,
|
81
87
|
Coordinate,
|
82
|
-
|
88
|
+
->(x, y, z) { Coordinate.new(x.to_i, y.to_i, z.to_i)},
|
83
89
|
true,
|
84
90
|
false
|
85
|
-
|
86
|
-
|
87
|
-
expression = CucumberExpression.new(
|
88
|
-
'A {int} thick line from {coordinate} to {coordinate}',
|
89
|
-
@parameter_type_registry
|
91
|
+
)
|
90
92
|
)
|
93
|
+
|
94
|
+
expression = CucumberExpression.new('A {int} thick line from {coordinate} to {coordinate}', @parameter_type_registry)
|
91
95
|
args = expression.match('A 5 thick line from 10,20,30 to 40,50,60')
|
92
96
|
|
93
97
|
thick = args[0].value(nil)
|
@@ -100,95 +104,110 @@ module Cucumber
|
|
100
104
|
expect(to).to eq(Coordinate.new(40, 50, 60))
|
101
105
|
end
|
102
106
|
|
103
|
-
it
|
107
|
+
it 'matches parameters with custom parameter type using optional capture group' do
|
104
108
|
parameter_type_registry = ParameterTypeRegistry.new
|
105
|
-
parameter_type_registry.define_parameter_type(
|
109
|
+
parameter_type_registry.define_parameter_type(
|
110
|
+
ParameterType.new(
|
106
111
|
'color',
|
107
112
|
[/red|blue|yellow/, /(?:dark|light) (?:red|blue|yellow)/],
|
108
113
|
Color,
|
109
|
-
|
114
|
+
->(s) { Color.new(s)},
|
110
115
|
true,
|
111
116
|
false
|
112
|
-
|
113
|
-
|
114
|
-
|
117
|
+
)
|
118
|
+
)
|
119
|
+
expression = CucumberExpression.new('I have a {color} ball', parameter_type_registry)
|
120
|
+
transformed_argument_value = expression.match('I have a dark red ball')[0].value(nil)
|
121
|
+
|
115
122
|
expect(transformed_argument_value).to eq(Color.new('dark red'))
|
116
123
|
end
|
117
124
|
|
118
|
-
it
|
119
|
-
@parameter_type_registry.define_parameter_type(
|
125
|
+
it 'defers transformation until queried from argument' do
|
126
|
+
@parameter_type_registry.define_parameter_type(
|
127
|
+
ParameterType.new(
|
120
128
|
'throwing',
|
121
129
|
/bad/,
|
122
130
|
CssColor,
|
123
|
-
|
131
|
+
->(s) { raise "Can't transform [#{s}]"},
|
124
132
|
true,
|
125
133
|
false
|
126
|
-
|
127
|
-
|
128
|
-
|
134
|
+
)
|
135
|
+
)
|
136
|
+
expression = CucumberExpression.new('I have a {throwing} parameter', @parameter_type_registry)
|
137
|
+
args = expression.match('I have a bad parameter')
|
138
|
+
|
129
139
|
expect {args[0].value(nil)}.to raise_error("Can't transform [bad]")
|
130
140
|
end
|
131
141
|
|
132
|
-
describe
|
133
|
-
it
|
142
|
+
describe 'conflicting parameter type' do
|
143
|
+
it 'is detected for type name' do
|
134
144
|
expect {
|
135
|
-
@parameter_type_registry.define_parameter_type(
|
145
|
+
@parameter_type_registry.define_parameter_type(
|
146
|
+
ParameterType.new(
|
136
147
|
'color',
|
137
148
|
/.*/,
|
138
149
|
CssColor,
|
139
|
-
|
150
|
+
->(s) { CssColor.new(s)},
|
140
151
|
true,
|
141
152
|
false
|
142
|
-
|
143
|
-
|
153
|
+
)
|
154
|
+
)
|
155
|
+
}.to raise_error('There is already a parameter with name color')
|
144
156
|
end
|
145
157
|
|
146
|
-
it
|
147
|
-
@parameter_type_registry.define_parameter_type(
|
158
|
+
it 'is not detected for type' do
|
159
|
+
@parameter_type_registry.define_parameter_type(
|
160
|
+
ParameterType.new(
|
148
161
|
'whatever',
|
149
162
|
/.*/,
|
150
163
|
Color,
|
151
|
-
|
164
|
+
->(s) { Color.new(s)},
|
152
165
|
false,
|
153
166
|
false
|
154
|
-
|
167
|
+
)
|
168
|
+
)
|
155
169
|
end
|
156
170
|
|
157
|
-
it
|
158
|
-
@parameter_type_registry.define_parameter_type(
|
171
|
+
it 'is not detected for regexp' do
|
172
|
+
@parameter_type_registry.define_parameter_type(
|
173
|
+
ParameterType.new(
|
159
174
|
'css-color',
|
160
175
|
/red|blue|yellow/,
|
161
176
|
CssColor,
|
162
|
-
|
177
|
+
->(s) { CssColor.new(s)},
|
163
178
|
true,
|
164
179
|
false
|
165
|
-
|
180
|
+
)
|
181
|
+
)
|
182
|
+
css_color = CucumberExpression.new('I have a {css-color} ball', @parameter_type_registry)
|
183
|
+
css_color_value = css_color.match('I have a blue ball')[0].value(nil)
|
166
184
|
|
167
|
-
|
168
|
-
css_color_value = css_color.match("I have a blue ball")[0].value(nil)
|
169
|
-
expect(css_color_value).to eq(CssColor.new("blue"))
|
185
|
+
expect(css_color_value).to eq(CssColor.new('blue'))
|
170
186
|
|
171
|
-
color = CucumberExpression.new(
|
172
|
-
color_value = color.match(
|
173
|
-
|
187
|
+
color = CucumberExpression.new('I have a {color} ball', @parameter_type_registry)
|
188
|
+
color_value = color.match('I have a blue ball')[0].value(nil)
|
189
|
+
|
190
|
+
expect(color_value).to eq(Color.new('blue'))
|
174
191
|
end
|
175
192
|
end
|
176
193
|
end
|
177
194
|
|
178
195
|
describe RegularExpression do
|
179
|
-
it
|
196
|
+
it 'matches arguments with custom parameter types without a name' do
|
180
197
|
parameter_type_registry = ParameterTypeRegistry.new
|
181
|
-
parameter_type_registry.define_parameter_type(
|
198
|
+
parameter_type_registry.define_parameter_type(
|
199
|
+
ParameterType.new(
|
182
200
|
nil,
|
183
201
|
/red|blue|yellow/,
|
184
202
|
Color,
|
185
|
-
|
203
|
+
->(s) { Color.new(s)},
|
186
204
|
true,
|
187
205
|
false
|
188
|
-
|
189
|
-
|
206
|
+
)
|
207
|
+
)
|
190
208
|
expression = RegularExpression.new(/I have a (red|blue|yellow) ball/, parameter_type_registry)
|
191
|
-
value = expression.match(
|
209
|
+
value = expression.match('I have a red ball')[0].value(nil)
|
210
|
+
|
192
211
|
expect(value).to eq(Color.new('red'))
|
193
212
|
end
|
194
213
|
end
|
@@ -1,20 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cucumber/cucumber_expressions/parameter_type_registry'
|
2
4
|
require 'cucumber/cucumber_expressions/parameter_type'
|
3
5
|
require 'cucumber/cucumber_expressions/errors'
|
4
6
|
|
5
7
|
module Cucumber
|
6
8
|
module CucumberExpressions
|
9
|
+
CAPITALISED_WORD = /[A-Z]+\w+/.freeze
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
class
|
11
|
-
end
|
12
|
-
|
13
|
-
class Person
|
14
|
-
end
|
15
|
-
|
16
|
-
class Place
|
17
|
-
end
|
11
|
+
class Name; end
|
12
|
+
class Person; end
|
13
|
+
class Place; end
|
18
14
|
|
19
15
|
describe ParameterTypeRegistry do
|
20
16
|
before do
|
@@ -22,65 +18,64 @@ module Cucumber
|
|
22
18
|
end
|
23
19
|
|
24
20
|
it 'does not allow more than one prefer_for_regexp_match parameter type for each regexp' do
|
25
|
-
@registry.define_parameter_type(ParameterType.new(
|
26
|
-
@registry.define_parameter_type(ParameterType.new(
|
21
|
+
@registry.define_parameter_type(ParameterType.new('name', CAPITALISED_WORD, Name, ->(s) { Name.new}, true, true))
|
22
|
+
@registry.define_parameter_type(ParameterType.new('person', CAPITALISED_WORD, Person, ->(s) { Person.new}, true, false))
|
27
23
|
expect do
|
28
|
-
@registry.define_parameter_type(ParameterType.new(
|
24
|
+
@registry.define_parameter_type(ParameterType.new('place', CAPITALISED_WORD, Place, ->(s) { Place.new}, true, true))
|
29
25
|
end.to raise_error(
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
CucumberExpressionError,
|
27
|
+
'There can only be one preferential parameter type per regexp. The regexp /[A-Z]+\\w+/ is used for two preferential parameter types, {name} and {place}'
|
28
|
+
)
|
33
29
|
end
|
34
30
|
|
35
31
|
it 'looks up prefer_for_regexp_match parameter type by regexp' do
|
36
|
-
name = ParameterType.new(
|
37
|
-
person = ParameterType.new(
|
38
|
-
place = ParameterType.new(
|
32
|
+
name = ParameterType.new('name', CAPITALISED_WORD, Name, ->(s) { Name.new}, true, false)
|
33
|
+
person = ParameterType.new('person', CAPITALISED_WORD, Person, ->(s) { Person.new}, true, true)
|
34
|
+
place = ParameterType.new('place', CAPITALISED_WORD, Place, ->(s) { Place.new}, true, false)
|
39
35
|
|
40
36
|
@registry.define_parameter_type(name)
|
41
37
|
@registry.define_parameter_type(person)
|
42
38
|
@registry.define_parameter_type(place)
|
43
39
|
|
44
|
-
expect(@registry.lookup_by_regexp(CAPITALISED_WORD.source, /([A-Z]+\w+) and ([A-Z]+\w+)/,
|
40
|
+
expect(@registry.lookup_by_regexp(CAPITALISED_WORD.source, /([A-Z]+\w+) and ([A-Z]+\w+)/, 'Lisa and Bob')).to eq(person)
|
45
41
|
end
|
46
42
|
|
47
43
|
it 'throws ambiguous exception when no parameter types are prefer_for_regexp_match' do
|
48
|
-
name = ParameterType.new(
|
49
|
-
person = ParameterType.new(
|
50
|
-
place = ParameterType.new(
|
44
|
+
name = ParameterType.new('name', CAPITALISED_WORD, Name, ->(s) { Name.new}, true, false)
|
45
|
+
person = ParameterType.new('person', CAPITALISED_WORD, Person, ->(s) { Person.new}, true, false)
|
46
|
+
place = ParameterType.new('place', CAPITALISED_WORD, Place, ->(s) { Place.new}, true, false)
|
51
47
|
|
52
48
|
@registry.define_parameter_type(name)
|
53
49
|
@registry.define_parameter_type(person)
|
54
50
|
@registry.define_parameter_type(place)
|
55
51
|
|
56
52
|
expect do
|
57
|
-
expect(@registry.lookup_by_regexp(CAPITALISED_WORD.source, /([A-Z]+\w+) and ([A-Z]+\w+)/,
|
53
|
+
expect(@registry.lookup_by_regexp(CAPITALISED_WORD.source, /([A-Z]+\w+) and ([A-Z]+\w+)/, 'Lisa and Bob')).to eq(person)
|
58
54
|
end.to raise_error(
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
55
|
+
CucumberExpressionError,
|
56
|
+
"Your Regular Expression /([A-Z]+\\w+) and ([A-Z]+\\w+)/\n" \
|
57
|
+
"matches multiple parameter types with regexp /[A-Z]+\\w+/:\n" \
|
58
|
+
" {name}\n" \
|
59
|
+
" {person}\n" \
|
60
|
+
" {place}\n" \
|
61
|
+
"\n" \
|
62
|
+
"I couldn't decide which one to use. You have two options:\n" \
|
63
|
+
"\n" \
|
64
|
+
"1) Use a Cucumber Expression instead of a Regular Expression. Try one of these:\n" \
|
65
|
+
" {name} and {name}\n" \
|
66
|
+
" {name} and {person}\n" \
|
67
|
+
" {name} and {place}\n" \
|
68
|
+
" {person} and {name}\n" \
|
69
|
+
" {person} and {person}\n" \
|
70
|
+
" {person} and {place}\n" \
|
71
|
+
" {place} and {name}\n" \
|
72
|
+
" {place} and {person}\n" \
|
73
|
+
" {place} and {place}\n" \
|
74
|
+
"\n" \
|
75
|
+
"2) Make one of the parameter types preferential and continue to use a Regular Expression.\n" \
|
76
|
+
"\n"
|
77
|
+
)
|
82
78
|
end
|
83
79
|
end
|
84
80
|
end
|
85
81
|
end
|
86
|
-
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cucumber/cucumber_expressions/parameter_type'
|
2
4
|
|
3
5
|
module Cucumber
|
@@ -5,7 +7,7 @@ module Cucumber
|
|
5
7
|
describe ParameterType do
|
6
8
|
it 'does not allow ignore flag on regexp' do
|
7
9
|
expect do
|
8
|
-
ParameterType.new(
|
10
|
+
ParameterType.new('case-insensitive', /[a-z]+/i, String, ->(s) { s}, true, true)
|
9
11
|
end.to raise_error(
|
10
12
|
CucumberExpressionError,
|
11
13
|
"ParameterType Regexps can't use option Regexp::IGNORECASE")
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
require 'cucumber/cucumber_expressions/regular_expression'
|
3
5
|
require 'cucumber/cucumber_expressions/parameter_type_registry'
|
@@ -7,68 +9,74 @@ module Cucumber
|
|
7
9
|
describe RegularExpression do
|
8
10
|
Dir['../testdata/regular-expression/matching/*.yaml'].each do |path|
|
9
11
|
expectation = YAML.load_file(path)
|
12
|
+
|
10
13
|
it "matches #{path}" do
|
11
14
|
parameter_registry = ParameterTypeRegistry.new
|
12
15
|
expression = RegularExpression.new(Regexp.new(expectation['expression']), parameter_registry)
|
13
16
|
matches = expression.match(expectation['text'])
|
14
17
|
values = matches.map { |arg| arg.value(nil) }
|
18
|
+
|
15
19
|
expect(values).to eq(expectation['expected_args'])
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
19
|
-
it
|
20
|
-
expect(
|
23
|
+
it 'does not transform by default' do
|
24
|
+
expect(match(/(\d\d)/, '22')).to eq(['22'])
|
21
25
|
end
|
22
26
|
|
23
|
-
it
|
24
|
-
expect(
|
27
|
+
it 'does not transform anonymous' do
|
28
|
+
expect(match(/(.*)/, '22')).to eq(['22'])
|
25
29
|
end
|
26
30
|
|
27
|
-
it
|
28
|
-
expect(
|
31
|
+
it 'transforms negative int' do
|
32
|
+
expect(match(/(-?\d+)/, '-22')).to eq([-22])
|
29
33
|
end
|
30
34
|
|
31
|
-
it
|
32
|
-
expect(
|
35
|
+
it 'transforms positive int' do
|
36
|
+
expect(match(/(\d+)/, '22')).to eq([22])
|
33
37
|
end
|
34
38
|
|
35
|
-
it
|
36
|
-
expect(
|
39
|
+
it 'returns nil when there is no match' do
|
40
|
+
expect(match(/hello/, 'world')).to be_nil
|
37
41
|
end
|
38
42
|
|
39
|
-
it
|
40
|
-
expect(
|
43
|
+
it 'matches empty string when there is an empty string match' do
|
44
|
+
expect(match(/^The value equals "([^"]*)"$/, 'The value equals ""')).to eq([''])
|
41
45
|
end
|
42
46
|
|
43
|
-
it
|
44
|
-
expect(
|
47
|
+
it 'matches nested capture group without match' do
|
48
|
+
expect(match(/^a user( named "([^"]*)")?$/, 'a user')).to eq([nil])
|
45
49
|
end
|
46
50
|
|
47
|
-
it
|
48
|
-
expect(
|
51
|
+
it 'matches nested capture group with match' do
|
52
|
+
expect(match(/^a user( named "([^"]*)")?$/, 'a user named "Charlie"')).to eq(['Charlie'])
|
49
53
|
end
|
50
54
|
|
51
|
-
it
|
52
|
-
expect(
|
53
|
-
|
54
|
-
|
55
|
-
|
55
|
+
it 'ignores non capturing groups' do
|
56
|
+
expect(
|
57
|
+
match(
|
58
|
+
/(\S+) ?(can|cannot) (?:delete|cancel) the (\d+)(?:st|nd|rd|th) (attachment|slide) ?(?:upload)?/,
|
59
|
+
'I can cancel the 1st slide upload'
|
60
|
+
)
|
61
|
+
).to eq(['I', 'can', 1, 'slide'])
|
56
62
|
end
|
57
63
|
|
58
|
-
it
|
64
|
+
it 'matches capture group nested in optional one' do
|
59
65
|
regexp = /^a (pre-commercial transaction |pre buyer fee model )?purchase(?: for \$(\d+))?$/
|
60
|
-
|
61
|
-
expect(
|
62
|
-
expect(
|
66
|
+
|
67
|
+
expect(match(regexp, 'a purchase')).to eq([nil, nil])
|
68
|
+
expect(match(regexp, 'a purchase for $33')).to eq([nil, 33])
|
69
|
+
expect(match(regexp, 'a pre buyer fee model purchase')).to eq(['pre buyer fee model ', nil])
|
63
70
|
end
|
64
71
|
|
65
|
-
it
|
66
|
-
expect(
|
72
|
+
it 'works with escaped parentheses' do
|
73
|
+
expect(match(/Across the line\(s\)/, 'Across the line(s)')).to eq([])
|
67
74
|
end
|
68
75
|
|
69
|
-
it
|
76
|
+
it 'exposes source and regexp' do
|
70
77
|
regexp = /I have (\d+) cukes? in my (\+) now/
|
71
78
|
expression = RegularExpression.new(regexp, ParameterTypeRegistry.new)
|
79
|
+
|
72
80
|
expect(expression.regexp).to eq(regexp)
|
73
81
|
expect(expression.source).to eq(regexp.source)
|
74
82
|
end
|
@@ -77,6 +85,7 @@ module Cucumber
|
|
77
85
|
regular_expression = RegularExpression.new(expression, ParameterTypeRegistry.new)
|
78
86
|
arguments = regular_expression.match(text)
|
79
87
|
return nil if arguments.nil?
|
88
|
+
|
80
89
|
arguments.map { |arg| arg.value(nil) }
|
81
90
|
end
|
82
91
|
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cucumber/cucumber_expressions/tree_regexp'
|
2
4
|
|
3
5
|
module Cucumber
|
4
6
|
module CucumberExpressions
|
5
7
|
describe TreeRegexp do
|
6
|
-
it 'exposes group source' do
|
8
|
+
it 'exposes the group source' do
|
7
9
|
tr = TreeRegexp.new(/(a(?:b)?)(c)/)
|
8
|
-
expect(tr.group_builder.children.map{|gb| gb.source}).to eq(['a(?:b)?', 'c'])
|
10
|
+
expect(tr.group_builder.children.map {|gb| gb.source}).to eq(['a(?:b)?', 'c'])
|
9
11
|
end
|
10
12
|
|
11
|
-
it 'builds tree' do
|
13
|
+
it 'builds a tree' do
|
12
14
|
tr = TreeRegexp.new(/(a(?:b)?)(c)/)
|
13
15
|
group = tr.match('ac')
|
14
16
|
expect(group.value).to eq('ac')
|
@@ -78,7 +80,7 @@ module Cucumber
|
|
78
80
|
}.to raise_error(/Named capture groups are not supported/)
|
79
81
|
end
|
80
82
|
|
81
|
-
it 'matches optional group' do
|
83
|
+
it 'matches an optional group' do
|
82
84
|
tr = TreeRegexp.new(/^Something( with an optional argument)?/)
|
83
85
|
group = tr.match('Something')
|
84
86
|
expect(group.children[0].value).to eq(nil)
|
@@ -99,45 +101,45 @@ module Cucumber
|
|
99
101
|
expect(group.children[2].children[2].value).to eq('60')
|
100
102
|
end
|
101
103
|
|
102
|
-
it 'detects multiple non
|
104
|
+
it 'detects multiple non-capturing groups' do
|
103
105
|
tr = TreeRegexp.new(/(?:a)(:b)(\?c)(d)/)
|
104
|
-
group = tr.match(
|
106
|
+
group = tr.match('a:b?cd')
|
105
107
|
expect(group.children.length).to eq(3)
|
106
108
|
end
|
107
109
|
|
108
|
-
it 'works with escaped
|
110
|
+
it 'works with escaped backslashes' do
|
109
111
|
tr = TreeRegexp.new(/foo\\(bar|baz)/)
|
110
|
-
group = tr.match(
|
112
|
+
group = tr.match('foo\\bar')
|
111
113
|
expect(group.children.length).to eq(1)
|
112
114
|
end
|
113
115
|
|
114
|
-
it 'works with escaped
|
116
|
+
it 'works with escaped slashes' do
|
115
117
|
tr = TreeRegexp.new(/^I go to '\/(.+)'$/)
|
116
118
|
group = tr.match("I go to '/hello'")
|
117
119
|
expect(group.children.length).to eq(1)
|
118
120
|
end
|
119
121
|
|
120
|
-
it 'works with digit and word' do
|
122
|
+
it 'works with digit and word regexp metacharacters' do
|
121
123
|
tr = TreeRegexp.new(/^(\d) (\w+)$/)
|
122
|
-
group = tr.match(
|
124
|
+
group = tr.match('2 you')
|
123
125
|
expect(group.children.length).to eq(2)
|
124
126
|
end
|
125
127
|
|
126
|
-
it 'captures non
|
128
|
+
it 'captures non-capturing groups with capturing groups inside' do
|
127
129
|
tr = TreeRegexp.new(/the stdout(?: from "(.*?)")?/)
|
128
|
-
group = tr.match(
|
129
|
-
expect(group.value).to eq(
|
130
|
+
group = tr.match('the stdout')
|
131
|
+
expect(group.value).to eq('the stdout')
|
130
132
|
expect(group.children[0].value).to eq(nil)
|
131
133
|
expect(group.children.length).to eq(1)
|
132
134
|
end
|
133
135
|
|
134
136
|
it 'works with flags' do
|
135
137
|
tr = TreeRegexp.new(/HELLO/i)
|
136
|
-
group = tr.match(
|
137
|
-
expect(group.value).to eq(
|
138
|
+
group = tr.match('hello')
|
139
|
+
expect(group.value).to eq('hello')
|
138
140
|
end
|
139
141
|
|
140
|
-
it('does not consider
|
142
|
+
it('does not consider parentheses in regexp character classes as a group') do
|
141
143
|
tr = TreeRegexp.new(/^drawings: ([A-Z_, ()]+)$/)
|
142
144
|
group = tr.match('drawings: ONE, TWO(ABC)')
|
143
145
|
expect(group.value).to eq('drawings: ONE, TWO(ABC)')
|
@@ -152,14 +154,14 @@ module Cucumber
|
|
152
154
|
expect(group.children.length).to eq 0
|
153
155
|
end
|
154
156
|
|
155
|
-
it 'works with non
|
157
|
+
it 'works with non-capturing inline flags' do
|
156
158
|
tr = TreeRegexp.new(/(?i:HELLO)/)
|
157
159
|
group = tr.match('hello')
|
158
160
|
expect(group.value).to eq('hello')
|
159
161
|
expect(group.children.length).to eq 0
|
160
162
|
end
|
161
163
|
|
162
|
-
it 'works with empty capturing
|
164
|
+
it 'works with empty capturing groups' do
|
163
165
|
tr = TreeRegexp.new(/()/)
|
164
166
|
group = tr.match('')
|
165
167
|
expect(group.value).to eq('')
|
@@ -167,20 +169,19 @@ module Cucumber
|
|
167
169
|
expect(group.children.length).to eq 1
|
168
170
|
end
|
169
171
|
|
170
|
-
it 'works with empty non-capturing
|
172
|
+
it 'works with empty non-capturing groups' do
|
171
173
|
tr = TreeRegexp.new(/(?:)/)
|
172
174
|
group = tr.match('')
|
173
175
|
expect(group.value).to eq('')
|
174
176
|
expect(group.children.length).to eq 0
|
175
177
|
end
|
176
178
|
|
177
|
-
it 'works with empty non-look ahead' do
|
179
|
+
it 'works with empty non-look ahead groups' do
|
178
180
|
tr = TreeRegexp.new(/(?<=)/)
|
179
181
|
group = tr.match('')
|
180
182
|
expect(group.value).to eq('')
|
181
183
|
expect(group.children.length).to eq 0
|
182
184
|
end
|
183
|
-
|
184
185
|
end
|
185
186
|
end
|
186
187
|
end
|