cucumber 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/History.txt +56 -1
  2. data/Manifest.txt +70 -49
  3. data/config/hoe.rb +1 -1
  4. data/cucumber.yml +1 -1
  5. data/examples/i18n/bg/Rakefile +6 -0
  6. data/examples/i18n/bg/features/addition.feature +11 -0
  7. data/examples/i18n/bg/features/consecutive_calculations.feature +18 -0
  8. data/examples/i18n/bg/features/division.feature +16 -0
  9. data/examples/i18n/bg/features/step_definitons/calculator_steps.rb +24 -0
  10. data/examples/i18n/bg/features/support/env.rb +6 -0
  11. data/examples/i18n/bg/features/support/world.rb +8 -0
  12. data/examples/i18n/bg/lib/calculator.rb +24 -0
  13. data/examples/i18n/ru/features/support/world.rb +4 -3
  14. data/examples/i18n/sk/Rakefile +6 -0
  15. data/examples/i18n/sk/features/addition.feature +16 -0
  16. data/examples/i18n/sk/features/division.feature +9 -0
  17. data/examples/i18n/sk/features/step_definitons/calculator_steps.rb +24 -0
  18. data/examples/i18n/sk/lib/calculator.rb +14 -0
  19. data/examples/self_test/features/background/background_with_name.feature +7 -0
  20. data/examples/self_test/features/background/passing_background.feature +2 -2
  21. data/examples/self_test/features/step_definitions/sample_steps.rb +18 -2
  22. data/examples/self_test/features/undefined_multiline_args.feature +12 -0
  23. data/examples/sinatra/features/support/env.rb +2 -6
  24. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +1 -4
  25. data/examples/tickets/Rakefile +1 -1
  26. data/examples/tickets/features/229/tagged_hooks.feature +8 -0
  27. data/examples/tickets/features/229/tagged_hooks.rb +14 -0
  28. data/examples/tickets/features/270/back.feature +14 -0
  29. data/examples/tickets/features/270/back.steps.rb +14 -0
  30. data/examples/tickets/features/279/py_string_indent.feature +25 -0
  31. data/examples/tickets/features/279/py_string_indent.steps.rb +12 -0
  32. data/examples/tickets/features/279/wrong.feature_ +11 -0
  33. data/examples/tickets/features/step_definitons/tickets_steps.rb +0 -7
  34. data/features/background.feature +21 -3
  35. data/features/cucumber_cli.feature +18 -5
  36. data/features/cucumber_cli_outlines.feature +4 -1
  37. data/features/rake_task.feature +132 -0
  38. data/features/snippet.feature +23 -0
  39. data/features/step_definitions/cucumber_steps.rb +46 -15
  40. data/features/support/env.rb +61 -4
  41. data/features/usage.feature +5 -0
  42. data/gem_tasks/deployment.rake +1 -1
  43. data/lib/cucumber/ast/background.rb +14 -4
  44. data/lib/cucumber/ast/examples.rb +0 -12
  45. data/lib/cucumber/ast/feature.rb +2 -12
  46. data/lib/cucumber/ast/feature_element.rb +4 -8
  47. data/lib/cucumber/ast/features.rb +1 -1
  48. data/lib/cucumber/ast/outline_table.rb +20 -20
  49. data/lib/cucumber/ast/py_string.rb +6 -11
  50. data/lib/cucumber/ast/scenario.rb +1 -8
  51. data/lib/cucumber/ast/scenario_outline.rb +1 -11
  52. data/lib/cucumber/ast/step.rb +3 -9
  53. data/lib/cucumber/ast/step_collection.rb +0 -4
  54. data/lib/cucumber/ast/step_invocation.rb +5 -6
  55. data/lib/cucumber/ast/table.rb +5 -22
  56. data/lib/cucumber/ast/tags.rb +9 -9
  57. data/lib/cucumber/ast/visitor.rb +12 -25
  58. data/lib/cucumber/cli/configuration.rb +4 -4
  59. data/lib/cucumber/cli/main.rb +10 -3
  60. data/lib/cucumber/core_ext/instance_exec.rb +17 -4
  61. data/lib/cucumber/formatter/ansicolor.rb +1 -1
  62. data/lib/cucumber/formatter/console.rb +2 -1
  63. data/lib/cucumber/formatter/html.rb +21 -7
  64. data/lib/cucumber/formatter/pretty.rb +27 -20
  65. data/lib/cucumber/formatter/usage.rb +16 -0
  66. data/lib/cucumber/languages.yml +23 -5
  67. data/lib/cucumber/parser/feature.rb +231 -114
  68. data/lib/cucumber/parser/feature.tt +120 -25
  69. data/lib/cucumber/parser/table.rb +37 -25
  70. data/lib/cucumber/parser/table.tt +15 -3
  71. data/lib/cucumber/parser/treetop_ext.rb +48 -9
  72. data/lib/cucumber/rake/task.rb +29 -6
  73. data/lib/cucumber/step_definition.rb +4 -2
  74. data/lib/cucumber/step_mother.rb +143 -26
  75. data/lib/cucumber/version.rb +2 -2
  76. data/rails_generators/cucumber/templates/paths.rb +13 -4
  77. data/rails_generators/cucumber/templates/webrat_steps.rb +16 -0
  78. data/{specs → spec}/cucumber/ast/background_spec.rb +1 -0
  79. data/{specs → spec}/cucumber/ast/feature_factory.rb +1 -1
  80. data/{specs → spec}/cucumber/ast/feature_spec.rb +2 -2
  81. data/{specs → spec}/cucumber/ast/py_string_spec.rb +0 -0
  82. data/{specs → spec}/cucumber/ast/scenario_outline_spec.rb +0 -0
  83. data/{specs → spec}/cucumber/ast/scenario_spec.rb +0 -27
  84. data/{specs → spec}/cucumber/ast/step_collection_spec.rb +0 -0
  85. data/{specs → spec}/cucumber/ast/step_spec.rb +0 -0
  86. data/{specs → spec}/cucumber/ast/table_spec.rb +2 -2
  87. data/{specs → spec}/cucumber/broadcaster_spec.rb +0 -0
  88. data/{specs → spec}/cucumber/cli/configuration_spec.rb +0 -0
  89. data/{specs → spec}/cucumber/cli/main_spec.rb +5 -1
  90. data/spec/cucumber/core_ext/proc_spec.rb +54 -0
  91. data/{specs → spec}/cucumber/core_ext/string_spec.rb +0 -0
  92. data/{specs → spec}/cucumber/formatter/ansicolor_spec.rb +0 -0
  93. data/{specs → spec}/cucumber/formatter/color_io_spec.rb +0 -0
  94. data/{specs → spec}/cucumber/formatter/html/cucumber.css +0 -0
  95. data/{specs → spec}/cucumber/formatter/html/cucumber.js +0 -0
  96. data/{specs → spec}/cucumber/formatter/html/index.html +0 -0
  97. data/{specs → spec}/cucumber/formatter/html/jquery-1.3.min.js +0 -0
  98. data/{specs → spec}/cucumber/formatter/html/jquery.uitableedit.js +0 -0
  99. data/{specs → spec}/cucumber/formatters/profile_formatter_spec.rb +0 -0
  100. data/{specs → spec}/cucumber/parser/feature_parser_spec.rb +43 -41
  101. data/{specs → spec}/cucumber/parser/table_parser_spec.rb +0 -0
  102. data/{specs → spec}/cucumber/rails/stubs/mini_rails.rb +0 -0
  103. data/{specs → spec}/cucumber/rails/stubs/test_help.rb +0 -0
  104. data/{specs → spec}/cucumber/rails/world_spec.rb +0 -0
  105. data/{specs → spec}/cucumber/sell_cucumbers.feature +0 -0
  106. data/{specs → spec}/cucumber/step_definition_spec.rb +0 -0
  107. data/{specs → spec}/cucumber/step_mother_spec.rb +63 -4
  108. data/{specs → spec}/cucumber/treetop_parser/empty_feature.feature +0 -0
  109. data/{specs → spec}/cucumber/treetop_parser/empty_scenario.feature +0 -0
  110. data/{specs → spec}/cucumber/treetop_parser/empty_scenario_outline.feature +0 -0
  111. data/{specs → spec}/cucumber/treetop_parser/fit_scenario.feature +0 -0
  112. data/{specs → spec}/cucumber/treetop_parser/given_scenario.feature +0 -0
  113. data/{specs → spec}/cucumber/treetop_parser/invalid_scenario_outlines.feature +0 -0
  114. data/{specs → spec}/cucumber/treetop_parser/multiline_steps.feature +0 -0
  115. data/{specs → spec}/cucumber/treetop_parser/multiple_tables.feature +0 -0
  116. data/{specs → spec}/cucumber/treetop_parser/scenario_outline.feature +0 -0
  117. data/{specs → spec}/cucumber/treetop_parser/spaces.feature +0 -0
  118. data/{specs → spec}/cucumber/treetop_parser/test_dos.feature +0 -0
  119. data/{specs → spec}/cucumber/treetop_parser/with_comments.feature +0 -0
  120. data/{specs → spec}/cucumber/treetop_parser/with_tags.feature +0 -0
  121. data/{specs → spec}/cucumber/world/pending_spec.rb +0 -0
  122. data/{specs → spec}/spec.opts +0 -0
  123. data/{specs → spec}/spec_helper.rb +2 -11
  124. metadata +72 -51
  125. data/examples/tickets/cucumber.yml +0 -3
  126. data/lib/cucumber/parser/basic.rb +0 -0
  127. data/specs/cucumber/ast/tags_spec.rb +0 -19
  128. data/specs/cucumber/core_ext/proc_spec.rb +0 -37
