gherkin 2.1.5-i386-mingw32 → 2.2.0-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 +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
@@ -3,7 +3,159 @@ require 'gherkin/native'
|
|
3
3
|
module Gherkin
|
4
4
|
module Formatter
|
5
5
|
module Model
|
6
|
-
class
|
6
|
+
class Hashable
|
7
|
+
def to_hash
|
8
|
+
instance_variables.inject({}) do |hash, ivar|
|
9
|
+
value = instance_variable_get(ivar)
|
10
|
+
value = value.to_hash if value.respond_to?(:to_hash)
|
11
|
+
if Array === value
|
12
|
+
value = value.map do |e|
|
13
|
+
e.respond_to?(:to_hash) ? e.to_hash : e
|
14
|
+
end
|
15
|
+
end
|
16
|
+
hash[ivar[1..-1]] = value unless [[], nil].index(value)
|
17
|
+
hash
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class BasicStatement < Hashable
|
23
|
+
attr_reader :comments, :keyword, :name, :description, :line
|
24
|
+
|
25
|
+
def initialize(comments, keyword, name, description, line)
|
26
|
+
@comments, @keyword, @name, @description, @line = comments, keyword, name, description, line
|
27
|
+
end
|
28
|
+
|
29
|
+
def line_range
|
30
|
+
first = @comments.any? ? @comments[0].line : first_non_comment_line
|
31
|
+
first..line
|
32
|
+
end
|
33
|
+
|
34
|
+
def first_non_comment_line
|
35
|
+
@line
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class TagStatement < BasicStatement
|
40
|
+
attr_reader :tags
|
41
|
+
|
42
|
+
def initialize(comments, tags, keyword, name, description, line)
|
43
|
+
super(comments, keyword, name, description, line)
|
44
|
+
@tags = tags
|
45
|
+
end
|
46
|
+
|
47
|
+
def first_non_comment_line
|
48
|
+
@tags.any? ? @tags[0].line : @line
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Feature < TagStatement
|
53
|
+
native_impl('gherkin')
|
54
|
+
|
55
|
+
def initialize(comments, tags, keyword, name, description, line)
|
56
|
+
super(comments, tags, keyword, name, description, line)
|
57
|
+
end
|
58
|
+
|
59
|
+
def replay(formatter)
|
60
|
+
formatter.feature(self)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Background < BasicStatement
|
65
|
+
native_impl('gherkin')
|
66
|
+
|
67
|
+
def initialize(comments, keyword, name, description, line)
|
68
|
+
super(comments, keyword, name, description, line)
|
69
|
+
@type = "background"
|
70
|
+
end
|
71
|
+
|
72
|
+
def replay(formatter)
|
73
|
+
formatter.background(self)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Scenario < TagStatement
|
78
|
+
native_impl('gherkin')
|
79
|
+
|
80
|
+
def initialize(comments, tags, keyword, name, description, line)
|
81
|
+
super(comments, tags, keyword, name, description, line)
|
82
|
+
@type = "scenario"
|
83
|
+
end
|
84
|
+
|
85
|
+
def replay(formatter)
|
86
|
+
formatter.scenario(self)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class ScenarioOutline < TagStatement
|
91
|
+
native_impl('gherkin')
|
92
|
+
|
93
|
+
def initialize(comments, tags, keyword, name, description, line)
|
94
|
+
super(comments, tags, keyword, name, description, line)
|
95
|
+
@type = "scenario_outline"
|
96
|
+
end
|
97
|
+
|
98
|
+
def replay(formatter)
|
99
|
+
formatter.scenario_outline(self)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Examples < TagStatement
|
104
|
+
native_impl('gherkin')
|
105
|
+
|
106
|
+
attr_accessor :rows
|
107
|
+
|
108
|
+
def initialize(comments, tags, keyword, name, description, line, rows=nil)
|
109
|
+
super(comments, tags, keyword, name, description, line)
|
110
|
+
@rows = rows
|
111
|
+
end
|
112
|
+
|
113
|
+
def replay(formatter)
|
114
|
+
formatter.examples(self)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class Step < BasicStatement
|
119
|
+
native_impl('gherkin')
|
120
|
+
|
121
|
+
attr_accessor :multiline_arg, :result
|
122
|
+
|
123
|
+
def initialize(comments, keyword, name, description, line, multiline_arg=nil, result=nil)
|
124
|
+
super(comments, keyword, name, nil, line)
|
125
|
+
@multiline_arg = multiline_arg
|
126
|
+
@result = result
|
127
|
+
end
|
128
|
+
|
129
|
+
def line_range
|
130
|
+
range = super
|
131
|
+
case multiline_arg
|
132
|
+
when Array
|
133
|
+
range = range.first..multiline_arg[-1].line
|
134
|
+
when Model::PyString
|
135
|
+
range = range.first..multiline_arg.line_range.last
|
136
|
+
end
|
137
|
+
range
|
138
|
+
end
|
139
|
+
|
140
|
+
def replay(formatter)
|
141
|
+
formatter.step(self)
|
142
|
+
end
|
143
|
+
|
144
|
+
def to_hash
|
145
|
+
hash = super
|
146
|
+
if Array === @multiline_arg
|
147
|
+
hash['multiline_arg'] = {
|
148
|
+
'type' => 'table',
|
149
|
+
'value' => hash['multiline_arg']
|
150
|
+
}
|
151
|
+
elsif PyString === @multiline_arg
|
152
|
+
hash['multiline_arg']['type'] = 'py_string'
|
153
|
+
end
|
154
|
+
hash
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class Comment < Hashable
|
7
159
|
native_impl('gherkin')
|
8
160
|
|
9
161
|
attr_reader :value, :line
|
@@ -13,7 +165,7 @@ module Gherkin
|
|
13
165
|
end
|
14
166
|
end
|
15
167
|
|
16
|
-
class Tag
|
168
|
+
class Tag < Hashable
|
17
169
|
native_impl('gherkin')
|
18
170
|
|
19
171
|
attr_reader :name, :line
|
@@ -31,7 +183,7 @@ module Gherkin
|
|
31
183
|
end
|
32
184
|
end
|
33
185
|
|
34
|
-
class PyString
|
186
|
+
class PyString < Hashable
|
35
187
|
native_impl('gherkin')
|
36
188
|
|
37
189
|
attr_reader :value, :line
|
@@ -46,7 +198,7 @@ module Gherkin
|
|
46
198
|
end
|
47
199
|
end
|
48
200
|
|
49
|
-
class Row
|
201
|
+
class Row < Hashable
|
50
202
|
native_impl('gherkin')
|
51
203
|
|
52
204
|
attr_reader :comments, :cells, :line
|
@@ -56,21 +208,6 @@ module Gherkin
|
|
56
208
|
end
|
57
209
|
end
|
58
210
|
|
59
|
-
class Statement
|
60
|
-
native_impl('gherkin')
|
61
|
-
|
62
|
-
attr_reader :comments, :tags, :keyword, :name, :description, :line
|
63
|
-
|
64
|
-
def initialize(comments, tags, keyword, name, description, line)
|
65
|
-
@comments, @tags, @keyword, @name, @description, @line = comments, tags, keyword, name, description, line
|
66
|
-
end
|
67
|
-
|
68
|
-
def line_range
|
69
|
-
first = @comments[0] ? @comments[0].line : (@tags[0] ? @tags[0].line : line)
|
70
|
-
first..line
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
211
|
class Result
|
75
212
|
native_impl('gherkin')
|
76
213
|
|
@@ -20,12 +20,15 @@ module Gherkin
|
|
20
20
|
@format = MonochromeFormat.new #@monochrome ? MonochromeFormat.new : AnsiColorFormat.new
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def uri(uri)
|
24
24
|
@uri = uri
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
end
|
26
|
+
|
27
|
+
def feature(feature)
|
28
|
+
print_comments(feature.comments, '')
|
29
|
+
print_tags(feature.tags, '')
|
30
|
+
@io.puts "#{feature.keyword}: #{feature.name}"
|
31
|
+
print_description(feature.description, ' ', false)
|
29
32
|
end
|
30
33
|
|
31
34
|
def background(statement)
|
@@ -43,35 +46,32 @@ module Gherkin
|
|
43
46
|
print_description(statement.description, ' ')
|
44
47
|
end
|
45
48
|
|
46
|
-
def scenario_outline(
|
47
|
-
scenario(
|
49
|
+
def scenario_outline(scenario_outline)
|
50
|
+
scenario(scenario_outline)
|
48
51
|
end
|
49
52
|
|
50
|
-
def examples(
|
53
|
+
def examples(examples)
|
51
54
|
@io.puts
|
52
|
-
print_comments(
|
53
|
-
print_tags(
|
54
|
-
@io.puts " #{
|
55
|
-
print_description(
|
56
|
-
table(
|
55
|
+
print_comments(examples.comments, ' ')
|
56
|
+
print_tags(examples.tags, ' ')
|
57
|
+
@io.puts " #{examples.keyword}: #{examples.name}"
|
58
|
+
print_description(examples.description, ' ')
|
59
|
+
table(examples.rows)
|
57
60
|
end
|
58
61
|
|
59
|
-
def step(
|
60
|
-
name = Gherkin::Formatter::Argument.format(
|
62
|
+
def step(step)
|
63
|
+
name = Gherkin::Formatter::Argument.format(step.name, @format, (step.result ? step.result.arguments : []))
|
61
64
|
|
62
|
-
|
63
|
-
|
65
|
+
step_text = "#{step.keyword}#{step.name}"
|
66
|
+
step_text = self.__send__(step.result.status, step_text, @monochrome) if step.result
|
64
67
|
|
65
|
-
print_comments(
|
66
|
-
@io.puts(" #{
|
67
|
-
case multiline_arg
|
68
|
+
print_comments(step.comments, ' ')
|
69
|
+
@io.puts(" #{step_text}#{indented_step_location!(step.result ? step.result.stepdef_location : nil)}")
|
70
|
+
case step.multiline_arg
|
68
71
|
when Model::PyString
|
69
|
-
py_string(multiline_arg)
|
72
|
+
py_string(step.multiline_arg)
|
70
73
|
when Array
|
71
|
-
table(multiline_arg)
|
72
|
-
when NilClass
|
73
|
-
else
|
74
|
-
raise "Bad multiline_arg: #{multiline_arg.inspect}"
|
74
|
+
table(step.multiline_arg)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -5,13 +5,17 @@ module Gherkin
|
|
5
5
|
@regexen = regexen
|
6
6
|
end
|
7
7
|
|
8
|
-
def eval(names)
|
8
|
+
def eval(tags, names, ranges)
|
9
9
|
@regexen.detect do |regexp|
|
10
10
|
names.detect do |name|
|
11
11
|
name =~ regexp
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
def filter_table_body_rows(rows)
|
17
|
+
rows
|
18
|
+
end
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
@@ -6,25 +6,28 @@ module Gherkin
|
|
6
6
|
@tag_counts = tag_counts
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
10
|
-
@feature_tags = statement.tags
|
9
|
+
def uri(uri)
|
11
10
|
@uri = uri
|
12
|
-
@formatter.feature(statement, uri)
|
13
11
|
end
|
14
12
|
|
15
|
-
def
|
16
|
-
|
17
|
-
@formatter.
|
13
|
+
def feature(feature)
|
14
|
+
@feature_tags = feature.tags
|
15
|
+
@formatter.feature(feature)
|
18
16
|
end
|
19
17
|
|
20
|
-
def
|
21
|
-
@
|
22
|
-
@formatter.
|
18
|
+
def scenario(scenario)
|
19
|
+
record_tags((@feature_tags.to_a + scenario.tags.to_a).uniq, scenario.line)
|
20
|
+
@formatter.scenario(scenario)
|
23
21
|
end
|
24
22
|
|
25
|
-
def
|
26
|
-
|
27
|
-
@formatter.
|
23
|
+
def scenario_outline(scenario_outline)
|
24
|
+
@scenario_outline_tags = scenario_outline.tags
|
25
|
+
@formatter.scenario_outline(scenario_outline)
|
26
|
+
end
|
27
|
+
|
28
|
+
def examples(examples)
|
29
|
+
record_tags((@feature_tags.to_a + @scenario_outline_tags.to_a + examples.tags.to_a).uniq, examples.line)
|
30
|
+
@formatter.examples(examples)
|
28
31
|
end
|
29
32
|
|
30
33
|
private
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'gherkin/tag_expression'
|
2
|
+
|
3
|
+
module Gherkin
|
4
|
+
module Formatter
|
5
|
+
class TagFilter
|
6
|
+
def initialize(tags)
|
7
|
+
@tag_expression = TagExpression.new(tags)
|
8
|
+
end
|
9
|
+
|
10
|
+
def eval(tags, names, ranges)
|
11
|
+
@tag_expression.eval(tags.uniq.map{|tag| tag.name})
|
12
|
+
end
|
13
|
+
|
14
|
+
def filter_table_body_rows(rows)
|
15
|
+
rows
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/gherkin/json_parser.rb
CHANGED
@@ -1,102 +1,86 @@
|
|
1
1
|
require 'json'
|
2
|
-
require 'gherkin/
|
2
|
+
require 'gherkin/formatter/model'
|
3
|
+
require 'gherkin/native'
|
3
4
|
|
4
5
|
module Gherkin
|
5
6
|
class JSONParser
|
7
|
+
native_impl('gherkin')
|
6
8
|
|
7
9
|
def initialize(formatter)
|
8
10
|
@formatter = formatter
|
9
11
|
end
|
10
12
|
|
11
13
|
def parse(src, feature_uri='unknown.json', line_offset=0)
|
12
|
-
@
|
13
|
-
|
14
|
-
|
14
|
+
@formatter.uri(feature_uri)
|
15
|
+
o = JSON.parse(src)
|
16
|
+
|
17
|
+
Formatter::Model::Feature.new(comments(o), tags(o), keyword(o), name(o), description(o), line(o)).replay(@formatter)
|
18
|
+
(o["elements"] || []).each do |feature_element|
|
19
|
+
feature_element(feature_element).replay(@formatter)
|
20
|
+
(feature_element["steps"] || []).each do |step|
|
21
|
+
step(step).replay(@formatter)
|
22
|
+
end
|
23
|
+
(feature_element["examples"] || []).each do |eo|
|
24
|
+
Formatter::Model::Examples.new(comments(eo), tags(eo), keyword(eo), name(eo), description(eo), line(eo), rows(eo['rows'])).replay(@formatter)
|
25
|
+
end
|
26
|
+
end
|
15
27
|
|
16
|
-
|
17
|
-
@listener = listener
|
18
|
-
_parse(src, 'unknown.json', 0)
|
28
|
+
@formatter.eof
|
19
29
|
end
|
20
30
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
multiline_event(feature)
|
30
|
-
|
31
|
-
(feature["elements"] || []).each do |feature_element|
|
32
|
-
parse_element(feature_element)
|
31
|
+
def feature_element(o)
|
32
|
+
case o['type']
|
33
|
+
when 'background'
|
34
|
+
Formatter::Model::Background.new(comments(o), keyword(o), name(o), description(o), line(o))
|
35
|
+
when 'scenario'
|
36
|
+
Formatter::Model::Scenario.new(comments(o), tags(o), keyword(o), name(o), description(o), line(o))
|
37
|
+
when 'scenario_outline'
|
38
|
+
Formatter::Model::ScenarioOutline.new(comments(o), tags(o), keyword(o), name(o), description(o), line(o))
|
33
39
|
end
|
34
|
-
|
35
|
-
@listener.eof
|
36
40
|
end
|
37
41
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
(feature_element["examples"] || []).each do |examples|
|
46
|
-
comments_for(examples)
|
47
|
-
tags_for(examples)
|
48
|
-
multiline_event(examples)
|
49
|
-
rows_for(examples['table'])
|
42
|
+
def step(o)
|
43
|
+
multiline_arg = nil
|
44
|
+
if(ma = o['multiline_arg'])
|
45
|
+
if(ma['type'] == 'table')
|
46
|
+
multiline_arg = rows(ma['value'])
|
47
|
+
else
|
48
|
+
multiline_arg = Formatter::Model::PyString.new(ma['value'], ma['line'])
|
50
49
|
end
|
51
50
|
end
|
51
|
+
Formatter::Model::Step.new(comments(o), keyword(o), name(o), nil, line(o), multiline_arg)
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
55
|
-
(
|
56
|
-
@listener.comment(comment['value'], comment['line'])
|
57
|
-
end
|
54
|
+
def rows(o)
|
55
|
+
o.map{|row| Formatter::Model::Row.new(comments(row), row['cells'], row['line'])}
|
58
56
|
end
|
59
57
|
|
60
|
-
def
|
61
|
-
(
|
62
|
-
|
58
|
+
def comments(o)
|
59
|
+
(o['comments'] || []).map do |comment|
|
60
|
+
Formatter::Model::Comment.new(comment['value'], comment['line'])
|
63
61
|
end
|
64
62
|
end
|
65
63
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
@listener.step(step["keyword"], step["name"], step['line'])
|
70
|
-
multiline_arg_for(step)
|
64
|
+
def tags(o)
|
65
|
+
(o['tags'] || []).map do |tag|
|
66
|
+
Formatter::Model::Tag.new(tag['name'], tag['line'])
|
71
67
|
end
|
72
68
|
end
|
73
69
|
|
74
|
-
def
|
75
|
-
|
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
|
70
|
+
def keyword(o)
|
71
|
+
o['keyword']
|
83
72
|
end
|
84
73
|
|
85
|
-
def
|
86
|
-
|
87
|
-
comments_for(row)
|
88
|
-
@listener.row(cells_for(row), row['line'])
|
89
|
-
end
|
74
|
+
def name(o)
|
75
|
+
o['name']
|
90
76
|
end
|
91
77
|
|
92
|
-
def
|
93
|
-
|
78
|
+
def description(o)
|
79
|
+
o['description']
|
94
80
|
end
|
95
81
|
|
96
|
-
def
|
97
|
-
|
98
|
-
@listener.__send__(element['type'].to_sym, element["keyword"], element["name"] || "", element["description"] || "", element['line'])
|
99
|
-
end
|
82
|
+
def line(o)
|
83
|
+
o['line']
|
100
84
|
end
|
101
85
|
end
|
102
86
|
end
|