cucumber-cucumber-expressions 10.2.0 → 10.2.1
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/VERSION +1 -1
- data/examples.txt +4 -0
- data/lib/cucumber/cucumber_expressions/group.rb +1 -1
- data/lib/cucumber/cucumber_expressions/parameter_type_registry.rb +1 -1
- data/lib/cucumber/cucumber_expressions/tree_regexp.rb +53 -46
- data/spec/cucumber/cucumber_expressions/cucumber_expression_spec.rb +27 -0
- data/spec/cucumber/cucumber_expressions/tree_regexp_spec.rb +58 -5
- metadata +4 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bba8569a4b4b7ae2a05e97b5d2e5f7b8c455b6843175475a6d55d4fb58fe8e5
|
4
|
+
data.tar.gz: 443f0d744039bdd83e4aff50ef3e71738222e3436d8c094195b1e916f33078cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3548b8ae4d3ac5f91f8a5ad31bda608cf3bdf1d24150bb0c95206966e6e5ace38506830cdda614a1b0957e257a6be78607037ddba77e73521da05011eabdb84c
|
7
|
+
data.tar.gz: 89b1992ef048d7bdcf5c62aaa0038508bf80fbb5d5383a1cd96746c9f6dcf50223f44b7ddf5ac943d0e51515da2f631d6e03cce662c52660f59617c0eb822081
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
10.2.
|
1
|
+
10.2.1
|
data/examples.txt
CHANGED
@@ -18,7 +18,7 @@ module Cucumber
|
|
18
18
|
define_parameter_type(ParameterType.new('int', INTEGER_REGEXPS, Integer, lambda {|s = nil| s && s.to_i}, true, true))
|
19
19
|
define_parameter_type(ParameterType.new('float', FLOAT_REGEXP, Float, lambda {|s = nil| s && s.to_f}, true, false))
|
20
20
|
define_parameter_type(ParameterType.new('word', WORD_REGEXP, String, lambda {|s = nil| s}, false, false))
|
21
|
-
define_parameter_type(ParameterType.new('string', STRING_REGEXP, String, lambda {|
|
21
|
+
define_parameter_type(ParameterType.new('string', STRING_REGEXP, String, lambda { |s1, s2| arg = s1 != nil ? s1 : s2; arg.gsub(/\\"/, '"').gsub(/\\'/, "'")}, true, false))
|
22
22
|
define_parameter_type(ParameterType.new('', ANONYMOUS_REGEXP, String, lambda {|s = nil| s}, false, true))
|
23
23
|
end
|
24
24
|
|
@@ -8,68 +8,75 @@ module Cucumber
|
|
8
8
|
|
9
9
|
def initialize(regexp)
|
10
10
|
@regexp = regexp.is_a?(Regexp) ? regexp : Regexp.new(regexp)
|
11
|
-
@
|
11
|
+
@group_builder = create_group_builder(@regexp)
|
12
|
+
end
|
13
|
+
|
14
|
+
def match(s)
|
15
|
+
match = @regexp.match(s)
|
16
|
+
return nil if match.nil?
|
17
|
+
group_indices = (0..match.length).to_a.to_enum
|
18
|
+
@group_builder.build(match, group_indices)
|
19
|
+
end
|
20
|
+
|
21
|
+
private def is_non_capturing(source, i)
|
22
|
+
# Regex is valid. Bounds check not required.
|
23
|
+
if source[i+1] != '?'
|
24
|
+
# (X)
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
|
28
|
+
if source[i+2] != '<'
|
29
|
+
# (?:X)
|
30
|
+
# (?idmsuxU-idmsuxU)
|
31
|
+
# (?idmsux-idmsux:X)
|
32
|
+
# (?=X)
|
33
|
+
# (?!X)
|
34
|
+
# (?>X)
|
35
|
+
return true
|
36
|
+
end
|
37
|
+
|
38
|
+
if source[i+3] == '=' || source[i+3] == '!'
|
39
|
+
# (?<=X)
|
40
|
+
# (?<!X)
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
|
44
|
+
# (?<name>X)
|
45
|
+
raise CucumberExpressionError.new("Named capture groups are not supported. See https://github.com/cucumber/cucumber/issues/329")
|
46
|
+
end
|
47
|
+
|
48
|
+
private def create_group_builder(regexp)
|
49
|
+
source = regexp.source
|
50
|
+
stack = [GroupBuilder.new]
|
12
51
|
group_start_stack = []
|
13
|
-
last = nil
|
14
52
|
escaping = false
|
15
|
-
@non_capturing_maybe = false
|
16
|
-
@name_capturing_maybe = false
|
17
53
|
char_class = false
|
18
|
-
|
19
|
-
@regexp.source.each_char.with_index do |c, n|
|
54
|
+
source.each_char.with_index do |c, i|
|
20
55
|
if c == '[' && !escaping
|
21
56
|
char_class = true
|
22
57
|
elsif c == ']' && !escaping
|
23
58
|
char_class = false
|
24
59
|
elsif c == '(' && !escaping && !char_class
|
25
|
-
|
26
|
-
|
27
|
-
|
60
|
+
group_start_stack.push(i)
|
61
|
+
group_builder = GroupBuilder.new
|
62
|
+
non_capturing = is_non_capturing(source, i)
|
63
|
+
if non_capturing
|
64
|
+
group_builder.set_non_capturing!
|
65
|
+
end
|
66
|
+
stack.push(group_builder)
|
28
67
|
elsif c == ')' && !escaping && !char_class
|
29
|
-
gb =
|
68
|
+
gb = stack.pop
|
30
69
|
group_start = group_start_stack.pop
|
31
70
|
if gb.capturing?
|
32
|
-
gb.source =
|
33
|
-
|
71
|
+
gb.source = source[group_start + 1...i]
|
72
|
+
stack.last.add(gb)
|
34
73
|
else
|
35
|
-
gb.move_children_to(
|
74
|
+
gb.move_children_to(stack.last)
|
36
75
|
end
|
37
|
-
end_group
|
38
|
-
elsif c == '?' && last == '('
|
39
|
-
@non_capturing_maybe = true
|
40
|
-
elsif (c == '<') && @non_capturing_maybe
|
41
|
-
@name_capturing_maybe = true
|
42
|
-
elsif (c == ':' || c == '!' || c == '=') && last == '?' && @non_capturing_maybe
|
43
|
-
end_non_capturing_group
|
44
|
-
elsif (c == '=' || c == '!') && last == '<' && @name_capturing_maybe
|
45
|
-
end_non_capturing_group
|
46
|
-
elsif @name_capturing_maybe
|
47
|
-
raise CucumberExpressionError.new("Named capture groups are not supported. See https://github.com/cucumber/cucumber/issues/329")
|
48
76
|
end
|
49
|
-
|
50
77
|
escaping = c == '\\' && !escaping
|
51
|
-
last = c
|
52
78
|
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
def match(s)
|
57
|
-
match = @regexp.match(s)
|
58
|
-
return nil if match.nil?
|
59
|
-
group_indices = (0..match.length).to_a.to_enum
|
60
|
-
@group_builder.build(match, group_indices)
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def end_non_capturing_group
|
66
|
-
@stack.last.set_non_capturing!
|
67
|
-
end_group
|
68
|
-
end
|
69
|
-
|
70
|
-
def end_group
|
71
|
-
@non_capturing_maybe = false
|
72
|
-
@name_capturing_maybe = false
|
79
|
+
stack.pop
|
73
80
|
end
|
74
81
|
end
|
75
82
|
end
|
@@ -201,6 +201,33 @@ module Cucumber
|
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
204
|
+
|
205
|
+
it "unmatched optional groups have undefined values" do
|
206
|
+
parameter_type_registry = ParameterTypeRegistry.new
|
207
|
+
parameter_type_registry.define_parameter_type(
|
208
|
+
ParameterType.new(
|
209
|
+
'textAndOrNumber',
|
210
|
+
/([A-Z]+)?(?: )?([0-9]+)?/,
|
211
|
+
Object,
|
212
|
+
-> (s1, s2) {
|
213
|
+
[s1, s2]
|
214
|
+
},
|
215
|
+
false,
|
216
|
+
true
|
217
|
+
)
|
218
|
+
)
|
219
|
+
expression = CucumberExpression.new(
|
220
|
+
'{textAndOrNumber}',
|
221
|
+
parameter_type_registry
|
222
|
+
)
|
223
|
+
|
224
|
+
class World
|
225
|
+
end
|
226
|
+
|
227
|
+
expect(expression.match("TLA")[0].value(World.new)).to eq(["TLA", nil])
|
228
|
+
expect(expression.match("123")[0].value(World.new)).to eq([nil, "123"])
|
229
|
+
end
|
230
|
+
|
204
231
|
def match(expression, text)
|
205
232
|
cucumber_expression = CucumberExpression.new(expression, ParameterTypeRegistry.new)
|
206
233
|
args = cucumber_expression.match(text)
|
@@ -22,6 +22,7 @@ module Cucumber
|
|
22
22
|
group = tr.match('abc')
|
23
23
|
expect(group.value).to eq('abc')
|
24
24
|
expect(group.children.length).to eq 1
|
25
|
+
expect(group.children[0].value).to eq('c')
|
25
26
|
end
|
26
27
|
|
27
28
|
it 'ignores `?!` as a non-capturing group' do
|
@@ -55,6 +56,28 @@ module Cucumber
|
|
55
56
|
expect(group.children.length).to eq 1
|
56
57
|
end
|
57
58
|
|
59
|
+
it 'ignores `?<!` as a non-capturing group' do
|
60
|
+
tr = TreeRegexp.new(/a(.+)(?<!b)$/)
|
61
|
+
group = tr.match('abc')
|
62
|
+
expect(group.value).to eq('abc')
|
63
|
+
expect(group.children[0].value).to eq('bc')
|
64
|
+
expect(group.children.length).to eq 1
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'ignores `?>` as a non-capturing group' do
|
68
|
+
tr = TreeRegexp.new(/a(?>b)c/)
|
69
|
+
group = tr.match('abc')
|
70
|
+
expect(group.value).to eq('abc')
|
71
|
+
expect(group.children.length).to eq 0
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'throws an error when there are named capture groups because they are buggy in Ruby' do
|
75
|
+
# https://github.com/cucumber/cucumber/issues/329
|
76
|
+
expect {
|
77
|
+
TreeRegexp.new(/^I am a person( named "(?<first_name>.+) (?<last_name>.+)")?$/)
|
78
|
+
}.to raise_error(/Named capture groups are not supported/)
|
79
|
+
end
|
80
|
+
|
58
81
|
it 'matches optional group' do
|
59
82
|
tr = TreeRegexp.new(/^Something( with an optional argument)?/)
|
60
83
|
group = tr.match('Something')
|
@@ -122,12 +145,42 @@ module Cucumber
|
|
122
145
|
expect(group.children.length).to eq(1)
|
123
146
|
end
|
124
147
|
|
125
|
-
it '
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
148
|
+
it 'works with inline flags' do
|
149
|
+
tr = TreeRegexp.new(/(?i)HELLO/)
|
150
|
+
group = tr.match('hello')
|
151
|
+
expect(group.value).to eq('hello')
|
152
|
+
expect(group.children.length).to eq 0
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'works with non capturing inline flags' do
|
156
|
+
tr = TreeRegexp.new(/(?i:HELLO)/)
|
157
|
+
group = tr.match('hello')
|
158
|
+
expect(group.value).to eq('hello')
|
159
|
+
expect(group.children.length).to eq 0
|
130
160
|
end
|
161
|
+
|
162
|
+
it 'works with empty capturing group' do
|
163
|
+
tr = TreeRegexp.new(/()/)
|
164
|
+
group = tr.match('')
|
165
|
+
expect(group.value).to eq('')
|
166
|
+
expect(group.children[0].value).to eq('')
|
167
|
+
expect(group.children.length).to eq 1
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'works with empty non-capturing group' do
|
171
|
+
tr = TreeRegexp.new(/(?:)/)
|
172
|
+
group = tr.match('')
|
173
|
+
expect(group.value).to eq('')
|
174
|
+
expect(group.children.length).to eq 0
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'works with empty non-look ahead' do
|
178
|
+
tr = TreeRegexp.new(/(?<=)/)
|
179
|
+
group = tr.match('')
|
180
|
+
expect(group.value).to eq('')
|
181
|
+
expect(group.children.length).to eq 0
|
182
|
+
end
|
183
|
+
|
131
184
|
end
|
132
185
|
end
|
133
186
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-cucumber-expressions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.2.
|
4
|
+
version: 10.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aslak Hellesøy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -123,11 +123,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
requirements: []
|
126
|
-
|
127
|
-
rubygems_version: 2.7.6.2
|
126
|
+
rubygems_version: 3.1.2
|
128
127
|
signing_key:
|
129
128
|
specification_version: 4
|
130
|
-
summary: cucumber-expressions-10.2.
|
129
|
+
summary: cucumber-expressions-10.2.1
|
131
130
|
test_files:
|
132
131
|
- spec/capture_warnings.rb
|
133
132
|
- spec/cucumber/cucumber_expressions/argument_spec.rb
|