cucumber-cucumber-expressions 10.2.0 → 10.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5807f447d5dce48e6b1153547119c4ca61b20003f470728ec3e3d6675265aef2
4
- data.tar.gz: 12896256efd40509d7267019c02e3561b81d4f2be1b481fac1696400e5be7d04
3
+ metadata.gz: 5bba8569a4b4b7ae2a05e97b5d2e5f7b8c455b6843175475a6d55d4fb58fe8e5
4
+ data.tar.gz: 443f0d744039bdd83e4aff50ef3e71738222e3436d8c094195b1e916f33078cd
5
5
  SHA512:
6
- metadata.gz: 3c2eaff08f07d7cacc6d8f643b30dc51941c3bc2acb38e3f63f5d7c3dac7239c04982f41f2da73837c643a11d8c9ad55aee72944e31c1c6e8bd070e4e3ad6973
7
- data.tar.gz: 1ef0bb4db4c9ba93a4baa484cf4158169fcd4174659fa6e3d41588f8bee3307928d508319699957d75dd3f63d2242dc0dc481263ad2a07c3574511ac0051d9d7
6
+ metadata.gz: 3548b8ae4d3ac5f91f8a5ad31bda608cf3bdf1d24150bb0c95206966e6e5ace38506830cdda614a1b0957e257a6be78607037ddba77e73521da05011eabdb84c
7
+ data.tar.gz: 89b1992ef048d7bdcf5c62aaa0038508bf80fbb5d5383a1cd96746c9f6dcf50223f44b7ddf5ac943d0e51515da2f631d6e03cce662c52660f59617c0eb822081
data/VERSION CHANGED
@@ -1 +1 @@
1
- 10.2.0
1
+ 10.2.1
@@ -29,3 +29,7 @@ I have 22 cukes in my belly now
29
29
  I have {} cuke(s) in my {} now
30
30
  I have 22 cukes in my belly now
31
31
  ["22","belly"]
32
+ ---
33
+ /^a (pre-commercial transaction |pre buyer fee model )?purchase(?: for \$(\d+))?$/
34
+ a purchase for $33
35
+ [null,33]
@@ -11,7 +11,7 @@ module Cucumber
11
11
  end
12
12
 
13
13
  def values
14
- (children.empty? ? [self] : children).map(&:value).compact
14
+ (children.empty? ? [self] : children).map(&:value)
15
15
  end
16
16
  end
17
17
  end
@@ -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 {|s = nil| s && s.gsub(/\\"/, '"').gsub(/\\'/, "'")}, true, false))
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
- @stack = [GroupBuilder.new]
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
- @stack.push(GroupBuilder.new)
26
- group_start_stack.push(n + 1)
27
- @non_capturing_maybe = false
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 = @stack.pop
68
+ gb = stack.pop
30
69
  group_start = group_start_stack.pop
31
70
  if gb.capturing?
32
- gb.source = @regexp.source[group_start...n]
33
- @stack.last.add(gb)
71
+ gb.source = source[group_start + 1...i]
72
+ stack.last.add(gb)
34
73
  else
35
- gb.move_children_to(@stack.last)
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
- @group_builder = @stack.pop
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 'throws an error when there are named capture groups because they are buggy in Ruby' do
126
- # https://github.com/cucumber/cucumber/issues/329
127
- expect {
128
- TreeRegexp.new(/^I am a person( named "(?<first_name>.+) (?<last_name>.+)")?$/)
129
- }.to raise_error(/Named capture groups are not supported/)
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.0
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-05-28 00:00:00.000000000 Z
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
- rubyforge_project:
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.0
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