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.
Files changed (47) hide show
  1. data/History.txt +16 -0
  2. data/README.rdoc +1 -0
  3. data/Rakefile +1 -1
  4. data/VERSION.yml +2 -2
  5. data/features/json_formatter.feature +3 -11
  6. data/features/json_parser.feature +2 -5
  7. data/features/step_definitions/json_lexer_steps.rb +1 -1
  8. data/features/step_definitions/pretty_formatter_steps.rb +1 -1
  9. data/features/support/env.rb +2 -1
  10. data/java/src/main/java/gherkin/lexer/{.gitignore → i18n/.gitignore} +0 -0
  11. data/json-simple-1.1.dll +0 -0
  12. data/lib/gherkin.rb +1 -1
  13. data/lib/gherkin/formatter/filter_formatter.rb +52 -61
  14. data/lib/gherkin/formatter/json_formatter.rb +26 -94
  15. data/lib/gherkin/formatter/line_filter.rb +3 -3
  16. data/lib/gherkin/formatter/model.rb +156 -19
  17. data/lib/gherkin/formatter/pretty_formatter.rb +25 -25
  18. data/lib/gherkin/formatter/regexp_filter.rb +5 -1
  19. data/lib/gherkin/formatter/tag_count_formatter.rb +15 -12
  20. data/lib/gherkin/formatter/tag_filter.rb +19 -0
  21. data/lib/gherkin/json_parser.rb +49 -65
  22. data/lib/gherkin/lexer/i18n_lexer.rb +40 -0
  23. data/lib/gherkin/listener/formatter_listener.rb +11 -18
  24. data/lib/gherkin/parser/parser.rb +4 -5
  25. data/lib/gherkin/tools/stats_listener.rb +1 -1
  26. data/ragel/lexer.c.rl.erb +3 -1
  27. data/ragel/lexer.java.rl.erb +4 -4
  28. data/ragel/lexer.rb.rl.erb +3 -1
  29. data/spec/gherkin/fixtures/complex.json +2 -3
  30. data/spec/gherkin/formatter/model_spec.rb +1 -1
  31. data/spec/gherkin/formatter/pretty_formatter_spec.rb +11 -8
  32. data/spec/gherkin/i18n_spec.rb +3 -3
  33. data/spec/gherkin/java_lexer_spec.rb +1 -1
  34. data/spec/gherkin/json.rb +5 -0
  35. data/spec/gherkin/json_parser_spec.rb +49 -73
  36. data/spec/gherkin/lexer/i18n_lexer_spec.rb +33 -0
  37. data/spec/gherkin/sexp_recorder.rb +0 -2
  38. data/spec/spec_helper.rb +1 -0
  39. data/tasks/bench.rake +2 -2
  40. data/tasks/compile.rake +1 -1
  41. data/tasks/ikvm.rake +3 -1
  42. data/tasks/ragel_task.rb +1 -1
  43. data/tasks/release.rake +13 -1
  44. data/tasks/rspec.rake +0 -1
  45. metadata +17 -13
  46. data/lib/gherkin/i18n_lexer.rb +0 -38
  47. data/spec/gherkin/i18n_lexer_spec.rb +0 -26
@@ -5,9 +5,9 @@ module Gherkin
5
5
  @lines = lines
6
6
  end
7
7
 
8
- def eval(ranges)
9
- @lines.detect do |line|
10
- ranges.detect do |range|
8
+ def eval(tags, names, ranges)
9
+ ranges.detect do |range|
10
+ @lines.detect do |line|
11
11
  range.include?(line)
12
12
  end
13
13
  end
@@ -3,7 +3,159 @@ require 'gherkin/native'
3
3
  module Gherkin
4
4
  module Formatter
5
5
  module Model
6
- class Comment
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 feature(statement, uri)
23
+ def uri(uri)
24
24
  @uri = uri
25
- print_comments(statement.comments, '')
26
- print_tags(statement.tags, '')
27
- @io.puts "#{statement.keyword}: #{statement.name}"
28
- print_description(statement.description, ' ', false)
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(statement)
47
- scenario(statement)
49
+ def scenario_outline(scenario_outline)
50
+ scenario(scenario_outline)
48
51
  end
49
52
 
50
- def examples(statement, examples_rows)
53
+ def examples(examples)
51
54
  @io.puts
52
- print_comments(statement.comments, ' ')
53
- print_tags(statement.tags, ' ')
54
- @io.puts " #{statement.keyword}: #{statement.name}"
55
- print_description(statement.description, ' ')
56
- table(examples_rows)
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(statement, multiline_arg, result)
60
- name = Gherkin::Formatter::Argument.format(statement.name, @format, (result ? result.arguments : []))
62
+ def step(step)
63
+ name = Gherkin::Formatter::Argument.format(step.name, @format, (step.result ? step.result.arguments : []))
61
64
 
62
- step = "#{statement.keyword}#{statement.name}"
63
- step = self.__send__(result.status, step, @monochrome) if result
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(statement.comments, ' ')
66
- @io.puts(" #{step}#{indented_step_location!(result ? result.stepdef_location : nil)}")
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 feature(statement, uri)
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 scenario(statement)
16
- record_tags((@feature_tags.to_a + statement.tags.to_a).uniq, statement.line)
17
- @formatter.scenario(statement)
13
+ def feature(feature)
14
+ @feature_tags = feature.tags
15
+ @formatter.feature(feature)
18
16
  end
19
17
 
20
- def scenario_outline(statement)
21
- @scenario_outline_tags = statement.tags
22
- @formatter.scenario_outline(statement)
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 examples(statement, examples_rows)
26
- record_tags((@feature_tags.to_a + @scenario_outline_tags.to_a + statement.tags.to_a).uniq, statement.line)
27
- @formatter.examples(statement, examples_rows)
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
@@ -1,102 +1,86 @@
1
1
  require 'json'
2
- require 'gherkin/listener/formatter_listener'
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
- @listener = Listener::FormatterListener.new(@formatter)
13
- _parse(src, feature_uri, line_offset)
14
- end
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
- def parse_with_listener(src, listener)
17
- @listener = listener
18
- _parse(src, 'unknown.json', 0)
28
+ @formatter.eof
19
29
  end
20
30
 
21
- private
22
-
23
- def _parse(src, feature_uri, line_offset)
24
- @listener.location(feature_uri)
25
- feature = JSON.parse(src)
26
-
27
- comments_for(feature)
28
- tags_for(feature)
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 parse_element(feature_element)
39
- comments_for(feature_element)
40
- tags_for(feature_element)
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'])
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 comments_for(element)
55
- (element["comments"] || []).each do |comment|
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 tags_for(element)
61
- (element["tags"] || []).each do |tag|
62
- @listener.tag(tag['name'], tag['line'])
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 steps_for(element)
67
- element["steps"].each do |step|
68
- comments_for(step)
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 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
70
+ def keyword(o)
71
+ o['keyword']
83
72
  end
84
73
 
85
- def rows_for(rows)
86
- (rows || []).each do |row|
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 cells_for(row)
93
- row["cells"]
78
+ def description(o)
79
+ o['description']
94
80
  end
95
81
 
96
- def multiline_event(element)
97
- if element["keyword"]
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