cucumber-gherkin 18.1.1 → 19.0.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/bin/gherkin +6 -28
- data/lib/gherkin.rb +3 -3
- data/lib/gherkin/ast_builder.rb +45 -46
- data/lib/gherkin/gherkin-languages.json +4 -3
- data/lib/gherkin/gherkin_line.rb +1 -1
- data/lib/gherkin/pickles/compiler.rb +73 -73
- data/lib/gherkin/query.rb +16 -16
- data/lib/gherkin/stream/parser_message_stream.rb +19 -19
- data/lib/gherkin/token_scanner.rb +1 -1
- data/spec/gherkin/query_spec.rb +29 -32
- data/spec/gherkin/stream/parser_message_stream_spec.rb +6 -6
- metadata +10 -13
- data/lib/gherkin/stream/subprocess_message_stream.rb +0 -26
- data/spec/gherkin/stream/subprocess_message_stream_spec.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae75939385e17d02883ed75667a2d1034016602864c9a315367298774e972fe2
|
4
|
+
data.tar.gz: ebf7593f646b841f9bafa394973640a1930785ee75c5818f6bfd3996829a07d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42e4469320d69329ac01bebd5ef69e08ad67d87cefaff6d0c14264e6752817c927808675a9b158ccd0e7fd1a56c525ef9dd23ea8fc6de7839b7708dba588f118
|
7
|
+
data.tar.gz: 527c28e2cc74360692db23cc8824fd2124c2ada9eed56d40d7734f543887025fd2cfb532ec2ab2176680027b46c0fbb9532f0dc4c7a0ab296c6037c2376037c5
|
data/bin/gherkin
CHANGED
@@ -6,13 +6,11 @@ require 'optparse'
|
|
6
6
|
require 'json'
|
7
7
|
require 'cucumber/messages'
|
8
8
|
require 'gherkin'
|
9
|
-
require 'gherkin/stream/subprocess_message_stream'
|
10
9
|
|
11
10
|
options = {
|
12
11
|
include_source: true,
|
13
12
|
include_gherkin_document: true,
|
14
13
|
include_pickles: true,
|
15
|
-
format: 'protobuf',
|
16
14
|
predictable_ids: false
|
17
15
|
}
|
18
16
|
|
@@ -26,9 +24,6 @@ OptionParser.new do |opts|
|
|
26
24
|
opts.on("--[no-]pickles", "Don't print pickle messages") do |v|
|
27
25
|
options[:include_pickles] = v
|
28
26
|
end
|
29
|
-
opts.on("--format ndjson|protobuf", "Output format") do |v|
|
30
|
-
options[:format] = v
|
31
|
-
end
|
32
27
|
opts.on("--predictable-ids", "Generate incrementing ids rather than UUIDs") do |v|
|
33
28
|
options[:id_generator] = Cucumber::Messages::IdGenerator::Incrementing.new if v
|
34
29
|
end
|
@@ -36,33 +31,16 @@ end.parse!
|
|
36
31
|
|
37
32
|
def process_messages(messages, options)
|
38
33
|
messages.each do |message|
|
39
|
-
|
40
|
-
|
41
|
-
elsif options[:format] == 'protobuf'
|
42
|
-
message.write_delimited_to(STDOUT)
|
43
|
-
else
|
44
|
-
raise "Unsupported format: #{options[:format]}"
|
45
|
-
end
|
34
|
+
STDOUT.write(JSON.fast_generate(message))
|
35
|
+
STDOUT.write("\n")
|
46
36
|
end
|
47
37
|
end
|
48
38
|
|
49
|
-
gherkin_executable = ENV['GHERKIN_EXECUTABLE']
|
50
39
|
if ARGV.empty?
|
51
|
-
# Read
|
52
|
-
messages = Cucumber::Messages::
|
53
|
-
elsif gherkin_executable
|
54
|
-
# Read protobuf from STDIN
|
55
|
-
messages = Gherkin::Stream::SubprocessMessageStream.new(
|
56
|
-
gherkin_executable,
|
57
|
-
ARGV,
|
58
|
-
options[:include_source],
|
59
|
-
options[:include_gherkin_document],
|
60
|
-
options[:include_pickles]
|
61
|
-
).messages
|
40
|
+
# Read from STDIN
|
41
|
+
messages = Cucumber::Messages::NdjsonToMessageEnumerator.new(STDIN)
|
62
42
|
else
|
63
|
-
messages = Gherkin.from_paths(
|
64
|
-
ARGV,
|
65
|
-
options
|
66
|
-
)
|
43
|
+
messages = Gherkin.from_paths(ARGV, options)
|
67
44
|
end
|
45
|
+
|
68
46
|
process_messages(messages, options)
|
data/lib/gherkin.rb
CHANGED
@@ -30,10 +30,10 @@ module Gherkin
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def self.encode_source_message(uri, data)
|
33
|
-
|
33
|
+
{
|
34
34
|
uri: uri,
|
35
35
|
data: data,
|
36
|
-
|
37
|
-
}
|
36
|
+
mediaType: 'text/x.cucumber.gherkin+plain'
|
37
|
+
}
|
38
38
|
end
|
39
39
|
end
|
data/lib/gherkin/ast_builder.rb
CHANGED
@@ -24,10 +24,10 @@ module Gherkin
|
|
24
24
|
|
25
25
|
def build(token)
|
26
26
|
if token.matched_type == :Comment
|
27
|
-
@comments.push(
|
27
|
+
@comments.push({
|
28
28
|
location: get_location(token, 0),
|
29
29
|
text: token.matched_text
|
30
|
-
)
|
30
|
+
})
|
31
31
|
else
|
32
32
|
current_node.add(token.matched_type, token)
|
33
33
|
end
|
@@ -43,10 +43,10 @@ module Gherkin
|
|
43
43
|
|
44
44
|
def get_location(token, column)
|
45
45
|
column = column == 0 ? token.location[:column] : column
|
46
|
-
|
46
|
+
{
|
47
47
|
line: token.location[:line],
|
48
48
|
column: column
|
49
|
-
|
49
|
+
}.delete_if {|k,v| v.nil?}
|
50
50
|
end
|
51
51
|
|
52
52
|
def get_tags(node)
|
@@ -56,11 +56,11 @@ module Gherkin
|
|
56
56
|
|
57
57
|
tags_node.get_tokens(:TagLine).each do |token|
|
58
58
|
token.matched_items.each do |tag_item|
|
59
|
-
tags.push(
|
59
|
+
tags.push({
|
60
60
|
location: get_location(token, tag_item.column),
|
61
61
|
name: tag_item.text,
|
62
62
|
id: @id_generator.new_id
|
63
|
-
)
|
63
|
+
})
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
@@ -69,11 +69,11 @@ module Gherkin
|
|
69
69
|
|
70
70
|
def get_table_rows(node)
|
71
71
|
rows = node.get_tokens(:TableRow).map do |token|
|
72
|
-
|
72
|
+
{
|
73
73
|
id: @id_generator.new_id,
|
74
74
|
location: get_location(token, 0),
|
75
75
|
cells: get_cells(token)
|
76
|
-
|
76
|
+
}
|
77
77
|
end
|
78
78
|
ensure_cell_count(rows)
|
79
79
|
rows
|
@@ -81,26 +81,25 @@ module Gherkin
|
|
81
81
|
|
82
82
|
def ensure_cell_count(rows)
|
83
83
|
return if rows.empty?
|
84
|
-
cell_count = rows[0]
|
84
|
+
cell_count = rows[0][:cells].length
|
85
85
|
rows.each do |row|
|
86
|
-
if row
|
87
|
-
|
88
|
-
raise AstBuilderException.new("inconsistent cell count within the table", location)
|
86
|
+
if row[:cells].length != cell_count
|
87
|
+
raise AstBuilderException.new("inconsistent cell count within the table", row[:location])
|
89
88
|
end
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
93
92
|
def get_cells(table_row_token)
|
94
93
|
table_row_token.matched_items.map do |cell_item|
|
95
|
-
|
94
|
+
{
|
96
95
|
location: get_location(table_row_token, cell_item.column),
|
97
96
|
value: cell_item.text
|
98
|
-
|
97
|
+
}
|
99
98
|
end
|
100
99
|
end
|
101
100
|
|
102
101
|
def get_description(node)
|
103
|
-
node.get_single(:Description)
|
102
|
+
node.get_single(:Description) || ''
|
104
103
|
end
|
105
104
|
|
106
105
|
def get_steps(node)
|
@@ -114,45 +113,45 @@ module Gherkin
|
|
114
113
|
data_table = node.get_single(:DataTable)
|
115
114
|
doc_string = node.get_single(:DocString)
|
116
115
|
|
117
|
-
|
116
|
+
step = {
|
118
117
|
location: get_location(step_line, 0),
|
119
118
|
keyword: step_line.matched_keyword,
|
120
119
|
text: step_line.matched_text,
|
121
|
-
|
122
|
-
|
120
|
+
dataTable: data_table,
|
121
|
+
docString: doc_string,
|
123
122
|
id: @id_generator.new_id
|
124
|
-
|
123
|
+
}.delete_if {|k,v| v.nil?}
|
125
124
|
when :DocString
|
126
125
|
separator_token = node.get_tokens(:DocStringSeparator)[0]
|
127
126
|
media_type = separator_token.matched_text == '' ? nil : separator_token.matched_text
|
128
127
|
line_tokens = node.get_tokens(:Other)
|
129
128
|
content = line_tokens.map { |t| t.matched_text }.join("\n")
|
130
129
|
|
131
|
-
|
130
|
+
{
|
132
131
|
location: get_location(separator_token, 0),
|
133
132
|
content: content,
|
134
133
|
delimiter: separator_token.matched_keyword,
|
135
|
-
|
136
|
-
|
134
|
+
mediaType: media_type,
|
135
|
+
}.delete_if {|k,v| v.nil?}
|
137
136
|
when :DataTable
|
138
137
|
rows = get_table_rows(node)
|
139
|
-
|
140
|
-
location: rows[0]
|
138
|
+
{
|
139
|
+
location: rows[0][:location],
|
141
140
|
rows: rows,
|
142
|
-
|
141
|
+
}.delete_if {|k,v| v.nil?}
|
143
142
|
when :Background
|
144
143
|
background_line = node.get_token(:BackgroundLine)
|
145
144
|
description = get_description(node)
|
146
145
|
steps = get_steps(node)
|
147
146
|
|
148
|
-
|
147
|
+
{
|
149
148
|
id: @id_generator.new_id,
|
150
149
|
location: get_location(background_line, 0),
|
151
150
|
keyword: background_line.matched_keyword,
|
152
151
|
name: background_line.matched_text,
|
153
152
|
description: description,
|
154
153
|
steps: steps
|
155
|
-
|
154
|
+
}.delete_if {|k,v| v.nil?}
|
156
155
|
when :ScenarioDefinition
|
157
156
|
tags = get_tags(node)
|
158
157
|
scenario_node = node.get_single(:Scenario)
|
@@ -160,7 +159,7 @@ module Gherkin
|
|
160
159
|
description = get_description(scenario_node)
|
161
160
|
steps = get_steps(scenario_node)
|
162
161
|
examples = scenario_node.get_items(:ExamplesDefinition)
|
163
|
-
|
162
|
+
{
|
164
163
|
id: @id_generator.new_id,
|
165
164
|
tags: tags,
|
166
165
|
location: get_location(scenario_line, 0),
|
@@ -169,7 +168,7 @@ module Gherkin
|
|
169
168
|
description: description,
|
170
169
|
steps: steps,
|
171
170
|
examples: examples
|
172
|
-
|
171
|
+
}.delete_if {|k,v| v.nil?}
|
173
172
|
when :ExamplesDefinition
|
174
173
|
tags = get_tags(node)
|
175
174
|
examples_node = node.get_single(:Examples)
|
@@ -178,18 +177,18 @@ module Gherkin
|
|
178
177
|
rows = examples_node.get_single(:ExamplesTable)
|
179
178
|
|
180
179
|
table_header = rows.nil? ? nil : rows.first
|
181
|
-
table_body = rows.nil? ?
|
180
|
+
table_body = rows.nil? ? [] : rows[1..-1]
|
182
181
|
|
183
|
-
|
182
|
+
{
|
184
183
|
id: @id_generator.new_id,
|
185
184
|
tags: tags,
|
186
185
|
location: get_location(examples_line, 0),
|
187
186
|
keyword: examples_line.matched_keyword,
|
188
187
|
name: examples_line.matched_text,
|
189
188
|
description: description,
|
190
|
-
|
191
|
-
|
192
|
-
|
189
|
+
tableHeader: table_header,
|
190
|
+
tableBody: table_body,
|
191
|
+
}.delete_if {|k,v| v.nil?}
|
193
192
|
when :ExamplesTable
|
194
193
|
get_table_rows(node)
|
195
194
|
when :Description
|
@@ -206,17 +205,17 @@ module Gherkin
|
|
206
205
|
return unless feature_line
|
207
206
|
children = []
|
208
207
|
background = node.get_single(:Background)
|
209
|
-
children.push(
|
208
|
+
children.push({background: background}) if background
|
210
209
|
node.get_items(:ScenarioDefinition).each do |scenario|
|
211
|
-
children.push(
|
210
|
+
children.push({scenario: scenario})
|
212
211
|
end
|
213
212
|
node.get_items(:Rule).each do |rule|
|
214
|
-
children.push(
|
213
|
+
children.push({rule: rule})
|
215
214
|
end
|
216
215
|
description = get_description(header)
|
217
216
|
language = feature_line.matched_gherkin_dialect
|
218
217
|
|
219
|
-
|
218
|
+
{
|
220
219
|
tags: tags,
|
221
220
|
location: get_location(feature_line, 0),
|
222
221
|
language: language,
|
@@ -224,7 +223,7 @@ module Gherkin
|
|
224
223
|
name: feature_line.matched_text,
|
225
224
|
description: description,
|
226
225
|
children: children,
|
227
|
-
|
226
|
+
}.delete_if {|k,v| v.nil?}
|
228
227
|
when :Rule
|
229
228
|
header = node.get_single(:RuleHeader)
|
230
229
|
return unless header
|
@@ -233,13 +232,13 @@ module Gherkin
|
|
233
232
|
tags = get_tags(header)
|
234
233
|
children = []
|
235
234
|
background = node.get_single(:Background)
|
236
|
-
children.push(
|
235
|
+
children.push({background: background}) if background
|
237
236
|
node.get_items(:ScenarioDefinition).each do |scenario|
|
238
|
-
children.push(
|
237
|
+
children.push({scenario: scenario})
|
239
238
|
end
|
240
239
|
description = get_description(header)
|
241
240
|
|
242
|
-
|
241
|
+
{
|
243
242
|
id: @id_generator.new_id,
|
244
243
|
tags: tags,
|
245
244
|
location: get_location(rule_line, 0),
|
@@ -247,13 +246,13 @@ module Gherkin
|
|
247
246
|
name: rule_line.matched_text,
|
248
247
|
description: description,
|
249
248
|
children: children,
|
250
|
-
|
249
|
+
}.delete_if {|k,v| v.nil?}
|
251
250
|
when :GherkinDocument
|
252
251
|
feature = node.get_single(:Feature)
|
253
252
|
{
|
254
|
-
|
255
|
-
|
256
|
-
}
|
253
|
+
comments: @comments,
|
254
|
+
feature: feature
|
255
|
+
}.delete_if {|k,v| v.nil?}
|
257
256
|
else
|
258
257
|
return node
|
259
258
|
end
|
@@ -26,7 +26,7 @@
|
|
26
26
|
"name": "Afrikaans",
|
27
27
|
"native": "Afrikaans",
|
28
28
|
"rule": [
|
29
|
-
"
|
29
|
+
"Regel"
|
30
30
|
],
|
31
31
|
"scenario": [
|
32
32
|
"Voorbeeld",
|
@@ -1675,7 +1675,7 @@
|
|
1675
1675
|
"name": "Hungarian",
|
1676
1676
|
"native": "magyar",
|
1677
1677
|
"rule": [
|
1678
|
-
"
|
1678
|
+
"Szabály"
|
1679
1679
|
],
|
1680
1680
|
"scenario": [
|
1681
1681
|
"Példa",
|
@@ -2741,7 +2741,8 @@
|
|
2741
2741
|
"Сценарий"
|
2742
2742
|
],
|
2743
2743
|
"scenarioOutline": [
|
2744
|
-
"Структура сценария"
|
2744
|
+
"Структура сценария",
|
2745
|
+
"Шаблон сценария"
|
2745
2746
|
],
|
2746
2747
|
"then": [
|
2747
2748
|
"* ",
|
data/lib/gherkin/gherkin_line.rb
CHANGED
@@ -8,10 +8,10 @@ module Gherkin
|
|
8
8
|
def compile(gherkin_document, source)
|
9
9
|
pickles = []
|
10
10
|
|
11
|
-
return pickles unless gherkin_document
|
12
|
-
feature = gherkin_document
|
13
|
-
language = feature
|
14
|
-
tags = feature
|
11
|
+
return pickles unless gherkin_document[:feature]
|
12
|
+
feature = gherkin_document[:feature]
|
13
|
+
language = feature[:language]
|
14
|
+
tags = feature[:tags]
|
15
15
|
|
16
16
|
compile_feature(pickles, language, tags, feature, source)
|
17
17
|
pickles
|
@@ -21,14 +21,14 @@ module Gherkin
|
|
21
21
|
|
22
22
|
def compile_feature(pickles, language, tags, feature, source)
|
23
23
|
feature_background_steps = []
|
24
|
-
feature
|
25
|
-
if child
|
26
|
-
feature_background_steps.concat(child
|
27
|
-
elsif child
|
28
|
-
compile_rule(pickles, language, tags, feature_background_steps, child
|
24
|
+
feature[:children].each do |child|
|
25
|
+
if child[:background]
|
26
|
+
feature_background_steps.concat(child[:background][:steps])
|
27
|
+
elsif child[:rule]
|
28
|
+
compile_rule(pickles, language, tags, feature_background_steps, child[:rule], source)
|
29
29
|
else
|
30
|
-
scenario = child
|
31
|
-
if scenario
|
30
|
+
scenario = child[:scenario]
|
31
|
+
if scenario[:examples].empty?
|
32
32
|
compile_scenario(tags, feature_background_steps, scenario, language, pickles, source)
|
33
33
|
else
|
34
34
|
compile_scenario_outline(tags, feature_background_steps, scenario, language, pickles, source)
|
@@ -38,15 +38,15 @@ module Gherkin
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def compile_rule(pickles, language, feature_tags, feature_background_steps, rule, source)
|
41
|
-
tags = [].concat(feature_tags).concat(rule
|
41
|
+
tags = [].concat(feature_tags).concat(rule[:tags])
|
42
42
|
|
43
43
|
rule_background_steps = feature_background_steps.dup
|
44
|
-
rule
|
45
|
-
if child
|
46
|
-
rule_background_steps.concat(child
|
44
|
+
rule[:children].each do |child|
|
45
|
+
if child[:background]
|
46
|
+
rule_background_steps.concat(child[:background][:steps])
|
47
47
|
else
|
48
|
-
scenario = child
|
49
|
-
if scenario
|
48
|
+
scenario = child[:scenario]
|
49
|
+
if scenario[:examples].empty?
|
50
50
|
compile_scenario(tags, rule_background_steps, scenario, language, pickles, source)
|
51
51
|
else
|
52
52
|
compile_scenario_outline(tags, rule_background_steps, scenario, language, pickles, source)
|
@@ -56,51 +56,51 @@ module Gherkin
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def compile_scenario(inherited_tags, background_steps, scenario, language, pickles, source)
|
59
|
-
steps = scenario
|
59
|
+
steps = scenario[:steps].empty? ? [] : [].concat(pickle_steps(background_steps))
|
60
60
|
|
61
|
-
tags = [].concat(inherited_tags).concat(scenario
|
61
|
+
tags = [].concat(inherited_tags).concat(scenario[:tags])
|
62
62
|
|
63
|
-
scenario
|
63
|
+
scenario[:steps].each do |step|
|
64
64
|
steps.push(pickle_step(step))
|
65
65
|
end
|
66
66
|
|
67
|
-
pickle =
|
68
|
-
uri: source
|
67
|
+
pickle = {
|
68
|
+
uri: source[:uri],
|
69
69
|
id: @id_generator.new_id,
|
70
70
|
tags: pickle_tags(tags),
|
71
|
-
name: scenario
|
71
|
+
name: scenario[:name],
|
72
72
|
language: language,
|
73
|
-
|
73
|
+
astNodeIds: [scenario[:id]],
|
74
74
|
steps: steps
|
75
|
-
|
75
|
+
}
|
76
76
|
pickles.push(pickle)
|
77
77
|
end
|
78
78
|
|
79
79
|
def compile_scenario_outline(inherited_tags, background_steps, scenario, language, pickles, source)
|
80
|
-
scenario
|
81
|
-
variable_cells = examples
|
82
|
-
examples.
|
83
|
-
value_cells = values_row
|
84
|
-
steps = scenario
|
85
|
-
tags = [].concat(inherited_tags).concat(scenario
|
86
|
-
|
87
|
-
scenario
|
88
|
-
|
89
|
-
steps.push(
|
80
|
+
scenario[:examples].reject { |examples| examples[:tableHeader].nil? }.each do |examples|
|
81
|
+
variable_cells = examples[:tableHeader][:cells]
|
82
|
+
examples[:tableBody].each do |values_row|
|
83
|
+
value_cells = values_row[:cells]
|
84
|
+
steps = scenario[:steps].empty? ? [] : [].concat(pickle_steps(background_steps))
|
85
|
+
tags = [].concat(inherited_tags).concat(scenario[:tags]).concat(examples[:tags])
|
86
|
+
|
87
|
+
scenario[:steps].each do |scenario_step|
|
88
|
+
step = pickle_step_props(scenario_step, variable_cells, values_row)
|
89
|
+
steps.push(step)
|
90
90
|
end
|
91
91
|
|
92
|
-
pickle =
|
93
|
-
uri: source
|
92
|
+
pickle = {
|
93
|
+
uri: source[:uri],
|
94
94
|
id: @id_generator.new_id,
|
95
|
-
name: interpolate(scenario
|
95
|
+
name: interpolate(scenario[:name], variable_cells, value_cells),
|
96
96
|
language: language,
|
97
97
|
steps: steps,
|
98
98
|
tags: pickle_tags(tags),
|
99
|
-
|
100
|
-
scenario
|
101
|
-
values_row
|
99
|
+
astNodeIds: [
|
100
|
+
scenario[:id],
|
101
|
+
values_row[:id]
|
102
102
|
],
|
103
|
-
|
103
|
+
}
|
104
104
|
pickles.push(pickle)
|
105
105
|
|
106
106
|
end
|
@@ -110,7 +110,7 @@ module Gherkin
|
|
110
110
|
def interpolate(name, variable_cells, value_cells)
|
111
111
|
variable_cells.each_with_index do |variable_cell, n|
|
112
112
|
value_cell = value_cells[n]
|
113
|
-
name = name.gsub('<' + variable_cell
|
113
|
+
name = name.gsub('<' + variable_cell[:value] + '>', value_cell[:value])
|
114
114
|
end
|
115
115
|
name
|
116
116
|
end
|
@@ -122,57 +122,57 @@ module Gherkin
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def pickle_step(step)
|
125
|
-
|
125
|
+
pickle_step_props(step, [], nil)
|
126
126
|
end
|
127
127
|
|
128
128
|
def pickle_step_props(step, variable_cells, values_row)
|
129
|
-
value_cells = values_row ? values_row
|
129
|
+
value_cells = values_row ? values_row[:cells] : []
|
130
130
|
props = {
|
131
131
|
id: @id_generator.new_id,
|
132
|
-
|
133
|
-
text: interpolate(step
|
132
|
+
astNodeIds: [step[:id]],
|
133
|
+
text: interpolate(step[:text], variable_cells, value_cells),
|
134
134
|
}
|
135
135
|
if values_row
|
136
|
-
props[:
|
136
|
+
props[:astNodeIds].push(values_row[:id])
|
137
137
|
end
|
138
138
|
|
139
|
-
if step
|
140
|
-
data_table =
|
141
|
-
|
142
|
-
|
139
|
+
if step[:dataTable]
|
140
|
+
data_table = {
|
141
|
+
dataTable: pickle_data_table(step[:dataTable], variable_cells, value_cells)
|
142
|
+
}
|
143
143
|
props[:argument] = data_table
|
144
144
|
end
|
145
|
-
if step
|
146
|
-
doc_string =
|
147
|
-
|
148
|
-
|
145
|
+
if step[:docString]
|
146
|
+
doc_string = {
|
147
|
+
docString: pickle_doc_string(step[:docString], variable_cells, value_cells)
|
148
|
+
}
|
149
149
|
props[:argument] = doc_string
|
150
150
|
end
|
151
151
|
props
|
152
152
|
end
|
153
153
|
|
154
154
|
def pickle_data_table(data_table, variable_cells, value_cells)
|
155
|
-
|
156
|
-
rows: data_table
|
157
|
-
|
158
|
-
cells: row
|
159
|
-
|
160
|
-
value: interpolate(cell
|
161
|
-
|
155
|
+
{
|
156
|
+
rows: data_table[:rows].map do |row|
|
157
|
+
{
|
158
|
+
cells: row[:cells].map do |cell|
|
159
|
+
{
|
160
|
+
value: interpolate(cell[:value], variable_cells, value_cells)
|
161
|
+
}
|
162
162
|
end
|
163
|
-
|
163
|
+
}
|
164
164
|
end
|
165
|
-
|
165
|
+
}
|
166
166
|
end
|
167
167
|
|
168
168
|
def pickle_doc_string(doc_string, variable_cells, value_cells)
|
169
169
|
props = {
|
170
|
-
content: interpolate(doc_string
|
170
|
+
content: interpolate(doc_string[:content], variable_cells, value_cells)
|
171
171
|
}
|
172
|
-
if doc_string
|
173
|
-
props[:
|
172
|
+
if doc_string[:mediaType]
|
173
|
+
props[:mediaType] = interpolate(doc_string[:mediaType], variable_cells, value_cells)
|
174
174
|
end
|
175
|
-
|
175
|
+
props
|
176
176
|
end
|
177
177
|
|
178
178
|
def pickle_tags(tags)
|
@@ -180,10 +180,10 @@ module Gherkin
|
|
180
180
|
end
|
181
181
|
|
182
182
|
def pickle_tag(tag)
|
183
|
-
|
184
|
-
name: tag
|
185
|
-
|
186
|
-
|
183
|
+
{
|
184
|
+
name: tag[:name],
|
185
|
+
astNodeId: tag[:id]
|
186
|
+
}
|
187
187
|
end
|
188
188
|
end
|
189
189
|
end
|
data/lib/gherkin/query.rb
CHANGED
@@ -5,7 +5,7 @@ module Gherkin
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def update(message)
|
8
|
-
update_feature(message
|
8
|
+
update_feature(message[:gherkinDocument][:feature]) if message[:gherkinDocument]
|
9
9
|
end
|
10
10
|
|
11
11
|
def location(ast_node_id)
|
@@ -17,33 +17,33 @@ module Gherkin
|
|
17
17
|
|
18
18
|
def update_feature(feature)
|
19
19
|
return if feature.nil?
|
20
|
-
store_nodes_location(feature
|
20
|
+
store_nodes_location(feature[:tags])
|
21
21
|
|
22
|
-
feature
|
23
|
-
update_rule(child
|
24
|
-
update_background(child
|
25
|
-
update_scenario(child
|
22
|
+
feature[:children].each do |child|
|
23
|
+
update_rule(child[:rule]) if child[:rule]
|
24
|
+
update_background(child[:background]) if child[:background]
|
25
|
+
update_scenario(child[:scenario]) if child[:scenario]
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
def update_rule(rule)
|
30
|
-
rule
|
31
|
-
update_background(child
|
32
|
-
update_scenario(child
|
30
|
+
rule[:children].each do |child|
|
31
|
+
update_background(child[:background]) if child[:background]
|
32
|
+
update_scenario(child[:scenario]) if child[:scenario]
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
def update_background(background)
|
37
|
-
update_steps(background
|
37
|
+
update_steps(background[:steps])
|
38
38
|
end
|
39
39
|
|
40
40
|
def update_scenario(scenario)
|
41
41
|
store_node_location(scenario)
|
42
|
-
store_nodes_location(scenario
|
43
|
-
update_steps(scenario
|
44
|
-
scenario
|
45
|
-
store_nodes_location(examples
|
46
|
-
store_nodes_location(examples
|
42
|
+
store_nodes_location(scenario[:tags])
|
43
|
+
update_steps(scenario[:steps])
|
44
|
+
scenario[:examples].each do |examples|
|
45
|
+
store_nodes_location(examples[:tags] || [])
|
46
|
+
store_nodes_location(examples[:tableBody] || [])
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -56,7 +56,7 @@ module Gherkin
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def store_node_location(node)
|
59
|
-
@ast_node_locations[node
|
59
|
+
@ast_node_locations[node[:id]] = node[:location]
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -23,25 +23,25 @@ module Gherkin
|
|
23
23
|
enumerated = true
|
24
24
|
|
25
25
|
sources.each do |source|
|
26
|
-
y.yield(
|
26
|
+
y.yield({source: source}) if @options[:include_source]
|
27
27
|
begin
|
28
28
|
gherkin_document = nil
|
29
29
|
|
30
30
|
if @options[:include_gherkin_document]
|
31
31
|
gherkin_document = build_gherkin_document(source)
|
32
|
-
y.yield(
|
32
|
+
y.yield({gherkinDocument: gherkin_document})
|
33
33
|
end
|
34
34
|
if @options[:include_pickles]
|
35
35
|
gherkin_document ||= build_gherkin_document(source)
|
36
36
|
pickles = @compiler.compile(gherkin_document, source)
|
37
37
|
pickles.each do |pickle|
|
38
|
-
y.yield(
|
38
|
+
y.yield({pickle: pickle})
|
39
39
|
end
|
40
40
|
end
|
41
41
|
rescue CompositeParserException => err
|
42
|
-
yield_parse_errors(y, err.errors, source
|
42
|
+
yield_parse_errors(y, err.errors, source[:uri])
|
43
43
|
rescue ParserException => err
|
44
|
-
yield_parse_errors(y, [err], source
|
44
|
+
yield_parse_errors(y, [err], source[:uri])
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -51,28 +51,28 @@ module Gherkin
|
|
51
51
|
|
52
52
|
def yield_parse_errors(y, errors, uri)
|
53
53
|
errors.each do |err|
|
54
|
-
parse_error =
|
55
|
-
source:
|
54
|
+
parse_error = {
|
55
|
+
source: {
|
56
56
|
uri: uri,
|
57
|
-
location:
|
57
|
+
location: {
|
58
58
|
line: err.location[:line],
|
59
59
|
column: err.location[:column]
|
60
|
-
|
61
|
-
|
60
|
+
}.delete_if {|k,v| v.nil?}
|
61
|
+
},
|
62
62
|
message: err.message
|
63
|
-
|
64
|
-
y.yield(
|
63
|
+
}
|
64
|
+
y.yield({parseError: parse_error})
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
def sources
|
69
69
|
Enumerator.new do |y|
|
70
70
|
@paths.each do |path|
|
71
|
-
source =
|
71
|
+
source = {
|
72
72
|
uri: path,
|
73
73
|
data: File.open(path, 'r:UTF-8', &:read),
|
74
|
-
|
75
|
-
|
74
|
+
mediaType: 'text/x.cucumber.gherkin+plain'
|
75
|
+
}
|
76
76
|
y.yield(source)
|
77
77
|
end
|
78
78
|
@sources.each do |source|
|
@@ -84,12 +84,12 @@ module Gherkin
|
|
84
84
|
def build_gherkin_document(source)
|
85
85
|
if @options[:default_dialect]
|
86
86
|
token_matcher = TokenMatcher.new(@options[:default_dialect])
|
87
|
-
gd = @parser.parse(source
|
87
|
+
gd = @parser.parse(source[:data], token_matcher)
|
88
88
|
else
|
89
|
-
gd = @parser.parse(source
|
89
|
+
gd = @parser.parse(source[:data])
|
90
90
|
end
|
91
|
-
gd[:uri] = source
|
92
|
-
|
91
|
+
gd[:uri] = source[:uri]
|
92
|
+
gd
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
@@ -25,7 +25,7 @@ module Gherkin
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def read
|
28
|
-
location = {line: @line_number += 1
|
28
|
+
location = {line: @line_number += 1}
|
29
29
|
if @io.nil? || line = @io.gets
|
30
30
|
gherkin_line = line ? GherkinLine.new(line, location[:line]) : nil
|
31
31
|
Token.new(gherkin_line, location)
|
data/spec/gherkin/query_spec.rb
CHANGED
@@ -3,20 +3,17 @@ require 'gherkin'
|
|
3
3
|
require 'gherkin/query'
|
4
4
|
|
5
5
|
describe Gherkin::Query do
|
6
|
-
let(:subject) { Gherkin::Query.new
|
6
|
+
let(:subject) { Gherkin::Query.new }
|
7
7
|
|
8
8
|
def filter_messages_by_attribute(messages, attribute)
|
9
|
-
messages.map
|
10
|
-
return unless message.respond_to?(attribute)
|
11
|
-
message.send(attribute)
|
12
|
-
end.compact
|
9
|
+
messages.select { |message| message.has_key?(attribute) }.map { |message| message[attribute] }
|
13
10
|
end
|
14
11
|
|
15
12
|
def find_message_by_attribute(messages, attribute)
|
16
13
|
filter_messages_by_attribute(messages, attribute).first
|
17
14
|
end
|
18
15
|
|
19
|
-
let(:gherkin_document) { find_message_by_attribute(messages, :
|
16
|
+
let(:gherkin_document) { find_message_by_attribute(messages, :gherkinDocument) }
|
20
17
|
|
21
18
|
let(:messages) {
|
22
19
|
Gherkin.from_source(
|
@@ -80,8 +77,8 @@ describe Gherkin::Query do
|
|
80
77
|
}
|
81
78
|
end
|
82
79
|
|
83
|
-
let(:background) { find_message_by_attribute(gherkin_document
|
84
|
-
let(:scenarios) { filter_messages_by_attribute(gherkin_document
|
80
|
+
let(:background) { find_message_by_attribute(gherkin_document[:feature][:children], :background) }
|
81
|
+
let(:scenarios) { filter_messages_by_attribute(gherkin_document[:feature][:children], :scenario) }
|
85
82
|
let(:scenario) { scenarios.first }
|
86
83
|
|
87
84
|
it 'raises an exception when the AST node ID is unknown' do
|
@@ -89,68 +86,68 @@ describe Gherkin::Query do
|
|
89
86
|
end
|
90
87
|
|
91
88
|
it 'provides the location of a scenario' do
|
92
|
-
expect(subject.location(scenario
|
89
|
+
expect(subject.location(scenario[:id])).to eq(scenario[:location])
|
93
90
|
end
|
94
91
|
|
95
92
|
it 'provides the location of an examples table row' do
|
96
|
-
node = scenarios.last
|
97
|
-
expect(subject.location(node
|
93
|
+
node = scenarios.last[:examples].first[:tableBody].first
|
94
|
+
expect(subject.location(node[:id])).to eq(node[:location])
|
98
95
|
end
|
99
96
|
|
100
97
|
context 'when querying steps' do
|
101
|
-
let(:background_step) { background
|
102
|
-
let(:scenario_step) { scenario
|
98
|
+
let(:background_step) { background[:steps].first }
|
99
|
+
let(:scenario_step) { scenario[:steps].first }
|
103
100
|
|
104
101
|
it 'provides the location of a background step' do
|
105
|
-
expect(subject.location(background_step
|
102
|
+
expect(subject.location(background_step[:id])).to eq(background_step[:location])
|
106
103
|
end
|
107
104
|
|
108
105
|
it 'provides the location of a scenario step' do
|
109
|
-
expect(subject.location(scenario_step
|
106
|
+
expect(subject.location(scenario_step[:id])).to eq(scenario_step[:location])
|
110
107
|
end
|
111
108
|
end
|
112
109
|
|
113
110
|
context 'when querying tags' do
|
114
|
-
let(:feature_tag) { gherkin_document
|
115
|
-
let(:scenario_tag) { scenario
|
116
|
-
let(:example_tag) { scenarios.last
|
111
|
+
let(:feature_tag) { gherkin_document[:feature][:tags].first }
|
112
|
+
let(:scenario_tag) { scenario[:tags].first }
|
113
|
+
let(:example_tag) { scenarios.last[:examples].first[:tags].first }
|
117
114
|
|
118
115
|
it 'provides the location of a feature tags' do
|
119
|
-
expect(subject.location(feature_tag
|
116
|
+
expect(subject.location(feature_tag[:id])).to eq(feature_tag[:location])
|
120
117
|
end
|
121
118
|
|
122
119
|
it 'provides the location of a scenario tags' do
|
123
|
-
expect(subject.location(scenario_tag
|
120
|
+
expect(subject.location(scenario_tag[:id])).to eq(scenario_tag[:location])
|
124
121
|
end
|
125
122
|
|
126
123
|
it 'provides the location of a scenario example tags' do
|
127
|
-
expect(subject.location(example_tag
|
124
|
+
expect(subject.location(example_tag[:id])).to eq(example_tag[:location])
|
128
125
|
end
|
129
126
|
end
|
130
127
|
|
131
128
|
context 'when children are scoped in a Rule' do
|
132
|
-
let(:rule) { find_message_by_attribute(gherkin_document
|
133
|
-
let(:rule_background) { find_message_by_attribute(rule
|
134
|
-
let(:rule_background_step) { rule_background
|
135
|
-
let(:rule_scenario) { find_message_by_attribute(rule
|
136
|
-
let(:rule_scenario_step) { rule_scenario
|
137
|
-
let(:rule_scenario_tag) { rule_scenario
|
129
|
+
let(:rule) { find_message_by_attribute(gherkin_document[:feature][:children], :rule) }
|
130
|
+
let(:rule_background) { find_message_by_attribute(rule[:children], :background) }
|
131
|
+
let(:rule_background_step) { rule_background[:steps].first }
|
132
|
+
let(:rule_scenario) { find_message_by_attribute(rule[:children], :scenario) }
|
133
|
+
let(:rule_scenario_step) { rule_scenario[:steps].first }
|
134
|
+
let(:rule_scenario_tag) { rule_scenario[:tags].first }
|
138
135
|
|
139
136
|
it 'provides the location of a background step' do
|
140
|
-
expect(subject.location(rule_background_step
|
137
|
+
expect(subject.location(rule_background_step[:id])).to eq(rule_background_step[:location])
|
141
138
|
end
|
142
139
|
|
143
140
|
it 'provides the location of a scenario' do
|
144
|
-
expect(subject.location(rule_scenario
|
141
|
+
expect(subject.location(rule_scenario[:id])).to eq(rule_scenario[:location])
|
145
142
|
end
|
146
143
|
|
147
144
|
it 'provides the location of a scenario tag' do
|
148
|
-
expect(subject.location(rule_scenario_tag
|
145
|
+
expect(subject.location(rule_scenario_tag[:id])).to eq(rule_scenario_tag[:location])
|
149
146
|
end
|
150
147
|
|
151
148
|
it 'provides the location of a scenario step' do
|
152
|
-
expect(subject.location(rule_scenario_step
|
149
|
+
expect(subject.location(rule_scenario_step[:id])).to eq(rule_scenario_step[:location])
|
153
150
|
end
|
154
151
|
end
|
155
152
|
end
|
156
|
-
end
|
153
|
+
end
|
@@ -11,11 +11,11 @@ module Gherkin
|
|
11
11
|
}
|
12
12
|
|
13
13
|
let(:source_feature) {
|
14
|
-
|
14
|
+
{
|
15
15
|
uri: '//whatever/uri',
|
16
16
|
data: feature_content,
|
17
|
-
|
18
|
-
}
|
17
|
+
mediaType: 'text/x.cucumber.gherkin+plain'
|
18
|
+
}
|
19
19
|
}
|
20
20
|
|
21
21
|
let(:options) {
|
@@ -25,10 +25,10 @@ module Gherkin
|
|
25
25
|
}
|
26
26
|
|
27
27
|
let(:gherkin_document) {
|
28
|
-
ParserMessageStream.new([], [source_feature], options).messages.first
|
28
|
+
ParserMessageStream.new([], [source_feature], options).messages.first[:gherkinDocument]
|
29
29
|
}
|
30
30
|
|
31
|
-
let(:scenario_id) { gherkin_document
|
31
|
+
let(:scenario_id) { gherkin_document[:feature][:children].first[:scenario][:id] }
|
32
32
|
|
33
33
|
context '#messages' do
|
34
34
|
it "raises an exception on second iteration" do
|
@@ -64,4 +64,4 @@ module Gherkin
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
67
|
-
end
|
67
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-gherkin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 19.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gáspár Nagy
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-05-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: cucumber-messages
|
@@ -18,20 +18,20 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
21
|
+
version: '16.0'
|
22
22
|
- - ">="
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version:
|
24
|
+
version: 16.0.0
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
28
|
requirements:
|
29
29
|
- - "~>"
|
30
30
|
- !ruby/object:Gem::Version
|
31
|
-
version: '
|
31
|
+
version: '16.0'
|
32
32
|
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: 16.0.0
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: rake
|
37
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,7 +95,6 @@ files:
|
|
95
95
|
- lib/gherkin/pickles/compiler.rb
|
96
96
|
- lib/gherkin/query.rb
|
97
97
|
- lib/gherkin/stream/parser_message_stream.rb
|
98
|
-
- lib/gherkin/stream/subprocess_message_stream.rb
|
99
98
|
- lib/gherkin/token.rb
|
100
99
|
- lib/gherkin/token_formatter_builder.rb
|
101
100
|
- lib/gherkin/token_matcher.rb
|
@@ -107,7 +106,6 @@ files:
|
|
107
106
|
- spec/gherkin/parser_spec.rb
|
108
107
|
- spec/gherkin/query_spec.rb
|
109
108
|
- spec/gherkin/stream/parser_message_stream_spec.rb
|
110
|
-
- spec/gherkin/stream/subprocess_message_stream_spec.rb
|
111
109
|
homepage: https://github.com/cucumber/gherkin-ruby
|
112
110
|
licenses:
|
113
111
|
- MIT
|
@@ -136,13 +134,12 @@ requirements: []
|
|
136
134
|
rubygems_version: 3.1.2
|
137
135
|
signing_key:
|
138
136
|
specification_version: 4
|
139
|
-
summary: cucumber-gherkin-
|
137
|
+
summary: cucumber-gherkin-19.0.0
|
140
138
|
test_files:
|
141
139
|
- spec/capture_warnings.rb
|
142
|
-
- spec/gherkin/gherkin_line_spec.rb
|
143
140
|
- spec/gherkin/dialect_spec.rb
|
141
|
+
- spec/gherkin/gherkin_line_spec.rb
|
142
|
+
- spec/gherkin/gherkin_spec.rb
|
144
143
|
- spec/gherkin/parser_spec.rb
|
145
|
-
- spec/gherkin/stream/parser_message_stream_spec.rb
|
146
|
-
- spec/gherkin/stream/subprocess_message_stream_spec.rb
|
147
144
|
- spec/gherkin/query_spec.rb
|
148
|
-
- spec/gherkin/
|
145
|
+
- spec/gherkin/stream/parser_message_stream_spec.rb
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'open3'
|
2
|
-
require 'cucumber/messages'
|
3
|
-
|
4
|
-
module Gherkin
|
5
|
-
module Stream
|
6
|
-
class SubprocessMessageStream
|
7
|
-
def initialize(gherkin_executable, paths, print_source, print_ast, print_pickles)
|
8
|
-
@gherkin_executable, @paths, @print_source, @print_ast, @print_pickles = gherkin_executable, paths, print_source, print_ast, print_pickles
|
9
|
-
end
|
10
|
-
|
11
|
-
def messages
|
12
|
-
args = [@gherkin_executable]
|
13
|
-
args.push('--no-source') unless @print_source
|
14
|
-
args.push('--no-ast') unless @print_ast
|
15
|
-
args.push('--no-pickles') unless @print_pickles
|
16
|
-
args = args.concat(@paths)
|
17
|
-
stdin, stdout, stderr, wait_thr = Open3.popen3(*args)
|
18
|
-
if(stdout.eof?)
|
19
|
-
error = stderr.read
|
20
|
-
raise error
|
21
|
-
end
|
22
|
-
Cucumber::Messages::BinaryToMessageEnumerator.new(stdout)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'rspec'
|
2
|
-
require 'gherkin/stream/subprocess_message_stream'
|
3
|
-
|
4
|
-
module Gherkin
|
5
|
-
module Stream
|
6
|
-
describe SubprocessMessageStream do
|
7
|
-
it "works" do
|
8
|
-
cucumber_messages = SubprocessMessageStream.new(
|
9
|
-
"./bin/gherkin",
|
10
|
-
["testdata/good/minimal.feature"],
|
11
|
-
true, true, true
|
12
|
-
)
|
13
|
-
messages = cucumber_messages.messages.to_a
|
14
|
-
expect(messages.length).to eq(3)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|