gherkin 3.2.0 → 4.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/LICENSE +1 -1
- data/Makefile +5 -1
- data/bin/gherkin-generate-ast +2 -1
- data/bin/gherkin-generate-pickles +2 -1
- data/bin/gherkin-generate-tokens +2 -1
- data/gherkin-ruby.razor +4 -4
- data/gherkin.gemspec +1 -1
- data/lib/gherkin/ast_builder.rb +24 -10
- data/lib/gherkin/dialect.rb +1 -1
- data/lib/gherkin/gherkin-languages.json +1 -0
- data/lib/gherkin/parser.rb +561 -154
- data/lib/gherkin/pickles/compiler.rb +22 -22
- data/lib/gherkin/token_matcher.rb +2 -2
- data/lib/gherkin/token_scanner.rb +2 -2
- data/spec/gherkin/parser_spec.rb +204 -70
- metadata +3 -3
@@ -1,20 +1,21 @@
|
|
1
|
-
require_relative '../dialect'
|
2
|
-
|
3
1
|
module Gherkin
|
4
2
|
module Pickles
|
5
3
|
class Compiler
|
6
|
-
def compile(
|
4
|
+
def compile(gherkin_document, path)
|
7
5
|
pickles = []
|
8
|
-
dialect = Dialect.for(feature[:language])
|
9
6
|
|
7
|
+
return pickles unless gherkin_document[:feature]
|
8
|
+
feature = gherkin_document[:feature]
|
10
9
|
feature_tags = feature[:tags]
|
11
|
-
background_steps =
|
10
|
+
background_steps = []
|
12
11
|
|
13
|
-
feature[:
|
14
|
-
if(scenario_definition[:type] == :
|
15
|
-
|
12
|
+
feature[:children].each do |scenario_definition|
|
13
|
+
if(scenario_definition[:type] == :Background)
|
14
|
+
background_steps = pickle_steps(scenario_definition, path)
|
15
|
+
elsif(scenario_definition[:type] == :Scenario)
|
16
|
+
compile_scenario(feature_tags, background_steps, scenario_definition, path, pickles)
|
16
17
|
else
|
17
|
-
compile_scenario_outline(feature_tags, background_steps, scenario_definition,
|
18
|
+
compile_scenario_outline(feature_tags, background_steps, scenario_definition, path, pickles)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
return pickles
|
@@ -22,7 +23,9 @@ module Gherkin
|
|
22
23
|
|
23
24
|
private
|
24
25
|
|
25
|
-
def compile_scenario(feature_tags, background_steps, scenario,
|
26
|
+
def compile_scenario(feature_tags, background_steps, scenario, path, pickles)
|
27
|
+
return if scenario[:steps].empty?
|
28
|
+
|
26
29
|
steps = [].concat(background_steps)
|
27
30
|
|
28
31
|
tags = [].concat(feature_tags).concat(scenario[:tags])
|
@@ -33,16 +36,17 @@ module Gherkin
|
|
33
36
|
|
34
37
|
pickle = {
|
35
38
|
tags: pickle_tags(tags, path),
|
36
|
-
name: scenario[:
|
39
|
+
name: scenario[:name],
|
37
40
|
locations: [pickle_location(scenario[:location], path)],
|
38
41
|
steps: steps
|
39
42
|
}
|
40
43
|
pickles.push(pickle)
|
41
44
|
end
|
42
45
|
|
43
|
-
def compile_scenario_outline(feature_tags, background_steps, scenario_outline,
|
44
|
-
|
45
|
-
|
46
|
+
def compile_scenario_outline(feature_tags, background_steps, scenario_outline, path, pickles)
|
47
|
+
return if scenario_outline[:steps].empty?
|
48
|
+
|
49
|
+
scenario_outline[:examples].reject { |examples| examples[:tableHeader].nil? }.each do |examples|
|
46
50
|
variable_cells = examples[:tableHeader][:cells]
|
47
51
|
examples[:tableBody].each do |values|
|
48
52
|
value_cells = values[:cells]
|
@@ -64,7 +68,7 @@ module Gherkin
|
|
64
68
|
end
|
65
69
|
|
66
70
|
pickle = {
|
67
|
-
name:
|
71
|
+
name: interpolate(scenario_outline[:name], variable_cells, value_cells),
|
68
72
|
steps: steps,
|
69
73
|
tags: pickle_tags(tags, path),
|
70
74
|
locations: [
|
@@ -115,13 +119,9 @@ module Gherkin
|
|
115
119
|
name
|
116
120
|
end
|
117
121
|
|
118
|
-
def
|
119
|
-
|
120
|
-
|
121
|
-
pickle_step(step, path)
|
122
|
-
end
|
123
|
-
else
|
124
|
-
[]
|
122
|
+
def pickle_steps(scenario_definition, path)
|
123
|
+
scenario_definition[:steps].map do |step|
|
124
|
+
pickle_step(step, path)
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
data/spec/gherkin/parser_spec.rb
CHANGED
@@ -12,45 +12,167 @@ module Gherkin
|
|
12
12
|
scanner = TokenScanner.new("Feature: test")
|
13
13
|
ast = parser.parse(scanner)
|
14
14
|
expect(ast).to eq({
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
feature: {
|
16
|
+
type: :Feature,
|
17
|
+
tags: [],
|
18
|
+
location: {line: 1, column: 1},
|
19
|
+
language: "en",
|
20
|
+
keyword: "Feature",
|
21
|
+
name: "test",
|
22
|
+
children: []
|
23
|
+
},
|
24
|
+
comments: [],
|
25
|
+
type: :GherkinDocument
|
23
26
|
})
|
24
27
|
end
|
25
28
|
|
29
|
+
it "parses a complex feature" do
|
30
|
+
# This should include every significant type of thing within the language
|
31
|
+
feature_text = "@feature_tag\n" +
|
32
|
+
"Feature: feature name\n" +
|
33
|
+
" feature description\n" +
|
34
|
+
"\n" +
|
35
|
+
" Background: background name\n" +
|
36
|
+
" background description\n" +
|
37
|
+
" * a step\n" +
|
38
|
+
"\n" +
|
39
|
+
" @scenario_tag\n" +
|
40
|
+
" Scenario: scenario name\n" +
|
41
|
+
" scenario description\n" +
|
42
|
+
" * a step with a table\n" +
|
43
|
+
" | a table |\n" +
|
44
|
+
"\n" +
|
45
|
+
" @outline_tag\n" +
|
46
|
+
" Scenario Outline: outline name\n" +
|
47
|
+
" outline description\n" +
|
48
|
+
" * a step with a doc string\n" +
|
49
|
+
" \"\"\" content_type\n" +
|
50
|
+
" lots of text\n" +
|
51
|
+
" \"\"\"\n" +
|
52
|
+
" # Random file comment\n" +
|
53
|
+
" @example_tag\n" +
|
54
|
+
" Examples: examples name\n" +
|
55
|
+
" examples description\n" +
|
56
|
+
" | param |\n" +
|
57
|
+
" | value |\n"
|
58
|
+
|
59
|
+
parser = Parser.new
|
60
|
+
scanner = TokenScanner.new(feature_text)
|
61
|
+
ast = parser.parse(scanner)
|
62
|
+
|
63
|
+
expect(ast).to eq({
|
64
|
+
feature: {type: :Feature,
|
65
|
+
tags: [{type: :Tag,
|
66
|
+
location: {line: 1, column: 1},
|
67
|
+
name: "@feature_tag"}],
|
68
|
+
location: {line: 2, column: 1},
|
69
|
+
language: "en",
|
70
|
+
keyword: "Feature",
|
71
|
+
name: "feature name",
|
72
|
+
description: " feature description",
|
73
|
+
children: [{type: :Background,
|
74
|
+
location: {line: 5, column: 4},
|
75
|
+
keyword: "Background",
|
76
|
+
name: "background name",
|
77
|
+
description: " background description",
|
78
|
+
steps: [{type: :Step,
|
79
|
+
location: {line: 7, column: 5},
|
80
|
+
keyword: "* ",
|
81
|
+
text: "a step"}]},
|
82
|
+
{type: :Scenario,
|
83
|
+
tags: [{type: :Tag,
|
84
|
+
location: {line: 9, column: 3},
|
85
|
+
name: "@scenario_tag"}],
|
86
|
+
location: {line: 10, column: 3},
|
87
|
+
keyword: "Scenario",
|
88
|
+
name: "scenario name",
|
89
|
+
description: " scenario description",
|
90
|
+
steps: [{type: :Step,
|
91
|
+
location: {line: 12, column: 5},
|
92
|
+
keyword: "* ",
|
93
|
+
text: "a step with a table",
|
94
|
+
argument: {type: :DataTable,
|
95
|
+
location: {line: 13, column: 7},
|
96
|
+
rows: [{type: :TableRow,
|
97
|
+
location: {line: 13, column: 7},
|
98
|
+
cells: [{type: :TableCell,
|
99
|
+
location: {line: 13, column: 9},
|
100
|
+
value: "a table"}]}]}}]},
|
101
|
+
{type: :ScenarioOutline,
|
102
|
+
tags: [{type: :Tag,
|
103
|
+
location: {line: 15, column: 3},
|
104
|
+
name: "@outline_tag"}],
|
105
|
+
location: {line: 16, column: 3},
|
106
|
+
keyword: "Scenario Outline",
|
107
|
+
name: "outline name",
|
108
|
+
description: " outline description",
|
109
|
+
steps: [{type: :Step,
|
110
|
+
location: {line: 18, column: 5},
|
111
|
+
keyword: "* ",
|
112
|
+
text: "a step with a doc string",
|
113
|
+
argument: {type: :DocString,
|
114
|
+
location: {line: 19, column: 7},
|
115
|
+
contentType: "content_type",
|
116
|
+
content: " lots of text"}}],
|
117
|
+
examples: [{type: :Examples,
|
118
|
+
tags: [{type: :Tag,
|
119
|
+
location: {line: 23, column: 3},
|
120
|
+
name: "@example_tag"}],
|
121
|
+
location: {line: 24, column: 3},
|
122
|
+
keyword: "Examples",
|
123
|
+
name: "examples name",
|
124
|
+
description: " examples description",
|
125
|
+
tableHeader: {type: :TableRow,
|
126
|
+
location: {line: 26, column: 5},
|
127
|
+
cells: [{type: :TableCell,
|
128
|
+
location: {line: 26, column: 7},
|
129
|
+
value: "param"}]},
|
130
|
+
tableBody: [{type: :TableRow,
|
131
|
+
location: {line: 27, column: 5},
|
132
|
+
cells: [{type: :TableCell,
|
133
|
+
location: {line: 27, column: 7},
|
134
|
+
value: "value"}]}]}]}],
|
135
|
+
},
|
136
|
+
comments: [{type: :Comment,
|
137
|
+
location: {line: 22, column: 1},
|
138
|
+
text: " # Random file comment"}],
|
139
|
+
type: :GherkinDocument}
|
140
|
+
)
|
141
|
+
end
|
142
|
+
|
26
143
|
it "parses string feature" do
|
27
144
|
parser = Parser.new
|
28
145
|
ast = parser.parse("Feature: test")
|
29
146
|
expect(ast).to eq({
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
147
|
+
feature: {
|
148
|
+
type: :Feature,
|
149
|
+
tags: [],
|
150
|
+
location: {line: 1, column: 1},
|
151
|
+
language: "en",
|
152
|
+
keyword: "Feature",
|
153
|
+
name: "test",
|
154
|
+
children: []
|
155
|
+
},
|
156
|
+
comments: [],
|
157
|
+
type: :GherkinDocument
|
38
158
|
})
|
39
159
|
end
|
40
160
|
|
41
161
|
it "parses io feature" do
|
42
162
|
parser = Parser.new
|
43
163
|
ast = parser.parse(StringIO.new("Feature: test"))
|
44
|
-
|
45
164
|
expect(ast).to eq({
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
165
|
+
feature: {
|
166
|
+
type: :Feature,
|
167
|
+
tags: [],
|
168
|
+
location: {line: 1, column: 1},
|
169
|
+
language: "en",
|
170
|
+
keyword: "Feature",
|
171
|
+
name: "test",
|
172
|
+
children: []
|
173
|
+
},
|
174
|
+
comments: [],
|
175
|
+
type: :GherkinDocument
|
54
176
|
})
|
55
177
|
end
|
56
178
|
|
@@ -60,24 +182,30 @@ module Gherkin
|
|
60
182
|
ast2 = parser.parse(TokenScanner.new("Feature: test2"))
|
61
183
|
|
62
184
|
expect(ast1).to eq({
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
185
|
+
feature: {
|
186
|
+
type: :Feature,
|
187
|
+
tags: [],
|
188
|
+
location: {line: 1, column: 1},
|
189
|
+
language: "en",
|
190
|
+
keyword: "Feature",
|
191
|
+
name: "test",
|
192
|
+
children: []
|
193
|
+
},
|
194
|
+
comments: [],
|
195
|
+
type: :GherkinDocument
|
71
196
|
})
|
72
197
|
expect(ast2).to eq({
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
198
|
+
feature: {
|
199
|
+
type: :Feature,
|
200
|
+
tags: [],
|
201
|
+
location: {line: 1, column: 1},
|
202
|
+
language: "en",
|
203
|
+
keyword: "Feature",
|
204
|
+
name: "test2",
|
205
|
+
children: []
|
206
|
+
},
|
207
|
+
comments: [],
|
208
|
+
type: :GherkinDocument
|
81
209
|
})
|
82
210
|
end
|
83
211
|
|
@@ -102,27 +230,30 @@ module Gherkin
|
|
102
230
|
matcher)
|
103
231
|
|
104
232
|
expect(ast).to eq({
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
:
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
:
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
233
|
+
feature: {
|
234
|
+
type: :Feature,
|
235
|
+
tags: [],
|
236
|
+
location: {line: 1, column: 1},
|
237
|
+
language: "en",
|
238
|
+
keyword: "Feature",
|
239
|
+
name: "Foo",
|
240
|
+
children: [{
|
241
|
+
:type=>:Scenario,
|
242
|
+
:tags=>[],
|
243
|
+
:location=>{:line=>2, :column=>3},
|
244
|
+
:keyword=>"Scenario",
|
245
|
+
:name=>"Bar",
|
246
|
+
:steps=>[{
|
247
|
+
:type=>:Step,
|
248
|
+
:location=>{:line=>3, :column=>5},
|
249
|
+
:keyword=>"Given ",
|
250
|
+
:text=>"x",
|
251
|
+
:argument=>{:type=>:DocString,
|
252
|
+
:location=>{:line=>4, :column=>7},
|
253
|
+
:content=>"closed docstring"}}]}]
|
254
|
+
},
|
255
|
+
comments: [],
|
256
|
+
type: :GherkinDocument
|
126
257
|
})
|
127
258
|
end
|
128
259
|
|
@@ -132,14 +263,17 @@ module Gherkin
|
|
132
263
|
scanner = TokenScanner.new("Egenskap: i18n support")
|
133
264
|
ast = parser.parse(scanner, matcher)
|
134
265
|
expect(ast).to eq({
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
266
|
+
feature: {
|
267
|
+
type: :Feature,
|
268
|
+
tags: [],
|
269
|
+
location: {line: 1, column: 1},
|
270
|
+
language: "no",
|
271
|
+
keyword: "Egenskap",
|
272
|
+
name: "i18n support",
|
273
|
+
children: []
|
274
|
+
},
|
275
|
+
comments: [],
|
276
|
+
type: :GherkinDocument
|
143
277
|
})
|
144
278
|
end
|
145
279
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gherkin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.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: 2016-
|
13
|
+
date: 2016-04-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -131,7 +131,7 @@ rubyforge_project:
|
|
131
131
|
rubygems_version: 2.4.5
|
132
132
|
signing_key:
|
133
133
|
specification_version: 4
|
134
|
-
summary: gherkin-
|
134
|
+
summary: gherkin-4.0.0
|
135
135
|
test_files:
|
136
136
|
- spec/capture_warnings.rb
|
137
137
|
- spec/coverage.rb
|