cucumber-cucumber-expressions 8.3.1 → 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: d75b7265f9a2c2142d7733b064bb4e6ec6d317d1f32ba9e4148e42512b90a4df
4
- data.tar.gz: c7f8fa3ce1e9eccaf40fcbfd9288ed8302ea1b13b2cb8aa385a64abaf94a2d15
3
+ metadata.gz: 5bba8569a4b4b7ae2a05e97b5d2e5f7b8c455b6843175475a6d55d4fb58fe8e5
4
+ data.tar.gz: 443f0d744039bdd83e4aff50ef3e71738222e3436d8c094195b1e916f33078cd
5
5
  SHA512:
6
- metadata.gz: a05e6facfd23519c59b261e253a623097c892108a9b66d3fd330128b9651be4923f01b16666cf61c82abc112c6b5fcee987703b0c4198462148b6a174b51ba24
7
- data.tar.gz: '09a81cd8ef765626765d0f269063c284266cf2153d3b80c4cdeacb464aeea41b4df9967ba256a3f8a27bd06f89c2f650cffffc903e4d5206504e05ff1daa2e50'
6
+ metadata.gz: 3548b8ae4d3ac5f91f8a5ad31bda608cf3bdf1d24150bb0c95206966e6e5ace38506830cdda614a1b0957e257a6be78607037ddba77e73521da05011eabdb84c
7
+ data.tar.gz: 89b1992ef048d7bdcf5c62aaa0038508bf80fbb5d5383a1cd96746c9f6dcf50223f44b7ddf5ac943d0e51515da2f631d6e03cce662c52660f59617c0eb822081
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.1
@@ -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 = '8.3.1'
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
@@ -32,21 +32,21 @@ endif
32
32
  endif
33
33
  .PHONY: gem
34
34
 
35
- $(GEM): clean .tested
35
+ $(GEM): .tested
36
36
  gem build $(GEMSPEC)
37
37
  test -s "$(GEM)" || { echo "Gem not built: $(GEM)"; exit 1; }
38
38
 
39
- pre-release: update-version update-dependencies gem
39
+ remove-local-dependencies:
40
+ cat Gemfile | sed 's/^gem /#gem /' > Gemfile.tmp
41
+ mv Gemfile.tmp Gemfile
42
+ .PHONY: remove-local-dependencies
43
+
44
+ pre-release: remove-local-dependencies update-version update-dependencies gem
40
45
  .PHONY: pre-release
41
46
 
42
47
  update-version:
43
48
  ifdef NEW_VERSION
44
- ifneq (,$(GEMSPEC))
45
- sed -i "s/\(s\.version *= *'\)[0-9]*\.[0-9]*\.[0-9]*\('\)/\1$(NEW_VERSION)\2/" $(GEMSPEC)
46
- endif
47
- else
48
- @echo -e "\033[0;31mNEW_VERSION is not defined. Can't update version :-(\033[0m"
49
- exit 1
49
+ @echo "$(NEW_VERSION)" > VERSION
50
50
  endif
51
51
  .PHONY: update-version
52
52
 
@@ -59,12 +59,13 @@ endif
59
59
  .PHONY: publish
60
60
 
61
61
  post-release:
62
- @echo "No post-release needed for ruby"
62
+ cat Gemfile | sed 's/^#gem /gem /' > Gemfile.tmp
63
+ mv Gemfile.tmp Gemfile
63
64
  .PHONY: post-release
64
65
 
65
66
  clean: clean-ruby
66
67
  .PHONY: clean
67
68
 
68
69
  clean-ruby:
69
- rm -f .deps .linked .tested* Gemfile.lock *.gem
70
+ rm -rf .deps .linked .tested* Gemfile.lock *.gem acceptance
70
71
  .PHONY: clean-ruby
