cucumber-cucumber-expressions 9.0.0 → 10.2.2
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/README.md +0 -2
- data/Rakefile +1 -3
- data/VERSION +1 -0
- data/cucumber-cucumber-expressions.gemspec +4 -4
- data/default.mk +13 -6
- data/examples.txt +8 -0
- data/lib/cucumber/cucumber_expressions/group.rb +1 -1
- data/lib/cucumber/cucumber_expressions/parameter_type_matcher.rb +2 -2
- 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 +5 -27
- data/spec/coverage.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f6e54987a67d95d7c35141dc8956493e6296d510030350c5faafaa616a80c75
|
4
|
+
data.tar.gz: c52783e660007e7c9229566a9ccc2e3a790ae30bd9305fb3a6a4549fd5b6ca2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0e349576811fa2fa0c99b7461d020dc8b0dc4320e0cfead5adc3fddd237c2a3b99b1d6c85729ee5d05c9d1b0fd74b89553b381da514c149fe62bb7d7b813a27
|
7
|
+
data.tar.gz: 47b74fb77924ee62e500a526094f57057bc1b1d997d1944c4559115ddc36febe3f36dcd71730458ee1285c30879b6997570bf7a31d411dd56cedda4c99ffc635
|
data/README.md
CHANGED
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)
|
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 =
|
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
|
-
|
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 -
|
82
|
+
rm -rf .deps .linked .tested* Gemfile.lock *.gem acceptance
|
76
83
|
.PHONY: clean-ruby
|
data/examples.txt
CHANGED
@@ -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]
|
@@ -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(/\
|
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(/\
|
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 {|
|
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:
|
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-
|
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
|
-
|
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-
|
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
|