cucumber 0.2.3 → 0.3.0

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 (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