@@ -19,6 +19,7 @@ module Cucumber
19
19
  @options = options
20
20
  @delim = delim
21
21
  @indent = 0
22
+ @exceptions = []
22
23
  end
23
24
 
24
25
  def visit_features(features)
@@ -119,26 +120,33 @@ module Cucumber
119
120
  super
120
121
  end
121
122
 
122
- def visit_step_name(keyword, step_match, status, source_indent, background)
123
- @step_matches ||= []
124
- non_failed_background_step_outside_background = !@in_background && background && (status != :failed)
125
- @skip_step = @step_matches.index(step_match) || non_failed_background_step_outside_background
126
- @step_matches << step_match
127
-
128
- unless(@skip_step)
129
- source_indent = nil unless @options[:source]
130
- formatted_step_name = format_step(keyword, step_match, status, source_indent)
131
- @io.puts(" " + formatted_step_name)
123
+ def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
124
+ if exception
125
+ return if @exceptions.index(exception)
126
+ @exceptions << exception
132
127
  end
128
+ return if status != :failed && @in_background ^ background
129
+
130
+ # @step_matches ||= []
131
+ # return if @step_matches.index(step_match)
132
+ # @step_matches << step_match
133
+
134
+ @status = status
135
+ super
136
+ end
137
+
138
+ def visit_step_name(keyword, step_match, status, source_indent, background)
139
+ source_indent = nil unless @options[:source]
140
+ formatted_step_name = format_step(keyword, step_match, status, source_indent)
141
+ @io.puts(" " + formatted_step_name)
133
142
  end