@@ -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]
@@ -0,0 +1,22 @@
1
+ require 'cucumber/cucumber_expressions/errors'
2
+ require 'cucumber/cucumber_expressions/cucumber_expression'
3
+ require 'cucumber/cucumber_expressions/regular_expression'
4
+
5
+ module Cucumber
6
+ module CucumberExpressions
7
+ class ExpressionFactory
8
+ def initialize(parameter_type_registry)
9
+ @parameter_type_registry = parameter_type_registry
10
+ end
11
+
12
+ def create_expression(string_or_regexp)
13
+ case string_or_regexp
14
+ when String then CucumberExpression.new(string_or_regexp, @parameter_type_registry)
15
+ when Regexp then RegularExpression.new(string_or_regexp, @parameter_type_registry)
16
+ else
17
+ raise CucumberExpressionError.new("Can't create an expression from #{string_or_regexp.inspect}")
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -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)
@@ -0,0 +1,23 @@
1
+ require 'cucumber/cucumber_expressions/expression_factory'
2
+
3
+ module Cucumber
4
+ module CucumberExpressions
5
+ describe ExpressionFactory do
6
+ before do
7
+ @expression_factory = ExpressionFactory.new(ParameterTypeRegistry.new)
8
+ end
9
+
10
+ it 'creates a RegularExpression' do
11
+ expect(@expression_factory.create_expression(/x/).class).to eq(RegularExpression)
12
+ end
13
+
14
+ it 'creates a CucumberExpression' do
15
+ expect(@expression_factory.create_expression('{int}').class).to eq(CucumberExpression)
16
+ end
17
+
18
+ it 'creates a XXXRegularExpression' do
19
+ expect {@expression_factory.create_expression('hello {x}')}.to raise_error("Undefined parameter type {x}")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -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: 8.3.1
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-01-10 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
@@ -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
@@ -94,6 +75,7 @@ files:
94
75
  - lib/cucumber/cucumber_expressions/cucumber_expression.rb
95
76
  - lib/cucumber/cucumber_expressions/cucumber_expression_generator.rb
96
77
  - lib/cucumber/cucumber_expressions/errors.rb
78
+ - lib/cucumber/cucumber_expressions/expression_factory.rb
97
79
  - lib/cucumber/cucumber_expressions/generated_expression.rb
98
80
  - lib/cucumber/cucumber_expressions/group.rb
99
81
  - lib/cucumber/cucumber_expressions/group_builder.rb
@@ -104,7 +86,6 @@ files:
104
86
  - lib/cucumber/cucumber_expressions/tree_regexp.rb
105
87
  - scripts/update-gemspec
106
88
  - spec/capture_warnings.rb
107
- - spec/coverage.rb
108
89
  - spec/cucumber/cucumber_expressions/argument_spec.rb
109
90
  - spec/cucumber/cucumber_expressions/combinatorial_generated_expression_factory_test.rb
110
91
  - spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb
@@ -112,6 +93,7 @@ files:
112
93
  - spec/cucumber/cucumber_expressions/cucumber_expression_spec.rb
113
94
  - spec/cucumber/cucumber_expressions/custom_parameter_type_spec.rb
114
95
  - spec/cucumber/cucumber_expressions/expression_examples_spec.rb
96
+ - spec/cucumber/cucumber_expressions/expression_factory_spec.rb
115
97
  - spec/cucumber/cucumber_expressions/parameter_type_registry_spec.rb
116
98
  - spec/cucumber/cucumber_expressions/parameter_type_spec.rb
117
99
  - spec/cucumber/cucumber_expressions/regular_expression_spec.rb
@@ -141,14 +123,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
123
  - !ruby/object:Gem::Version
142
124
  version: '0'
143
125
  requirements: []
144
- rubyforge_project:
145
- rubygems_version: 2.7.6.2
126
+ rubygems_version: 3.1.2
146
127
  signing_key:
147
128
  specification_version: 4
148
- summary: cucumber-expressions-8.3.1
129
+ summary: cucumber-expressions-10.2.1
149
130
  test_files:
150
131
  - spec/capture_warnings.rb
151
- - spec/coverage.rb
152
132
  - spec/cucumber/cucumber_expressions/argument_spec.rb
153
133
  - spec/cucumber/cucumber_expressions/combinatorial_generated_expression_factory_test.rb
154
134
  - spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb
@@ -156,6 +136,7 @@ test_files:
156
136
  - spec/cucumber/cucumber_expressions/cucumber_expression_spec.rb
157
137
  - spec/cucumber/cucumber_expressions/custom_parameter_type_spec.rb
158
138
  - spec/cucumber/cucumber_expressions/expression_examples_spec.rb
139
+ - spec/cucumber/cucumber_expressions/expression_factory_spec.rb
159
140
  - spec/cucumber/cucumber_expressions/parameter_type_registry_spec.rb
160
141
  - spec/cucumber/cucumber_expressions/parameter_type_spec.rb
161
142
  - spec/cucumber/cucumber_expressions/regular_expression_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