kosmas58-cucumber 0.2.2.1 → 0.2.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/History.txt +57 -5
  2. data/Manifest.txt +21 -4
  3. data/bin/cucumber +1 -1
  4. data/config/hoe.rb +2 -2
  5. data/examples/i18n/Rakefile +6 -8
  6. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
  7. data/examples/i18n/ar/lib/calculator.rb +1 -0
  8. data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +1 -1
  9. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +1 -1
  10. data/examples/i18n/en/features/step_definitons/calculator_steps.rb +1 -1
  11. data/examples/i18n/es/features/step_definitons/calculador_steps.rb +1 -1
  12. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +1 -1
  13. data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +1 -1
  14. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +1 -1
  15. data/examples/i18n/id/features/step_definitons/calculator_steps.rb +1 -1
  16. data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +1 -1
  17. data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +1 -1
  18. data/examples/i18n/ko/features/addition.feature +1 -1
  19. data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +1 -1
  20. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +1 -1
  21. data/examples/i18n/no/features/support/env.rb +1 -1
  22. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +1 -1
  23. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +1 -1
  24. data/examples/i18n/ru/features/support/env.rb +1 -1
  25. data/examples/i18n/ru/features/support/world.rb +4 -3
  26. data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +1 -1
  27. data/examples/i18n/sk/Rakefile +6 -0
  28. data/examples/i18n/sk/features/addition.feature +16 -0
  29. data/examples/i18n/sk/features/division.feature +9 -0
  30. data/examples/i18n/sk/features/step_definitons/calculator_steps.rb +24 -0
  31. data/examples/i18n/sk/lib/calculator.rb +14 -0
  32. data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +1 -1
  33. data/examples/i18n/zh-TW/features/step_definitons/calculator_steps.rb +1 -1
  34. data/examples/self_test/features/background/background_with_name.feature +7 -0
  35. data/examples/self_test/features/step_definitions/sample_steps.rb +8 -2
  36. data/examples/self_test/features/undefined_multiline_args.feature +12 -0
  37. data/examples/sinatra/features/support/env.rb +2 -6
  38. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +1 -4
  39. data/examples/tickets/Rakefile +1 -1
  40. data/examples/tickets/features/246.feature +4 -0
  41. data/examples/tickets/features/270/back.feature +14 -0
  42. data/examples/tickets/features/270/back.steps.rb +14 -0
  43. data/examples/tickets/features/step_definitons/246_steps.rb +3 -0
  44. data/features/background.feature +21 -4
  45. data/features/cucumber_cli.feature +18 -5
  46. data/features/cucumber_cli_outlines.feature +5 -2
  47. data/features/snippet.feature +23 -0
  48. data/features/step_definitions/cucumber_steps.rb +6 -2
  49. data/features/usage.feature +5 -0
  50. data/gem_tasks/rspec.rake +3 -2
  51. data/lib/cucumber/ast/background.rb +3 -3
  52. data/lib/cucumber/ast/examples.rb +0 -12
  53. data/lib/cucumber/ast/feature.rb +2 -12
  54. data/lib/cucumber/ast/feature_element.rb +0 -8
  55. data/lib/cucumber/ast/features.rb +1 -1
  56. data/lib/cucumber/ast/outline_table.rb +14 -22
  57. data/lib/cucumber/ast/py_string.rb +6 -11
  58. data/lib/cucumber/ast/scenario.rb +1 -8
  59. data/lib/cucumber/ast/scenario_outline.rb +1 -11
  60. data/lib/cucumber/ast/step.rb +3 -9
  61. data/lib/cucumber/ast/step_collection.rb +0 -4
  62. data/lib/cucumber/ast/step_invocation.rb +5 -6
  63. data/lib/cucumber/ast/table.rb +26 -22
  64. data/lib/cucumber/ast/tags.rb +0 -8
  65. data/lib/cucumber/ast/visitor.rb +12 -25
  66. data/lib/cucumber/cli/configuration.rb +2 -2
  67. data/lib/cucumber/cli/main.rb +5 -2
  68. data/lib/cucumber/core_ext/instance_exec.rb +17 -4
  69. data/lib/cucumber/formatter/ansicolor.rb +10 -2
  70. data/lib/cucumber/formatter/console.rb +2 -1
  71. data/lib/cucumber/formatter/html.rb +21 -7
  72. data/lib/cucumber/formatter/pretty.rb +27 -20
  73. data/lib/cucumber/formatter/usage.rb +16 -0
  74. data/lib/cucumber/languages.yml +68 -7
  75. data/lib/cucumber/parser/feature.rb +238 -135
  76. data/lib/cucumber/parser/feature.tt +117 -22
  77. data/lib/cucumber/parser/i18n.tt +4 -0
  78. data/lib/cucumber/parser/table.rb +37 -25
  79. data/lib/cucumber/parser/table.tt +15 -3
  80. data/lib/cucumber/parser/treetop_ext.rb +48 -9
  81. data/lib/cucumber/parser.rb +2 -7
  82. data/lib/cucumber/step_definition.rb +13 -14
  83. data/lib/cucumber/step_mother.rb +93 -11
  84. data/lib/cucumber/version.rb +2 -2
  85. data/rails_generators/cucumber/templates/env.rb +1 -1
  86. data/rails_generators/cucumber/templates/paths.rb +15 -5
  87. data/rails_generators/cucumber/templates/webrat_steps.rb +8 -0
  88. data/spec/cucumber/ast/background_spec.rb +1 -0
  89. data/spec/cucumber/ast/feature_factory.rb +1 -1
  90. data/spec/cucumber/ast/feature_spec.rb +2 -2
  91. data/spec/cucumber/ast/scenario_spec.rb +0 -27
  92. data/spec/cucumber/ast/table_spec.rb +23 -2
  93. data/spec/cucumber/core_ext/proc_spec.rb +25 -8
  94. data/spec/cucumber/parser/feature_parser_spec.rb +43 -41
  95. data/spec/cucumber/step_definition_spec.rb +8 -0
  96. data/spec/cucumber/step_mother_spec.rb +48 -0
  97. data/spec/spec_helper.rb +2 -11
  98. metadata +17 -6
  99. data/examples/tickets/cucumber.yml +0 -3
  100. data/lib/cucumber/parser/basic.rb +0 -0
  101. data/spec/cucumber/ast/tags_spec.rb +0 -19
