gherkin 2.1.4-i386-mingw32 → 2.1.5-i386-mingw32
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.
- data/History.txt +8 -0
- data/Rakefile +3 -2
- data/VERSION.yml +1 -1
- data/features/json_formatter.feature +62 -36
- data/features/json_parser.feature +51 -37
- data/features/step_definitions/json_formatter_steps.rb +5 -10
- data/lib/gherkin/formatter/filter_formatter.rb +4 -9
- data/lib/gherkin/formatter/json_formatter.rb +48 -23
- data/lib/gherkin/i18n.rb +1 -1
- data/lib/gherkin/json_parser.rb +36 -49
- data/spec/gherkin/fixtures/complex.json +72 -52
- data/spec/gherkin/fixtures/scenario_without_steps.feature +5 -0
- data/spec/gherkin/formatter/filter_formatter_spec.rb +5 -0
- data/spec/gherkin/json_parser_spec.rb +38 -49
- data/tasks/release.rake +1 -1
- metadata +33 -16
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 2.1.5 (2010-07-17)
|
2
|
+
|
3
|
+
=== Bugfixes
|
4
|
+
* Line filter works on JRuby with Scenarios without steps. (Aslak Hellesøy)
|
5
|
+
|
6
|
+
=== Changed Features
|
7
|
+
* The JSON schema now puts background inside the "elements" Array. Makes parsing simpler. (Aslak Hellesøy)
|
8
|
+
|
1
9
|
== 2.1.4 (2010-07-14)
|
2
10
|
|
3
11
|
=== Bugfixes
|
data/Rakefile
CHANGED
@@ -19,8 +19,9 @@ begin
|
|
19
19
|
gem.authors = ["Mike Sassak", "Gregory Hnatiuk", "Aslak Hellesøy"]
|
20
20
|
gem.executables = ["gherkin"]
|
21
21
|
gem.add_dependency "trollop", "~> 1.16.2"
|
22
|
-
gem.add_development_dependency '
|
23
|
-
gem.add_development_dependency
|
22
|
+
gem.add_development_dependency 'awesome_print', '~> 0.2.1'
|
23
|
+
gem.add_development_dependency 'rspec', '~> 2.0.0.beta.17'
|
24
|
+
gem.add_development_dependency "cucumber", "~> 0.8.5"
|
24
25
|
gem.add_development_dependency "rake-compiler", "~> 0.7.0" unless defined?(JRUBY_VERSION)
|
25
26
|
|
26
27
|
gem.files -= FileList['ikvm/**/*']
|
data/VERSION.yml
CHANGED
@@ -16,9 +16,11 @@ Feature: JSON formatter
|
|
16
16
|
Then the outputted JSON should be:
|
17
17
|
"""
|
18
18
|
{
|
19
|
-
"
|
19
|
+
"type": "feature",
|
20
|
+
"comments": [{"value": "# language: no", "line": 1}, {"value": "# Another comment", "line": 2}],
|
20
21
|
"keyword": "Egenskap",
|
21
22
|
"name": "Kjapp",
|
23
|
+
"description": "",
|
22
24
|
"line": 3,
|
23
25
|
"uri": "test.feature"
|
24
26
|
}
|
@@ -71,16 +73,19 @@ Feature: JSON formatter
|
|
71
73
|
Then the outputted JSON should be:
|
72
74
|
"""
|
73
75
|
{
|
76
|
+
"type": "feature",
|
77
|
+
"tags": [{"name": "@one", "line":1}],
|
74
78
|
"keyword": "Feature",
|
75
79
|
"name": "OH HAI",
|
76
|
-
"
|
80
|
+
"description": "",
|
77
81
|
"line": 2,
|
78
82
|
"uri": "test.feature",
|
79
83
|
"elements":[
|
80
84
|
{
|
85
|
+
"type": "scenario",
|
81
86
|
"keyword": "Scenario",
|
82
87
|
"name": "Fujin",
|
83
|
-
"
|
88
|
+
"description": "",
|
84
89
|
"line": 4,
|
85
90
|
"steps": [
|
86
91
|
{
|
@@ -96,10 +101,11 @@ Feature: JSON formatter
|
|
96
101
|
]
|
97
102
|
},
|
98
103
|
{
|
99
|
-
"
|
104
|
+
"type": "scenario",
|
105
|
+
"tags": [{"name": "@two", "line":8}],
|
100
106
|
"keyword": "Scenario",
|
101
107
|
"name": "_why",
|
102
|
-
"
|
108
|
+
"description": "",
|
103
109
|
"line": 9,
|
104
110
|
"steps": [
|
105
111
|
{
|
@@ -115,10 +121,11 @@ Feature: JSON formatter
|
|
115
121
|
]
|
116
122
|
},
|
117
123
|
{
|
118
|
-
"
|
124
|
+
"type": "scenario_outline",
|
125
|
+
"tags": [{"name": "@three", "line":13}, {"name": "@four", "line":13}],
|
119
126
|
"keyword": "Scenario Outline",
|
120
127
|
"name": "Life",
|
121
|
-
"
|
128
|
+
"description": "",
|
122
129
|
"line": 14,
|
123
130
|
"steps": [
|
124
131
|
{
|
@@ -129,9 +136,11 @@ Feature: JSON formatter
|
|
129
136
|
],
|
130
137
|
"examples": [
|
131
138
|
{
|
132
|
-
"
|
139
|
+
"type": "examples",
|
140
|
+
"tags": [{"name": "@five", "line":17}],
|
133
141
|
"keyword": "Examples",
|
134
142
|
"name": "Real life",
|
143
|
+
"description": "",
|
135
144
|
"line": 18,
|
136
145
|
"table": [
|
137
146
|
{
|
@@ -151,39 +160,48 @@ Feature: JSON formatter
|
|
151
160
|
]
|
152
161
|
},
|
153
162
|
{
|
163
|
+
"type": "scenario",
|
154
164
|
"keyword": "Scenario",
|
155
165
|
"name": "who stole my mojo?",
|
156
|
-
"
|
166
|
+
"description": "",
|
157
167
|
"line": 23,
|
158
168
|
"steps": [
|
159
169
|
{
|
160
170
|
"keyword": "When ",
|
161
171
|
"name": "I was",
|
162
172
|
"line": 24,
|
163
|
-
"
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
173
|
+
"multiline_arg": {
|
174
|
+
"type": "table",
|
175
|
+
"value": [
|
176
|
+
{
|
177
|
+
"line": 25,
|
178
|
+
"cells": ["asleep"]
|
179
|
+
}
|
180
|
+
]
|
181
|
+
}
|
169
182
|
},
|
170
183
|
{
|
171
184
|
"keyword": "And ",
|
172
185
|
"name": "so",
|
173
186
|
"line": 26,
|
174
|
-
"
|
187
|
+
"multiline_arg": {
|
188
|
+
"type": "py_string",
|
189
|
+
"value": "innocent",
|
190
|
+
"line": 27
|
191
|
+
}
|
175
192
|
}
|
176
193
|
]
|
177
194
|
},
|
178
195
|
{
|
179
|
-
"comments": ["# The"],
|
180
|
-
"keyword": "Scenario Outline",
|
181
196
|
"type": "scenario_outline",
|
182
|
-
"
|
197
|
+
"comments": [{"value": "# The", "line":31}],
|
198
|
+
"keyword": "Scenario Outline",
|
183
199
|
"name": "with",
|
200
|
+
"description": "",
|
201
|
+
"line": 32,
|
184
202
|
"steps": [
|
185
203
|
{
|
186
|
-
"comments": ["# all"],
|
204
|
+
"comments": [{"value": "# all", "line":33}],
|
187
205
|
"keyword": "Then ",
|
188
206
|
"line": 34,
|
189
207
|
"name": "nice"
|
@@ -191,13 +209,15 @@ Feature: JSON formatter
|
|
191
209
|
],
|
192
210
|
"examples": [
|
193
211
|
{
|
194
|
-
"
|
212
|
+
"type": "examples",
|
213
|
+
"comments": [{"value": "# comments", "line": 36}, {"value": "# everywhere", "line": 37}],
|
195
214
|
"keyword": "Examples",
|
196
215
|
"name": "An example",
|
216
|
+
"description": "",
|
197
217
|
"line": 38,
|
198
218
|
"table": [
|
199
219
|
{
|
200
|
-
"comments": ["# I mean"],
|
220
|
+
"comments": [{"value": "# I mean", "line": 39}],
|
201
221
|
"line": 40,
|
202
222
|
"cells": ["partout"]
|
203
223
|
}
|
@@ -224,27 +244,33 @@ Feature: JSON formatter
|
|
224
244
|
Then the outputted JSON should be:
|
225
245
|
"""
|
226
246
|
{
|
247
|
+
"type": "feature",
|
227
248
|
"keyword": "Feature",
|
228
249
|
"name": "Kjapp",
|
250
|
+
"description": "",
|
229
251
|
"line": 1,
|
230
252
|
"uri": "test.feature",
|
231
|
-
"background": {
|
232
|
-
"keyword": "Background",
|
233
|
-
"line": 3,
|
234
|
-
"name": "No idea what Kjapp means",
|
235
|
-
"steps": [
|
236
|
-
{
|
237
|
-
"keyword": "Given ",
|
238
|
-
"line": 4,
|
239
|
-
"name": "I Google it"
|
240
|
-
}
|
241
|
-
]
|
242
|
-
},
|
243
253
|
"elements": [
|
244
254
|
{
|
245
|
-
"
|
246
|
-
"keyword": "
|
255
|
+
"type": "background",
|
256
|
+
"keyword": "Background",
|
257
|
+
"line": 3,
|
258
|
+
"name": "No idea what Kjapp means",
|
259
|
+
"description": "",
|
260
|
+
"steps": [
|
261
|
+
{
|
262
|
+
"keyword": "Given ",
|
263
|
+
"line": 4,
|
264
|
+
"name": "I Google it"
|
265
|
+
}
|
266
|
+
]
|
267
|
+
},
|
268
|
+
{
|
247
269
|
"type": "scenario",
|
270
|
+
"comments": [{"value": "# Writing JSON by hand sucks", "line": 6}],
|
271
|
+
"keyword": "Scenario",
|
272
|
+
"name": "",
|
273
|
+
"description": "",
|
248
274
|
"line": 7,
|
249
275
|
"steps": [
|
250
276
|
{
|
@@ -10,7 +10,11 @@ Feature: JSON lexer
|
|
10
10
|
Given the following JSON is parsed:
|
11
11
|
"""
|
12
12
|
{
|
13
|
-
"
|
13
|
+
"type": "feature",
|
14
|
+
"comments": [
|
15
|
+
{"value": "# language: no"},
|
16
|
+
{"value": "# Another comment"}
|
17
|
+
],
|
14
18
|
"description": "",
|
15
19
|
"keyword": "Egenskap",
|
16
20
|
"name": "Kjapp",
|
@@ -29,10 +33,11 @@ Feature: JSON lexer
|
|
29
33
|
Given the following JSON is parsed:
|
30
34
|
"""
|
31
35
|
{
|
36
|
+
"type": "feature",
|
32
37
|
"comments": [],
|
33
38
|
"keyword": "Feature",
|
34
39
|
"name": "OH HAI",
|
35
|
-
"tags": ["@one"],
|
40
|
+
"tags": [{"name": "@one"}],
|
36
41
|
"uri": "test.feature",
|
37
42
|
"description": "",
|
38
43
|
"elements":[
|
@@ -61,7 +66,7 @@ Feature: JSON lexer
|
|
61
66
|
},
|
62
67
|
{
|
63
68
|
"comments": [],
|
64
|
-
"tags": ["@two"],
|
69
|
+
"tags": [{"name": "@two"}],
|
65
70
|
"keyword": "Scenario",
|
66
71
|
"name": "_why",
|
67
72
|
"description": "",
|
@@ -84,7 +89,7 @@ Feature: JSON lexer
|
|
84
89
|
},
|
85
90
|
{
|
86
91
|
"comments": [],
|
87
|
-
"tags": ["@three", "@four"],
|
92
|
+
"tags": [{"name": "@three"}, {"name": "@four"}],
|
88
93
|
"keyword": "Scenario Outline",
|
89
94
|
"name": "Life",
|
90
95
|
"description": "",
|
@@ -100,8 +105,9 @@ Feature: JSON lexer
|
|
100
105
|
],
|
101
106
|
"examples": [
|
102
107
|
{
|
108
|
+
"type": "examples",
|
103
109
|
"comments": [],
|
104
|
-
"tags": ["@five"],
|
110
|
+
"tags": [{"name": "@five"}],
|
105
111
|
"keyword": "Examples",
|
106
112
|
"name": "Real life",
|
107
113
|
"description": "",
|
@@ -140,25 +146,32 @@ Feature: JSON lexer
|
|
140
146
|
"keyword": "When ",
|
141
147
|
"name": "I was",
|
142
148
|
"line": 24,
|
143
|
-
"
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
149
|
+
"multiline_arg": {
|
150
|
+
"type": "table",
|
151
|
+
"value": [
|
152
|
+
{
|
153
|
+
"comments": [],
|
154
|
+
"line": 25,
|
155
|
+
"cells": ["asleep"]
|
156
|
+
}
|
157
|
+
]
|
158
|
+
}
|
150
159
|
},
|
151
160
|
{
|
152
161
|
"comments": [],
|
153
162
|
"keyword": "And ",
|
154
163
|
"name": "so",
|
155
164
|
"line": 26,
|
156
|
-
"
|
165
|
+
"multiline_arg": {
|
166
|
+
"type": "py_string",
|
167
|
+
"value": "innocent",
|
168
|
+
"line": 27
|
169
|
+
}
|
157
170
|
}
|
158
171
|
]
|
159
172
|
},
|
160
173
|
{
|
161
|
-
"comments": ["# The"],
|
174
|
+
"comments": [{"value": "# The"}],
|
162
175
|
"tags": [],
|
163
176
|
"keyword": "Scenario Outline",
|
164
177
|
"description": "",
|
@@ -167,7 +180,7 @@ Feature: JSON lexer
|
|
167
180
|
"name": "with",
|
168
181
|
"steps": [
|
169
182
|
{
|
170
|
-
"comments": ["# all"],
|
183
|
+
"comments": [{"value": "# all"}],
|
171
184
|
"keyword": "Then ",
|
172
185
|
"line": 34,
|
173
186
|
"name": "nice"
|
@@ -175,22 +188,21 @@ Feature: JSON lexer
|
|
175
188
|
],
|
176
189
|
"examples": [
|
177
190
|
{
|
178
|
-
"
|
191
|
+
"type": "examples",
|
192
|
+
"comments": [{"value": "# comments"}, {"value": "# everywhere"}],
|
179
193
|
"tags": [],
|
180
194
|
"keyword": "Examples",
|
181
195
|
"name": "An example",
|
182
|
-
// TODO - the description should now be the comment
|
183
|
-
// It should be on the first row of the examples_table!
|
184
196
|
"description": "",
|
185
197
|
"line": 38,
|
186
198
|
"table": [
|
187
199
|
{
|
188
|
-
"comments": ["# I mean"],
|
200
|
+
"comments": [{"value": "# I mean"}],
|
189
201
|
"line": 40,
|
190
202
|
"cells": ["partout"]
|
191
203
|
},
|
192
204
|
{
|
193
|
-
"comments": ["# I really mean"],
|
205
|
+
"comments": [{"value": "# I really mean"}],
|
194
206
|
"line": 40,
|
195
207
|
"cells": ["bartout"]
|
196
208
|
}
|
@@ -251,35 +263,37 @@ Feature: JSON lexer
|
|
251
263
|
Given the following JSON is parsed:
|
252
264
|
"""
|
253
265
|
{
|
266
|
+
"type": "feature",
|
254
267
|
"comments": [],
|
255
268
|
"description": "",
|
256
269
|
"keyword": "Feature",
|
257
270
|
"name": "Kjapp",
|
258
271
|
"tags": [],
|
259
272
|
"uri": "test.feature",
|
260
|
-
"background": {
|
261
|
-
"comments": [],
|
262
|
-
"description": "",
|
263
|
-
"keyword": "Background",
|
264
|
-
"line": 2,
|
265
|
-
"name": "No idea what Kjapp means",
|
266
|
-
"steps": [
|
267
|
-
{
|
268
|
-
"comments": [],
|
269
|
-
"keyword": "Given ",
|
270
|
-
"line": 3,
|
271
|
-
"name": "I Google it"
|
272
|
-
}
|
273
|
-
]
|
274
|
-
},
|
275
273
|
"elements": [
|
276
274
|
{
|
277
|
-
"
|
275
|
+
"type": "background",
|
276
|
+
"comments": [],
|
277
|
+
"description": "",
|
278
|
+
"keyword": "Background",
|
279
|
+
"line": 2,
|
280
|
+
"name": "No idea what Kjapp means",
|
281
|
+
"steps": [
|
282
|
+
{
|
283
|
+
"comments": [],
|
284
|
+
"keyword": "Given ",
|
285
|
+
"line": 3,
|
286
|
+
"name": "I Google it"
|
287
|
+
}
|
288
|
+
]
|
289
|
+
},
|
290
|
+
{
|
291
|
+
"type": "scenario",
|
292
|
+
"comments": [{"value": "# Writing JSON by hand sucks"}],
|
278
293
|
"tags": [],
|
279
294
|
"keyword": "Scenario",
|
280
295
|
"name": "",
|
281
296
|
"description": "",
|
282
|
-
"type": "scenario",
|
283
297
|
"line": 6,
|
284
298
|
"steps": [
|
285
299
|
{
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'ap' # awesome_print gem
|
1
2
|
require 'stringio'
|
2
3
|
require 'gherkin/formatter/json_formatter'
|
3
4
|
require 'gherkin/listener/formatter_listener'
|
@@ -17,16 +18,10 @@ end
|
|
17
18
|
|
18
19
|
Then /^the outputted JSON should be:$/ do |expected_json|
|
19
20
|
require 'json'
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
actual.should == expected
|
25
|
-
rescue # Haven't figured out how to order Hash on JRuby (JSON pure). Retry with possibly worse error message.
|
26
|
-
expected = JSON.parse(expected_json)
|
27
|
-
actual = JSON.parse(@io.string)
|
28
|
-
actual.should == expected
|
29
|
-
end
|
21
|
+
announce JSON.pretty_generate(JSON.parse(@io.string))
|
22
|
+
expected = JSON.parse(expected_json).ai
|
23
|
+
actual = JSON.parse(@io.string).ai
|
24
|
+
actual.should == expected
|
30
25
|
end
|
31
26
|
|
32
27
|
|
@@ -109,28 +109,23 @@ module Gherkin
|
|
109
109
|
def replay!
|
110
110
|
case @filter
|
111
111
|
when TagExpression
|
112
|
-
background_ok = false
|
113
112
|
feature_element_ok = @filter.eval(tag_names(@feature_tags.to_a + @feature_element_tags.to_a))
|
114
113
|
examples_ok = @filter.eval(tag_names(@feature_tags.to_a + @feature_element_tags.to_a + @examples_tags.to_a)) if @examples_tags
|
115
114
|
when RegexpFilter
|
116
|
-
background_ok = @filter.eval([@background_name]) if @background_name
|
117
115
|
feature_element_ok = @filter.eval([@feature_element_name])
|
118
116
|
examples_ok = @filter.eval([@feature_element_name, @examples_name]) if @examples_name
|
119
117
|
when LineFilter
|
120
|
-
background_ok = @filter.eval([@background_range]) if @background_range
|
121
118
|
feature_element_ok = @filter.eval([@feature_element_range]) if @feature_element_range
|
122
119
|
examples_ok = @filter.eval([@feature_element_range, @examples_range]) if @examples_range
|
123
120
|
end
|
124
121
|
|
125
|
-
if
|
122
|
+
if feature_element_ok || examples_ok
|
126
123
|
replay_events!(@feature_events)
|
127
124
|
replay_events!(@background_events)
|
125
|
+
replay_events!(@feature_element_events)
|
128
126
|
|
129
|
-
if
|
130
|
-
replay_events!(@
|
131
|
-
if examples_ok
|
132
|
-
replay_events!(@examples_events)
|
133
|
-
end
|
127
|
+
if examples_ok
|
128
|
+
replay_events!(@examples_events)
|
134
129
|
end
|
135
130
|
end
|
136
131
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'json/pure' # Needed to make JSON.generate work.
|
3
3
|
require 'gherkin/rubify'
|
4
|
+
require 'gherkin/formatter/model'
|
4
5
|
|
5
6
|
module Gherkin
|
6
7
|
module Formatter
|
@@ -12,22 +13,19 @@ module Gherkin
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def feature(statement, uri)
|
15
|
-
@json_hash = statement_hash(
|
16
|
+
@json_hash = statement_hash('feature', statement)
|
16
17
|
@json_hash['uri'] = uri
|
17
18
|
end
|
18
19
|
|
19
20
|
def background(statement)
|
20
|
-
|
21
|
-
@in_background = true
|
21
|
+
add_step_container('background', statement)
|
22
22
|
end
|
23
23
|
|
24
24
|
def scenario(statement)
|
25
|
-
@in_background = false
|
26
25
|
add_step_container('scenario', statement)
|
27
26
|
end
|
28
27
|
|
29
28
|
def scenario_outline(statement)
|
30
|
-
@in_background = false
|
31
29
|
add_step_container('scenario_outline', statement)
|
32
30
|
end
|
33
31
|
|
@@ -50,15 +48,31 @@ module Gherkin
|
|
50
48
|
|
51
49
|
def statement_hash(type, statement)
|
52
50
|
element = {
|
53
|
-
'comments' => statement.comments.map{|comment| comment.value},
|
54
|
-
'tags' => statement.tags.map{|tag| tag.name},
|
55
51
|
'keyword' => statement.keyword,
|
56
52
|
'name' => statement.name,
|
57
|
-
'description' => statement.description,
|
58
53
|
'line' => statement.line,
|
59
54
|
}
|
60
|
-
element['type'] = type
|
61
|
-
|
55
|
+
element['type'] = type if type
|
56
|
+
add_comments(element, statement)
|
57
|
+
add_tags(element, statement)
|
58
|
+
element['description'] = statement.description if statement.description
|
59
|
+
element
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_comments(element, comment_holder)
|
63
|
+
if comment_holder.comments && comment_holder.comments.any?
|
64
|
+
element['comments'] = comment_holder.comments.map do |comment|
|
65
|
+
{'value' => comment.value, 'line' => comment.line}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_tags(element, statement)
|
71
|
+
if statement.tags && statement.tags.any?
|
72
|
+
element['tags'] = statement.tags.map do |tag|
|
73
|
+
{'name' => tag.name, 'line' => tag.line}
|
74
|
+
end
|
75
|
+
end
|
62
76
|
end
|
63
77
|
|
64
78
|
def add_element(type, statement)
|
@@ -69,7 +83,7 @@ module Gherkin
|
|
69
83
|
end
|
70
84
|
|
71
85
|
def add_examples(statement)
|
72
|
-
element = statement_hash(
|
86
|
+
element = statement_hash('examples', statement)
|
73
87
|
last_element['examples'] ||= []
|
74
88
|
last_element['examples'] << element
|
75
89
|
element
|
@@ -81,27 +95,38 @@ module Gherkin
|
|
81
95
|
end
|
82
96
|
|
83
97
|
def last_element
|
84
|
-
|
85
|
-
@json_hash['background']
|
86
|
-
else
|
87
|
-
@json_hash['elements'][-1]
|
88
|
-
end
|
98
|
+
@json_hash['elements'][-1]
|
89
99
|
end
|
90
100
|
|
91
101
|
def to_hash_array(rows)
|
92
102
|
rows.map do |row|
|
93
|
-
|
103
|
+
e = {"cells" => row.cells.to_a, "line" => row.line}
|
104
|
+
add_comments(e, row)
|
105
|
+
e
|
94
106
|
end
|
95
107
|
end
|
96
108
|
|
97
109
|
def step_arg_to_hash(multiline_arg)
|
98
|
-
return {} if multiline_arg.nil?
|
99
110
|
multiline_arg = rubify(multiline_arg)
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
111
|
+
case multiline_arg
|
112
|
+
when Array
|
113
|
+
{
|
114
|
+
"multiline_arg" => {
|
115
|
+
"type" => "table",
|
116
|
+
"value" => to_hash_array(multiline_arg)
|
117
|
+
}
|
118
|
+
}
|
119
|
+
when Model::PyString
|
120
|
+
{
|
121
|
+
"multiline_arg" => {
|
122
|
+
"type" => "py_string",
|
123
|
+
"value" => multiline_arg.value,
|
124
|
+
"line" => multiline_arg.line
|
125
|
+
}
|
126
|
+
}
|
127
|
+
else
|
128
|
+
{}
|
129
|
+
end
|
105
130
|
end
|
106
131
|
end
|
107
132
|
end
|
data/lib/gherkin/i18n.rb
CHANGED
data/lib/gherkin/json_parser.rb
CHANGED
@@ -26,17 +26,11 @@ module Gherkin
|
|
26
26
|
|
27
27
|
comments_for(feature)
|
28
28
|
tags_for(feature)
|
29
|
-
multiline_event(
|
29
|
+
multiline_event(feature)
|
30
30
|
|
31
|
-
|
32
|
-
comments_for(feature["background"])
|
33
|
-
multiline_event(:background, feature["background"])
|
34
|
-
steps_for(feature["background"])
|
35
|
-
end
|
36
|
-
|
37
|
-
feature["elements"].each do |feature_element|
|
31
|
+
(feature["elements"] || []).each do |feature_element|
|
38
32
|
parse_element(feature_element)
|
39
|
-
end
|
33
|
+
end
|
40
34
|
|
41
35
|
@listener.eof
|
42
36
|
end
|
@@ -44,71 +38,64 @@ module Gherkin
|
|
44
38
|
def parse_element(feature_element)
|
45
39
|
comments_for(feature_element)
|
46
40
|
tags_for(feature_element)
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
multiline_event(feature_element)
|
42
|
+
steps_for(feature_element)
|
43
|
+
|
44
|
+
if feature_element["type"] == "scenario_outline"
|
45
|
+
(feature_element["examples"] || []).each do |examples|
|
46
|
+
comments_for(examples)
|
47
|
+
tags_for(examples)
|
48
|
+
multiline_event(examples)
|
49
|
+
rows_for(examples['table'])
|
50
|
+
end
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
def parse_outline(scenario_outline)
|
54
|
-
multiline_event(:scenario_outline, scenario_outline)
|
55
|
-
steps_for(scenario_outline)
|
56
|
-
scenario_outline["examples"].each do |examples|
|
57
|
-
comments_for(examples)
|
58
|
-
tags_for(examples)
|
59
|
-
multiline_event(:examples, examples)
|
60
|
-
rows_for(examples)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def parse_scenario(scenario)
|
65
|
-
multiline_event(:scenario, scenario)
|
66
|
-
steps_for(scenario)
|
67
|
-
end
|
68
|
-
|
69
54
|
def comments_for(element)
|
70
|
-
element["comments"].each do |comment|
|
71
|
-
@listener.comment(comment,
|
72
|
-
end
|
55
|
+
(element["comments"] || []).each do |comment|
|
56
|
+
@listener.comment(comment['value'], comment['line'])
|
57
|
+
end
|
73
58
|
end
|
74
59
|
|
75
60
|
def tags_for(element)
|
76
|
-
element["tags"].each do |tag|
|
77
|
-
@listener.tag(tag,
|
78
|
-
end
|
61
|
+
(element["tags"] || []).each do |tag|
|
62
|
+
@listener.tag(tag['name'], tag['line'])
|
63
|
+
end
|
79
64
|
end
|
80
65
|
|
81
66
|
def steps_for(element)
|
82
67
|
element["steps"].each do |step|
|
83
68
|
comments_for(step)
|
84
|
-
@listener.step(step["keyword"], step["name"],
|
85
|
-
|
86
|
-
rows_for(step)
|
69
|
+
@listener.step(step["keyword"], step["name"], step['line'])
|
70
|
+
multiline_arg_for(step)
|
87
71
|
end
|
88
72
|
end
|
89
73
|
|
90
|
-
def
|
91
|
-
|
74
|
+
def multiline_arg_for(element)
|
75
|
+
if ma = element["multiline_arg"]
|
76
|
+
case ma["type"]
|
77
|
+
when "py_string"
|
78
|
+
@listener.py_string(ma["value"], ma["line"])
|
79
|
+
when "table"
|
80
|
+
rows_for(ma["value"])
|
81
|
+
end
|
82
|
+
end
|
92
83
|
end
|
93
84
|
|
94
|
-
def rows_for(
|
95
|
-
|
85
|
+
def rows_for(rows)
|
86
|
+
(rows || []).each do |row|
|
96
87
|
comments_for(row)
|
97
|
-
@listener.row(cells_for(row),
|
98
|
-
end
|
88
|
+
@listener.row(cells_for(row), row['line'])
|
89
|
+
end
|
99
90
|
end
|
100
91
|
|
101
92
|
def cells_for(row)
|
102
93
|
row["cells"]
|
103
94
|
end
|
104
95
|
|
105
|
-
def
|
106
|
-
element["line"].to_i || 0
|
107
|
-
end
|
108
|
-
|
109
|
-
def multiline_event(type, element)
|
96
|
+
def multiline_event(element)
|
110
97
|
if element["keyword"]
|
111
|
-
@listener.__send__(type, element["keyword"], element["name"] || "", element["description"] || "",
|
98
|
+
@listener.__send__(element['type'].to_sym, element["keyword"], element["name"] || "", element["description"] || "", element['line'])
|
112
99
|
end
|
113
100
|
end
|
114
101
|
end
|
@@ -1,40 +1,48 @@
|
|
1
|
-
{
|
1
|
+
{
|
2
|
+
"type": "feature",
|
3
|
+
"name": "Feature Text",
|
2
4
|
"keyword": "Feature",
|
3
5
|
"description": "In order to test multiline forms",
|
4
6
|
"tags": [
|
5
|
-
"@tag1",
|
6
|
-
"@tag2"
|
7
|
+
{"name": "@tag1"},
|
8
|
+
{"name": "@tag2"}
|
7
9
|
],
|
8
|
-
"background" : {
|
9
|
-
"description": "",
|
10
|
-
"name": "",
|
11
|
-
"keyword": "Background",
|
12
|
-
"steps": [
|
13
|
-
{ "name": "this is a background step",
|
14
|
-
"keyword": "Given " },
|
15
|
-
{ "name": "this is another one",
|
16
|
-
"keyword": "When ",
|
17
|
-
"line": 412 }
|
18
|
-
]
|
19
|
-
},
|
20
10
|
"elements": [
|
11
|
+
{ "type": "background",
|
12
|
+
"description": "",
|
13
|
+
"name": "",
|
14
|
+
"keyword": "Background",
|
15
|
+
"steps": [
|
16
|
+
{ "name": "this is a background step",
|
17
|
+
"keyword": "Given " },
|
18
|
+
{ "name": "this is another one",
|
19
|
+
"keyword": "When ",
|
20
|
+
"line": 412 }
|
21
|
+
]
|
22
|
+
},
|
21
23
|
{ "type": "scenario_outline",
|
22
24
|
"keyword": "Scenario Outline",
|
23
25
|
"name": "An Scenario Outline",
|
24
26
|
"description": "",
|
25
|
-
"tags": [
|
27
|
+
"tags": [
|
28
|
+
{"name": "@foo"}
|
29
|
+
],
|
26
30
|
"steps": [
|
27
31
|
{ "name": "A step with a table",
|
28
32
|
"keyword": "Given ",
|
29
|
-
"
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
"multiline_arg": {
|
34
|
+
"type": "table",
|
35
|
+
"value" : [
|
36
|
+
{"cells":
|
37
|
+
[ "a","row","for","a","step" ]
|
38
|
+
}
|
39
|
+
]
|
40
|
+
}
|
34
41
|
}
|
35
42
|
],
|
36
43
|
"examples": [
|
37
|
-
{ "
|
44
|
+
{ "type": "examples",
|
45
|
+
"name": "Sweet Example",
|
38
46
|
"keyword": "Examples",
|
39
47
|
"description": "",
|
40
48
|
"table" : [
|
@@ -45,7 +53,7 @@
|
|
45
53
|
[ "The","Blanks" ]
|
46
54
|
}
|
47
55
|
],
|
48
|
-
"tags" : [ "@exampletag" ]
|
56
|
+
"tags" : [ {"name": "@exampletag"} ]
|
49
57
|
}
|
50
58
|
]
|
51
59
|
},
|
@@ -54,8 +62,8 @@
|
|
54
62
|
"name" : "Reading a Scenario",
|
55
63
|
"description": "",
|
56
64
|
"tags" : [
|
57
|
-
"@tag3",
|
58
|
-
"@tag4"
|
65
|
+
{"name": "@tag3"},
|
66
|
+
{"name": "@tag4"}
|
59
67
|
],
|
60
68
|
"steps" : [
|
61
69
|
{ "name" : "there is a step",
|
@@ -68,38 +76,45 @@
|
|
68
76
|
"keyword": "Scenario",
|
69
77
|
"name" : "Reading a second scenario",
|
70
78
|
"description": "With two lines of text",
|
71
|
-
"tags" : [ "@tag3" ],
|
79
|
+
"tags" : [ {"name": "@tag3"} ],
|
72
80
|
"steps" : [
|
73
81
|
{ "name" : "a third step with a table",
|
74
82
|
"keyword": "Given ",
|
75
|
-
"
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
"multiline_arg": {
|
84
|
+
"type": "table",
|
85
|
+
"value": [
|
86
|
+
{
|
87
|
+
"cells" : [ "a","b" ],
|
88
|
+
"line" : 987
|
89
|
+
},
|
90
|
+
{ "cells" :
|
91
|
+
[ "c","d" ]
|
92
|
+
},
|
93
|
+
{ "cells" :
|
94
|
+
[ "e", "f" ]
|
95
|
+
}
|
96
|
+
]
|
97
|
+
}
|
86
98
|
},
|
87
99
|
{ "name" : "I am still testing things",
|
88
100
|
"keyword": "Given ",
|
89
|
-
"
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
"multiline_arg": {
|
102
|
+
"type": "table",
|
103
|
+
"value": [
|
104
|
+
{ "cells" :
|
105
|
+
[ "g","h" ]
|
106
|
+
},
|
107
|
+
{ "cells" :
|
108
|
+
[ "e","r" ]
|
109
|
+
},
|
110
|
+
{ "cells" :
|
111
|
+
[ "k", "i" ]
|
112
|
+
},
|
113
|
+
{ "cells" :
|
114
|
+
[ "n", "" ]
|
115
|
+
}
|
116
|
+
]
|
117
|
+
}
|
103
118
|
},
|
104
119
|
{ "name" : "I am done testing these tables",
|
105
120
|
"keyword": "Given " },
|
@@ -114,7 +129,12 @@
|
|
114
129
|
"steps" : [
|
115
130
|
{ "name" : "All work and no play",
|
116
131
|
"keyword": "Given ",
|
117
|
-
"
|
132
|
+
"multiline_arg": {
|
133
|
+
"type": "py_string",
|
134
|
+
"value": "Makes Homer something something\nAnd something else",
|
135
|
+
"line": 777
|
136
|
+
}
|
137
|
+
},
|
118
138
|
{ "name" : "crazy",
|
119
139
|
"keyword": "Given " }
|
120
140
|
]
|
@@ -92,6 +92,11 @@ module Gherkin
|
|
92
92
|
|
93
93
|
context "lines" do
|
94
94
|
context "on the same line as feature element keyword" do
|
95
|
+
it "should filter on scenario without line" do
|
96
|
+
self.file = 'scenario_without_steps.feature'
|
97
|
+
verify_filter([3], 1..4)
|
98
|
+
end
|
99
|
+
|
95
100
|
it "should filter on scenario line" do
|
96
101
|
verify_filter([16], 1..19)
|
97
102
|
end
|
@@ -22,7 +22,7 @@ module Gherkin
|
|
22
22
|
|
23
23
|
describe "A barely empty feature" do
|
24
24
|
it "should scan a feature with no elements" do
|
25
|
-
@parser.parse_with_listener('{ "keyword": "Feature", "name": "One", "description": "", "line" : 3 }', @listener)
|
25
|
+
@parser.parse_with_listener('{ "type": "feature", "keyword": "Feature", "name": "One", "description": "", "line" : 3 }', @listener)
|
26
26
|
@listener.to_sexp.should == [
|
27
27
|
[:location, "unknown.json"],
|
28
28
|
[:feature, "Feature", "One", "", 3],
|
@@ -31,23 +31,12 @@ module Gherkin
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
describe "Missing line numbers" do
|
35
|
-
it "should indicate a line number of 0 if a line attribute doesn't exist" do
|
36
|
-
@parser.parse_with_listener('{ "name": "My Sweet Featur", "keyword": "Feature", "description": "" }', @listener)
|
37
|
-
@listener.to_sexp.should == [
|
38
|
-
[:location, "unknown.json"],
|
39
|
-
[:feature, "Feature", "My Sweet Featur", "", 0],
|
40
|
-
[:eof]
|
41
|
-
]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
34
|
describe "Keywords" do
|
46
35
|
it "should use the keyword from the source when provided" do
|
47
|
-
@parser.parse_with_listener('{ "name" : "My Sweet Featur", "language": "fr", "keyword": "Feature", "description": "" }', @listener)
|
36
|
+
@parser.parse_with_listener('{ "type": "feature", "name" : "My Sweet Featur", "language": "fr", "keyword": "Feature", "description": "" }', @listener)
|
48
37
|
@listener.to_sexp.should == [
|
49
38
|
[:location, "unknown.json"],
|
50
|
-
[:feature, "Feature", "My Sweet Featur", "",
|
39
|
+
[:feature, "Feature", "My Sweet Featur", "", nil],
|
51
40
|
[:eof]
|
52
41
|
]
|
53
42
|
end
|
@@ -58,42 +47,42 @@ module Gherkin
|
|
58
47
|
@parser.parse_with_listener(fixture("complex.json"), @listener)
|
59
48
|
@listener.to_sexp.should == [
|
60
49
|
[:location, "unknown.json"],
|
61
|
-
[:tag, "@tag1",
|
62
|
-
[:tag, "@tag2",
|
63
|
-
[:feature, "Feature", "Feature Text","In order to test multiline forms",
|
64
|
-
[:background, "Background", "", "",
|
65
|
-
[:step, "Given ", "this is a background step",
|
50
|
+
[:tag, "@tag1", nil],
|
51
|
+
[:tag, "@tag2", nil],
|
52
|
+
[:feature, "Feature", "Feature Text","In order to test multiline forms", nil],
|
53
|
+
[:background, "Background", "", "", nil],
|
54
|
+
[:step, "Given ", "this is a background step", nil],
|
66
55
|
[:step, "When ", "this is another one", 412],
|
67
|
-
[:tag, "@foo",
|
68
|
-
[:scenario_outline, "Scenario Outline", "An Scenario Outline","",
|
69
|
-
[:step, "Given ", "A step with a table",
|
70
|
-
[:row, %w{a row for a step},
|
71
|
-
[:tag, "@exampletag",
|
72
|
-
[:examples, "Examples", "Sweet Example", "",
|
73
|
-
[:row, %w{Fill In},
|
74
|
-
[:row, %w{The Blanks},
|
75
|
-
[:tag, "@tag3",
|
76
|
-
[:tag, "@tag4",
|
77
|
-
[:scenario, "Scenario", "Reading a Scenario", "",
|
78
|
-
[:step, "Given ", "there is a step",
|
79
|
-
[:step, "But ", "not another step",
|
80
|
-
[:tag, "@tag3",
|
81
|
-
[:scenario, "Scenario", "Reading a second scenario", "With two lines of text",
|
82
|
-
[:step, "Given ", "a third step with a table",
|
83
|
-
[:row, %w{a b},
|
84
|
-
[:row, %w{c d},
|
85
|
-
[:row, %w{e f},
|
86
|
-
[:step, "Given ", "I am still testing things",
|
87
|
-
[:row, %w{g h},
|
88
|
-
[:row, %w{e r},
|
89
|
-
[:row, %w{k i},
|
90
|
-
[:row, ['n', ''],
|
91
|
-
[:step, "Given ", "I am done testing these tables",
|
92
|
-
[:step, "Given ", "I am happy",
|
93
|
-
[:scenario, "Scenario", "Hammerzeit", "",
|
94
|
-
[:step, "Given ", "All work and no play",
|
95
|
-
[:py_string, "Makes Homer something something\nAnd something else",
|
96
|
-
[:step, "Given ", "crazy",
|
56
|
+
[:tag, "@foo", nil],
|
57
|
+
[:scenario_outline, "Scenario Outline", "An Scenario Outline","", nil],
|
58
|
+
[:step, "Given ", "A step with a table", nil],
|
59
|
+
[:row, %w{a row for a step}, nil],
|
60
|
+
[:tag, "@exampletag", nil],
|
61
|
+
[:examples, "Examples", "Sweet Example", "", nil],
|
62
|
+
[:row, %w{Fill In}, nil],
|
63
|
+
[:row, %w{The Blanks}, nil],
|
64
|
+
[:tag, "@tag3", nil],
|
65
|
+
[:tag, "@tag4", nil],
|
66
|
+
[:scenario, "Scenario", "Reading a Scenario", "", nil],
|
67
|
+
[:step, "Given ", "there is a step", nil],
|
68
|
+
[:step, "But ", "not another step", nil],
|
69
|
+
[:tag, "@tag3", nil],
|
70
|
+
[:scenario, "Scenario", "Reading a second scenario", "With two lines of text", nil],
|
71
|
+
[:step, "Given ", "a third step with a table", nil],
|
72
|
+
[:row, %w{a b}, 987],
|
73
|
+
[:row, %w{c d}, nil],
|
74
|
+
[:row, %w{e f}, nil],
|
75
|
+
[:step, "Given ", "I am still testing things", nil],
|
76
|
+
[:row, %w{g h}, nil],
|
77
|
+
[:row, %w{e r}, nil],
|
78
|
+
[:row, %w{k i}, nil],
|
79
|
+
[:row, ['n', ''], nil],
|
80
|
+
[:step, "Given ", "I am done testing these tables", nil],
|
81
|
+
[:step, "Given ", "I am happy", nil],
|
82
|
+
[:scenario, "Scenario", "Hammerzeit", "", nil],
|
83
|
+
[:step, "Given ", "All work and no play", nil],
|
84
|
+
[:py_string, "Makes Homer something something\nAnd something else", 777],
|
85
|
+
[:step, "Given ", "crazy", nil],
|
97
86
|
[:eof]
|
98
87
|
]
|
99
88
|
end
|
data/tasks/release.rake
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gherkin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 2.1.
|
9
|
+
- 5
|
10
|
+
version: 2.1.5
|
11
11
|
platform: i386-mingw32
|
12
12
|
authors:
|
13
13
|
- Mike Sassak
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-07-
|
20
|
+
date: 2010-07-17 00:00:00 +02:00
|
21
21
|
default_executable: gherkin
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
@@ -37,43 +37,59 @@ dependencies:
|
|
37
37
|
type: :runtime
|
38
38
|
version_requirements: *id001
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
|
-
name:
|
40
|
+
name: awesome_print
|
41
41
|
prerelease: false
|
42
42
|
requirement: &id002 !ruby/object:Gem::Requirement
|
43
43
|
none: false
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
hash:
|
47
|
+
hash: 21
|
48
|
+
segments:
|
49
|
+
- 0
|
50
|
+
- 2
|
51
|
+
- 1
|
52
|
+
version: 0.2.1
|
53
|
+
type: :development
|
54
|
+
version_requirements: *id002
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
prerelease: false
|
58
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ~>
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
hash: 62196417
|
48
64
|
segments:
|
49
65
|
- 2
|
50
66
|
- 0
|
51
67
|
- 0
|
52
68
|
- beta
|
53
|
-
-
|
54
|
-
version: 2.0.0.beta.
|
69
|
+
- 17
|
70
|
+
version: 2.0.0.beta.17
|
55
71
|
type: :development
|
56
|
-
version_requirements: *
|
72
|
+
version_requirements: *id003
|
57
73
|
- !ruby/object:Gem::Dependency
|
58
74
|
name: cucumber
|
59
75
|
prerelease: false
|
60
|
-
requirement: &
|
76
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
61
77
|
none: false
|
62
78
|
requirements:
|
63
79
|
- - ~>
|
64
80
|
- !ruby/object:Gem::Version
|
65
|
-
hash:
|
81
|
+
hash: 53
|
66
82
|
segments:
|
67
83
|
- 0
|
68
84
|
- 8
|
69
|
-
-
|
70
|
-
version: 0.8.
|
85
|
+
- 5
|
86
|
+
version: 0.8.5
|
71
87
|
type: :development
|
72
|
-
version_requirements: *
|
88
|
+
version_requirements: *id004
|
73
89
|
- !ruby/object:Gem::Dependency
|
74
90
|
name: rake-compiler
|
75
91
|
prerelease: false
|
76
|
-
requirement: &
|
92
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
77
93
|
none: false
|
78
94
|
requirements:
|
79
95
|
- - ~>
|
@@ -85,7 +101,7 @@ dependencies:
|
|
85
101
|
- 0
|
86
102
|
version: 0.7.0
|
87
103
|
type: :development
|
88
|
-
version_requirements: *
|
104
|
+
version_requirements: *id005
|
89
105
|
description: A fast Gherkin lexer/parser based on the Ragel State Machine Compiler.
|
90
106
|
email: cukes@googlegroups.com
|
91
107
|
executables:
|
@@ -272,6 +288,7 @@ files:
|
|
272
288
|
- spec/gherkin/fixtures/i18n_no.feature
|
273
289
|
- spec/gherkin/fixtures/i18n_zh-CN.feature
|
274
290
|
- spec/gherkin/fixtures/scenario_outline_with_tags.feature
|
291
|
+
- spec/gherkin/fixtures/scenario_without_steps.feature
|
275
292
|
- spec/gherkin/fixtures/simple_with_comments.feature
|
276
293
|
- spec/gherkin/fixtures/simple_with_tags.feature
|
277
294
|
- spec/gherkin/fixtures/with_bom.feature
|