cucumber 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/History.txt +27 -0
  2. data/VERSION.yml +3 -2
  3. data/cucumber.gemspec +11 -5
  4. data/examples/watir/features/support/screenshots.rb +1 -2
  5. data/features/call_many_steps.feature +124 -0
  6. data/features/default_snippets.feature +2 -2
  7. data/features/expand.feature +13 -2
  8. data/features/language_help.feature +1 -1
  9. data/features/report_called_undefined_steps.feature +1 -1
  10. data/features/snippet.feature +2 -2
  11. data/features/support/env.rb +3 -5
  12. data/features/tag_logic.feature +32 -0
  13. data/features/wire_protocol.feature +7 -7
  14. data/lib/cucumber.rb +6 -0
  15. data/lib/cucumber/ast/background.rb +1 -1
  16. data/lib/cucumber/ast/comment.rb +1 -1
  17. data/lib/cucumber/ast/examples.rb +1 -1
  18. data/lib/cucumber/ast/feature.rb +1 -1
  19. data/lib/cucumber/ast/feature_element.rb +2 -3
  20. data/lib/cucumber/ast/features.rb +1 -1
  21. data/lib/cucumber/ast/outline_table.rb +17 -4
  22. data/lib/cucumber/ast/py_string.rb +3 -1
  23. data/lib/cucumber/ast/scenario.rb +3 -1
  24. data/lib/cucumber/ast/scenario_outline.rb +2 -2
  25. data/lib/cucumber/ast/step.rb +1 -1
  26. data/lib/cucumber/ast/step_collection.rb +1 -1
  27. data/lib/cucumber/ast/step_invocation.rb +2 -1
  28. data/lib/cucumber/ast/table.rb +3 -3
  29. data/lib/cucumber/ast/tags.rb +18 -11
  30. data/lib/cucumber/ast/tree_walker.rb +16 -0
  31. data/lib/cucumber/cli/main.rb +3 -2
  32. data/lib/cucumber/cli/options.rb +4 -6
  33. data/lib/cucumber/cli/profile_loader.rb +4 -0
  34. data/lib/cucumber/filter.rb +2 -2
  35. data/lib/cucumber/formatter/ansicolor.rb +8 -0
  36. data/lib/cucumber/formatter/pretty.rb +3 -4
  37. data/lib/cucumber/language_support/language_methods.rb +4 -3
  38. data/lib/cucumber/languages.yml +1 -1
  39. data/lib/cucumber/parser.rb +2 -0
  40. data/lib/cucumber/parser/common.rb +170 -0
  41. data/lib/cucumber/parser/common.tt +21 -0
  42. data/lib/cucumber/parser/feature.rb +7 -291
  43. data/lib/cucumber/parser/feature.tt +7 -43
  44. data/lib/cucumber/parser/i18n.tt +2 -0
  45. data/lib/cucumber/parser/natural_language.rb +9 -0
  46. data/lib/cucumber/parser/py_string.rb +276 -0
  47. data/lib/cucumber/parser/py_string.tt +45 -0
  48. data/lib/cucumber/parser/table.rb +5 -120
  49. data/lib/cucumber/parser/table.tt +2 -13
  50. data/lib/cucumber/platform.rb +3 -2
  51. data/lib/cucumber/rails/active_record.rb +2 -21
  52. data/lib/cucumber/rails/world.rb +2 -1
  53. data/lib/cucumber/rb_support/rb_hook.rb +2 -1
  54. data/lib/cucumber/rb_support/rb_language.rb +8 -6
  55. data/lib/cucumber/rb_support/rb_step_definition.rb +4 -0
  56. data/lib/cucumber/rb_support/rb_world.rb +16 -37
  57. data/lib/cucumber/step_mother.rb +86 -2
  58. data/lib/cucumber/wire_support/wire_language.rb +2 -2
  59. data/lib/cucumber/wire_support/wire_protocol.rb +1 -1
  60. data/rails_generators/cucumber/cucumber_generator.rb +3 -1
  61. data/rails_generators/cucumber/templates/cucumber.rake +4 -2
  62. data/rails_generators/cucumber/templates/webrat_steps.rb +28 -28
  63. data/spec/cucumber/ast/background_spec.rb +2 -1
  64. data/spec/cucumber/ast/scenario_spec.rb +3 -1
  65. data/spec/cucumber/formatter/console_spec.rb +1 -1
  66. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +14 -5
  67. data/spec/cucumber/step_mother_spec.rb +1 -1
  68. data/spec/cucumber/world/pending_spec.rb +1 -1
  69. metadata +8 -3