@@ -20,25 +20,42 @@ module Cucumber
20
20
  bg:background?
21
21
  feature_elements
22
22
  comment? {
23
- def build
24
- background = bg.respond_to?(:build) ? bg.build : nil
25
- Ast::Feature.new(
26
- background,
27
- comment.build,
28
- tags.build,
29
- header.text_value,
30
- feature_elements.build(background)
31
- )
23
+ def has_tags?(tag_names)
24
+ tags.has_tags?(tag_names)
25
+ end
26
+
27
+ def build(filter)
28
+ if(filter.nil? || feature_elements.accept?(filter))
29
+ background = bg.respond_to?(:build) ? bg.build : nil
30
+ Ast::Feature.new(
31
+ background,
32
+ comment.build,
33
+ tags.build,
34
+ header.text_value,
35
+ feature_elements.build(background, filter)
36
+ )
37
+ end
32
38
  end
33
39
  }
34
40
  end
35
41
 
36
42
  rule tags
37
43
  white ts:(tag (space/eol)+)* {
44
+ def at_line?(line)
45
+ ts.elements.detect{|e| e.tag.line == line}
46
+ end
47
+
48
+ def has_tags?(tags)
49
+ tag_names.detect{|tag_name| tags.index(tag_name)}
50
+ end
51
+
38
52
  def build
39
- tag_names = ts.elements.map{|e| e.tag.tag_name.text_value}
40
53
  Ast::Tags.new(ts.line, tag_names)
41
54
  end
55
+
56
+ def tag_names
57
+ ts.elements.map{|e| e.tag.tag_name.text_value}
58
+ end
42
59
  }
43
60
  end
44
61
 
@@ -59,12 +76,13 @@ module Cucumber
59
76
  end
60
77
 
61
78
  rule background
