gherkin 1.0.30 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.rspec +1 -0
  2. data/History.txt +19 -0
  3. data/Rakefile +4 -4
  4. data/VERSION.yml +2 -2
  5. data/features/feature_parser.feature +11 -0
  6. data/features/json_formatter.feature +238 -0
  7. data/features/pretty_formatter.feature +9 -0
  8. data/features/step_definitions/gherkin_steps.rb +1 -1
  9. data/features/step_definitions/json_formatter_steps.rb +32 -0
  10. data/features/step_definitions/pretty_formatter_steps.rb +24 -23
  11. data/features/support/env.rb +3 -3
  12. data/lib/gherkin/formatter/json_formatter.rb +82 -0
  13. data/lib/gherkin/formatter/pretty_formatter.rb +73 -78
  14. data/lib/gherkin/i18n.rb +22 -18
  15. data/lib/gherkin/i18n.yml +9 -9
  16. data/lib/gherkin/i18n_lexer.rb +2 -2
  17. data/lib/gherkin/parser/event.rb +6 -6
  18. data/lib/gherkin/parser/filter_listener.rb +5 -1
  19. data/lib/gherkin/parser/formatter_listener.rb +113 -0
  20. data/lib/gherkin/parser/json_parser.rb +102 -0
  21. data/lib/gherkin/parser/parser.rb +10 -2
  22. data/lib/gherkin/parser/row.rb +15 -0
  23. data/lib/gherkin/rubify.rb +2 -0
  24. data/lib/gherkin/tools/files.rb +1 -1
  25. data/lib/gherkin/tools/reformat.rb +1 -2
  26. data/lib/gherkin/tools/stats.rb +1 -1
  27. data/lib/gherkin/tools/stats_listener.rb +5 -5
  28. data/ragel/lexer.c.rl.erb +41 -12
  29. data/ragel/lexer.java.rl.erb +26 -17
  30. data/ragel/lexer.rb.rl.erb +10 -5
  31. data/ragel/lexer_common.rl.erb +6 -6
  32. data/spec/gherkin/c_lexer_spec.rb +2 -2
  33. data/spec/gherkin/fixtures/complex.js +105 -0
  34. data/spec/gherkin/formatter/argument_spec.rb +3 -3
  35. data/spec/gherkin/formatter/colors_spec.rb +3 -4
  36. data/spec/gherkin/formatter/pretty_formatter_spec.rb +21 -50
  37. data/spec/gherkin/i18n_lexer_spec.rb +6 -6
  38. data/spec/gherkin/i18n_spec.rb +16 -9
  39. data/spec/gherkin/java_lexer_spec.rb +1 -2
  40. data/spec/gherkin/output_stream_string_io.rb +24 -0
  41. data/spec/gherkin/parser/filter_listener_spec.rb +16 -9
  42. data/spec/gherkin/parser/formatter_listener_spec.rb +134 -0
  43. data/spec/gherkin/parser/json_parser_spec.rb +129 -0
  44. data/spec/gherkin/parser/parser_spec.rb +9 -9
  45. data/spec/gherkin/parser/tag_expression_spec.rb +8 -8
  46. data/spec/gherkin/rb_lexer_spec.rb +1 -1
  47. data/spec/gherkin/sexp_recorder.rb +21 -1
  48. data/spec/gherkin/shared/{lexer_spec.rb → lexer_group.rb} +172 -102
  49. data/spec/gherkin/shared/{py_string_spec.rb → py_string_group.rb} +21 -17
  50. data/spec/gherkin/shared/{row_spec.rb → row_group.rb} +36 -19
  51. data/spec/gherkin/shared/{tags_spec.rb → tags_group.rb} +13 -9
  52. data/spec/spec_helper.rb +18 -38
  53. data/tasks/bench.rake +3 -3
  54. data/tasks/compile.rake +13 -14
  55. data/tasks/rspec.rake +6 -11
  56. metadata +42 -28
  57. data/features/pretty_printer.feature +0 -14
  58. data/spec/gherkin/csharp_lexer_spec.rb +0 -20
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -1,3 +1,22 @@
1
+ == 2.0.0
2
+
3
+ We're breaking the old listener API in this release, and added a new JSON formatter,
4
+ which calls for a new major version.
5
+
6
+ === New Features
7
+ * New JSON formatter. (Aslak Hellesøy, Joseph Wilk)
8
+ * New synonyms for Hungarian (Bence Golda)
9
+ * Upgraded to use RSpec 2.0.0 (Aslak Hellesøy)
10
+
11
+ === Bugfixes
12
+ * undefined method `<=>' on JRuby (#52 Aslak Hellesøy)
13
+ * Include link to explanation of LexingError (Mike Sassak)
14
+
15
+ === Changed Features
16
+ * The formatter API has completely changed. There is a Gherkin Listener API and a Formatter API.
17
+ The FormatterListener acts as an adapter between them. (Aslak Hellesøy)
18
+ * The listener API now has an additional argument for description (text following the first line of Feature:, Scenario: etc.) (Gregroy Hnatiuk, Matt Wynne)
19
+
1
20
  == 1.0.30 (2010-05-18)
2
21
 
3
22
  === New Features
data/Rakefile CHANGED
@@ -18,10 +18,10 @@ begin
18
18
  gem.homepage = "http://github.com/aslakhellesoy/gherkin"
19
19
  gem.authors = ["Mike Sassak", "Gregory Hnatiuk", "Aslak Hellesøy"]
20
20
  gem.executables = ["gherkin"]
21
- gem.add_dependency "trollop", ">= 1.16.2"
22
- gem.add_development_dependency "rspec", ">= 1.3.0"
23
- gem.add_development_dependency "cucumber", ">= 0.7.2"
24
- gem.add_development_dependency "rake-compiler", ">= 0.7.0" unless defined?(JRUBY_VERSION)
21
+ gem.add_dependency "trollop", "~> 1.16.2"
22
+ gem.add_development_dependency 'rspec', '~> 2.0.0.beta.11'
23
+ gem.add_development_dependency "cucumber", "~> 0.8.1"
24
+ gem.add_development_dependency "rake-compiler", "~> 0.7.0" unless defined?(JRUBY_VERSION)
25
25
 
26
26
  gem.files -= FileList['ikvm/**/*']
27
27
  gem.files -= FileList['java/**/*']
@@ -1,5 +1,5 @@
1
1
  ---
2
- :major: 1
2
+ :major: 2
3
3
  :minor: 0
4
4
  :build:
5
- :patch: 30
5
+ :patch: 0
@@ -73,6 +73,17 @@ Feature: Gherkin Feature lexer
73
73
  """
74
74
  Then there should be parse errors on lines 1 through 3
75
75
 
76
+ Scenario: Multiple Features in file
77
+ Given the following text is parsed:
78
+ """
79
+ Feature:
80
+ Scenario: Hi
81
+ Feature: Uh ohs
82
+ Scenario Outline:
83
+ Feature: This is silly
84
+ """
85
+ Then there should be parse errors on lines 3 and 5
86
+
76
87
  Scenario: Tag ends background and scenario
77
88
  Given the following text is parsed:
78
89
  """
@@ -0,0 +1,238 @@
1
+ Feature: JSON formatter
2
+ In order to support greater access to features
3
+ we want JSON
4
+
5
+ Background:
6
+ Given a JSON formatter
7
+ And a "ruby" "root" parser
8
+
9
+ Scenario: Only a Feature
10
+ Given the following text is parsed:
11
+ """
12
+ # language: no
13
+ # Another comment
14
+ Egenskap: Kjapp
15
+ """
16
+ Then the outputted JSON should be:
17
+ """
18
+ {
19
+ "comments": ["# language: no", "# Another comment"],
20
+ "description": "",
21
+ "keyword": "Egenskap",
22
+ "name": "Kjapp",
23
+ "tags": [],
24
+ "uri": "test.feature"
25
+ }
26
+ """
27
+
28
+ Scenario: Feature with two scenarios
29
+ Given the following text is parsed:
30
+ """
31
+ @one
32
+ Feature: OH HAI
33
+
34
+ Scenario: Fujin
35
+ Given wind
36
+ Then spirit
37
+
38
+ @two
39
+ Scenario: _why
40
+ Given chunky
41
+ Then bacon
42
+
43
+ @three @four
44
+ Scenario Outline: Life
45
+ Given some <boredom>
46
+
47
+ @five
48
+ Examples: Real life
49
+ |boredom|
50
+ |airport|
51
+ |meeting|
52
+
53
+ Scenario: who stole my mojo?
54
+ When I was
55
+ |asleep|
56
+ And so
57
+ \"\"\"
58
+ innocent
59
+ \"\"\"
60
+
61
+ # The
62
+ Scenario Outline: with
63
+ # all
64
+ Then nice
65
+
66
+ # comments
67
+ # everywhere
68
+ Examples: An example
69
+ # I mean
70
+ | partout |
71
+ """
72
+ Then the outputted JSON should be:
73
+ """
74
+ {
75
+ "comments": [],
76
+ "keyword": "Feature",
77
+ "name": "OH HAI",
78
+ "tags": ["@one"],
79
+ "uri": "test.feature",
80
+ "description": "",
81
+ "elements":[
82
+ {
83
+ "comments": [],
84
+ "tags": [],
85
+ "keyword": "Scenario",
86
+ "name": "Fujin",
87
+ "description": "",
88
+ "line": 4,
89
+ "steps": [
90
+ {
91
+ "comments": [],
92
+ "keyword": "Given ",
93
+ "name": "wind",
94
+ "line": 5,
95
+ "multiline_arg": null
96
+ },
97
+ {
98
+ "comments": [],
99
+ "keyword": "Then ",
100
+ "name": "spirit",
101
+ "line": 6,
102
+ "multiline_arg": null
103
+ }
104
+ ]
105
+ },
106
+ {
107
+ "comments": [],
108
+ "tags": ["@two"],
109
+ "keyword": "Scenario",
110
+ "name": "_why",
111
+ "description": "",
112
+ "line": 9,
113
+ "steps": [
114
+ {
115
+ "comments": [],
116
+ "keyword": "Given ",
117
+ "name": "chunky",
118
+ "line": 10,
119
+ "multiline_arg": null
120
+ },
121
+ {
122
+ "comments": [],
123
+ "keyword": "Then ",
124
+ "name": "bacon",
125
+ "line": 11,
126
+ "multiline_arg": null
127
+ }
128
+ ]
129
+ },
130
+ {
131
+ "comments": [],
132
+ "tags": ["@three", "@four"],
133
+ "keyword": "Scenario Outline",
134
+ "name": "Life",
135
+ "description": "",
136
+ "line": 14,
137
+ "steps": [
138
+ {
139
+ "comments": [],
140
+ "keyword": "Given ",
141
+ "name": "some <boredom>",
142
+ "line": 15,
143
+ "multiline_arg": null
144
+ }
145
+ ]
146
+ },
147
+ {
148
+ "comments": [],
149
+ "tags": ["@five"],
150
+ "keyword": "Examples",
151
+ "name": "Real life",
152
+ "description": "",
153
+ "line": 18,
154
+ "examples_table": [
155
+ {
156
+ "comments": [],
157
+ "cells": ["boredom"],
158
+ "line": 19
159
+ },
160
+ {
161
+ "comments": [],
162
+ "cells": ["airport"],
163
+ "line": 20
164
+ },
165
+ {
166
+ "comments": [],
167
+ "cells": ["meeting"],
168
+ "line": 21
169
+ }
170
+ ]
171
+ },
172
+ {
173
+ "comments": [],
174
+ "tags": [],
175
+ "keyword": "Scenario",
176
+ "name": "who stole my mojo?",
177
+ "description": "",
178
+ "line": 23,
179
+ "steps": [
180
+ {
181
+ "comments": [],
182
+ "keyword": "When ",
183
+ "name": "I was",
184
+ "line": 24,
185
+ "multiline_arg": [
186
+ {
187
+ "comments": [],
188
+ "line": 25,
189
+ "cells": ["asleep"]
190
+ }
191
+ ]
192
+ },
193
+ {
194
+ "comments": [],
195
+ "keyword": "And ",
196
+ "name": "so",
197
+ "line": 26,
198
+ "multiline_arg": "innocent"
199
+ }
200
+ ]
201
+ },
202
+ {
203
+ "comments": ["# The"],
204
+ "tags": [],
205
+ "keyword": "Scenario Outline",
206
+ "description": "",
207
+ "line": 32,
208
+ "name": "with",
209
+ "steps": [
210
+ {
211
+ "comments": ["# all"],
212
+ "keyword": "Then ",
213
+ "line": 34,
214
+ "name": "nice",
215
+ "multiline_arg": null
216
+ }
217
+ ]
218
+ },
219
+ {
220
+ "comments": ["# comments", "# everywhere"],
221
+ "tags": [],
222
+ "keyword": "Examples",
223
+ "name": "An example",
224
+ // TODO - the description should now be the comment
225
+ // It should be on the first row of the examples_table!
226
+ "description": "# I mean",
227
+ "line": 38,
228
+ "examples_table": [
229
+ {
230
+ "comments": [],
231
+ "line": 40,
232
+ "cells": ["partout"]
233
+ }
234
+ ]
235
+ }
236
+ ]
237
+ }
238
+ """
@@ -0,0 +1,9 @@
1
+ Feature: Pretty Formatter
2
+ In order to have pretty gherkin
3
+ I want to verify that all prettified cucumber features parse OK
4
+
5
+ Scenario: Parse all the features in Cucumber
6
+ Given I have Cucumber's source code next to Gherkin's
7
+ When I find all of the .feature files
8
+ And I parse the prettified representation of each of them
9
+ Then they should all be identical to the pretty output
@@ -4,7 +4,7 @@ Given /^a "([^\"]*)" "([^\"]*)" parser$/ do |ruby_or_native, parser_name|
4
4
  end
5
5
 
6
6
  Given "the following text is parsed:" do |text|
7
- @lexer.scan(text)
7
+ @lexer.scan(text, "test.feature", 0)
8
8
  end
9
9
 
10
10
  Then "there should be no parse errors" do
@@ -0,0 +1,32 @@
1
+ require 'stringio'
2
+ require 'gherkin/formatter/json_formatter'
3
+ require 'gherkin/parser/formatter_listener'
4
+
5
+ # Monkey patching so that Hash.to_json has a predictable result.
6
+ class Hash
7
+ alias orig_keys keys
8
+ def keys
9
+ orig_keys.sort
10
+ end
11
+ end
12
+
13
+ Given /^a JSON formatter$/ do
14
+ @io = StringIO.new
15
+ @listener = Gherkin::Parser::FormatterListener.new(Gherkin::Formatter::JSONFormatter.new(@io))
16
+ end
17
+
18
+ Then /^the outputted JSON should be:$/ do |expected_json|
19
+ require 'json'
20
+ expected = JSON.pretty_generate(JSON.parse(expected_json))
21
+ actual = JSON.pretty_generate(JSON.parse(@io.string))
22
+ begin
23
+ actual.should == expected
24
+ rescue # Haven't figured out how to order Hash on JRuby (JSON pure). Retry with possibly worse error message.
25
+ expected = JSON.parse(expected_json)
26
+ actual = JSON.parse(@io.string)
27
+ actual.should == expected
28
+ end
29
+ end
30
+
31
+
32
+
@@ -4,52 +4,53 @@ require 'gherkin/formatter/pretty_formatter'
4
4
 
5
5
  module PrettyPlease
6
6
  def pretty(source)
7
- io = StringIO.new
8
- listener = Gherkin::Formatter::PrettyFormatter.new(io)
9
- parser = Gherkin::Parser::Parser.new(listener, true)
10
- lexer = Gherkin::I18nLexer.new(parser)
11
- lexer.scan(source)
12
- io.rewind
13
- io.read
7
+ io = StringIO.new
8
+ formatter = Gherkin::Formatter::PrettyFormatter.new(io, false)
9
+ listener = Gherkin::Parser::FormatterListener.new(formatter)
10
+ parser = Gherkin::Parser::Parser.new(listener, true)
11
+ lexer = Gherkin::I18nLexer.new(parser)
12
+ lexer.scan(source, "test.feature", 0)
13
+ io.string
14
14
  end
15
15
  end
16
16
 
17
17
  World(PrettyPlease)
18
18
 
19
- Given /^I have Cucumber's home dir defined in CUCUMBER_HOME$/ do
20
- @cucumber_home = ENV['CUCUMBER_HOME']
21
- raise "No CUCUMBER_HOME" if @cucumber_home.nil?
19
+ Given /^I have Cucumber's source code next to Gherkin's$/ do
20
+ @cucumber_home = File.dirname(__FILE__) + '/../../../cucumber'
21
+ raise "No Cucumber source in #{@cucumber_home}" unless File.file?(@cucumber_home + '/bin/cucumber')
22
22
  end
23
23
 
24
24
  When /^I find all of the \.feature files$/ do
25
- @features = Dir["#{@cucumber_home}/**/*.feature"].sort
25
+ @feature_paths = Dir["#{@cucumber_home}/**/*.feature"].sort
26
26
  end
27
27
 
28
28
  When /^I parse the prettified representation of each of them$/ do
29
- @errors = [['Path', 'Error']]
30
- @features.each do |feature|
29
+ @error = false
30
+ @feature_paths.each do |feature_path|
31
31
  pretty1 = nil
32
32
  pretty2 = nil
33
33
  begin
34
- pretty1 = pretty(IO.read(feature))
34
+ pretty1 = pretty(IO.read(feature_path))
35
35
  pretty2 = pretty(pretty1)
36
36
  pretty2.should == pretty1
37
- rescue Spec::Expectations::ExpectationNotMetError => e
38
- File.open("p1.feature", "wb") {|io| io.write(pretty1)}
39
- File.open("p2.feature", "wb") {|io| io.write(pretty2)}
40
- announce "========== #{feature}:"
37
+ rescue RSpec::Expectations::ExpectationNotMetError => e
38
+ announce "=========="
39
+ announce feature_path
41
40
  if(e.message =~ /(@@.*)/m)
42
41
  announce $1
42
+ @error = true
43
+ File.open("p1.feature", "wb") {|io| io.write(pretty1)}
44
+ File.open("p2.feature", "wb") {|io| io.write(pretty2)}
43
45
  else
44
- announce "??? NO DIFF ???"
46
+ announce "Identical, except for newlines"
45
47
  end
46
- @errors << [feature, "See announced diff"]
47
48
  rescue => e
48
- @errors << [feature, e.message]
49
+ e.message << "\nFatal error happened when parsing #{feature_path}"
49
50
  end
50
51
  end
51
52
  end
52
53
 
53
- Then /^the following files should have errors:$/ do |table|
54
- table.diff!(@errors)
54
+ Then /^they should all be identical to the pretty output$/ do
55
+ raise "Some features didn't do pretty well" if @error
55
56
  end
@@ -1,10 +1,10 @@
1
1
  # I'm sure there's a better way than this...
2
- %w{/../../lib /../../spec/gherkin}.each do |path|
2
+ %w{ /../../spec /../../lib}.each do |path|
3
3
  $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + path)
4
4
  end
5
-
6
5
  require 'gherkin'
7
- require "sexp_recorder"
6
+ require "gherkin/sexp_recorder"
7
+ require 'gherkin/output_stream_string_io'
8
8
 
9
9
  module TransformHelpers
10
10
  def tr_line_number(step_arg)