cucumber-tag-expressions 6.0.0 → 6.1.0
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/lib/cucumber/tag_expressions/expressions.rb +10 -8
- data/lib/cucumber/tag_expressions/parser.rb +45 -56
- data/lib/cucumber/tag_expressions.rb +2 -0
- data/spec/errors_spec.rb +2 -3
- data/spec/evaluations_spec.rb +1 -2
- data/spec/parsing_spec.rb +2 -3
- data/spec/spec_helper.rb +4 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0f706cda9810598cd7d38933b862a0e50e2870be4525012e64e4b0b6596b3b3
|
4
|
+
data.tar.gz: 40b6af7268af69b1af1406d567cf0e536bd00d6d28dd3a6693a29c822b4e4876
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 838196e211cb93599402f1ae4f928ca91f039a2a3ae5cdf7b1245e1ad8dc5609edf5ca1ce6f6e56d722a642c37a3afa6a7d8c89ce8a0baf3de8f2ee551631287
|
7
|
+
data.tar.gz: 3ab907243a1fa9a2ab3330829650f6fdf8769dcc532b7fddb04bc70bf8acaaa51e5fa74426840975d1bfcf15fd32084a2fcccab0f950d374dd10775457d5d665
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
module TagExpressions
|
3
5
|
# Literal expression node
|
@@ -12,10 +14,10 @@ module Cucumber
|
|
12
14
|
|
13
15
|
def to_s
|
14
16
|
@value
|
15
|
-
.gsub(/\\/,
|
16
|
-
.gsub(/\(/,
|
17
|
-
.gsub(/\)/,
|
18
|
-
.gsub(/\s/,
|
17
|
+
.gsub(/\\/, '\\\\\\\\')
|
18
|
+
.gsub(/\(/, '\\(')
|
19
|
+
.gsub(/\)/, '\\)')
|
20
|
+
.gsub(/\s/, '\\ ')
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
@@ -30,8 +32,8 @@ module Cucumber
|
|
30
32
|
end
|
31
33
|
|
32
34
|
def to_s
|
33
|
-
if @expression.is_a?(And)|| @expression.is_a?(Or)
|
34
|
-
# -- HINT: Binary
|
35
|
+
if @expression.is_a?(And) || @expression.is_a?(Or)
|
36
|
+
# -- HINT: Binary operations already provide "( ... )"
|
35
37
|
"not #{@expression}"
|
36
38
|
else
|
37
39
|
"not ( #{@expression} )"
|
@@ -72,12 +74,12 @@ module Cucumber
|
|
72
74
|
end
|
73
75
|
|
74
76
|
class True
|
75
|
-
def evaluate(
|
77
|
+
def evaluate(_variables)
|
76
78
|
true
|
77
79
|
end
|
78
80
|
|
79
81
|
def to_s
|
80
|
-
|
82
|
+
'true'
|
81
83
|
end
|
82
84
|
end
|
83
85
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cucumber/tag_expressions/expressions'
|
2
4
|
|
3
5
|
module Cucumber
|
4
6
|
module TagExpressions
|
@@ -8,30 +10,29 @@ module Cucumber
|
|
8
10
|
@operators = []
|
9
11
|
|
10
12
|
@operator_types = {
|
11
|
-
'or'
|
13
|
+
'or' => { type: :binary_operator, precedence: 0, assoc: :left },
|
12
14
|
'and' => { type: :binary_operator, precedence: 1, assoc: :left },
|
13
15
|
'not' => { type: :unary_operator, precedence: 2, assoc: :right },
|
14
|
-
')'
|
15
|
-
'('
|
16
|
+
')' => { type: :close_paren, precedence: -1 },
|
17
|
+
'(' => { type: :open_paren, precedence: 1 }
|
16
18
|
}
|
17
19
|
end
|
18
20
|
|
19
21
|
def parse(infix_expression)
|
20
22
|
expected_token_type = :operand
|
21
|
-
|
22
23
|
tokens = tokenize(infix_expression)
|
23
24
|
return True.new if tokens.empty?
|
24
25
|
|
25
26
|
tokens.each do |token|
|
26
27
|
if @operator_types[token]
|
27
|
-
expected_token_type = send("handle_#{@operator_types
|
28
|
+
expected_token_type = send("handle_#{@operator_types.dig(token, :type)}", infix_expression, token, expected_token_type)
|
28
29
|
else
|
29
30
|
expected_token_type = handle_literal(infix_expression, token, expected_token_type)
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
34
|
while @operators.any?
|
34
|
-
raise %
|
35
|
+
raise %{Tag expression "#{infix_expression}" could not be parsed because of syntax error: Unmatched (.} if @operators.last == '('
|
35
36
|
|
36
37
|
push_expression(pop(@operators))
|
37
38
|
end
|
@@ -42,67 +43,56 @@ module Cucumber
|
|
42
43
|
private
|
43
44
|
|
44
45
|
def assoc_of(token, value)
|
45
|
-
@operator_types
|
46
|
+
@operator_types.dig(token, :assoc) == value
|
46
47
|
end
|
47
48
|
|
48
49
|
def lower_precedence?(operation)
|
49
|
-
(assoc_of(operation, :left) &&
|
50
|
-
|
51
|
-
(assoc_of(operation, :right) &&
|
52
|
-
precedence(operation) < precedence(@operators.last))
|
50
|
+
(assoc_of(operation, :left) && precedence(operation) <= precedence(@operators.last)) ||
|
51
|
+
(assoc_of(operation, :right) && precedence(operation) < precedence(@operators.last))
|
53
52
|
end
|
54
53
|
|
55
54
|
def operator?(token)
|
56
|
-
@operator_types
|
57
|
-
@operator_types[token][:type] == :binary_operator
|
55
|
+
[:unary_operator, :binary_operator].include?(@operator_types.dig(token, :type))
|
58
56
|
end
|
59
57
|
|
60
58
|
def precedence(token)
|
61
|
-
@operator_types
|
59
|
+
@operator_types.dig(token, :precedence)
|
62
60
|
end
|
63
61
|
|
64
62
|
def tokenize(infix_expression)
|
65
63
|
tokens = []
|
66
64
|
escaped = false
|
67
|
-
token =
|
68
|
-
infix_expression.chars.each do |
|
65
|
+
token = +''
|
66
|
+
infix_expression.chars.each do |char|
|
69
67
|
if escaped
|
70
|
-
|
71
|
-
|
72
|
-
escaped = false
|
73
|
-
else
|
74
|
-
raise %Q{Tag expression "#{infix_expression}" could not be parsed because of syntax error: Illegal escape before "#{ch}".}
|
68
|
+
unless char == '(' || char == ')' || char == '\\' || whitespace?(char)
|
69
|
+
raise %(Tag expression "#{infix_expression}" could not be parsed because of syntax error: Illegal escape before "#{char}".)
|
75
70
|
end
|
76
|
-
|
71
|
+
|
72
|
+
token += char
|
73
|
+
escaped = false
|
74
|
+
elsif char == '\\'
|
77
75
|
escaped = true
|
78
|
-
elsif
|
79
|
-
if token.length
|
76
|
+
elsif char == '(' || char == ')' || whitespace?(char)
|
77
|
+
if token.length.positive?
|
80
78
|
tokens.push(token)
|
81
|
-
token =
|
82
|
-
end
|
83
|
-
if !ch.match(/\s/)
|
84
|
-
tokens.push(ch)
|
79
|
+
token = +''
|
85
80
|
end
|
81
|
+
tokens.push(char) unless whitespace?(char)
|
86
82
|
else
|
87
|
-
token +=
|
83
|
+
token += char
|
88
84
|
end
|
89
85
|
end
|
90
|
-
if token.length
|
91
|
-
tokens.push(token)
|
92
|
-
end
|
86
|
+
tokens.push(token) if token.length.positive?
|
93
87
|
tokens
|
94
88
|
end
|
95
89
|
|
96
90
|
def push_expression(token)
|
97
91
|
case token
|
98
|
-
when 'and'
|
99
|
-
|
100
|
-
when '
|
101
|
-
|
102
|
-
when 'not'
|
103
|
-
@expressions.push(Not.new(pop(@expressions)))
|
104
|
-
else
|
105
|
-
@expressions.push(Literal.new(token))
|
92
|
+
when 'and'; @expressions.push(And.new(*pop(@expressions, 2)))
|
93
|
+
when 'or'; @expressions.push(Or.new(*pop(@expressions, 2)))
|
94
|
+
when 'not'; @expressions.push(Not.new(pop(@expressions)))
|
95
|
+
else @expressions.push(Literal.new(token))
|
106
96
|
end
|
107
97
|
end
|
108
98
|
|
@@ -114,10 +104,7 @@ module Cucumber
|
|
114
104
|
|
115
105
|
def handle_binary_operator(infix_expression, token, expected_token_type)
|
116
106
|
check(infix_expression, expected_token_type, :operator)
|
117
|
-
while @operators.any? && operator?(@operators.last) &&
|
118
|
-
lower_precedence?(token)
|
119
|
-
push_expression(pop(@operators))
|
120
|
-
end
|
107
|
+
push_expression(pop(@operators)) while @operators.any? && operator?(@operators.last) && lower_precedence?(token)
|
121
108
|
@operators.push(token)
|
122
109
|
:operand
|
123
110
|
end
|
@@ -130,10 +117,8 @@ module Cucumber
|
|
130
117
|
|
131
118
|
def handle_close_paren(infix_expression, _token, expected_token_type)
|
132
119
|
check(infix_expression, expected_token_type, :operator)
|
133
|
-
while @operators.any? && @operators.last != '('
|
134
|
-
|
135
|
-
end
|
136
|
-
raise %Q{Tag expression "#{infix_expression}" could not be parsed because of syntax error: Unmatched ).} if @operators.empty?
|
120
|
+
push_expression(pop(@operators)) while @operators.any? && @operators.last != '('
|
121
|
+
raise %{Tag expression "#{infix_expression}" could not be parsed because of syntax error: Unmatched ).} if @operators.empty?
|
137
122
|
|
138
123
|
pop(@operators) if @operators.last == '('
|
139
124
|
:operator
|
@@ -146,16 +131,20 @@ module Cucumber
|
|
146
131
|
end
|
147
132
|
|
148
133
|
def check(infix_expression, expected_token_type, token_type)
|
149
|
-
if expected_token_type
|
150
|
-
|
151
|
-
|
134
|
+
return if expected_token_type == token_type
|
135
|
+
|
136
|
+
raise %(Tag expression "#{infix_expression}" could not be parsed because of syntax error: Expected #{expected_token_type}.)
|
152
137
|
end
|
153
138
|
|
154
|
-
def pop(array,
|
155
|
-
result = array.pop(
|
156
|
-
raise('Empty stack') if result.
|
139
|
+
def pop(array, amount = 1)
|
140
|
+
result = array.pop(amount)
|
141
|
+
raise('Empty stack') if result.length != amount
|
142
|
+
|
143
|
+
amount == 1 ? result.first : result
|
144
|
+
end
|
157
145
|
|
158
|
-
|
146
|
+
def whitespace?(char)
|
147
|
+
char.match(/\s/)
|
159
148
|
end
|
160
149
|
end
|
161
150
|
end
|
data/spec/errors_spec.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'yaml'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
3
|
tests = YAML.load_file('../testdata/errors.yml')
|
5
4
|
|
@@ -7,7 +6,7 @@ describe 'Errors' do
|
|
7
6
|
tests.each do |test|
|
8
7
|
let(:parser) { Cucumber::TagExpressions::Parser.new }
|
9
8
|
|
10
|
-
it
|
9
|
+
it "fails to parse '#{test['expression']}' with '#{test['error']}'" do
|
11
10
|
expect { parser.parse(test['expression']) }.to raise_error(test['error'])
|
12
11
|
end
|
13
12
|
end
|
data/spec/evaluations_spec.rb
CHANGED
data/spec/parsing_spec.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'yaml'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
3
|
tests = YAML.load_file('../testdata/parsing.yml')
|
5
4
|
|
@@ -7,7 +6,7 @@ describe 'Parsing' do
|
|
7
6
|
let(:parser) { Cucumber::TagExpressions::Parser.new }
|
8
7
|
|
9
8
|
tests.each do |test|
|
10
|
-
it
|
9
|
+
it "parses '#{test['expression']}' into '#{test['formatted']}'" do
|
11
10
|
expect(parser.parse(test['expression']).to_s).to eq(test['formatted'])
|
12
11
|
end
|
13
12
|
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-tag-expressions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrea Nodari
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-01-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- spec/errors_spec.rb
|
73
73
|
- spec/evaluations_spec.rb
|
74
74
|
- spec/parsing_spec.rb
|
75
|
+
- spec/spec_helper.rb
|
75
76
|
homepage: https://cucumber.io/docs/cucumber/api/#tag-expressions
|
76
77
|
licenses:
|
77
78
|
- MIT
|
@@ -100,8 +101,9 @@ requirements: []
|
|
100
101
|
rubygems_version: 3.4.10
|
101
102
|
signing_key:
|
102
103
|
specification_version: 4
|
103
|
-
summary: cucumber-tag-expressions-6.
|
104
|
+
summary: cucumber-tag-expressions-6.1.0
|
104
105
|
test_files:
|
105
106
|
- spec/errors_spec.rb
|
106
107
|
- spec/evaluations_spec.rb
|
107
108
|
- spec/parsing_spec.rb
|
109
|
+
- spec/spec_helper.rb
|