134
143
 
135
144
  def visit_multiline_arg(multiline_arg)
136
- return if @options[:no_multiline] || @skip_step
145
+ return if @options[:no_multiline]
137
146
  super
138
147
  end
139
148
 
140
149
  def visit_exception(exception, status)
141
- return if @skip_step
142
150
  print_exception(exception, status, @indent)
143
151
  @io.flush
144
152
  end
@@ -147,21 +155,20 @@ module Cucumber
147
155
  @io.print @delim.indent(@indent)
148
156
  super
149
157
  @io.puts
150
- print_exception(table_row.exception, :failed, @indent) if table_row.exception
158
+ if table_row.exception && !@exceptions.index(table_row.exception)
159
+ print_exception(table_row.exception, :failed, @indent)
160
+ end
151
161
  end
152
162
 
153
- def visit_py_string(string, status)
154
- s = "\"\"\"\n#{string}\n\"\"\"".indent(@indent)
163
+ def visit_py_string(string)
164
+ s = %{"""\n#{string}\n"""}.indent(@indent)
155
165
  s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}.join("\n")
156
- @io.puts(format_string(s, status))
166
+ @io.puts(format_string(s, @status))
157
167
  @io.flush
158
168
  end
159
169
 
160
- def visit_table_cell(table_cell)
161
- super
162
- end
163
-
164
170
  def visit_table_cell_value(value, width, status)
171
+ status ||= @status || :passed
165
172
  @io.print(' ' + format_string((value.to_s || '').ljust(width), status) + " #{@delim}")
166
173
  @io.flush
167
174
  end
@@ -10,6 +10,7 @@ module Cucumber
10
10
  @io = io
11
11
  @options = options
12
12
  @step_definitions = Hash.new { |h,step_definition| h[step_definition] = [] }
13
+ @all_step_definitions = step_mother.step_definitions.dup
13
14
  @locations = []
14
15
  end
15
16
 
@@ -32,6 +33,7 @@ module Cucumber
32
33
  description = format_step(keyword, step_match, status, nil)
33
34
  length = (keyword + step_match.format_args).jlength
34
35
  @step_definitions[step_match.step_definition] << [step_match, description, length, location]
36
+ @all_step_definitions.delete(step_match.step_definition)
35
37
  end
36
38
  end
37
39
 
@@ -63,6 +65,20 @@ module Cucumber
63
65
  @io.puts format_string(" # #{file_colon_line}".indent(max_length - length), :comment)
64
66
  end
65
67
  end
68
+
69
+ print_unused_step_definitions
70
+ end
71
+
72
+ def print_unused_step_definitions
73
+ if @all_step_definitions.any?
74
+ max_length = @all_step_definitions.map{|step_definition| step_definition.text_length}.max
75
+
76
+ @io.puts format_string("(::) UNUSED (::)", :failed)
77
+ @all_step_definitions.each do |step_definition|
78
+ @io.print format_string(step_definition.regexp.inspect, :failed)
79
+ @io.puts format_string(" # #{step_definition.file_colon_line}".indent(max_length - step_definition.text_length), :comment)
80
+ end
81
+ end
66
82
  end
67
83
  end
68
84
  end
@@ -299,8 +299,11 @@
299
299
  native: polski
300
300
  encoding: UTF-8
301
301
  feature: Właściwość
302
+ background: Założenia
302
303
  scenario: Scenariusz
303
- given: Dane
304
+ scenario_outline: Szablon scenariusza
305
+ examples: Przykłady
306
+ given: Zakładając
304
307
  when: Jeżeli
305
308
  then: Wtedy
306
309
  and: Oraz
@@ -311,13 +314,13 @@
311
314
  native: português
312
315
  encoding: UTF-8
313
316
  background: Contexto
314
- feature: Característica
315
- scenario: Cenário
316
- scenario_outline: Esquema do Cenário
317
+ feature: Funcionalidade
318
+ scenario: Cenário|Cenario
319
+ scenario_outline: Esquema do Cenário|Esquema do Cenario
317
320
  examples: Exemplos
318
321
  given: Dado
319
322
  when: Quando
320
- then: Então
323
+ then: Então|Entao
321
324
  and: E
322
325
  but: Mas
323
326
  space_after_keyword: true
@@ -435,3 +438,18 @@
435
438
  and: 그리고
436
439
  but: 하지만
437
440
  space_after_keyword: false
441
+ "bg":
442
+ name: Bulgarian
443
+ native: български
444
+ encoding: UTF-8
445
+ feature: Функционалност
446
+ background: Предистория
447
+ scenario: Сценарий
448
+ scenario_outline: Рамка на сценарий
449
+ examples: Примери
450
+ given: Дадено
451
+ when: Когато
452
+ then: То
453
+ and: И
454
+ but: Но
455
+ space_after_keyword: true
@@ -56,15 +56,21 @@ module Cucumber
56
56
  end