@@ -76,8 +76,8 @@ module Cucumber
76
76
  steps.at_line?(line)
77
77
  end
78
78
 
79
- def matches_tags?(tag_names)
80
- Ast::Tags.matches?(self.parent.tags.tag_names, tag_names)
79
+ def matches_tags?(tag_name_lists)
80
+ Ast::Tags.matches?(self.parent.tags.tag_names, tag_name_lists)
81
81
  end
82
82
 
83
83
  def build
@@ -116,10 +116,10 @@ module Cucumber
116
116
  tags.at_line?(line)
117
117
  end
118
118
 
119
- def matches_tags?(tag_names)
119
+ def matches_tags?(tag_name_lists)
120
120
  feature_tag_names = self.parent.parent.tags.tag_names
121
121
  source_tag_names = (feature_tag_names + tags.tag_names).uniq
122
- Ast::Tags.matches?(source_tag_names, tag_names)
122
+ Ast::Tags.matches?(source_tag_names, tag_name_lists)
123
123
  end
124
124
 
125
125
  def matches_name?(regexp_to_match)
@@ -153,10 +153,10 @@ module Cucumber
153
153
  steps.at_line?(line)
154
154
  end
155
155
 
156
- def matches_tags?(tag_names)
156
+ def matches_tags?(tag_name_lists)
157
157
  feature_tag_names = self.parent.parent.tags.tag_names
158
158
  source_tag_names = (feature_tag_names + tags.tag_names).uniq
159
- Ast::Tags.matches?(source_tag_names, tag_names)
159
+ Ast::Tags.matches?(source_tag_names, tag_name_lists)
160
160
  end
161
161
 
162
162
  def matches_name?(regexp_to_match)
@@ -238,7 +238,7 @@ module Cucumber
238
238
  table.at_line?(line)
239
239
  end
240
240
 
241
- def matches_tags?(tag_names)
241
+ def matches_tags?(tag_name_lists)
242
242
  true
243
243
  end
244
244
 
@@ -276,42 +276,6 @@ module Cucumber
276
276
  (step_keyword keyword_space) / scenario_keyword / scenario_outline_keyword / table / tag / comment_line
277
277
  end
278
278
 
279
- rule py_string
280
- open_py_string s:(!close_py_string .)* close_py_string {
281
- def at_line?(line)
282
- line >= open_py_string.line && line <= close_py_string.line
283
- end
284
-
285
- def build
286
- Ast::PyString.new(open_py_string.line, close_py_string.line, s.text_value, open_py_string.indentation)
287
- end
288
- }
289
- end
290
-
291
- rule open_py_string
292
- indent:space* '"""' space* eol {
293
- def indentation
294
- indent.text_value.length
295
- end
296
-
297
- def line
298
- indent.line
299
- end
300
- }
301
- end
302
-
303
- rule close_py_string
304
- eol space* quotes:'"""' white {
305
- def line
306
- quotes.line
307
- end
308
- }
309
- end
310
-
311
- rule white
312
- (space / eol)*
313
- end
314
-
315
279
  end
316
280
  end
317
281
  end
@@ -2,8 +2,10 @@ module Cucumber
2
2
  module Parser
3
3
  module I18n
4
4
  grammar <%= keywords('grammar_name', true) %>
5
+ include Common
5
6
  include Feature
6
7
  include Table
8
+ include PyString
7
9
 
8
10
  rule feature
9
11
  feature_sub
@@ -18,6 +18,7 @@ module Cucumber
18
18
  raise "Language not supported: #{lang.inspect}" if @keywords.nil?
19
19
  @keywords['grammar_name'] = @keywords['name'].gsub(/\s/, '')
20
20
  register_adverbs(step_mother) if step_mother
21
+ @parser = nil
21
22
  end
22
23
 
23
24
  def register_adverbs(step_mother)
@@ -67,6 +68,14 @@ module Cucumber
67
68
  def and_keywords
