gherkin 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/History.txt +15 -6
  2. data/README.rdoc +23 -0
  3. data/Rakefile +1 -0
  4. data/VERSION.yml +1 -1
  5. data/features/step_definitions/gherkin_steps.rb +1 -1
  6. data/features/step_definitions/{pretty_printer_steps.rb → pretty_listener_step.rb} +2 -2
  7. data/gherkin.gemspec +24 -35
  8. data/java/Gherkin.iml +8 -14
  9. data/java/src/{gherkin → main/java/gherkin}/lexer/.gitignore +0 -0
  10. data/lib/gherkin.rb +1 -1
  11. data/lib/gherkin/c_lexer.rb +2 -2
  12. data/lib/gherkin/{format → formatter}/argument.rb +1 -1
  13. data/lib/gherkin/{tools → formatter}/colors.rb +1 -1
  14. data/lib/gherkin/{format → formatter}/monochrome_format.rb +1 -1
  15. data/lib/gherkin/{tools → formatter}/pretty_listener.rb +8 -9
  16. data/lib/gherkin/i18n.rb +27 -5
  17. data/lib/gherkin/i18n_lexer.rb +18 -44
  18. data/lib/gherkin/parser/filter_listener.rb +191 -0
  19. data/lib/gherkin/parser/parser.rb +142 -0
  20. data/lib/gherkin/parser/sexp.rb +45 -0
  21. data/lib/gherkin/parser/tag_expression.rb +46 -0
  22. data/lib/gherkin/rb_lexer.rb +2 -2
  23. data/ragel/lexer_common.rl.erb +1 -1
  24. data/spec/gherkin/{format → formatter}/argument_spec.rb +2 -2
  25. data/spec/gherkin/{tools → formatter}/colors_spec.rb +2 -2
  26. data/spec/gherkin/{tools → formatter}/pretty_listener_spec.rb +5 -5
  27. data/spec/gherkin/i18n_lexer_spec.rb +3 -3
  28. data/spec/gherkin/parser/filter_listener_spec.rb +363 -0
  29. data/spec/gherkin/parser/parser_spec.rb +35 -0
  30. data/spec/gherkin/parser/tag_expression_spec.rb +120 -0
  31. data/spec/gherkin/rb_lexer_spec.rb +0 -1
  32. data/spec/gherkin/sexp_recorder.rb +3 -3
  33. data/spec/gherkin/shared/lexer_spec.rb +19 -19
  34. data/spec/gherkin/shared/tags_spec.rb +4 -4
  35. data/tasks/bench.rake +2 -2
  36. data/tasks/compile.rake +1 -1
  37. data/tasks/ragel_task.rb +1 -1
  38. metadata +25 -36
  39. data/java/build.xml +0 -16
  40. data/java/src/gherkin/FixJava.java +0 -37
  41. data/java/src/gherkin/I18nLexer.java +0 -48
  42. data/java/src/gherkin/Lexer.java +0 -5
  43. data/java/src/gherkin/LexingError.java +0 -7
  44. data/java/src/gherkin/Listener.java +0 -29
  45. data/java/src/gherkin/Main.java +0 -17
  46. data/java/src/gherkin/ParseError.java +0 -22
  47. data/java/src/gherkin/Parser.java +0 -191
  48. data/java/src/gherkin/formatter/Argument.java +0 -39
  49. data/java/src/gherkin/formatter/ArgumentFormat.java +0 -17
  50. data/java/src/gherkin/formatter/Colors.java +0 -7
  51. data/java/src/gherkin/formatter/Formatter.java +0 -15
  52. data/java/src/gherkin/formatter/PrettyFormatter.java +0 -219
  53. data/java/src/gherkin/parser/StateMachineReader.java +0 -67
  54. data/java/test/gherkin/formatter/ArgumentTest.java +0 -17
  55. data/lib/gherkin/lexer.rb +0 -35
  56. data/lib/gherkin/parser.rb +0 -19
  57. data/lib/gherkin/rb_parser.rb +0 -125
  58. data/spec/gherkin/parser_spec.rb +0 -33