57
57
 
58
58
  module Feature2
59
- def build
60
- background = bg.respond_to?(:build) ? bg.build : nil
61
- Ast::Feature.new(
62
- background,
63
- comment.build,
64
- tags.build,
65
- header.text_value,
66
- feature_elements.build(background)
67
- )
59
+ def has_tags?(tag_names)
60
+ tags.has_tags?(tag_names)
61
+ end
62
+
63
+ def build(filter)
64
+ if(filter.nil? || feature_elements.accept?(filter))
65
+ background = bg.respond_to?(:build) ? bg.build : nil
66
+ Ast::Feature.new(
67
+ background,
68
+ comment.build,
69
+ tags.build,
70
+ header.text_value,
71
+ feature_elements.build(background, filter)
72
+ )
73
+ end
68
74
  end
69
75
  end
70
76
 
@@ -118,12 +124,12 @@ module Cucumber
118
124
  r8 = nil
119
125
  else
120
126
  self.index = i8
121
- r8 = SyntaxNode.new(input, index...index)
127
+ r8 = instantiate_node(SyntaxNode,input, index...index)
122
128
  end
123
129
  s7 << r8
124
130
  if r8
125
131
  if index < input_length
126
- r13 = (SyntaxNode).new(input, index...(index + 1))
132
+ r13 = instantiate_node(SyntaxNode,input, index...(index + 1))
127
133
  @index += 1
128
134
  else
129
135
  terminal_parse_failure("any character")
@@ -132,7 +138,7 @@ module Cucumber
132
138
  s7 << r13
133
139
  end
134
140
  if s7.last
135
- r7 = (SyntaxNode).new(input, i7...index, s7)
141
+ r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
136
142
  r7.extend(Feature0)
137
143
  else
138
144
  self.index = i7
@@ -144,14 +150,14 @@ module Cucumber
144
150
  break
145
151
  end
146
152
  end
147
- r6 = SyntaxNode.new(input, i6...index, s6)
153
+ r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
148
154
  s0 << r6
149
155
  if r6
150
156
  r15 = _nt_background
151
157
  if r15
152
158
  r14 = r15
153
159
  else
154
- r14 = SyntaxNode.new(input, index...index)
160
+ r14 = instantiate_node(SyntaxNode,input, index...index)
155
161
  end
156
162
  s0 << r14
157
163
  if r14
@@ -162,7 +168,7 @@ module Cucumber
162
168
  if r18
163
169
  r17 = r18
164
170
  else
165
- r17 = SyntaxNode.new(input, index...index)
171
+ r17 = instantiate_node(SyntaxNode,input, index...index)
166
172
  end
167
173
  s0 << r17
168
174
  end
@@ -174,7 +180,7 @@ module Cucumber
174
180
  end
175
181
  end
176
182
  if s0.last
177
- r0 = (SyntaxNode).new(input, i0...index, s0)
183
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
178
184
  r0.extend(Feature1)
179
185
  r0.extend(Feature2)
180
186
  else
@@ -205,10 +211,21 @@ module Cucumber
205
211
  end
206
212
 
207
213
  module Tags2
214
+ def at_line?(line)
215
+ ts.elements.detect{|e| e.tag.line == line}
216
+ end
217
+
218
+ def has_tags?(tags)
219
+ (tag_names & tags).any?
220
+ end
221
+
208
222
  def build
209
- tag_names = ts.elements.map{|e| e.tag.tag_name.text_value}
210
223
  Ast::Tags.new(ts.line, tag_names)
211
224
  end
225
+
226
+ def tag_names
227
+ @tag_names ||= ts.elements.map{|e| e.tag.tag_name.text_value}
228
+ end
212
229
  end
213
230
 
214
231
  def _nt_tags
@@ -254,12 +271,12 @@ module Cucumber
254
271
  self.index = i5
255
272
  r5 = nil
256
273
  else
257
- r5 = SyntaxNode.new(input, i5...index, s5)
274
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
258
275
  end
259
276
  s3 << r5
260
277
  end
261
278
  if s3.last
262
- r3 = (SyntaxNode).new(input, i3...index, s3)
279
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
263
280
  r3.extend(Tags0)
264
281
  else
265
282
  self.index = i3
@@ -271,11 +288,11 @@ module Cucumber
271
288
  break
272
289
  end
273
290
  end
274
- r2 = SyntaxNode.new(input, i2...index, s2)
291
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
275
292
  s0 << r2
276
293
  end
277
294
  if s0.last
278
- r0 = (SyntaxNode).new(input, i0...index, s0)
295
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
279
296
  r0.extend(Tags1)
280
297
  r0.extend(Tags2)
281
298
  else
@@ -304,7 +321,7 @@ module Cucumber
304
321
 
305
322
  i0, s0 = index, []
306
323
  if input.index('@', index) == index
307
- r1 = (SyntaxNode).new(input, index...(index + 1))
324
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
308
325
  @index += 1
309
326
  else
310
327
  terminal_parse_failure('@')
@@ -315,7 +332,7 @@ module Cucumber
315
332
  s2, i2 = [], index
316
333
  loop do
317
334
  if input.index(Regexp.new('[^@\\r\\n\\t ]'), index) == index
318
- r3 = (SyntaxNode).new(input, index...(index + 1))
335
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
319
336
  @index += 1
320
337
  else
321
338
  r3 = nil
@@ -330,12 +347,12 @@ module Cucumber
330
347
  self.index = i2
