cucumber-cucumber-expressions 9.0.0 → 10.2.2

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: 50f04f03031779e787930c81c808d37f1187cc5eeed2e6913b8855d982a3213a
4
- data.tar.gz: f907efdb6c7750b8a3e32efda1abd99e4353e368b9794ddeca9241ccaf647047
3
+ metadata.gz: 5f6e54987a67d95d7c35141dc8956493e6296d510030350c5faafaa616a80c75
4
+ data.tar.gz: c52783e660007e7c9229566a9ccc2e3a790ae30bd9305fb3a6a4549fd5b6ca2e
5
5
  SHA512:
6
- metadata.gz: f72b64fdca5fcfbc472128a074b7c72a5d54fbe48bba746dff1bd07f65427207bb85a933465336edeca68334bbce3994663a1ba2c4c241cdc898d0c40de61380
7
- data.tar.gz: 48f73da5f1a77c0c8b754ccc8d235b5622f02ee18a926be5f372b58d79a7cb8a0e3c45c202e3e56b3146279c3799eb947c95958bb853ab7f682765ccabf5314e
6
+ metadata.gz: d0e349576811fa2fa0c99b7461d020dc8b0dc4320e0cfead5adc3fddd237c2a3b99b1d6c85729ee5d05c9d1b0fd74b89553b381da514c149fe62bb7d7b813a27
7
+ data.tar.gz: 47b74fb77924ee62e500a526094f57057bc1b1d997d1944c4559115ddc36febe3f36dcd71730458ee1285c30879b6997570bf7a31d411dd56cedda4c99ffc635
data/README.md CHANGED
@@ -1,5 +1,3 @@
1
1
  # Cucumber Expressions for Ruby
2
2
 
3
- [![Build Status](https://travis-ci.org/cucumber/cucumber-expressions-ruby.svg?branch=master)](https://travis-ci.org/cucumber/cucumber-expressions-ruby)
4
-
5
3
  [The docs are here](https://cucumber.io/docs/cucumber/cucumber-expressions/).
data/Rakefile CHANGED
@@ -10,9 +10,7 @@ Dir['./rake/*.rb'].each do |f|
10
10
  end
11
11
 
12
12
  require "rspec/core/rake_task"
13
- RSpec::Core::RakeTask.new(:spec) do |t|
14
- t.ruby_opts = %w[-r./spec/coverage -w]
15
- end
13
+ RSpec::Core::RakeTask.new(:spec)
16
14
 
17
15
  require_relative 'spec/capture_warnings'
18
16
  include CaptureWarnings
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 10.2.2
@@ -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 = '9.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}"
@@ -22,9 +25,6 @@ Gem::Specification.new do |s|
22
25
  s.add_development_dependency 'rake', '~> 13.0', '>= 13.0.1'
23
26
  s.add_development_dependency 'rspec', '~> 3.9', '>= 3.9.0'
24
27
 
25
- # For coverage reports
26
- s.add_development_dependency 'coveralls', '~> 0.8', '>= 0.8.23'
27
-
28
28
  s.rubygems_version = ">= 1.6.1"
29
29
  s.files = `git ls-files`.split("\n").reject {|path| path =~ /\.gitignore$/ }
30
30
  s.test_files = `git ls-files -- spec/*`.split("\n")
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: 9.0.0
4
+ version: 10.2.2
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-02-14 00:00:00.000000000 Z
11
+ date: 2020-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -50,26 +50,6 @@ dependencies:
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 3.9.0
53
- - !ruby/object:Gem::Dependency
54
- name: coveralls
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: '0.8'
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: 0.8.23
63
- type: :development
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: '0.8'
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: 0.8.23
73
53
  description: Cucumber Expressions - a simpler alternative to Regular Expressions
74
54
  email: cukes@googlegroups.com
75
55
  executables: []
@@ -86,6 +66,7 @@ files:
86
66
  - Makefile
87
67
  - README.md
88
68
  - Rakefile
69
+ - VERSION
89
70
  - cucumber-cucumber-expressions.gemspec
90
71
  - default.mk
91
72
  - examples.txt
@@ -105,7 +86,6 @@ files:
105
86
  - lib/cucumber/cucumber_expressions/tree_regexp.rb
106
87
  - scripts/update-gemspec
107
88
  - spec/capture_warnings.rb
108
- - spec/coverage.rb
109
89
  - spec/cucumber/cucumber_expressions/argument_spec.rb
110
90
  - spec/cucumber/cucumber_expressions/combinatorial_generated_expression_factory_test.rb
111
91
  - spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb
@@ -143,14 +123,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
123
  - !ruby/object:Gem::Version
144
124
  version: '0'
145
125
  requirements: []
146
- rubyforge_project:
147
- rubygems_version: 2.7.6.2
126
+ rubygems_version: 3.1.2
148
127
  signing_key:
149
128
  specification_version: 4
150
- summary: cucumber-expressions-9.0.0
129
+ summary: cucumber-expressions-10.2.2
151
130
  test_files:
152
131
  - spec/capture_warnings.rb
153
- - spec/coverage.rb
154
132
  - spec/cucumber/cucumber_expressions/argument_spec.rb
155
133
  - spec/cucumber/cucumber_expressions/combinatorial_generated_expression_factory_test.rb
156
134
  - spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'simplecov'
3
- formatters = [ SimpleCov::Formatter::HTMLFormatter ]
4
-
5
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(*formatters)
6
- SimpleCov.add_filter 'spec/'
7
- SimpleCov.start