cucumber-expressions 5.0.13 → 5.0.14
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/.travis.yml +6 -4
- data/cucumber-expressions.gemspec +1 -1
- data/lib/cucumber/cucumber_expressions/cucumber_expression.rb +44 -32
- data/lib/cucumber/cucumber_expressions/cucumber_expression_generator.rb +5 -3
- data/lib/cucumber/cucumber_expressions/tree_regexp.rb +3 -0
- data/spec/cucumber/cucumber_expressions/cucumber_expression_generator_spec.rb +17 -0
- data/spec/cucumber/cucumber_expressions/cucumber_expression_spec.rb +5 -1
- data/spec/cucumber/cucumber_expressions/tree_regexp_spec.rb +7 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0bf6d072730fe70e07cee26eb6ad35ea6da0395
|
4
|
+
data.tar.gz: 81fe11dab1fe72475a6d59902c42c83b9c9cf3c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48d4cee7861530cd5643c7737c7ee0aa1ac18c5c573b47eaa6a1ecce1efce1dd3f2d4eed4303d1347e9522f65557f322295dd4c7dd17f28b1c4825ce0e1ebbe3
|
7
|
+
data.tar.gz: 32c6108014efbf5ae47e260580bd919057d08f04c00c90866408d957c6c0525968c2bfb9c9b6a8d833869c0c27775b5eb7cb28faf054e357e348803dd09d4031
|
data/.travis.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'cucumber-expressions'
|
4
|
-
s.version = '5.0.
|
4
|
+
s.version = '5.0.14'
|
5
5
|
s.authors = ["Aslak Hellesøy"]
|
6
6
|
s.description = 'Cucumber Expressions - a simpler alternative to Regular Expressions'
|
7
7
|
s.summary = "cucumber-expressions-#{s.version}"
|
@@ -7,46 +7,24 @@ module Cucumber
|
|
7
7
|
class CucumberExpression
|
8
8
|
# Does not include (){} characters because they have special meaning
|
9
9
|
ESCAPE_REGEXP = /([\\^\[$.|?*+\]])/
|
10
|
-
PARAMETER_REGEXP = /{([^}]+)}/
|
11
|
-
OPTIONAL_REGEXP =
|
10
|
+
PARAMETER_REGEXP = /(\\\\)?{([^}]+)}/
|
11
|
+
OPTIONAL_REGEXP = /(\\\\)?\(([^)]+)\)/
|
12
12
|
ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP = /([^\s^\/]+)((\/[^\s^\/]+)+)/
|
13
|
+
DOUBLE_ESCAPE = '\\\\'
|
13
14
|
|
14
15
|
attr_reader :source
|
15
16
|
|
16
17
|
def initialize(expression, parameter_type_registry)
|
17
18
|
@source = expression
|
18
19
|
@parameter_types = []
|
19
|
-
|
20
|
-
|
20
|
+
|
21
|
+
expression = process_escapes(expression)
|
22
|
+
expression = process_optional(expression)
|
23
|
+
expression = process_alternation(expression)
|
24
|
+
expression = process_parameters(expression, parameter_type_registry)
|
25
|
+
expression = "^#{expression}$"
|
21
26
|
|
22
|
-
|
23
|
-
|
24
|
-
# Create non-capturing, optional capture groups from parenthesis
|
25
|
-
expression = expression.gsub(OPTIONAL_REGEXP, '(?:\1)?')
|
26
|
-
|
27
|
-
expression = expression.gsub(ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP) do |_|
|
28
|
-
"(?:#{$1}#{$2.tr('/', '|')})"
|
29
|
-
end
|
30
|
-
|
31
|
-
loop do
|
32
|
-
match = PARAMETER_REGEXP.match(expression, match_offset)
|
33
|
-
break if match.nil?
|
34
|
-
|
35
|
-
type_name = match[1]
|
36
|
-
|
37
|
-
parameter_type = parameter_type_registry.lookup_by_type_name(type_name)
|
38
|
-
raise UndefinedParameterTypeError.new(type_name) if parameter_type.nil?
|
39
|
-
@parameter_types.push(parameter_type)
|
40
|
-
|
41
|
-
text = expression.slice(match_offset...match.offset(0)[0])
|
42
|
-
capture_regexp = build_capture_regexp(parameter_type.regexps)
|
43
|
-
match_offset = match.offset(0)[1]
|
44
|
-
regexp += text
|
45
|
-
regexp += capture_regexp
|
46
|
-
end
|
47
|
-
regexp += expression.slice(match_offset..-1)
|
48
|
-
regexp += '$'
|
49
|
-
@tree_regexp = TreeRegexp.new(regexp)
|
27
|
+
@tree_regexp = TreeRegexp.new(expression)
|
50
28
|
end
|
51
29
|
|
52
30
|
def match(text)
|
@@ -63,6 +41,40 @@ module Cucumber
|
|
63
41
|
|
64
42
|
private
|
65
43
|
|
44
|
+
def process_escapes(expression)
|
45
|
+
expression.gsub(ESCAPE_REGEXP, '\\\\\1')
|
46
|
+
end
|
47
|
+
|
48
|
+
def process_optional(expression)
|
49
|
+
# Create non-capturing, optional capture groups from parenthesis
|
50
|
+
expression.gsub(OPTIONAL_REGEXP) do
|
51
|
+
# look for double-escaped parentheses
|
52
|
+
$1 == DOUBLE_ESCAPE ? "\\(#{$2}\\)" : "(?:#{$2})?"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def process_alternation(expression)
|
57
|
+
expression.gsub(ALTERNATIVE_NON_WHITESPACE_TEXT_REGEXP) do
|
58
|
+
"(?:#{$1}#{$2.tr('/', '|')})"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def process_parameters(expression, parameter_type_registry)
|
63
|
+
# Create non-capturing, optional capture groups from parenthesis
|
64
|
+
expression.gsub(PARAMETER_REGEXP) do
|
65
|
+
if ($1 == DOUBLE_ESCAPE)
|
66
|
+
"\\{#{$2}\\}"
|
67
|
+
else
|
68
|
+
type_name = $2
|
69
|
+
parameter_type = parameter_type_registry.lookup_by_type_name(type_name)
|
70
|
+
raise UndefinedParameterTypeError.new(type_name) if parameter_type.nil?
|
71
|
+
@parameter_types.push(parameter_type)
|
72
|
+
|
73
|
+
build_capture_regexp(parameter_type.regexps)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
66
78
|
def build_capture_regexp(regexps)
|
67
79
|
return "(#{regexps[0]})" if regexps.size == 1
|
68
80
|
capture_groups = regexps.map { |group| "(?:#{group})" }
|
@@ -51,7 +51,7 @@ module Cucumber
|
|
51
51
|
|
52
52
|
parameter_type_combinations.push(parameter_types)
|
53
53
|
|
54
|
-
expression_template +=
|
54
|
+
expression_template += escape(text.slice(pos...best_parameter_type_matcher.start))
|
55
55
|
expression_template += "{%s}"
|
56
56
|
|
57
57
|
pos = best_parameter_type_matcher.start + best_parameter_type_matcher.group.length
|
@@ -64,7 +64,7 @@ module Cucumber
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
expression_template +=
|
67
|
+
expression_template += escape(text.slice(pos..-1))
|
68
68
|
|
69
69
|
CombinatorialGeneratedExpressionFactory.new(
|
70
70
|
expression_template,
|
@@ -94,8 +94,10 @@ module Cucumber
|
|
94
94
|
result
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
97
|
+
def escape(s)
|
98
98
|
s.gsub(/%/, '%%')
|
99
|
+
.gsub(/\(/, '\\(')
|
100
|
+
.gsub(/\{/, '\\{')
|
99
101
|
end
|
100
102
|
end
|
101
103
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'cucumber/cucumber_expressions/group_builder'
|
2
|
+
require 'cucumber/cucumber_expressions/errors'
|
2
3
|
|
3
4
|
module Cucumber
|
4
5
|
module CucumberExpressions
|
@@ -33,6 +34,8 @@ module Cucumber
|
|
33
34
|
elsif c == ':' && non_capturing_maybe
|
34
35
|
stack.last.set_non_capturing!
|
35
36
|
non_capturing_maybe = false
|
37
|
+
elsif c == '<' && non_capturing_maybe
|
38
|
+
raise CucumberExpressionError.new("Named capture groups are not supported. See https://github.com/cucumber/cucumber/issues/329")
|
36
39
|
end
|
37
40
|
|
38
41
|
escaping = c == '\\' && !escaping
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'cucumber/cucumber_expressions/cucumber_expression_generator'
|
2
|
+
require 'cucumber/cucumber_expressions/cucumber_expression'
|
2
3
|
require 'cucumber/cucumber_expressions/parameter_type'
|
3
4
|
require 'cucumber/cucumber_expressions/parameter_type_registry'
|
4
5
|
|
@@ -28,6 +29,18 @@ module Cucumber
|
|
28
29
|
assert_expression("hello", [], "hello")
|
29
30
|
end
|
30
31
|
|
32
|
+
it "generates expression with escaped left parenthesis" do
|
33
|
+
assert_expression(
|
34
|
+
"\\(iii)", [],
|
35
|
+
"(iii)")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "generates expression with escaped left curly brace" do
|
39
|
+
assert_expression(
|
40
|
+
"\\{iii}", [],
|
41
|
+
"{iii}")
|
42
|
+
end
|
43
|
+
|
31
44
|
it "generates expression for int float arg" do
|
32
45
|
assert_expression(
|
33
46
|
"I have {int} cukes and {float} euro", ["int", "float"],
|
@@ -105,6 +118,10 @@ module Cucumber
|
|
105
118
|
generated_expression = @generator.generate_expression(text)
|
106
119
|
expect(generated_expression.parameter_names).to eq(expected_argument_names)
|
107
120
|
expect(generated_expression.source).to eq(expected_expression)
|
121
|
+
|
122
|
+
cucumber_expression = CucumberExpression.new(generated_expression.source, @parameter_type_registry)
|
123
|
+
match = cucumber_expression.match(text)
|
124
|
+
expect(match.length).to eq(expected_argument_names.length)
|
108
125
|
end
|
109
126
|
end
|
110
127
|
end
|
@@ -26,7 +26,7 @@ module Cucumber
|
|
26
26
|
it('matches multiple double quoted strings') do
|
27
27
|
expect(match('three {string} and {string} mice', 'three "blind" and "crippled" mice')).to eq(['blind', 'crippled'])
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it('matches single quoted string') do
|
31
31
|
expect(match('three {string} mice', "three 'blind' mice")).to eq(['blind'])
|
32
32
|
end
|
@@ -55,6 +55,10 @@ module Cucumber
|
|
55
55
|
expect(match('three {string} mice', "three 'bl\\'nd' mice")).to eq(["bl'nd"])
|
56
56
|
end
|
57
57
|
|
58
|
+
it 'matches escaped parentheses' do
|
59
|
+
expect(match('three \\(exceptionally) {string} mice', 'three (exceptionally) "blind" mice')).to eq(['blind'])
|
60
|
+
end
|
61
|
+
|
58
62
|
it "matches int" do
|
59
63
|
expect(match("{int}", "22")).to eq([22])
|
60
64
|
end
|
@@ -84,6 +84,13 @@ module Cucumber
|
|
84
84
|
group = tr.match("hello")
|
85
85
|
expect(group.value).to eq("hello")
|
86
86
|
end
|
87
|
+
|
88
|
+
it 'throws an error when there are named capture groups because they are buggy in Ruby' do
|
89
|
+
# https://github.com/cucumber/cucumber/issues/329
|
90
|
+
expect {
|
91
|
+
TreeRegexp.new(/^I am a person( named "(?<first_name>.+) (?<last_name>.+)")?$/)
|
92
|
+
}.to raise_error(/Named capture groups are not supported/)
|
93
|
+
end
|
87
94
|
end
|
88
95
|
end
|
89
96
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-expressions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.14
|
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: 2018-
|
11
|
+
date: 2018-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -131,7 +131,7 @@ rubyforge_project:
|
|
131
131
|
rubygems_version: 2.6.8
|
132
132
|
signing_key:
|
133
133
|
specification_version: 4
|
134
|
-
summary: cucumber-expressions-5.0.
|
134
|
+
summary: cucumber-expressions-5.0.14
|
135
135
|
test_files:
|
136
136
|
- spec/capture_warnings.rb
|
137
137
|
- spec/coverage.rb
|