331
348
  r2 = nil
332
349
  else
333
- r2 = SyntaxNode.new(input, i2...index, s2)
350
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
334
351
  end
335
352
  s0 << r2
336
353
  end
337
354
  if s0.last
338
- r0 = (SyntaxNode).new(input, i0...index, s0)
355
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
339
356
  r0.extend(Tag0)
340
357
  else
341
358
  self.index = i0
@@ -381,7 +398,7 @@ module Cucumber
381
398
  s1 << r3
382
399
  end
383
400
  if s1.last
384
- r1 = (SyntaxNode).new(input, i1...index, s1)
401
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
385
402
  r1.extend(Comment0)
386
403
  else
387
404
  self.index = i1
@@ -393,7 +410,7 @@ module Cucumber
393
410
  break
394
411
  end
395
412
  end
396
- r0 = SyntaxNode.new(input, i0...index, s0)
413
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
397
414
  r0.extend(Comment1)
398
415
 
399
416
  node_cache[:comment][start_index] = r0
@@ -417,7 +434,7 @@ module Cucumber
417
434
 
418
435
  i0, s0 = index, []
419
436
  if input.index('#', index) == index
420
- r1 = (SyntaxNode).new(input, index...(index + 1))
437
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
421
438
  @index += 1
422
439
  else
423
440
  terminal_parse_failure('#')
@@ -429,7 +446,7 @@ module Cucumber
429
446
  s0 << r2
430
447
  end
431
448
  if s0.last
432
- r0 = (SyntaxNode).new(input, i0...index, s0)
449
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
433
450
  r0.extend(CommentLine0)
434
451
  else
435
452
  self.index = i0
@@ -454,8 +471,12 @@ module Cucumber
454
471
  elements[2]
455
472
  end
456
473
 
474
+ def name
475
+ elements[4]
476
+ end
477
+
457
478
  def steps
458
- elements[5]
479
+ elements[6]
459
480
  end
460
481
  end
461
482
 
@@ -464,7 +485,8 @@ module Cucumber
464
485
  Ast::Background.new(
465
486
  comment.build,
466
487
  background_keyword.line,
467
- background_keyword.text_value,
488
+ background_keyword.text_value,
489
+ name.text_value,
468
490
  steps.build
469
491
  )
470
492
  end
@@ -497,47 +519,56 @@ module Cucumber
497
519
  break
498
520
  end
499
521
  end
500
- r4 = SyntaxNode.new(input, i4...index, s4)
522
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
501
523
  s0 << r4
502
524
  if r4
503
- i6 = index
504
- s7, i7 = [], index
505
- loop do
506
- r8 = _nt_eol
507
- if r8
508
- s7 << r8
509
- else
510
- break
511
- end
512
- end
513
- if s7.empty?
514
- self.index = i7
515
- r7 = nil
516
- else
517
- r7 = SyntaxNode.new(input, i7...index, s7)
518
- end
525
+ r7 = _nt_line_to_eol
519
526
  if r7
520
527
  r6 = r7
521
528
  else
522
- r9 = _nt_eof
523
- if r9
524
- r6 = r9
525
- else
526
- self.index = i6
527
- r6 = nil
528
- end
529
+ r6 = instantiate_node(SyntaxNode,input, index...index)
529
530
  end
530
531
  s0 << r6
531
532
  if r6
532
- r10 = _nt_steps
533
- s0 << r10
533
+ i8 = index
534
+ s9, i9 = [], index
535
+ loop do
536
+ r10 = _nt_eol
537
+ if r10
538
+ s9 << r10
539
+ else
540
+ break
541
+ end
542
+ end
543
+ if s9.empty?
544
+ self.index = i9
545
+ r9 = nil
546
+ else
547
+ r9 = instantiate_node(SyntaxNode,input, i9...index, s9)
548
+ end
549
+ if r9
550
+ r8 = r9
551
+ else
552
+ r11 = _nt_eof
553
+ if r11
554
+ r8 = r11
555
+ else
556
+ self.index = i8
557
+ r8 = nil
558
+ end
559
+ end
560
+ s0 << r8
561
+ if r8
562
+ r12 = _nt_steps
563
+ s0 << r12
564
+ end
534
565
  end
535
566
  end
536
567
  end
537
568
  end
538
569
  end
539
570
  if s0.last
540
- r0 = (SyntaxNode).new(input, i0...index, s0)
571
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
541
572
  r0.extend(Background0)
542
573
  r0.extend(Background1)
543
574
  else
@@ -551,8 +582,16 @@ module Cucumber
551
582
  end
552
583
 
553
584
  module FeatureElements0
554
- def build(background)
555
- elements.map{|s| s.build(background)}
585
+ def accept?(filter)
586
+ filter.nil? || elements.empty? || elements.detect{|feature_element| filter.accept?(feature_element)}
587
+ end
588
+
589
+ def build(background, filter)
590
+ elements.map do |feature_element|
591
+ if filter.nil? || filter.accept?(feature_element)
592
+ feature_element.build(background, filter)
593
+ end
594
+ end.compact
556
595
  end
557
596
  end
558
597
 
@@ -585,7 +624,7 @@ module Cucumber
585
624
  break
586
625
  end
587
626
  end
588
- r0 = SyntaxNode.new(input, i0...index, s0)
627
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
589
628
  r0.extend(FeatureElements0)
590
629
 
591
630
  node_cache[:feature_elements][start_index] = r0