62
- comment white background_keyword space* (eol+ / eof) steps {
79
+ comment white background_keyword space* name:line_to_eol? (eol+ / eof) steps {
63
80
  def build
64
81
  Ast::Background.new(
65
82
  comment.build,
66
83
  background_keyword.line,
67
- background_keyword.text_value,
84
+ background_keyword.text_value,
85
+ name.text_value,
68
86
  steps.build
69
87
  )
70
88
  end
@@ -73,15 +91,38 @@ module Cucumber
73
91
 
74
92
  rule feature_elements
75
93
  (scenario / scenario_outline)* {
76
- def build(background)
77
- elements.map{|s| s.build(background)}
94
+ def accept?(filter)
95
+ filter.nil? || elements.empty? || elements.detect{|feature_element| filter.accept?(feature_element)}
96
+ end
97
+
98
+ def build(background, filter)
99
+ elements.map do |feature_element|
100
+ if filter.nil? || filter.accept?(feature_element)
101
+ feature_element.build(background, filter)
102
+ end
103
+ end.compact
78
104
  end
79
105
  }
80
106
  end
81
107
 
82
108
  rule scenario
83
109
  comment tags white scenario_keyword space* name:line_to_eol white steps white {
84
- def build(background)
110
+ def at_line?(line)
111
+ scenario_keyword.line == line ||
112
+ steps.at_line?(line) ||
113
+ tags.at_line?(line)
114
+ end
115
+
116
+ def has_tags?(tag_names)
117
+ feature_tags = self.parent.parent.tags
118
+ tags.has_tags?(tag_names) || feature_tags.has_tags?(tag_names)
119
+ end
120
+
121
+ def matches_name?(name_to_match)
122
+ name.text_value == name_to_match
123
+ end
124
+
125
+ def build(background, filter)
85
126
  Ast::Scenario.new(
86
127
  background,
87
128
  comment.build,
@@ -97,7 +138,27 @@ module Cucumber
97
138
 
98
139
  rule scenario_outline
99
140
  comment tags white scenario_outline_keyword space* name:line_to_eol white steps examples_sections white {
100
- def build(background)
141
+ def at_line?(line)
142
+ outline_at_line?(line) ||
143
+ examples_sections.at_line?(line) ||
144
+ tags.at_line?(line)
145
+ end
146
+
147
+ def outline_at_line?(line)
148
+ scenario_outline_keyword.line == line ||
149
+ steps.at_line?(line)
150
+ end
151
+
152
+ def has_tags?(tag_names)
153
+ feature_tags = self.parent.parent.tags
154
+ tags.has_tags?(tag_names) || feature_tags.has_tags?(tag_names)
155
+ end
156
+
157
+ def matches_name?(name_to_match)
158
+ name.text_value == name_to_match
159
+ end
160
+
161
+ def build(background, filter)
101
162
  Ast::ScenarioOutline.new(
102
163
  background,
103
164
  comment.build,
@@ -106,7 +167,7 @@ module Cucumber
106
167
  scenario_outline_keyword.text_value,
107
168
  name.text_value,
108
169
  steps.build,
109
- examples_sections.build
170
+ examples_sections.build(filter, self)
110
171
  )
111
172
  end
112
173
  }
@@ -114,6 +175,10 @@ module Cucumber
114
175
 
115
176
  rule steps
116
177
  step* {
178
+ def at_line?(line)
179
+ elements.detect{|e| e.at_line?(line)}
180
+ end
181
+
117
182
  def build
118
183
  elements.map{|e| e.build}
119
184
  end
@@ -121,7 +186,12 @@ module Cucumber
121
186
  end
122
187
 
123
188
  rule step
124
- comment space* step_keyword space* name:line_to_eol (eol+ / eof) multi:multiline_arg? white {
189
+ comment space* step_keyword keyword_space name:line_to_eol (eol+ / eof) multi:multiline_arg? white {
190
+ def at_line?(line)
191
+ step_keyword.line == line ||
192
+ (multi.respond_to?(:at_line?) && multi.at_line?(line))
193
+ end
194
+
125
195
  def build
126
196
  if multi.respond_to?(:build)
127
197
  Ast::Step.new(step_keyword.line, step_keyword.text_value, name.text_value.strip, multi.build)
@@ -134,16 +204,37 @@ module Cucumber
134
204
 
135
205
  rule examples_sections
136
206
  examples* {
137
- def build
138
- elements.map{|e| e.build}
207
+ def at_line?(line)
208
+ elements.detect { |e| e.at_line?(line) }
209
+ end
210
+
211
+ def build(filter, scenario_outline)
212
+ elements.map do |e|
213
+ if(filter.nil? || filter.accept?(e) || filter.outline_at_line?(scenario_outline))
214
+ e.build(filter, scenario_outline)
215
+ end
216
+ end.compact
139
217
  end
140
218
  }
141
219
  end
142
220
 
143
221
  rule examples
144
222
  space* examples_keyword space* name:line_to_eol? eol table white {
145
- def build
146
- [examples_keyword.line, examples_keyword.text_value, name.text_value, table.raw]
223
+ def at_line?(line)
224
+ examples_keyword.line == line ||
225
+ table.at_line?(line)
226
+ end
227
+
228
+ def has_tags?(tag_names)
229
+ true
230
+ end
231
+
232
+ def outline_at_line?(line)
233
+ true
234
+ end
235
+
236
+ def build(filter, scenario_outline)
237
+ [examples_keyword.line, examples_keyword.text_value, name.text_value, table.raw(filter, scenario_outline)]
147
238
  end
148
239
  }
149
240
  end
@@ -158,6 +249,10 @@ module Cucumber
158
249
 
159
250
  rule py_string
160
251
  open_py_string s:(!close_py_string .)* close_py_string {
252
+ def at_line?(line)
253
+ line >= open_py_string.line && line <= close_py_string.line
254
+ end
255
+
161
256
  def build
162
257
  Ast::PyString.new(open_py_string.line, close_py_string.line, s.text_value, open_py_string.indentation)
163
258
  end
@@ -22,6 +22,10 @@ module Cucumber
22
22
  (<%= keywords('but') %>)
23
23
  end
24
24
 
25
+ rule keyword_space
26
+ <%= keywords('space_after_keyword', true) ? 'space+' : 'space*' %>
27
+ end
28
+
25
29
  rule examples_keyword
26
30
  (<%= keywords('examples') %>) ':'?
27
31
  end
@@ -14,12 +14,20 @@ module Cucumber
14
14
  end
15
15
 
16
16
  module Table0
17
- def build
17
+ def at_line?(line)
18
+ elements.detect{|table_row| table_row.at_line?(line)}
19
+ end
20
+
21
+ def build(filter=nil)
18
22
  Ast::Table.new(raw)
19
23
  end
20
24
 
21
- def raw
22
- elements.map{|e| e.build}
25
+ def raw(filter=nil, scenario_outline=nil)
26
+ elements.map do |table_row|
27
+ if(filter.nil? || table_row == elements[0] || filter.at_line?(table_row) || (scenario_outline && filter.outline_at_line?(scenario_outline)))
28
+ table_row.build
29
+ end
30
+ end.compact
23
31
  end
24
32
  end
25
33
 
@@ -44,7 +52,7 @@ module Cucumber
44
52
  self.index = i0
45
53
  r0 = nil
46
54
  else
47
- r0 = SyntaxNode.new(input, i0...index, s0)
55
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
48
56
  r0.extend(Table0)
49
57
  end
50
58
 
@@ -68,6 +76,10 @@ module Cucumber
68
76
  end
69
77
 
70
78
  module TableRow2
79
+ def at_line?(line)
80
+ cells.line == line
81
+ end
82
+
71
83
  def build
72
84
  row = cells.elements.map do |elt|
73
85
  value = elt.cell.text_value.strip
@@ -101,11 +113,11 @@ module Cucumber
101
113
  break
102
114
  end
103
115
  end
104
- r1 = SyntaxNode.new(input, i1...index, s1)
116
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
105
117
  s0 << r1
106
118
  if r1
107
119
  if input.index('|', index) == index
108
- r3 = (SyntaxNode).new(input, index...(index + 1))
120
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
109
121
  @index += 1
110
122
  else
111
123
  terminal_parse_failure('|')
@@ -120,7 +132,7 @@ module Cucumber
120
132
  s5 << r6
121
133
  if r6
122
134
  if input.index('|', index) == index
123
- r7 = (SyntaxNode).new(input, index...(index + 1))
135
+ r7 = instantiate_node(SyntaxNode,input, index...(index + 1))
124
136
  @index += 1
125
137
  else
126
138
  terminal_parse_failure('|')
@@ -129,7 +141,7 @@ module Cucumber
129
141
  s5 << r7
130
142
  end
131
143
  if s5.last
132
- r5 = (SyntaxNode).new(input, i5...index, s5)
144
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
133
145
  r5.extend(TableRow0)
134
146
  else
135
147
  self.index = i5
@@ -145,7 +157,7 @@ module Cucumber
145
157
  self.index = i4
146
158
  r4 = nil
147
159
  else
148
- r4 = SyntaxNode.new(input, i4...index, s4)
160
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
149
161
  end
150
162
  s0 << r4
151
163
  if r4
@@ -158,7 +170,7 @@ module Cucumber
158
170
  break
159
171
  end
160
172
  end
161
- r8 = SyntaxNode.new(input, i8...index, s8)
173
+ r8 = instantiate_node(SyntaxNode,input, i8...index, s8)
162
174
  s0 << r8
163
175
  if r8
164
176
  i10 = index
@@ -175,7 +187,7 @@ module Cucumber
175
187
  self.index = i11
176
188
  r11 = nil
177
189
  else
178
- r11 = SyntaxNode.new(input, i11...index, s11)
190
+ r11 = instantiate_node(SyntaxNode,input, i11...index, s11)
179
191
  end
180
192
  if r11
181
193
  r10 = r11
@@ -194,7 +206,7 @@ module Cucumber
194
206
  end
195
207
  end
196
208
  if s0.last
197
- r0 = (SyntaxNode).new(input, i0...index, s0)
209
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
198
210
  r0.extend(TableRow1)
199
211
  r0.extend(TableRow2)
200
212
  else
@@ -224,7 +236,7 @@ module Cucumber
224
236
  i2 = index
225
237
  i3 = index
226
238
  if input.index('|', index) == index
227
- r4 = (SyntaxNode).new(input, index...(index + 1))
239
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
228
240
  @index += 1
229
241
  else
230
242
  terminal_parse_failure('|')
@@ -245,12 +257,12 @@ module Cucumber
245
257
  r2 = nil
246
258
  else
247
259
  self.index = i2
248
- r2 = SyntaxNode.new(input, index...index)
260
+ r2 = instantiate_node(SyntaxNode,input, index...index)
249
261
  end
250
262
  s1 << r2
251
263
  if r2
252
264
  if index < input_length
253
- r6 = (SyntaxNode).new(input, index...(index + 1))
265
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
254
266
  @index += 1
255
267
  else
256
268
  terminal_parse_failure("any character")
@@ -259,7 +271,7 @@ module Cucumber
259
271
  s1 << r6
260
272
  end
261
273
  if s1.last
262
- r1 = (SyntaxNode).new(input, i1...index, s1)
274
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
263
275
  r1.extend(Cell0)
264
276
  else
265
277
  self.index = i1
@@ -271,7 +283,7 @@ module Cucumber
271
283
  break
272
284
  end
273
285
  end
274
- r0 = SyntaxNode.new(input, i0...index, s0)
286
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
275
287
 
276
288
  node_cache[:cell][start_index] = r0
277
289
 
@@ -287,7 +299,7 @@ module Cucumber
287
299
  end
288
300
 
289
301
  if input.index(Regexp.new('[ \\t]'), index) == index
290
- r0 = (SyntaxNode).new(input, index...(index + 1))
302
+ r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
291
303
  @index += 1
292
304
  else
293
305
  r0 = nil
@@ -311,7 +323,7 @@ module Cucumber
311
323
 
312
324
  i0 = index
313
325
  if input.index("\n", index) == index
314
- r1 = (SyntaxNode).new(input, index...(index + 1))
326
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
315
327
  @index += 1
316
328
  else
317
329
  terminal_parse_failure("\n")
@@ -322,7 +334,7 @@ module Cucumber
322
334
  else
323
335
  i2, s2 = index, []
324
336
  if input.index("\r", index) == index
325
- r3 = (SyntaxNode).new(input, index...(index + 1))
337
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
326
338
  @index += 1
327
339
  else
328
340
  terminal_parse_failure("\r")
@@ -331,7 +343,7 @@ module Cucumber
331
343
  s2 << r3
332
344
  if r3
333
345
  if input.index("\n", index) == index
334
- r5 = (SyntaxNode).new(input, index...(index + 1))
346
+ r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
335
347
  @index += 1
336
348
  else
337
349
  terminal_parse_failure("\n")
@@ -340,12 +352,12 @@ module Cucumber
340
352
  if r5
341
353
  r4 = r5
342
354
  else
343
- r4 = SyntaxNode.new(input, index...index)
355
+ r4 = instantiate_node(SyntaxNode,input, index...index)
344
356
  end
345
357
  s2 << r4
346
358
  end
347
359
  if s2.last
348
- r2 = (SyntaxNode).new(input, i2...index, s2)
360
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
349
361
  r2.extend(Eol0)
350
362
  else
351
363
  self.index = i2
@@ -374,7 +386,7 @@ module Cucumber
374
386
 
375
387
  i0 = index
376
388
  if index < input_length
377
- r1 = (SyntaxNode).new(input, index...(index + 1))
389
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
378
390
  @index += 1
379
391
  else
380
392
  terminal_parse_failure("any character")
@@ -384,7 +396,7 @@ module Cucumber
384
396
  r0 = nil
385
397
  else
386
398
  self.index = i0
387
- r0 = SyntaxNode.new(input, index...index)
399
+ r0 = instantiate_node(SyntaxNode,input, index...index)
388
400
  end
389
401
 
390
402
  node_cache[:eof][start_index] = r0
@@ -10,18 +10,30 @@ module Cucumber
10
10
 
11
11
  rule table
12
12
  table_row+ {
13
- def build
13
+ def at_line?(line)
14
+ elements.detect{|table_row| table_row.at_line?(line)}
15
+ end
16
+
17
+ def build(filter=nil)
14
18
  Ast::Table.new(raw)
15
19
  end
16
20
 
17
- def raw
18
- elements.map{|e| e.build}
21
+ def raw(filter=nil, scenario_outline=nil)
22
+ elements.map do |table_row|
23
+ if(filter.nil? || table_row == elements[0] || filter.at_line?(table_row) || (scenario_outline && filter.outline_at_line?(scenario_outline)))
24
+ table_row.build
25
+ end
26
+ end.compact
19
27
  end
20
28
  }
21
29
  end
22
30
 
23
31
  rule table_row
24
32
  space* '|' cells:(cell '|')+ space* (eol+ / eof) {
33
+ def at_line?(line)
34
+ cells.line == line
35
+ end
36
+
25
37
  def build
26
38
  row = cells.elements.map do |elt|
27
39
  value = elt.cell.text_value.strip
@@ -12,37 +12,76 @@ end
12
12
 
13
13
  module Cucumber
14
14
  module Parser
15
- module TreetopExt
15
+ class Filter
16
+ def initialize(lines, options)
17
+ @lines = lines
18
+ @include_tags = options[:include_tags] || []
19
+ @exclude_tags = options[:exclude_tags] || []
20
+ @names = options[:scenario_names] || []
21
+ end
22
+
23
+ def accept?(syntax_node)
24
+ at_line?(syntax_node) &&
25
+ matches_tags?(syntax_node) &&
26
+ matches_names?(syntax_node)
27
+ end
28
+
29
+ def at_line?(syntax_node)
30
+ @lines.nil? || @lines.empty? || @lines.detect{|line| syntax_node.at_line?(line)}
31
+ end
32
+
33
+ def outline_at_line?(syntax_node)
34
+ @lines.nil? || @lines.empty? || @lines.detect{|line| syntax_node.outline_at_line?(line)}
35
+ end
36
+
37
+ def matches_tags?(syntax_node)
38
+ !excluded_by_tags?(syntax_node) &&
39
+ included_by_tags?(syntax_node)
40
+ end
41
+
42
+ def included_by_tags?(syntax_node)
43
+ @include_tags.empty? || syntax_node.has_tags?(@include_tags)
44
+ end
45
+
46
+ def excluded_by_tags?(syntax_node)
47
+ @exclude_tags.any? && syntax_node.has_tags?(@exclude_tags)
48
+ end
49
+
50
+ def matches_names?(syntax_node)
51
+ @names.nil? || @names.empty? || @names.detect{|name| syntax_node.matches_name?(name)}
52
+ end
53
+ end
54
+
55
+ module TreetopExt
16
56
  FILE_COLON_LINE_PATTERN = /^([\w\W]*?):([\d:]+)$/
17
57
 
18
58
  # Parses a file and returns a Cucumber::Ast
19
- def parse_file(file)
59
+ def parse_file(file, options)
20
60
  _, path, lines = *FILE_COLON_LINE_PATTERN.match(file)
21
61
  if path
22
62
  lines = lines.split(':').map { |line| line.to_i }
23
63
  else
24
64
  path = file
25
- lines = []
26
65
  end
66
+ filter = Filter.new(lines, options)
27
67
 
28
- loader = lambda { |io| parse_or_fail(io.read, path) }
68
+ loader = lambda { |io| parse_or_fail(io.read, filter, path) }
29
69
  feature = if path =~ /^http/
30
70
  require 'open-uri'
31
71
  open(path, &loader)
32
72
  else
33
73
  File.open(path, Cucumber.file_mode('r'), &loader)
34
74
  end
35
- feature.lines = lines
36
75
  feature
37
76
  end
38
77
 
39
- def parse_or_fail(s, file=nil, line_offset=0)
40
- parse_tree = parse(s)
78
+ def parse_or_fail(string, filter=nil, file=nil, line_offset=0)
79
+ parse_tree = parse(string)
41
80
  if parse_tree.nil?
42
81
  raise Cucumber::Parser::SyntaxError.new(self, file, line_offset)
43
82
  else
44
- ast = parse_tree.build
45
- ast.file = file
83
+ ast = parse_tree.build(filter) # may return nil if it doesn't match filter.
84
+ ast.file = file unless ast.nil?
46
85
  ast
47
86
  end
48
87
  end
@@ -13,12 +13,6 @@ module Cucumber
13
13
  #
14
14
  # The AST classes are defined in the Cucumber::Ast module.
15
15
  module Parser
16
- translator = Module.new do
17
- def keywordz(key)
18
- 'Scenario'
19
- end
20
- end
21
-
22
16
  def self.load_parser(keywords)
23
17
  Loader.new(keywords)
24
18
  end
@@ -34,7 +28,8 @@ module Cucumber
34
28
  require 'cucumber/parser/feature'
35
29
  end
36
30
 
37
- def keywords(key)
31
+ def keywords(key, raw=false)
32
+ return @keywords[key] if raw
38
33
  values = @keywords[key].split('|')
39
34
  values.map{|value| "'#{value}'"}.join(" / ")
40
35
  end
@@ -56,24 +56,23 @@ module Cucumber
56
56
  # end
57
57
  #
58
58
  class StepDefinition
59
- def self.snippet_text(step_keyword, step_name)
59
+ PARAM_PATTERN = /"([^\"]*)"/
60
+ ESCAPED_PARAM_PATTERN = '"([^\\"]*)"'
61
+
62
+ def self.snippet_text(step_keyword, step_name, multiline_arg_class = nil)
60
63
  escaped = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
61
- param_pattern = /"([^\"]*)"/
64
+ escaped = escaped.gsub(PARAM_PATTERN, ESCAPED_PARAM_PATTERN)
62
65
 
63
- match = escaped.match(param_pattern)
64
- if match
65
- n = 0
66
- block_args = match.captures.map do |a|
67
- n += 1
68
- "arg#{n}"
69
- end
70
- block_arg_string = " |#{block_args.join(", ")}|"
71
- else
72
- block_arg_string = ""
66
+ n = 0
67
+ block_args = escaped.scan(ESCAPED_PARAM_PATTERN).map do |a|
68
+ n += 1
69
+ "arg#{n}"
73
70
  end
71
+ block_args << multiline_arg_class.default_arg_name unless multiline_arg_class.nil?
72
+ block_arg_string = block_args.empty? ? "" : " |#{block_args.join(", ")}|"
73
+ multiline_class_string = multiline_arg_class ? "# #{multiline_arg_class.default_arg_name} is a #{multiline_arg_class.to_s}\n " : ""
74
74
 
75
- escaped = escaped.gsub(param_pattern, '"([^\\"]*)"')
76
- "#{step_keyword} /^#{escaped}$/ do#{block_arg_string}\n pending\nend"
75
+ "#{step_keyword} /^#{escaped}$/ do#{block_arg_string}\n #{multiline_class_string}pending\nend"
77
76
  end
78
77
 
79
78
  class MissingProc < StandardError