@@ -1,9 +1,9 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
- require 'gherkin/tools/pretty_listener'
2
+ require 'gherkin/formatter/pretty_listener'
3
3
 
4
4
 
5
5
  module Gherkin
6
- module Tools
6
+ module Formatter
7
7
  describe Colors do
8
8
  include Colors
9
9
 
@@ -1,11 +1,11 @@
1
1
  # encoding: utf-8
2
2
  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
- require 'gherkin/tools/pretty_listener'
4
- require 'gherkin/format/argument'
3
+ require 'gherkin/formatter/pretty_listener'
4
+ require 'gherkin/formatter/argument'
5
5
  require 'stringio'
6
6
 
7
7
  module Gherkin
8
- module Tools
8
+ module Formatter
9
9
  describe PrettyListener do
10
10
  def assert_io(s)
11
11
  @io.rewind
@@ -16,7 +16,7 @@ module Gherkin
16
16
  def assert_pretty(text)
17
17
  io = StringIO.new
18
18
  l = PrettyListener.new(io, true)
19
- parser = Gherkin::Parser.new(l, true, "root")
19
+ parser = Gherkin::Parser::Parser.new(l, true, "root")
20
20
  lexer = Gherkin::I18nLexer.new(parser, true)
21
21
  lexer.scan(text)
22
22
  io.rewind
@@ -95,7 +95,7 @@ module Gherkin
95
95
 
96
96
  it "should highlight arguments for regular steps" do
97
97
  passed = defined?(JRUBY_VERSION) ? 'passed' : :passed
98
- @l.step("Given ", "I have 999 cukes in my belly", 3, passed, [Gherkin::Format::Argument.new(7, '999')], nil)
98
+ @l.step("Given ", "I have 999 cukes in my belly", 3, passed, [Gherkin::Formatter::Argument.new(7, '999')], nil)
99
99
  assert_io(" Given I have 999 cukes in my belly\n")
100
100
  end
101
101
 
@@ -9,14 +9,14 @@ module Gherkin
9
9
 
10
10
  it "should store the i18n language of the last scanned feature" do
11
11
  @lexer.scan("# language: fr\n")
12
- @lexer.i18n_language.should == "fr"
12
+ @lexer.i18n_language.key.should == "fr"
13
13
  @lexer.scan("# language: no\n")
14
- @lexer.i18n_language.should == "no"
14
+ @lexer.i18n_language.key.should == "no"
15
15
  end
16
16
 
17
17
  it "should use English i18n by default" do
18
18
  @lexer.scan("Feature: foo\n")