@@ -628,7 +667,22 @@ module Cucumber
628
667
  end
629
668
 
630
669
  module Scenario1
631
- def build(background)
670
+ def at_line?(line)
671
+ scenario_keyword.line == line ||
672
+ steps.at_line?(line) ||
673
+ tags.at_line?(line)
674
+ end
675
+
676
+ def has_tags?(tag_names)
677
+ feature_tags = self.parent.parent.tags
678
+ tags.has_tags?(tag_names) || feature_tags.has_tags?(tag_names)
679
+ end
680
+
681
+ def matches_name?(name_to_match)
682
+ name.text_value == name_to_match
683
+ end
684
+
685
+ def build(background, filter)
632
686
  Ast::Scenario.new(
633
687
  background,
634
688
  comment.build,
@@ -671,7 +725,7 @@ module Cucumber
671
725
  break
672
726
  end
673
727
  end
674
- r5 = SyntaxNode.new(input, i5...index, s5)
728
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
675
729
  s0 << r5
676
730
  if r5
677
731
  r7 = _nt_line_to_eol
@@ -694,7 +748,7 @@ module Cucumber
694
748
  end
695
749
  end
696
750
  if s0.last
697
- r0 = (SyntaxNode).new(input, i0...index, s0)
751
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
698
752
  r0.extend(Scenario0)
699
753
  r0.extend(Scenario1)
700
754
  else
@@ -746,7 +800,27 @@ module Cucumber
746
800
  end
747
801
 
748
802
  module ScenarioOutline1
749
- def build(background)
803
+ def at_line?(line)
804
+ outline_at_line?(line) ||
805
+ examples_sections.at_line?(line) ||
806
+ tags.at_line?(line)
807
+ end
808
+
809
+ def outline_at_line?(line)
810
+ scenario_outline_keyword.line == line ||
811
+ steps.at_line?(line)
812
+ end
813
+
814
+ def has_tags?(tag_names)
815
+ feature_tags = self.parent.parent.tags
816
+ tags.has_tags?(tag_names) || feature_tags.has_tags?(tag_names)
817
+ end
818
+
819
+ def matches_name?(name_to_match)
820
+ name.text_value == name_to_match
821
+ end
822
+
823
+ def build(background, filter)
750
824
  Ast::ScenarioOutline.new(
751
825
  background,
752
826
  comment.build,
@@ -755,7 +829,7 @@ module Cucumber
755
829
  scenario_outline_keyword.text_value,
756
830
  name.text_value,
757
831
  steps.build,
758
- examples_sections.build
832
+ examples_sections.build(filter, self)
759
833
  )
760
834
  end
761
835
  end
@@ -790,7 +864,7 @@ module Cucumber
790
864
  break
791
865
  end
792
866
  end
793
- r5 = SyntaxNode.new(input, i5...index, s5)
867
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
794
868
  s0 << r5
795
869
  if r5
796
870
  r7 = _nt_line_to_eol
@@ -817,7 +891,7 @@ module Cucumber
817
891
  end
818
892
  end
819
893
  if s0.last
820
- r0 = (SyntaxNode).new(input, i0...index, s0)
894
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
821
895
  r0.extend(ScenarioOutline0)
822
896
  r0.extend(ScenarioOutline1)
823
897
  else
@@ -831,6 +905,10 @@ module Cucumber
831
905
  end
832
906
 
833
907
  module Steps0
908
+ def at_line?(line)
909
+ elements.detect{|e| e.at_line?(line)}
910
+ end
911
+
834
912
  def build
835
913
  elements.map{|e| e.build}
836
914
  end
@@ -853,7 +931,7 @@ module Cucumber
853
931
  break
854
932
  end
855
933
  end
856
- r0 = SyntaxNode.new(input, i0...index, s0)
934
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
857
935
  r0.extend(Steps0)
858
936
 
859
937
  node_cache[:steps][start_index] = r0
@@ -888,6 +966,11 @@ module Cucumber
888
966
  end
889
967
 
890
968
  module Step1
969
+ def at_line?(line)
970
+ step_keyword.line == line ||
971
+ (multi.respond_to?(:at_line?) && multi.at_line?(line))
972
+ end
973
+
891
974
  def build
892
975
  if multi.respond_to?(:build)
893
976
  Ast::Step.new(step_keyword.line, step_keyword.text_value, name.text_value.strip, multi.build)
@@ -918,7 +1001,7 @@ module Cucumber
918
1001
  break
919
1002
  end
920
1003
  end
921
- r2 = SyntaxNode.new(input, i2...index, s2)
1004
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
922
1005
  s0 << r2
923
1006
  if r2
924
1007
  r4 = _nt_step_keyword
@@ -944,7 +1027,7 @@ module Cucumber
944
1027
  self.index = i8
945
1028
  r8 = nil
946
1029
  else
947
- r8 = SyntaxNode.new(input, i8...index, s8)
1030
+ r8 = instantiate_node(SyntaxNode,input, i8...index, s8)
948
1031
  end
949
1032
  if r8
950
1033
  r7 = r8
@@ -963,7 +1046,7 @@ module Cucumber
963
1046
  if r12
964
1047
  r11 = r12
965
1048
  else
966
- r11 = SyntaxNode.new(input, index...index)
1049
+ r11 = instantiate_node(SyntaxNode,input, index...index)
967
1050
  end
968
1051
  s0 << r11
969
1052
  if r11
@@ -977,7 +1060,7 @@ module Cucumber
977
1060
  end
978
1061
  end
979
1062
  if s0.last
980
- r0 = (SyntaxNode).new(input, i0...index, s0)
1063
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
981
1064
  r0.extend(Step0)
982
1065
  r0.extend(Step1)
983
1066
  else
@@ -991,8 +1074,16 @@ module Cucumber
991
1074
  end
992
1075
 
993
1076
  module ExamplesSections0
994
- def build
995
- elements.map{|e| e.build}
1077
+ def at_line?(line)
1078
+ elements.detect { |e| e.at_line?(line) }
1079
+ end
1080
+
1081
+ def build(filter, scenario_outline)
1082
+ elements.map do |e|
1083
+ if(filter.nil? || filter.accept?(e) || filter.outline_at_line?(scenario_outline))
1084
+ e.build(filter, scenario_outline)
1085
+ end
1086
+ end.compact
996
1087
  end
997
1088
  end
998
1089
 
@@ -1013,7 +1104,7 @@ module Cucumber
1013
1104
  break
1014
1105
  end
1015
1106
  end
1016
- r0 = SyntaxNode.new(input, i0...index, s0)
1107
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
1017
1108
  r0.extend(ExamplesSections0)
1018
1109
 
1019
1110
  node_cache[:examples_sections][start_index] = r0
@@ -1044,8 +1135,21 @@ module Cucumber
1044
1135
  end
1045
1136
 
1046
1137
  module Examples1
1047
- def build
1048
- [examples_keyword.line, examples_keyword.text_value, name.text_value, table.raw]
1138
+ def at_line?(line)
1139
+ examples_keyword.line == line ||
1140
+ table.at_line?(line)
1141
+ end
1142
+
1143
+ def has_tags?(tag_names)
1144
+ true
1145
+ end
1146
+
1147
+ def outline_at_line?(line)
1148
+ true
1149
+ end
1150
+
1151
+ def build(filter, scenario_outline)
1152
+ [examples_keyword.line, examples_keyword.text_value, name.text_value, table.raw(filter, scenario_outline)]
1049
1153
  end
1050
1154
  end
1051
1155
 
@@ -1067,7 +1171,7 @@ module Cucumber
1067
1171
  break
1068
1172
  end
1069
1173
  end
1070
- r1 = SyntaxNode.new(input, i1...index, s1)
1174
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
1071
1175
  s0 << r1
1072
1176
  if r1
1073
1177
  r3 = _nt_examples_keyword
@@ -1082,14 +1186,14 @@ module Cucumber
1082
1186
  break
1083
1187
  end
1084
1188
  end
1085
- r4 = SyntaxNode.new(input, i4...index, s4)
1189
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
1086
1190
  s0 << r4
1087
1191
  if r4
1088
1192
  r7 = _nt_line_to_eol
1089
1193
  if r7
1090
1194
  r6 = r7
1091
1195
  else
1092
- r6 = SyntaxNode.new(input, index...index)
1196
+ r6 = instantiate_node(SyntaxNode,input, index...index)
1093
1197
  end
1094
1198
  s0 << r6
1095
1199
  if r6
@@ -1108,7 +1212,7 @@ module Cucumber
1108
1212
  end
1109
1213
  end
1110
1214
  if s0.last
1111
- r0 = (SyntaxNode).new(input, i0...index, s0)
1215
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
1112
1216
  r0.extend(Examples0)
1113
1217
  r0.extend(Examples1)
1114
1218
  else
@@ -1168,12 +1272,12 @@ module Cucumber
1168
1272
  r2 = nil
1169
1273
  else
1170
1274
  self.index = i2
1171
- r2 = SyntaxNode.new(input, index...index)
1275
+ r2 = instantiate_node(SyntaxNode,input, index...index)
1172
1276
  end
1173
1277
  s1 << r2
1174
1278
  if r2
1175
1279
  if index < input_length
1176
- r4 = (SyntaxNode).new(input, index...(index + 1))
1280
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
1177
1281
  @index += 1
1178
1282
  else
1179
1283
  terminal_parse_failure("any character")
@@ -1182,7 +1286,7 @@ module Cucumber
1182
1286
  s1 << r4
1183
1287
  end
1184
1288
  if s1.last
1185
- r1 = (SyntaxNode).new(input, i1...index, s1)
1289
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
1186
1290
  r1.extend(LineToEol0)
1187
1291
  else
1188
1292
  self.index = i1
@@ -1194,7 +1298,7 @@ module Cucumber
1194
1298
  break
1195
1299
  end
1196
1300
  end
1197
- r0 = SyntaxNode.new(input, i0...index, s0)
1301
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
1198
1302
 
1199
1303
  node_cache[:line_to_eol][start_index] = r0
1200
1304
 
@@ -1219,6 +1323,10 @@ module Cucumber
1219
1323
  end
1220
1324
 
1221
1325
  module PyString2
1326
+ def at_line?(line)
1327
+ line >= open_py_string.line && line <= close_py_string.line
1328
+ end
1329
+
1222
1330
  def build
1223
1331
  Ast::PyString.new(open_py_string.line, close_py_string.line, s.text_value, open_py_string.indentation)
1224
1332
  end
@@ -1245,12 +1353,12 @@ module Cucumber
1245
1353
  r4 = nil
1246
1354
  else
1247
1355
  self.index = i4
1248
- r4 = SyntaxNode.new(input, index...index)
1356
+ r4 = instantiate_node(SyntaxNode,input, index...index)
1249
1357
  end
1250
1358
  s3 << r4
1251
1359
  if r4
1252
1360
  if index < input_length
1253
- r6 = (SyntaxNode).new(input, index...(index + 1))
1361
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
1254
1362
  @index += 1
1255
1363
  else
1256
1364
  terminal_parse_failure("any character")
@@ -1259,7 +1367,7 @@ module Cucumber
1259
1367
  s3 << r6
1260
1368
  end
1261
1369
  if s3.last
1262
- r3 = (SyntaxNode).new(input, i3...index, s3)
1370
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
1263
1371
  r3.extend(PyString0)
1264
1372
  else
1265
1373
  self.index = i3
@@ -1271,7 +1379,7 @@ module Cucumber
1271
1379
  break
1272
1380
  end
1273
1381
  end
1274
- r2 = SyntaxNode.new(input, i2...index, s2)
1382
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
1275
1383
  s0 << r2
1276
1384
  if r2
1277
1385
  r7 = _nt_close_py_string
@@ -1279,7 +1387,7 @@ module Cucumber
1279
1387
  end
1280
1388
  end
1281
1389
  if s0.last
1282
- r0 = (SyntaxNode).new(input, i0...index, s0)
1390
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
1283
1391
  r0.extend(PyString1)
1284
1392
  r0.extend(PyString2)
1285
1393
  else
@@ -1293,7 +1401,7 @@ module Cucumber
1293
1401
  end
1294
1402
 
1295
1403
  module OpenPyString0
1296
- def white
1404
+ def indent
1297
1405
  elements[0]
1298
1406
  end
1299
1407
 
@@ -1304,11 +1412,11 @@ module Cucumber
1304
1412
 
1305
1413
  module OpenPyString1
1306
1414
  def indentation
1307
- white.text_value.length
1415
+ indent.text_value.length
1308
1416
  end
1309
1417
 
1310
1418
  def line
1311
- white.line
1419
+ indent.line
1312
1420
  end
1313
1421
  end
1314
1422
 
@@ -1321,37 +1429,46 @@ module Cucumber
1321
1429
  end
1322
1430
 
1323
1431
  i0, s0 = index, []
1324
- r1 = _nt_white
1432
+ s1, i1 = [], index
1433
+ loop do
1434
+ r2 = _nt_space
1435
+ if r2
1436
+ s1 << r2
1437
+ else
1438
+ break
1439
+ end
1440
+ end
1441
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
1325
1442
  s0 << r1
1326
1443
  if r1
1327
1444
  if input.index('"""', index) == index
1328
- r2 = (SyntaxNode).new(input, index...(index + 3))
1445
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 3))
1329
1446
  @index += 3
