gherkin 2.1.5 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +16 -0
- data/README.rdoc +1 -0
- data/Rakefile +1 -1
- data/VERSION.yml +2 -2
- data/features/json_formatter.feature +3 -11
- data/features/json_parser.feature +2 -5
- data/features/step_definitions/json_lexer_steps.rb +1 -1
- data/features/step_definitions/pretty_formatter_steps.rb +1 -1
- data/features/support/env.rb +2 -1
- data/java/src/main/java/gherkin/lexer/{.gitignore → i18n/.gitignore} +0 -0
- data/json-simple-1.1.dll +0 -0
- data/lib/gherkin.rb +1 -1
- data/lib/gherkin/formatter/filter_formatter.rb +52 -61
- data/lib/gherkin/formatter/json_formatter.rb +26 -94
- data/lib/gherkin/formatter/line_filter.rb +3 -3
- data/lib/gherkin/formatter/model.rb +156 -19
- data/lib/gherkin/formatter/pretty_formatter.rb +25 -25
- data/lib/gherkin/formatter/regexp_filter.rb +5 -1
- data/lib/gherkin/formatter/tag_count_formatter.rb +15 -12
- data/lib/gherkin/formatter/tag_filter.rb +19 -0
- data/lib/gherkin/json_parser.rb +49 -65
- data/lib/gherkin/lexer/i18n_lexer.rb +40 -0
- data/lib/gherkin/listener/formatter_listener.rb +11 -18
- data/lib/gherkin/parser/parser.rb +4 -5
- data/lib/gherkin/tools/stats_listener.rb +1 -1
- data/ragel/lexer.c.rl.erb +3 -1
- data/ragel/lexer.java.rl.erb +4 -4
- data/ragel/lexer.rb.rl.erb +3 -1
- data/spec/gherkin/fixtures/complex.json +2 -3
- data/spec/gherkin/formatter/model_spec.rb +1 -1
- data/spec/gherkin/formatter/pretty_formatter_spec.rb +11 -8
- data/spec/gherkin/i18n_spec.rb +3 -3
- data/spec/gherkin/java_lexer_spec.rb +1 -1
- data/spec/gherkin/json.rb +5 -0
- data/spec/gherkin/json_parser_spec.rb +49 -73
- data/spec/gherkin/lexer/i18n_lexer_spec.rb +33 -0
- data/spec/gherkin/sexp_recorder.rb +0 -2
- data/spec/spec_helper.rb +1 -0
- data/tasks/bench.rake +2 -2
- data/tasks/compile.rake +1 -1
- data/tasks/ikvm.rake +3 -1
- data/tasks/ragel_task.rb +1 -1
- data/tasks/release.rake +13 -1
- data/tasks/rspec.rake +0 -1
- metadata +17 -13
- data/lib/gherkin/i18n_lexer.rb +0 -38
- data/spec/gherkin/i18n_lexer_spec.rb +0 -26
data/History.txt
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== 2.2.0 (2010-07-26)
|
2
|
+
|
3
|
+
This release breaks some APIs since the previous 2.1.5 release. If you install gherkin 2.2.0 you must also upgrade to
|
4
|
+
Cucumber 0.9.0.
|
5
|
+
|
6
|
+
=== Bugfixes
|
7
|
+
* I18nLexer doesn't recognise language header with \r\n on OS X. (#70 Aslak Hellesøy)
|
8
|
+
|
9
|
+
=== New Features
|
10
|
+
* Pure Java FilterFormatter. (Aslak Hellesøy)
|
11
|
+
* Pure Java JSONFormatter. (Aslak Hellesøy)
|
12
|
+
|
13
|
+
=== Changed Features
|
14
|
+
* All formatter events take exactly one argument. Each argument is a single object with all data. (Aslak Hellesøy)
|
15
|
+
* Several java classes have moved to a different package in order to improve separation of concerns. (Aslak Hellesøy)
|
16
|
+
|
1
17
|
== 2.1.5 (2010-07-17)
|
2
18
|
|
3
19
|
=== Bugfixes
|
data/README.rdoc
CHANGED
@@ -32,6 +32,7 @@ E.g. in Bash, export RL_LANG="en,fr,no". This can be quite helpful when modifyin
|
|
32
32
|
** java/pom.xml
|
33
33
|
** ikvm/Gherkin/Gherkin.csproj
|
34
34
|
* Make sure both JRuby and MRI has the latest Cucumber installed (from source) otherwise the jruby gem might not get the jar inside it.
|
35
|
+
** Install cucumber without gherkin dep: gem install --ignore-dependencies pkg/cucumber
|
35
36
|
* rake release:ALL
|
36
37
|
* Announce on Cucumber list, IRC and Twitter.
|
37
38
|
|
data/Rakefile
CHANGED
@@ -21,7 +21,7 @@ begin
|
|
21
21
|
gem.add_dependency "trollop", "~> 1.16.2"
|
22
22
|
gem.add_development_dependency 'awesome_print', '~> 0.2.1'
|
23
23
|
gem.add_development_dependency 'rspec', '~> 2.0.0.beta.17'
|
24
|
-
gem.add_development_dependency "cucumber", "~> 0.
|
24
|
+
gem.add_development_dependency "cucumber", "~> 0.9.0"
|
25
25
|
gem.add_development_dependency "rake-compiler", "~> 0.7.0" unless defined?(JRUBY_VERSION)
|
26
26
|
|
27
27
|
gem.files -= FileList['ikvm/**/*']
|
data/VERSION.yml
CHANGED
@@ -16,13 +16,11 @@ Feature: JSON formatter
|
|
16
16
|
Then the outputted JSON should be:
|
17
17
|
"""
|
18
18
|
{
|
19
|
-
"type": "feature",
|
20
19
|
"comments": [{"value": "# language: no", "line": 1}, {"value": "# Another comment", "line": 2}],
|
21
20
|
"keyword": "Egenskap",
|
22
21
|
"name": "Kjapp",
|
23
22
|
"description": "",
|
24
|
-
"line": 3
|
25
|
-
"uri": "test.feature"
|
23
|
+
"line": 3
|
26
24
|
}
|
27
25
|
"""
|
28
26
|
|
@@ -73,13 +71,11 @@ Feature: JSON formatter
|
|
73
71
|
Then the outputted JSON should be:
|
74
72
|
"""
|
75
73
|
{
|
76
|
-
"type": "feature",
|
77
74
|
"tags": [{"name": "@one", "line":1}],
|
78
75
|
"keyword": "Feature",
|
79
76
|
"name": "OH HAI",
|
80
77
|
"description": "",
|
81
78
|
"line": 2,
|
82
|
-
"uri": "test.feature",
|
83
79
|
"elements":[
|
84
80
|
{
|
85
81
|
"type": "scenario",
|
@@ -136,13 +132,12 @@ Feature: JSON formatter
|
|
136
132
|
],
|
137
133
|
"examples": [
|
138
134
|
{
|
139
|
-
"type": "examples",
|
140
135
|
"tags": [{"name": "@five", "line":17}],
|
141
136
|
"keyword": "Examples",
|
142
137
|
"name": "Real life",
|
143
138
|
"description": "",
|
144
139
|
"line": 18,
|
145
|
-
"
|
140
|
+
"rows": [
|
146
141
|
{
|
147
142
|
"cells": ["boredom"],
|
148
143
|
"line": 19
|
@@ -209,13 +204,12 @@ Feature: JSON formatter
|
|
209
204
|
],
|
210
205
|
"examples": [
|
211
206
|
{
|
212
|
-
"type": "examples",
|
213
207
|
"comments": [{"value": "# comments", "line": 36}, {"value": "# everywhere", "line": 37}],
|
214
208
|
"keyword": "Examples",
|
215
209
|
"name": "An example",
|
216
210
|
"description": "",
|
217
211
|
"line": 38,
|
218
|
-
"
|
212
|
+
"rows": [
|
219
213
|
{
|
220
214
|
"comments": [{"value": "# I mean", "line": 39}],
|
221
215
|
"line": 40,
|
@@ -244,12 +238,10 @@ Feature: JSON formatter
|
|
244
238
|
Then the outputted JSON should be:
|
245
239
|
"""
|
246
240
|
{
|
247
|
-
"type": "feature",
|
248
241
|
"keyword": "Feature",
|
249
242
|
"name": "Kjapp",
|
250
243
|
"description": "",
|
251
244
|
"line": 1,
|
252
|
-
"uri": "test.feature",
|
253
245
|
"elements": [
|
254
246
|
{
|
255
247
|
"type": "background",
|
@@ -10,7 +10,6 @@ Feature: JSON lexer
|
|
10
10
|
Given the following JSON is parsed:
|
11
11
|
"""
|
12
12
|
{
|
13
|
-
"type": "feature",
|
14
13
|
"comments": [
|
15
14
|
{"value": "# language: no"},
|
16
15
|
{"value": "# Another comment"}
|
@@ -33,7 +32,6 @@ Feature: JSON lexer
|
|
33
32
|
Given the following JSON is parsed:
|
34
33
|
"""
|
35
34
|
{
|
36
|
-
"type": "feature",
|
37
35
|
"comments": [],
|
38
36
|
"keyword": "Feature",
|
39
37
|
"name": "OH HAI",
|
@@ -112,7 +110,7 @@ Feature: JSON lexer
|
|
112
110
|
"name": "Real life",
|
113
111
|
"description": "",
|
114
112
|
"line": 18,
|
115
|
-
"
|
113
|
+
"rows": [
|
116
114
|
{
|
117
115
|
"comments": [],
|
118
116
|
"cells": ["boredom"],
|
@@ -195,7 +193,7 @@ Feature: JSON lexer
|
|
195
193
|
"name": "An example",
|
196
194
|
"description": "",
|
197
195
|
"line": 38,
|
198
|
-
"
|
196
|
+
"rows": [
|
199
197
|
{
|
200
198
|
"comments": [{"value": "# I mean"}],
|
201
199
|
"line": 40,
|
@@ -263,7 +261,6 @@ Feature: JSON lexer
|
|
263
261
|
Given the following JSON is parsed:
|
264
262
|
"""
|
265
263
|
{
|
266
|
-
"type": "feature",
|
267
264
|
"comments": [],
|
268
265
|
"description": "",
|
269
266
|
"keyword": "Feature",
|
@@ -12,7 +12,7 @@ Given /^a JSON lexer$/ do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
Given /^the following JSON is parsed:$/ do |text|
|
15
|
-
@json_parser.parse(JSON.pretty_generate(JSON.parse(text)))
|
15
|
+
@json_parser.parse(JSON.pretty_generate(JSON.parse(text)), "unknown.json")
|
16
16
|
end
|
17
17
|
|
18
18
|
Then /^the outputted text should be:$/ do |expected_text|
|
@@ -23,7 +23,7 @@ module PrettyPlease
|
|
23
23
|
result = StringIO.new
|
24
24
|
pretty_formatter = Gherkin::Formatter::PrettyFormatter.new(result, false)
|
25
25
|
json_parser = Gherkin::JSONParser.new(pretty_formatter)
|
26
|
-
json_parser.parse(json.string)
|
26
|
+
json_parser.parse(json.string, "#{feature_path}.json")
|
27
27
|
|
28
28
|
result.string
|
29
29
|
end
|
data/features/support/env.rb
CHANGED
@@ -3,8 +3,9 @@
|
|
3
3
|
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + path)
|
4
4
|
end
|
5
5
|
require 'gherkin'
|
6
|
-
require
|
6
|
+
require 'gherkin/sexp_recorder'
|
7
7
|
require 'gherkin/output_stream_string_io'
|
8
|
+
require 'gherkin/json'
|
8
9
|
|
9
10
|
module TransformHelpers
|
10
11
|
def tr_line_number(step_arg)
|
File without changes
|
data/json-simple-1.1.dll
ADDED
Binary file
|
data/lib/gherkin.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require 'gherkin/i18n_lexer'
|
1
|
+
require 'gherkin/lexer/i18n_lexer'
|
2
2
|
require 'gherkin/parser/parser'
|
@@ -1,19 +1,19 @@
|
|
1
|
-
require 'gherkin/rubify'
|
2
1
|
require 'gherkin/tag_expression'
|
3
2
|
require 'gherkin/formatter/regexp_filter'
|
4
3
|
require 'gherkin/formatter/line_filter'
|
4
|
+
require 'gherkin/formatter/tag_filter'
|
5
5
|
require 'gherkin/formatter/model'
|
6
|
+
require 'gherkin/native'
|
6
7
|
|
7
8
|
module Gherkin
|
8
9
|
module Formatter
|
9
10
|
class FilterFormatter
|
10
|
-
|
11
|
+
native_impl('gherkin')
|
11
12
|
|
12
13
|
def initialize(formatter, filters)
|
13
14
|
@formatter = formatter
|
14
15
|
@filter = detect_filter(filters)
|
15
16
|
|
16
|
-
|
17
17
|
@feature_tags = []
|
18
18
|
@feature_element_tags = []
|
19
19
|
@examples_tags = []
|
@@ -24,67 +24,59 @@ module Gherkin
|
|
24
24
|
@examples_events = []
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
@
|
29
|
-
|
30
|
-
|
27
|
+
def uri(uri)
|
28
|
+
@formatter.uri(uri)
|
29
|
+
end
|
30
|
+
|
31
|
+
def feature(feature)
|
32
|
+
@feature_tags = feature.tags
|
33
|
+
@feature_name = feature.name
|
34
|
+
@feature_events = [feature]
|
31
35
|
end
|
32
36
|
|
33
|
-
def background(
|
34
|
-
@feature_element_name =
|
35
|
-
@feature_element_range =
|
36
|
-
@background_events = [
|
37
|
+
def background(background)
|
38
|
+
@feature_element_name = background.name
|
39
|
+
@feature_element_range = background.line_range
|
40
|
+
@background_events = [background]
|
37
41
|
end
|
38
42
|
|
39
|
-
def scenario(
|
43
|
+
def scenario(scenario)
|
40
44
|
replay!
|
41
|
-
@feature_element_tags =
|
42
|
-
@feature_element_name =
|
43
|
-
@feature_element_range =
|
44
|
-
@feature_element_events = [
|
45
|
-
@examples_events.clear
|
45
|
+
@feature_element_tags = scenario.tags
|
46
|
+
@feature_element_name = scenario.name
|
47
|
+
@feature_element_range = scenario.line_range
|
48
|
+
@feature_element_events = [scenario]
|
46
49
|
end
|
47
50
|
|
48
|
-
def scenario_outline(
|
51
|
+
def scenario_outline(scenario_outline)
|
49
52
|
replay!
|
50
|
-
@feature_element_tags =
|
51
|
-
@feature_element_name =
|
52
|
-
@feature_element_range =
|
53
|
-
@feature_element_events = [
|
54
|
-
@examples_events.clear
|
53
|
+
@feature_element_tags = scenario_outline.tags
|
54
|
+
@feature_element_name = scenario_outline.name
|
55
|
+
@feature_element_range = scenario_outline.line_range
|
56
|
+
@feature_element_events = [scenario_outline]
|
55
57
|
end
|
56
58
|
|
57
|
-
def examples(
|
59
|
+
def examples(examples)
|
58
60
|
replay!
|
59
|
-
@examples_tags =
|
60
|
-
@examples_name =
|
61
|
+
@examples_tags = examples.tags
|
62
|
+
@examples_name = examples.name
|
61
63
|
|
62
|
-
table_body_range =
|
63
|
-
@examples_range =
|
64
|
-
if(
|
65
|
-
|
64
|
+
table_body_range = examples.rows[1].line..examples.rows[-1].line
|
65
|
+
@examples_range = examples.line_range.first..table_body_range.last
|
66
|
+
if(@filter.eval([], [], [table_body_range]))
|
67
|
+
examples.rows = @filter.filter_table_body_rows(examples.rows)
|
66
68
|
end
|
67
|
-
@examples_events = [
|
69
|
+
@examples_events = [examples]
|
68
70
|
end
|
69
71
|
|
70
|
-
def step(
|
71
|
-
args = [:step, statement, multiline_arg, result]
|
72
|
+
def step(step)
|
72
73
|
if @feature_element_events.any?
|
73
|
-
@feature_element_events <<
|
74
|
+
@feature_element_events << step
|
74
75
|
else
|
75
|
-
@background_events <<
|
76
|
+
@background_events << step
|
76
77
|
end
|
77
78
|
|
78
|
-
|
79
|
-
step_range = statement.line_range
|
80
|
-
case rubify(multiline_arg)
|
81
|
-
when Model::PyString
|
82
|
-
step_range = step_range.first..multiline_arg.line_range.last
|
83
|
-
when Array
|
84
|
-
step_range = step_range.first..multiline_arg.to_a[-1].line
|
85
|
-
end
|
86
|
-
@feature_element_range = @feature_element_range.first..step_range.last
|
87
|
-
end
|
79
|
+
@feature_element_range = @feature_element_range.first..step.line_range.last
|
88
80
|
end
|
89
81
|
|
90
82
|
def eof
|
@@ -102,22 +94,21 @@ module Gherkin
|
|
102
94
|
when Regexp
|
103
95
|
RegexpFilter.new(filters)
|
104
96
|
when String
|
105
|
-
|
97
|
+
TagFilter.new(filters)
|
106
98
|
end
|
107
99
|
end
|
108
100
|
|
109
101
|
def replay!
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
102
|
+
feature_element_ok = @filter.eval(
|
103
|
+
(@feature_tags + @feature_element_tags),
|
104
|
+
[@feature_name, @feature_element_name].compact,
|
105
|
+
[@feature_element_range].compact
|
106
|
+
)
|
107
|
+
examples_ok = @filter.eval(
|
108
|
+
(@feature_tags + @feature_element_tags + @examples_tags),
|
109
|
+
[@feature_name, @feature_element_name, @examples_name].compact,
|
110
|
+
[@feature_element_range, @examples_range].compact
|
111
|
+
)
|
121
112
|
|
122
113
|
if feature_element_ok || examples_ok
|
123
114
|
replay_events!(@feature_events)
|
@@ -128,15 +119,15 @@ module Gherkin
|
|
128
119
|
replay_events!(@examples_events)
|
129
120
|
end
|
130
121
|
end
|
131
|
-
end
|
132
122
|
|
133
|
-
|
134
|
-
|
123
|
+
@examples_events.clear
|
124
|
+
@examples_tags.clear
|
125
|
+
@examples_name = nil
|
135
126
|
end
|
136
127
|
|
137
128
|
def replay_events!(events)
|
138
129
|
events.each do |event|
|
139
|
-
@formatter
|
130
|
+
event.replay(@formatter)
|
140
131
|
end
|
141
132
|
events.clear
|
142
133
|
end
|
@@ -1,132 +1,64 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'json/pure' # Needed to make JSON.generate work.
|
3
|
-
require 'gherkin/rubify'
|
4
3
|
require 'gherkin/formatter/model'
|
4
|
+
require 'gherkin/native'
|
5
5
|
|
6
6
|
module Gherkin
|
7
7
|
module Formatter
|
8
8
|
class JSONFormatter
|
9
|
-
|
9
|
+
native_impl('gherkin')
|
10
10
|
|
11
11
|
def initialize(io)
|
12
12
|
@io = io
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
@json_hash = statement_hash('feature', statement)
|
17
|
-
@json_hash['uri'] = uri
|
15
|
+
def uri(uri)
|
18
16
|
end
|
19
17
|
|
20
|
-
def
|
21
|
-
|
18
|
+
def feature(feature)
|
19
|
+
@feature_hash = feature.to_hash
|
22
20
|
end
|
23
21
|
|
24
|
-
def
|
25
|
-
|
22
|
+
def background(background)
|
23
|
+
feature_elements << background.to_hash
|
26
24
|
end
|
27
25
|
|
28
|
-
def
|
29
|
-
|
26
|
+
def scenario(scenario)
|
27
|
+
feature_elements << scenario.to_hash
|
30
28
|
end
|
31
29
|
|
32
|
-
def
|
33
|
-
|
34
|
-
@table_container['table'] = to_hash_array(examples_rows)
|
30
|
+
def scenario_outline(scenario_outline)
|
31
|
+
feature_elements << scenario_outline.to_hash
|
35
32
|
end
|
36
33
|
|
37
|
-
def
|
38
|
-
|
39
|
-
last_element['steps'] ||= []
|
40
|
-
last_element['steps'] << @table_container
|
34
|
+
def examples(examples)
|
35
|
+
all_examples << examples.to_hash
|
41
36
|
end
|
42
37
|
|
43
|
-
def
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def statement_hash(type, statement)
|
50
|
-
element = {
|
51
|
-
'keyword' => statement.keyword,
|
52
|
-
'name' => statement.name,
|
53
|
-
'line' => statement.line,
|
54
|
-
}
|
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
|
38
|
+
def step(step)
|
39
|
+
steps << step.to_hash
|
76
40
|
end
|
77
41
|
|
78
|
-
def
|
79
|
-
|
80
|
-
@json_hash['elements'] ||= []
|
81
|
-
@json_hash['elements'] << element
|
82
|
-
element
|
42
|
+
def eof
|
43
|
+
@io.write(@feature_hash.to_json)
|
83
44
|
end
|
84
45
|
|
85
|
-
|
86
|
-
element = statement_hash('examples', statement)
|
87
|
-
last_element['examples'] ||= []
|
88
|
-
last_element['examples'] << element
|
89
|
-
element
|
90
|
-
end
|
46
|
+
private
|
91
47
|
|
92
|
-
def
|
93
|
-
|
94
|
-
last_element['steps'] = []
|
48
|
+
def feature_elements
|
49
|
+
@feature_hash['elements'] ||= []
|
95
50
|
end
|
96
51
|
|
97
|
-
def
|
98
|
-
|
52
|
+
def feature_element
|
53
|
+
feature_elements[-1]
|
99
54
|
end
|
100
55
|
|
101
|
-
def
|
102
|
-
|
103
|
-
e = {"cells" => row.cells.to_a, "line" => row.line}
|
104
|
-
add_comments(e, row)
|
105
|
-
e
|
106
|
-
end
|
56
|
+
def all_examples
|
57
|
+
feature_element['examples'] ||= []
|
107
58
|
end
|
108
59
|
|
109
|
-
def
|
110
|
-
|
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
|
60
|
+
def steps
|
61
|
+
feature_element['steps'] ||= []
|
130
62
|
end
|
131
63
|
end
|
132
64
|
end
|