19
- @lexer.i18n_language.should == "en"
19
+ @lexer.i18n_language.key.should == "en"
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,363 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
+ require 'gherkin/parser/filter_listener'
4
+ require 'gherkin/formatter/pretty_listener'
5
+ require 'stringio'
6
+
7
+ module Gherkin
8
+ module Parser
9
+ describe FilterListener do
10
+
11
+ class LineListener
12
+ attr_reader :lines
13
+
14
+ def method_missing(*sexp_args)
15
+ @lines ||= []
16
+ @lines << sexp_args[-1]
17
+ end
18
+ end
19
+
20
+ def verify_filters(expected_lines, filters)
21
+ line_listener = LineListener.new
22
+ scan(line_listener, filters)
23
+ line_listener.lines.should == expected_lines
24
+ end
25
+
26
+ def verify_output(expected_output, filters)
27
+ io = StringIO.new
28
+ scan(Gherkin::Formatter::PrettyListener.new(io, true), filters)
29
+ io.rewind
30
+ io.read.should == expected_output
31
+ end
32
+
33
+ def scan(listener, filters)
34
+ tag_expressions = filters.delete(:tag_expressions)
35
+ filters[:tag_expression] = TagExpression.new(*tag_expressions) if tag_expressions
36
+ filter_listener = FilterListener.new(listener, filters)
37
+ parser = Gherkin::Parser::Parser.new(filter_listener, true, "root")
38
+ lexer = Gherkin::I18nLexer.new(parser, true)
39
+ lexer.scan(@input)
40
+ end
41
+
42
+ context "Scenario" do
43
+ before do
44
+ @input = %{Feature: 1
45
+ Scenario: 2
46
+ Given 3
47
+
48
+ Scenario: 5
49
+ Given 6
50
+ }
51
+ end
52
+
53
+ it "should not replay anything if no lines match" do
54
+ verify_filters([:eof], [90])
55
+ end
56
+
57
+ it "should not replay anything if no names match" do
58
+ verify_filters([:eof], [/pudding/])
59
+ end
60
+
61
+ it "should replay identically when there is no filter" do
62
+ verify_filters([1,2,3,5,6,:eof], [])
63
+ end
64
+
65
+ it "should replay identically when line filter is feature line" do
66
+ verify_filters([1,2,3,5,6,:eof], [1])
67
+ end
68
+
69
+ it "should match scenario line of first scenario" do
70
+ verify_filters([1,2,3,:eof], [2])
71
+ end
72
+
73
+ it "should match name of first scenario" do
74
+ verify_filters([1,2,3,:eof], [/2/])
75
+ end
76
+
77
+ it "should match step line of first scenario" do
78
+ verify_filters([1,2,3,:eof], [3])
79
+ end
80
+
81
+ it "should match step line of second scenario" do
82
+ verify_filters([1,5,6,:eof], [6])
83
+ end
84
+
85
+ it "should replay identically (except newlines) when the filter matches both scenarios" do
86
+ verify_filters([1,2,3,5,6,:eof], [3,6])
87
+ end
88
+ end
89
+
90
+ context "Scenario with py_string" do
91
+ before do
92
+ @input = %{Feature: 1
93
+ Scenario: 2
94
+ Given 3
95
+ """
96
+ 5
97
+ """
98
+
99
+ Scenario: 8
100
+ Given 9
101
+ }
102
+ end
103
+
104
+ it "should replay identically when there is no filter" do
105
+ verify_filters([1,2,3,4,8,9,:eof], {})
106
+ end
107
+
108
+ it "should filter on py_string line" do
109
+ verify_filters([1,2,3,4,:eof], [4])
110
+ end
111
+ end
112
+
113
+ context "Scenario with Table and Comment and Tag" do
114
+ before do
115
+ @input = %{#language:en
116
+ Feature: 2
117
+ # 3
118
+ Scenario: 4
119
+ Given 5
120
+ When 6
121
+
122
+ @tag8
123
+ Scenario: 9
124
+ Given 10
125
+ When 11
126
+ | 12 | 12 |
127
+ | 13 | 13 |
128
+ }
129
+ end
130
+
131
+ it "should replay identically when there is no filter" do
132
+ verify_filters([1,2,3,4,5,6,8,9,10,11,12,13,:eof], [])
133
+ end
134
+
135
+ it "should match step line of first scenario" do
136
+ verify_filters([1,2,3,4,5,6,:eof], [5])
137
+ end
138
+
139
+ it "should match scenario line of second scenario" do
140
+ verify_filters([1,2,8,9,10,11,12,13,:eof], [9])
141
+ end
142
+
143
+ it "should match tag of second scenario" do
144
+ verify_filters([1,2,8,9,10,11,12,13,:eof], ['@tag8'])
145
+ end
146
+
147
+ it "should return everything when a line is given in each scenario" do
148
+ verify_filters([1,2,3,4,5,6,8,9,10,11,12,13,:eof], [6,9])
149
+ end
150
+
151
+ it "should return a scenario when a line is given for its tag" do
152
+ verify_filters([1,2,8,9,10,11,12,13,:eof], [8])
153
+ end
154
+
155
+ it "should return a scenario when a line is given for its comment" do
156
+ verify_filters([1,2,3,4,5,6,:eof], [3])
157
+ end
158
+ end
159
+
160
+ context "Scenario with Background and Comment" do
161
+ before do
162
+ @input = %{#language:en
163
+ Feature: 2
164
+ # 3
165
+ Background: 4
166
+ Given 5
167
+
168
+ # 7
169
+ Scenario: 8
170
+ Given 9
171
+ When 10
172
+
173
+ Scenario: 12
174
+ Given 13
175
+ When 14
176
+ | 15 | 16 |
177
+ | 15 | 16 |
178
+ }
179
+ end
180
+
181
+ it "should replay identically when there is no filter" do
182
+ verify_filters([1,2,3,4,5,7,8,9,10,12,13,14,15,16,:eof], [])
183
+ end
184
+
185
+ it "should replay identically when filtering on the line of a background step" do
186
+ verify_filters([1,2,3,4,5,7,8,9,10,12,13,14,15,16,:eof], [5])
187
+ end
188
+
189
+ it "should replay identically when filtering on the line of the background" do
190
+ verify_filters([1,2,3,4,5,7,8,9,10,12,13,14,15,16,:eof], [4])
191
+ end
192
+
193
+ it "should replay the background on step line of first scenario" do
194
+ verify_filters([1,2,3,4,5,7,8,9,10,:eof], [9])
195
+ end
196
+ end
197
+
198
+ context "Scenario Outline" do
199
+ before do
200
+ @input = %{Feature: 1
201
+
202
+ @tag3
203
+ Scenario Outline: 4
204
+ Given <foo> 5
205
+ When <bar> 6
206
+
207
+ @tag8
208
+ Examples: 9
209
+ | foo | bar |
210
+ | 11 | 11 |
211
+ | 12 | 12 |
212
+ | 13 | 13 |
213
+ | 14 | 14 |
214
+ | 15 | 15 |
215
+
216
+ @tag17
217
+ Examples: 18
218
+ | snip | snap |
219
+ | 20 | 20 |
220
+ | 21 | 21 |
221
+
222
+ Scenario: 23
223
+ Given 24
224
+ When 25
225
+ }
226
+ end
227
+
228
+ it "should match step line of first scenario outline" do
229
+ verify_filters([1,3,4,5,6,8,9,10,11,12,13,14,15,17,18,19,20,21,:eof], [6])
230
+ end
231
+
232
+ it "should match examples line of second scenario outline" do
233
+ verify_filters([1,3,4,5,6,17,18,19,20,21,:eof], [18])
234
+ end
235
+
236
+ it "should match examples name of second scenario outline" do
237
+ verify_filters([1,3,4,5,6,17,18,19,20,21,:eof], [/18/])
238
+ end
239
+
240
+ it "should match header row line of second scenario outline" do
241
+ verify_filters([1,3,4,5,6,17,18,19,20,21,:eof], [19])
242
+ end
243
+
244
+ it "should match an example row of first scenario outline" do
245
+ verify_filters([1,3,4,5,6,8,9,10,13,:eof], [13])
246
+ end
247
+
248
+ it "should match an example row of second scenario outline" do
249
+ verify_filters([1,3,4,5,6,17,18,19,20,:eof], [20])
250
+ end
251
+
252
+ it "should match 2 example rows of first scenario outline" do
253
+ verify_filters([1,3,4,5,6,8,9,10,12,14,:eof], [12,14])
254
+ end
255
+
256
+ it "should replay itself properly" do
257
+ filtered = %{Feature: 1
258
+
259
+ @tag3
260
+ Scenario Outline: 4
261
+ Given <foo> 5
262
+ When <bar> 6
263
+
264
+ @tag8
265
+ Examples: 9
266
+ | foo | bar |
267
+ | 12 | 12 |
268
+ | 14 | 14 |
269
+ }
270
+
271
+ verify_output(filtered, [12,14])
272
+ end
273
+ end
274
+
275
+ context "Scenarios with tags on both feature and scenarios" do
276
+ before do
277
+ # Lines with more than one tag per line will be repeated
278
+ @input = %{#language:en
279
+ @a @b
280
+ Feature: 3
281
+ @c @d
282
+ Scenario: 5
283
+ Given 6
284
+
285
+ @c @e
286
+ Scenario: 9
287
+ Given 10
288
+
289
+ Scenario: 12
290
+ Given 13
291
+ }
292
+ end
293
+
294
+ it "should match @d" do
295
+ verify_filters([1,2,2,3,4,4,5,6,:eof], ['@d'])
296
+ end
297
+
298
+ it "should match everything when feature tag matches" do
299
+ verify_filters([1,2,2,3,4,4,5,6,8,8,9,10,12,13,:eof], ['@a'])
300
+ end
301
+
302
+ it "should match @a && !@d" do
303
+ verify_filters([1,2,2,3,8,8,9,10,12,13,:eof], ['@a','~@d'])
304
+ end
305
+
306
+ it "should match @d || @e" do
307
+ verify_filters([1,2,2,3,4,4,5,6,8,8,9,10,:eof], ['@d,@e'])
308
+ end
309
+ end
310
+
311
+ context "Scenario Outlines with tags on examples" do
312
+ before do
313
+ # Lines with more than one tag per line will be repeated
314
+ @input = %{#language:en
315
+ @a @b
316
+ Feature: 3
317
+ @d
318
+ Scenario Outline: 5
319
+ Given 6
320
+
321
+ @c @e
322
+ Examples: 9
323
+ | foo | bar |
324
+ | 11 | 11 |
325
+
326
+ @d @f
327
+ Examples: 14
328
+ | foo | bar |
329
+ | 16 | 16 |
330
+ | 17 | 17 |
331
+
332
+ Scenario: 19
333
+ Given 20
334
+ }
335
+ end
336
+
337
+ it "should match @c" do
338
+ verify_filters([1,2,2,3,4,5,6,8,8,9,10,11,:eof], ['@c'])
339
+ end
340
+
341
+ it "should match @d" do
342
+ verify_filters([1,2,2,3,4,5,6,8,8,9,10,11,13,13,14,15,16,17,:eof], ['@d'])
343
+ end
344
+
345
+ it "should match @f" do
346
+ verify_filters([1,2,2,3,4,5,6,13,13,14,15,16,17,:eof], ['@f'])
347
+ end
348
+
349
+ it "should match @a and not @c" do
350
+ verify_filters([1,2,2,3,4,5,6,13,13,14,15,16,17,19,20,:eof], ['@a','~@c'])
351
+ end
352
+
353
+ it "should match @c or @d" do
354
+ verify_filters([1,2,2,3,4,5,6,8,8,9,10,11,13,13,14,15,16,17,:eof], ['@c,@d'])
355
+ end
356
+
357
+ it "should not match @m" do
358
+ verify_filters([:eof], ['@m'])
359
+ end
360
+ end
361
+ end
362
+ end
363
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'gherkin/parser/parser'
3
+
4
+ module Gherkin
5
+ module Parser
6
+ describe Parser do
7
+ before do
8
+ @listener = mock('listener')
9
+ @parser = Parser.new(@listener, true)
10
+ end
11
+
12
+ it "should delegate events to the listener" do
13
+ @listener.should_receive(:comment).with("# Content", 1)
14
+ @parser.comment("# Content", 1)
15
+ end
16
+
17
+ it "should raise helpful error messages by default" do
18
+ lambda {
19
+ @parser.scenario("Scenario", "My pet scenario", 12)
20
+ }.should raise_error(/Parse error on line 12\. Found scenario when expecting one of: comment, feature, tag\. \(Current state: root\)\.$/)
21
+ end
22
+
23
+ it "should allow empty files" do
24
+ @listener.should_receive(:eof)
25
+ @parser.eof
26
+ end
27
+
28
+ it "should delegate an error message when raise on error is false" do
29
+ @listener.should_receive(:syntax_error).with(sym(:root), sym(:background), a([:comment, :feature, :tag]), 1)
30
+ @parser = Parser.new(@listener, false)
31
+ @parser.background("Background", "Content", 1)
32
+ end
33
+ end
34
+ end
35
+ end