1330
1447
  else
1331
1448
  terminal_parse_failure('"""')
1332
- r2 = nil
1449
+ r3 = nil
1333
1450
  end
1334
- s0 << r2
1335
- if r2
1336
- s3, i3 = [], index
1451
+ s0 << r3
1452
+ if r3
1453
+ s4, i4 = [], index
1337
1454
  loop do
1338
- r4 = _nt_space
1339
- if r4
1340
- s3 << r4
1455
+ r5 = _nt_space
1456
+ if r5
1457
+ s4 << r5
1341
1458
  else
1342
1459
  break
1343
1460
  end
1344
1461
  end
1345
- r3 = SyntaxNode.new(input, i3...index, s3)
1346
- s0 << r3
1347
- if r3
1348
- r5 = _nt_eol
1349
- s0 << r5
1462
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
1463
+ s0 << r4
1464
+ if r4
1465
+ r6 = _nt_eol
1466
+ s0 << r6
1350
1467
  end
1351
1468
  end
1352
1469
  end
1353
1470
  if s0.last
1354
- r0 = (SyntaxNode).new(input, i0...index, s0)
1471
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
1355
1472
  r0.extend(OpenPyString0)
1356
1473
  r0.extend(OpenPyString1)
1357
1474
  else
@@ -1405,11 +1522,11 @@ module Cucumber
1405
1522
  break
1406
1523
  end
1407
1524
  end
1408
- r2 = SyntaxNode.new(input, i2...index, s2)
1525
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
1409
1526
  s0 << r2
1410
1527
  if r2
1411
1528
  if input.index('"""', index) == index
1412
- r4 = (SyntaxNode).new(input, index...(index + 3))
1529
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 3))
1413
1530
  @index += 3
1414
1531
  else
1415
1532
  terminal_parse_failure('"""')
@@ -1423,7 +1540,7 @@ module Cucumber
1423
1540
  end
1424
1541
  end
1425
1542
  if s0.last
1426
- r0 = (SyntaxNode).new(input, i0...index, s0)
1543
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
1427
1544
  r0.extend(ClosePyString0)
1428
1545
  r0.extend(ClosePyString1)
1429
1546
  else
@@ -1465,7 +1582,7 @@ module Cucumber
1465
1582
  break
1466
1583
  end
1467
1584
  end
1468
- r0 = SyntaxNode.new(input, i0...index, s0)
1585
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
1469
1586
 
1470
1587
  node_cache[:white][start_index] = r0
1471
1588
 
@@ -1479,4 +1596,4 @@ module Cucumber
1479
1596
  end
1480
1597
 
1481
1598
  end
1482
- end
1599
+ end