68
69
  @keywords['and'].split('|')
69
70
  end
71
+
72
+ def step_keywords
73
+ %w{given when then and but}.map{|key| @keywords[key].split('|')}.flatten.uniq
74
+ end
75
+
76
+ def space_after_keyword
77
+ @keywords['space_after_keyword']
78
+ end
70
79
  end
71
80
  end
72
81
  end
@@ -0,0 +1,276 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Cucumber
5
+ module Parser
6
+ # TIP: When you hack on the grammar, just delete py_string.rb in this directory.
7
+ # Also make sure you have uninstalled all cucumber gems (don't forget xxx-cucumber
8
+ # github gems).
9
+ #
10
+ # Treetop will then generate the parser in-memory. When you're happy, just generate
11
+ # the rb file with tt feature.tt
12
+ module PyString
13
+ include Treetop::Runtime
14
+
15
+ def root
16
+ @root || :py_string
17
+ end
18
+
19
+ include Common
20
+
21
+ module PyString0
22
+ end
23
+
24
+ module PyString1
25
+ def open_py_string
26
+ elements[0]
27
+ end
28
+
29
+ def s
30
+ elements[1]
31
+ end
32
+
33
+ def close_py_string
34
+ elements[2]
35
+ end
36
+ end
37
+
38
+ module PyString2
39
+ def at_line?(line)
40
+ line >= open_py_string.line && line <= close_py_string.line
41
+ end
42
+
43
+ def build(filter=nil)
44
+ Ast::PyString.new(open_py_string.line, close_py_string.line, s.text_value, open_py_string.indentation)
45
+ end
46
+ end
47
+
48
+ def _nt_py_string
49
+ start_index = index
50
+ if node_cache[:py_string].has_key?(index)
51
+ cached = node_cache[:py_string][index]
52
+ @index = cached.interval.end if cached
53
+ return cached
54
+ end
55
+
56
+ i0, s0 = index, []
57
+ r1 = _nt_open_py_string
58
+ s0 << r1
59
+ if r1
60
+ s2, i2 = [], index
61
+ loop do
62
+ i3, s3 = index, []
63
+ i4 = index
64
+ r5 = _nt_close_py_string
65
+ if r5
66
+ r4 = nil
67
+ else
68
+ @index = i4
69
+ r4 = instantiate_node(SyntaxNode,input, index...index)
70
+ end
71
+ s3 << r4
72
+ if r4
73
+ if index < input_length
74
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
75
+ @index += 1
76
+ else
77
+ terminal_parse_failure("any character")
78
+ r6 = nil
79
+ end
80
+ s3 << r6
81
+ end
82
+ if s3.last
83
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
84
+ r3.extend(PyString0)
85
+ else
86
+ @index = i3
87
+ r3 = nil
88
+ end
89
+ if r3
90
+ s2 << r3
91
+ else
92
+ break
93
+ end
94
+ end
95
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
96
+ s0 << r2
97
+ if r2
98
+ r7 = _nt_close_py_string
99
+ s0 << r7
100
+ end
101
+ end
102
+ if s0.last
103
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
104
+ r0.extend(PyString1)
105
+ r0.extend(PyString2)
106
+ else
107
+ @index = i0
108
+ r0 = nil
109
+ end
110
+
111
+ node_cache[:py_string][start_index] = r0
112
+
113
+ r0
114
+ end
115
+
116
+ module OpenPyString0
117
+ def indent
118
+ elements[0]
119
+ end
120
+
121
+ def eol
122
+ elements[3]
123
+ end
124
+ end
125
+
126
+ module OpenPyString1
127
+ def indentation
128
+ indent.text_value.length
129
+ end
130
+
131
+ def line
132
+ indent.line
133
+ end
134
+ end
135
+
136
+ def _nt_open_py_string
137
+ start_index = index
138
+ if node_cache[:open_py_string].has_key?(index)
139
+ cached = node_cache[:open_py_string][index]
140
+ @index = cached.interval.end if cached
141
+ return cached
142
+ end
143
+
144
+ i0, s0 = index, []
145
+ s1, i1 = [], index
146
+ loop do
147
+ r2 = _nt_space
148
+ if r2
149
+ s1 << r2
150
+ else
151
+ break
152
+ end
153
+ end
154
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
155
+ s0 << r1
156
+ if r1
157
+ if has_terminal?('"""', false, index)
158
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 3))
159
+ @index += 3
160
+ else
161
+ terminal_parse_failure('"""')
162
+ r3 = nil
163
+ end
164
+ s0 << r3
165
+ if r3
166
+ s4, i4 = [], index
167
+ loop do
168
+ r5 = _nt_space
169
+ if r5
170
+ s4 << r5
171
+ else
172
+ break
173
+ end
174
+ end
175
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
176
+ s0 << r4
177
+ if r4
178
+ r6 = _nt_eol
179
+ s0 << r6
180
+ end
181
+ end
182
+ end
183
+ if s0.last
184
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
185
+ r0.extend(OpenPyString0)
186
+ r0.extend(OpenPyString1)
187
+ else
188
+ @index = i0
189
+ r0 = nil
190
+ end
191
+
192
+ node_cache[:open_py_string][start_index] = r0
193
+
194
+ r0
195
+ end
196
+
197
+ module ClosePyString0
198
+ def eol
199
+ elements[0]
200
+ end
201
+
202
+ def quotes
203
+ elements[2]
204
+ end
205
+
206
+ def white
207
+ elements[3]
208
+ end
209
+ end
210
+
211
+ module ClosePyString1
212
+ def line
213
+ quotes.line
214
+ end
215
+ end
216
+
217
+ def _nt_close_py_string
218
+ start_index = index
219
+ if node_cache[:close_py_string].has_key?(index)
220
+ cached = node_cache[:close_py_string][index]
221
+ @index = cached.interval.end if cached
222
+ return cached
223
+ end
224
+
225
+ i0, s0 = index, []
226
+ r1 = _nt_eol
227
+ s0 << r1
228
+ if r1
229
+ s2, i2 = [], index
230
+ loop do
231
+ r3 = _nt_space
232
+ if r3
233
+ s2 << r3
234
+ else
235
+ break
236
+ end
237
+ end
238
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
239
+ s0 << r2
240
+ if r2
241
+ if has_terminal?('"""', false, index)
242
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 3))
243
+ @index += 3
244
+ else
245
+ terminal_parse_failure('"""')
246
+ r4 = nil
247
+ end
248
+ s0 << r4
249
+ if r4
250
+ r5 = _nt_white
251
+ s0 << r5
252
+ end
253
+ end
254
+ end
255
+ if s0.last
256
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
257
+ r0.extend(ClosePyString0)
258
+ r0.extend(ClosePyString1)
259
+ else
260
+ @index = i0
261
+ r0 = nil
262
+ end
263
+
264
+ node_cache[:close_py_string][start_index] = r0
265
+
266
+ r0
267
+ end
268
+
269
+ end
270
+
271
+ class PyStringParser < Treetop::Runtime::CompiledParser
272
+ include PyString
273
+ end
274
+
275
+ end
276
+ end
@@ -0,0 +1,45 @@
1
+ module Cucumber
2
+ module Parser
3
+ # TIP: When you hack on the grammar, just delete py_string.rb in this directory.
4
+ # Also make sure you have uninstalled all cucumber gems (don't forget xxx-cucumber
5
+ # github gems).
6
+ #
7
+ # Treetop will then generate the parser in-memory. When you're happy, just generate
8
+ # the rb file with tt feature.tt
9
+ grammar PyString
10
+ include Common
11
+
12
+ rule py_string
13
+ open_py_string s:(!close_py_string .)* close_py_string {
14
+ def at_line?(line)
15
+ line >= open_py_string.line && line <= close_py_string.line
16
+ end
17
+
18
+ def build(filter=nil)
19
+ Ast::PyString.new(open_py_string.line, close_py_string.line, s.text_value, open_py_string.indentation)
20
+ end
21
+ }
22
+ end
23
+
24
+ rule open_py_string
25
+ indent:space* '"""' space* eol {
26
+ def indentation
27
+ indent.text_value.length
28
+ end
29
+
30
+ def line
31
+ indent.line
32
+ end
33
+ }
34
+ end
35
+
36
+ rule close_py_string
37
+ eol space* quotes:'"""' white {
38
+ def line
39
+ quotes.line
40
+ end
41
+ }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Cucumber
5
5
  module Parser
