cucumber-cucumber-expressions 10.0.0 → 10.3.0

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: 50c9796de315f381ef13e5ce25d8e6342b71c02a2e0b15067858806e3e312716
4
- data.tar.gz: c21a0b6a20af97e368833ba1ef95e22c7316d3fd9db677895c9ad0d2653b5f3e
3
+ metadata.gz: 705a1aa48bf85408fc0db737e50091584f930c7e73e6ffe485f5c8cdf0c8a9f4
4
+ data.tar.gz: 3d40ff2d7b847cb5b44aa547ab6e46791e769abccf7beaf14e5de9f0440710e3
5
5
  SHA512:
6
- metadata.gz: 56bb332b0b0bab9c250e855c13d94bd166ff660e3c6f054946a4f3b65dfc2ec9d79ef360ff4d2bf93fa73d943e396c38ac1405aaa348a5fa0bf9f35c65755339
7
- data.tar.gz: b60ff154a2f586a4765271e5ff838331d89337c3a13c32e039169a81d3ad42ebfc22332f9a6fcb518577ff17edc543781e83eb2849e45076f0a207379b4747d8
6
+ metadata.gz: e9407c5108c578c553831398255986de2bee9393500adb35f3528b359e05ae0cc3df966b163da15052623b0dfe01efb2b64e624a1976030dc0c9d355e279cf89
7
+ data.tar.gz: 51ce8f4c93b3948dbb36c34cd221f48aa29c2eb812fb4d7a582b2644b4118d1e6373d1de644c5d78470525bc80a9ab4dae6f414eec27ef55e3c6a76fedce2ee1
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 10.3.0
@@ -1,7 +1,10 @@
1
1
  # -*- encoding: utf-8 -*-
2
+
3
+ version = File.read(File.expand_path("VERSION", __dir__)).strip
4
+
2
5
  Gem::Specification.new do |s|
3
6
  s.name = 'cucumber-cucumber-expressions'
4
- s.version = '10.0.0'
7
+ s.version = version
5
8
  s.authors = ["Aslak Hellesøy"]
6
9
  s.description = 'Cucumber Expressions - a simpler alternative to Regular Expressions'
7
10
  s.summary = "cucumber-expressions-#{s.version}"
data/default.mk CHANGED
@@ -3,6 +3,10 @@ RUBY_SOURCE_FILES = $(shell find . -name "*.rb")
3
3
  GEMSPEC = $(shell find . -name "*.gemspec")
4
4
  LIBNAME := $(shell basename $$(dirname $$(pwd)))
5
5
  GEM := cucumber-$(LIBNAME)-$(NEW_VERSION).gem
6
+ IS_TESTDATA = $(findstring -testdata,${CURDIR})
7
+
8
+ # https://stackoverflow.com/questions/2483182/recursive-wildcards-in-gnu-make
9
+ rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
6
10
 
7
11
  default: .tested
8
12
  .PHONY: default
@@ -45,22 +49,25 @@ pre-release: remove-local-dependencies update-version update-dependencies gem
45
49
  .PHONY: pre-release
46
50
 
47
51
  update-version:
52
+ ifeq ($(IS_TESTDATA),-testdata)
53
+ # no-op
54
+ else
48
55
  ifdef NEW_VERSION
49
- ifneq (,$(GEMSPEC))
50
- sed -i "s/\(s\.version *= *'\)[0-9]*\.[0-9]*\.[0-9]*\('\)/\1$(NEW_VERSION)\2/" $(GEMSPEC)
56
+ @echo "$(NEW_VERSION)" > VERSION
51
57
  endif
52
- else
53
- @echo -e "\033[0;31mNEW_VERSION is not defined. Can't update version :-(\033[0m"
54
- exit 1
55
58
  endif
56
59
  .PHONY: update-version
57
60
 
58
61
  publish: gem
62
+ ifeq ($(IS_TESTDATA),-testdata)
63
+ # no-op
64
+ else
59
65
  ifneq (,$(GEMSPEC))
60
66
  gem push $(GEM)
61
67
  else
62
68
  @echo "Not publishing because there is no gemspec"
63
69
  endif
70
+ endif
64
71
  .PHONY: publish
65
72
 
66
73
  post-release:
@@ -72,5 +79,5 @@ clean: clean-ruby
72
79
  .PHONY: clean
73
80
 
74
81
  clean-ruby:
75
- rm -f .deps .linked .tested* Gemfile.lock *.gem
82
+ rm -rf .deps .linked .tested* Gemfile.lock *.gem acceptance
76
83
  .PHONY: clean-ruby
@@ -29,3 +29,11 @@ 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]
36
+ ---
37
+ Some ${float} of cukes at {int}° Celsius
38
+ Some $3.50 of cukes at 42° Celsius
39
+ [3.5,42]
@@ -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
@@ -47,12 +47,12 @@ module Cucumber
47
47
 
48
48
  def space_before_match_or_sentence_start?
49
49
  match_begin = @match.begin(0)
50
- match_begin == 0 || @text[match_begin - 1].match(/\s|\p{P}/)
50
+ match_begin == 0 || @text[match_begin - 1].match(/\p{Z}|\p{P}|\p{S}/)
51
51
  end
52
52
 
53
53
  def space_after_match_or_sentence_end?
54
54
  match_end = @match.end(0)
55
- match_end == @text.length || @text[match_end].match(/\s|\p{P}/)
55
+ match_end == @text.length || @text[match_end].match(/\p{Z}|\p{P}|\p{S}/)
56
56
  end
57
57
  end
58
58
  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.0.0
4
+ version: 10.3.0
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-03-31 00:00:00.000000000 Z
11
+ date: 2020-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -66,6 +66,7 @@ files:
66
66
  - Makefile
67
67
  - README.md
68
68
  - Rakefile
69
+ - VERSION
69
70
  - cucumber-cucumber-expressions.gemspec
70
71
  - default.mk
71
72
  - examples.txt
@@ -122,11 +123,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
123
  - !ruby/object:Gem::Version
123
124
  version: '0'
124
125
  requirements: []
125
- rubyforge_project:
126
- rubygems_version: 2.7.6.2
126
+ rubygems_version: 3.1.2
127
127
  signing_key:
128
128
  specification_version: 4
129
- summary: cucumber-expressions-10.0.0
129
+ summary: cucumber-expressions-10.3.0
130
130
  test_files:
131
131
  - spec/capture_warnings.rb
132
132
  - spec/cucumber/cucumber_expressions/argument_spec.rb