6
- # TIP: When you hack on the grammar, just delete feature.rb in this directory.
6
+ # TIP: When you hack on the grammar, just delete table.rb in this directory.
7
7
  # Also make sure you have uninstalled all cucumber gems (don't forget xxx-cucumber
8
8
  # github gems).
9
9
  #
@@ -16,6 +16,8 @@ module Cucumber
16
16
  @root || :table
17
17
  end
18
18
 
19
+ include Common
20
+
19
21
  module Table0
20
22
  def at_line?(line)
21
23
  elements.detect{|table_row| table_row.at_line?(line)}
@@ -265,9 +267,8 @@ module Cucumber
265
267
  s1 << r2
266
268
  if r2
267
269
  if index < input_length
268
- next_character = index + input[index..-1].match(/\A(.)/um).end(1)
269
- r6 = instantiate_node(SyntaxNode,input, index...next_character)
270
- @index = next_character
270
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
271
+ @index += 1
271
272
  else
272
273
  terminal_parse_failure("any character")
273
274
  r6 = nil
@@ -294,122 +295,6 @@ module Cucumber
294
295
  r0
295
296
  end
296
297
 
297
- def _nt_space
298
- start_index = index
299
- if node_cache[:space].has_key?(index)
300
- cached = node_cache[:space][index]
301
- @index = cached.interval.end if cached
302
- return cached
303
- end
304
-
305
- if has_terminal?('\G[ \\t]', true, index)
306
- next_character = index + input[index..-1].match(/\A(.)/um).end(1)
307
- r0 = instantiate_node(SyntaxNode, input, index...next_character)
308
- @index = next_character
309
- else
310
- r0 = nil
311
- end
312
-
313
- node_cache[:space][start_index] = r0
314
-
315
- r0
316
- end
317
-
318
- module Eol0
319
- end
320
-
321
- def _nt_eol
322
- start_index = index
323
- if node_cache[:eol].has_key?(index)
324
- cached = node_cache[:eol][index]
325
- @index = cached.interval.end if cached
326
- return cached
327
- end
328
-
329
- i0 = index
330
- if has_terminal?("\n", false, index)
331
- r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
332
- @index += 1
333
- else
334
- terminal_parse_failure("\n")
335
- r1 = nil
336
- end
337
- if r1
338
- r0 = r1
339
- else
340
- i2, s2 = index, []
341
- if has_terminal?("\r", false, index)
342
- r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
343
- @index += 1
344
- else
345
- terminal_parse_failure("\r")
346
- r3 = nil
347
- end
348
- s2 << r3
349
- if r3
350
- if has_terminal?("\n", false, index)
351
- r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
352
- @index += 1
353
- else
354
- terminal_parse_failure("\n")
355
- r5 = nil
356
- end
357
- if r5
358
- r4 = r5
359
- else
360
- r4 = instantiate_node(SyntaxNode,input, index...index)
361
- end
362
- s2 << r4
363
- end
364
- if s2.last
365
- r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
366
- r2.extend(Eol0)
367
- else
368
- @index = i2
369
- r2 = nil
370
- end
371
- if r2
372
- r0 = r2
373
- else
374
- @index = i0
375
- r0 = nil
376
- end
377
- end
378
-
379
- node_cache[:eol][start_index] = r0
380
-
381
- r0
382
- end
383
-
384
- def _nt_eof
385
- start_index = index
386
- if node_cache[:eof].has_key?(index)
387
- cached = node_cache[:eof][index]
388
- @index = cached.interval.end if cached
389
- return cached
390
- end
391
-
392
- i0 = index
393
- if index < input_length
394
- next_character = index + input[index..-1].match(/\A(.)/um).end(1)
395
- r1 = instantiate_node(SyntaxNode,input, index...next_character)
396
- @index = next_character
397
- else
398
- terminal_parse_failure("any character")
399
- r1 = nil
400
- end
401
- if r1
402
- r0 = nil
403
- else
404
- @index = i0
405
- r0 = instantiate_node(SyntaxNode,input, index...index)
406
- end
407
-
408
- node_cache[:eof][start_index] = r0
409
-
410
- r0
411
- end
412
-
413
298
  end
414
299
 
415
300
  class TableParser < Treetop::Runtime::CompiledParser