cucumber 0.3.0 → 0.3.1

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 (66) hide show
  1. data/History.txt +26 -1
  2. data/Manifest.txt +20 -1
  3. data/config/hoe.rb +5 -4
  4. data/examples/i18n/hu/Rakefile +6 -0
  5. data/examples/i18n/hu/features/addition.feature +16 -0
  6. data/examples/i18n/hu/features/division.feature +9 -0
  7. data/examples/i18n/hu/features/step_definitons/calculator_steps.rb +25 -0
  8. data/examples/i18n/hu/lib/calculator.rb +14 -0
  9. data/examples/i18n/lv/Rakefile +6 -0
  10. data/examples/i18n/lv/features/addition.feature +16 -0
  11. data/examples/i18n/lv/features/division.feature +9 -0
  12. data/examples/i18n/lv/features/step_definitons/calculator_steps.rb +24 -0
  13. data/examples/i18n/lv/lib/calculator.rb +14 -0
  14. data/examples/self_test/features/background/failing_background.feature +1 -0
  15. data/examples/self_test/features/multiline_name.feature +27 -0
  16. data/examples/self_test/features/search_sample.feature +22 -0
  17. data/examples/self_test/features/step_definitions/sample_steps.rb +3 -2
  18. data/examples/tickets/Rakefile +3 -3
  19. data/examples/tickets/features/236.feature +9 -9
  20. data/examples/tickets/features/272/hooks.feature +26 -0
  21. data/examples/tickets/features/272/hooks_steps.rb +53 -0
  22. data/examples/tickets/features/301/filter_background_tagged_hooks.feature +6 -0
  23. data/examples/tickets/features/301/filter_background_tagged_hooks_steps.rb +12 -0
  24. data/examples/tickets/features/306/only_background.feature +4 -0
  25. data/features/background.feature +2 -1
  26. data/features/cucumber_cli.feature +88 -12
  27. data/features/cucumber_cli_outlines.feature +32 -0
  28. data/features/custom_formatter.feature +2 -2
  29. data/features/multiline_names.feature +43 -0
  30. data/features/report_called_undefined_steps.feature +1 -1
  31. data/features/usage.feature +13 -4
  32. data/lib/cucumber/ast/background.rb +10 -13
  33. data/lib/cucumber/ast/feature.rb +5 -0
  34. data/lib/cucumber/ast/feature_element.rb +23 -12
  35. data/lib/cucumber/ast/outline_table.rb +10 -0
  36. data/lib/cucumber/ast/py_string.rb +5 -1
  37. data/lib/cucumber/ast/scenario.rb +17 -6
  38. data/lib/cucumber/ast/scenario_outline.rb +1 -6
  39. data/lib/cucumber/ast/step.rb +6 -3
  40. data/lib/cucumber/ast/step_collection.rb +9 -1
  41. data/lib/cucumber/ast/table.rb +8 -0
  42. data/lib/cucumber/ast/visitor.rb +2 -2
  43. data/lib/cucumber/cli/configuration.rb +15 -14
  44. data/lib/cucumber/formatter/console.rb +1 -1
  45. data/lib/cucumber/formatter/html.rb +1 -1
  46. data/lib/cucumber/formatter/pretty.rb +7 -8
  47. data/lib/cucumber/languages.yml +30 -0
  48. data/lib/cucumber/parser/feature.rb +214 -14
  49. data/lib/cucumber/parser/feature.tt +44 -14
  50. data/lib/cucumber/parser/treetop_ext.rb +3 -3
  51. data/lib/cucumber/rails/world.rb +6 -0
  52. data/lib/cucumber/step_mother.rb +2 -1
  53. data/lib/cucumber/version.rb +1 -1
  54. data/lib/cucumber/world.rb +2 -2
  55. data/rails_generators/cucumber/templates/paths.rb +11 -13
  56. data/rails_generators/feature/feature_generator.rb +1 -1
  57. data/spec/cucumber/ast/feature_element_spec.rb +40 -0
  58. data/spec/cucumber/ast/py_string_spec.rb +4 -0
  59. data/spec/cucumber/ast/table_spec.rb +20 -4
  60. data/spec/cucumber/ast/visitor_spec.rb +27 -0
  61. data/spec/cucumber/cli/configuration_spec.rb +4 -13
  62. data/spec/cucumber/cli/main_spec.rb +55 -153
  63. data/spec/cucumber/parser/feature_parser_spec.rb +79 -0
  64. data/spec/cucumber/step_mother_spec.rb +12 -5
  65. metadata +22 -13
  66. data/spec/cucumber/formatters/profile_formatter_spec.rb +0 -198
@@ -0,0 +1,6 @@
1
+ Feature https://rspec.lighthouseapp.com/projects/16211/tickets/301
2
+ Background: A background
3
+ Given whatever
4
+
5
+ Scenario: VB is not cool
6
+ Then VB should not be cool
@@ -0,0 +1,12 @@
1
+ require 'spec/expectations'
2
+
3
+ Before('@nothing_has_this_tag') do
4
+ @vb = :cool
5
+ end
6
+
7
+ Given /^whatever$/ do
8
+ end
9
+
10
+ Then /^VB should not be cool$/ do
11
+ @vb.should_not == :cool
12
+ end
@@ -0,0 +1,4 @@
1
+ Feature: woo yeah
2
+
3
+ Background:
4
+ Given passing step without a table
@@ -72,6 +72,7 @@ Feature: backgrounds
72
72
  When I run cucumber -q features/background/failing_background.feature --require features
73
73
  Then it should fail with
74
74
  """
75
+ @after_file
75
76
  Feature: Failing background sample
76
77
 
77
78
  Background:
@@ -79,7 +80,7 @@ Feature: backgrounds
79
80
  FAIL (RuntimeError)
80
81
  ./features/step_definitions/sample_steps.rb:2:in `flunker'
81
82
  ./features/step_definitions/sample_steps.rb:16:in `/^failing without a table$/'
82
- features/background/failing_background.feature:4:in `Given failing without a table'
83
+ features/background/failing_background.feature:5:in `Given failing without a table'
83
84
  And '10' cukes
84
85
 
85
86
  Scenario: failing background
@@ -191,6 +191,36 @@ Feature: Cucumber command line
191
191
  When I stop procrastinating
192
192
  And there is world peace
193
193
 
194
+ Feature: multiline
195
+
196
+ Background: I'm a multiline name
197
+ which goes on and on and on for three lines
198
+ yawn
199
+ Given passing without a table
200
+
201
+ Scenario: I'm a multiline name
202
+ which goes on and on and on for three lines
203
+ yawn
204
+ Given passing without a table
205
+
206
+ Scenario Outline: I'm a multiline name
207
+ which goes on and on and on for three lines
208
+ yawn
209
+ Given <state> without a table
210
+
211
+ Examples:
212
+ | state |
213
+ | passing |
214
+
215
+ Scenario Outline: name
216
+ Given <state> without a table
217
+
218
+ Examples: I'm a multiline name
219
+ which goes on and on and on for three lines
220
+ yawn
221
+ | state |
222
+ | passing |
223
+
194
224
  Feature: Outline Sample
195
225
 
196
226
  Scenario: I have no steps
@@ -229,6 +259,31 @@ Feature: Cucumber command line
229
259
  hello
230
260
  \"\"\"
231
261
 
262
+ Feature: search examples
263
+
264
+ Background: Hantu Pisang background match
265
+ Given passing without a table
266
+
267
+ Scenario: should match Hantu Pisang
268
+ Given passing without a table
269
+
270
+ Scenario: Ignore me
271
+ Given failing without a table
272
+
273
+ Scenario Outline: Ignore me
274
+ Given <state> without a table
275
+
276
+ Examples:
277
+ | state |
278
+ | failing |
279
+
280
+ Scenario Outline: Hantu Pisang match
281
+ Given <state> without a table
282
+
283
+ Examples:
284
+ | state |
285
+ | passing |
286
+
232
287
  Feature: undefined multiline args
233
288
 
234
289
  Scenario: pystring
@@ -242,8 +297,8 @@ Feature: Cucumber command line
242
297
  | table |
243
298
  | example |
244
299
 
245
- 14 scenarios
246
- 12 skipped steps
300
+ 21 scenarios
301
+ 26 skipped steps
247
302
  9 undefined steps
248
303
 
249
304
  """
@@ -274,24 +329,45 @@ Feature: Cucumber command line
274
329
 
275
330
  """
276
331
 
277
- Scenario: Run scenario specified by name using --scenario
278
- When I run cucumber --scenario Passing -q features
332
+ Scenario: Run feature elements which matches a name using --name
333
+ When I run cucumber --name Pisang -q features/
279
334
  Then it should pass with
280
335
  """
281
- @one
282
- Feature: Sample
336
+ Feature: search examples
283
337
 
284
- @three
285
- Scenario: Passing
286
- Given passing
287
- | a | b |
288
- | c | d |
338
+ Background: Hantu Pisang background match
339
+ Given passing without a table
289
340
 
290
- 1 scenario
341
+ Scenario: should match Hantu Pisang
342
+ Given passing without a table
343
+
344
+ Scenario Outline: Hantu Pisang match
345
+ Given <state> without a table
346
+
347
+ Examples:
348
+ | state |
349
+ | passing |
350
+
351
+ 2 scenarios
352
+ 4 passed steps
353
+
354
+ """
355
+
356
+ Scenario: Run a single background which matches a name using --name
357
+ When I run cucumber --name 'Hantu Pisang background' -q features/
358
+ Then it should pass with
359
+ """
360
+ Feature: search examples
361
+
362
+ Background: Hantu Pisang background match
363
+ Given passing without a table
364
+
365
+ 0 scenarios
291
366
  1 passed step
292
367
 
293
368
  """
294
369
 
370
+
295
371
  Scenario: Run with a tag that exists on 2 scenarios
296
372
  When I run cucumber -q features --tags three
297
373
  Then it should pass with
@@ -2,6 +2,38 @@ Feature: Cucumber command line
2
2
  In order to write better software
3
3
  Developers should be able to execute requirements as tests
4
4
 
5
+ Scenario: Run scenario outline with filtering on outline name
6
+ When I run cucumber -q features --name "Test state"
7
+ Then it should fail with
8
+ """
9
+ Feature: Outline Sample
10
+
11
+ Scenario Outline: Test state
12
+ Given <state> without a table
13
+ Given <other_state> without a table
14
+
15
+ Examples: Rainbow colours
16
+ | state | other_state |
17
+ | missing | passing |
18
+ | passing | passing |
19
+ | failing | passing |
20
+ FAIL (RuntimeError)
21
+ ./features/step_definitions/sample_steps.rb:2:in `flunker'
22
+ ./features/step_definitions/sample_steps.rb:16:in `/^failing without a table$/'
23
+ features/outline_sample.feature:6:in `Given <state> without a table'
24
+
25
+ Examples: Only passing
26
+ | state | other_state |
27
+ | passing | passing |
28
+
29
+ 4 scenarios
30
+ 1 failed step
31
+ 2 skipped steps
32
+ 1 undefined step
33
+ 4 passed steps
34
+
35
+ """
36
+
5
37
  Scenario: Run scenario outline steps only
6
38
  When I run cucumber -q features/outline_sample.feature:7
7
39
  Then it should fail with
@@ -4,8 +4,8 @@ Feature: Custom Formatter
4
4
  When I run cucumber --format Tag::Count features
5
5
  Then it should fail with
6
6
  """
7
- | four | lots | one | three | two |
8
- | 1 | 1 | 1 | 2 | 1 |
7
+ | after_file | four | lots | one | three | two |
8
+ | 1 | 1 | 1 | 1 | 2 | 1 |
9
9
 
10
10
  """
11
11
 
@@ -0,0 +1,43 @@
1
+ Feature: Multiline description names
2
+ In order to accurately document feature elements
3
+ As a cucumberist
4
+ I want to have multiline names
5
+
6
+ Scenario: multiline scenario
7
+ When I run cucumber features/multiline_name.feature --no-snippets
8
+ Then it should pass with
9
+ """
10
+ Feature: multiline
11
+
12
+ Background: I'm a multiline name # features/multiline_name.feature:3
13
+ which goes on and on and on for three lines
14
+ yawn
15
+ Given passing without a table # features/step_definitions/sample_steps.rb:12
16
+
17
+ Scenario: I'm a multiline name # features/multiline_name.feature:8
18
+ which goes on and on and on for three lines
19
+ yawn
20
+ Given passing without a table # features/step_definitions/sample_steps.rb:12
21
+
22
+ Scenario Outline: I'm a multiline name # features/multiline_name.feature:13
23
+ which goes on and on and on for three lines
24
+ yawn
25
+ Given <state> without a table # features/step_definitions/sample_steps.rb:12
26
+
27
+ Examples:
28
+ | state |
29
+ | passing |
30
+
31
+ Scenario Outline: name # features/multiline_name.feature:21
32
+ Given <state> without a table # features/step_definitions/sample_steps.rb:12
33
+
34
+ Examples: I'm a multiline name
35
+ which goes on and on and on for three lines
36
+ yawn
37
+ | state |
38
+ | passing |
39
+
40
+ 3 scenarios
41
+ 6 passed steps
42
+
43
+ """
@@ -23,7 +23,7 @@ Feature: Cucumber command line
23
23
  2 scenarios
24
24
  2 undefined steps
25
25
 
26
- You can implement step definitions for missing steps with these snippets:
26
+ You can implement step definitions for undefined steps with these snippets:
27
27
 
28
28
  Given /^this does not exist$/ do
29
29
  pending
@@ -9,18 +9,27 @@ Feature: Cucumber command line
9
9
  """
10
10
  /^passing without a table$/ # features/step_definitions/sample_steps.rb:12
11
11
  Given passing without a table # features/background/failing_background_after_success.feature:4
12
+ Given passing without a table # features/multiline_name.feature:6
13
+ Given passing without a table # features/multiline_name.feature:11
14
+ Given <state> without a table # features/multiline_name.feature:16
15
+ Given <state> without a table # features/multiline_name.feature:22
12
16
  Given <state> without a table # features/outline_sample.feature:6
13
17
  Given <other_state> without a table # features/outline_sample.feature:7
18
+ Given passing without a table # features/search_sample.feature:4
19
+ Given passing without a table # features/search_sample.feature:7
20
+ Given <state> without a table # features/search_sample.feature:19
14
21
  /^failing without a table$/ # features/step_definitions/sample_steps.rb:15
15
- Given failing without a table # features/background/failing_background.feature:4
22
+ Given failing without a table # features/background/failing_background.feature:5
16
23
  Given failing without a table # features/background/scenario_outline_failing_background.feature:4
24
+ Given failing without a table # features/search_sample.feature:10
25
+ Given <state> without a table # features/search_sample.feature:13
17
26
  /^a step definition that calls an undefined step$/ # features/step_definitions/sample_steps.rb:19
18
27
  Given a step definition that calls an undefined step # features/call_undefined_step_from_step_def.feature:4
19
28
  /^call step "(.*)"$/ # features/step_definitions/sample_steps.rb:23
20
29
  Given call step "a step definition that calls an undefined step" # features/call_undefined_step_from_step_def.feature:7
21
30
  /^'(.+)' cukes$/ # features/step_definitions/sample_steps.rb:27
22
31
  Given '10' cukes # features/background/background_with_name.feature:4
23
- And '10' cukes # features/background/failing_background.feature:5
32
+ And '10' cukes # features/background/failing_background.feature:6
24
33
  Given '10' cukes # features/background/passing_background.feature:4
25
34
  Given '10' cukes # features/background/scenario_outline_passing_background.feature:4
26
35
  Given '2' cukes # features/tons_of_cukes.feature:4
@@ -74,8 +83,8 @@ Feature: Cucumber command line
74
83
  Given '2' cukes # features/tons_of_cukes.feature:52
75
84
  /^I should have '(.+)' cukes$/ # features/step_definitions/sample_steps.rb:31
76
85
  Then I should have '10' cukes # features/background/background_with_name.feature:7
77
- Then I should have '10' cukes # features/background/failing_background.feature:8
78
- Then I should have '10' cukes # features/background/failing_background.feature:11
86
+ Then I should have '10' cukes # features/background/failing_background.feature:9
87
+ Then I should have '10' cukes # features/background/failing_background.feature:12
79
88
  Then I should have '10' cukes # features/background/passing_background.feature:7
80
89
  Then I should have '10' cukes # features/background/passing_background.feature:10
81
90
  Then I should have '10' cukes # features/background/pending_background.feature:7
@@ -4,12 +4,13 @@ module Cucumber
4
4
  module Ast
5
5
  class Background
6
6
  include FeatureElement
7
- attr_writer :feature
7
+ attr_reader :feature_elements
8
8
 
9
9
  def initialize(comment, line, keyword, name, steps)
10
10
  @comment, @line, @keyword, @name, @steps = comment, line, keyword, name, StepCollection.new(steps)
11
11
  attach_steps(steps)
12
12
  @step_invocations = @steps.step_invocations(true)
13
+ @feature_elements = []
13
14
  end
14
15
 
15
16
  def step_collection(step_invocations)
@@ -23,32 +24,28 @@ module Cucumber
23
24
 
24
25
  def accept(visitor)
25
26
  visitor.visit_comment(@comment)
26
- visitor.visit_background_name(@keyword, @name, file_colon_line(@line), source_indent(text_length))
27
- visitor.step_mother.before(self)
27
+ visitor.visit_background_name(@keyword, @name, file_colon_line(@line), source_indent(first_line_length))
28
+ visitor.step_mother.before(hook_context)
28
29
  visitor.visit_steps(@step_invocations)
29
30
  @failed = @step_invocations.detect{|step_invocation| step_invocation.exception}
30
- visitor.step_mother.after(self) if @failed
31
+ visitor.step_mother.after(hook_context) if @failed
31
32
  end
32
33
 
33
34
  def accept_hook?(hook)
34
- # TODO: When background is involved - no tag based hook filtering is occurring with
35
- # the current implementation. All hooks will be executed. This is because of the line
36
- # visitor.step_mother.before(self)
37
- # in the #accept method above. Instead, we should really be passing the first scenario
38
- # here. We currently don't have access to that, so a refactoring is in order to make that happen.
39
- true
35
+ false
40
36
  end
41
37
 
42
38
  def failed?
43
39
  @failed
44
40
  end
45
41
 
46
- def text_length
47
- @keyword.jlength
42
+ def hook_context
43
+ @feature_elements.first || self
48
44
  end
49
45
 
50
46
  def to_sexp
51
47
  sexp = [:background, @line, @keyword]
48
+ sexp += [@name] unless @name.empty?
52
49
  comment = @comment.to_sexp
53
50
  sexp += [comment] if comment
54
51
  steps = @steps.to_sexp
@@ -57,4 +54,4 @@ module Cucumber
57
54
  end
58
55
  end
59
56
  end
60
- end
57
+ end
@@ -8,6 +8,7 @@ module Cucumber
8
8
  def initialize(background, comment, tags, name, feature_elements)
9
9
  @background, @comment, @tags, @name, @feature_elements = background, comment, tags, name, feature_elements
10
10
 
11
+ background.feature = self if background
11
12
  @feature_elements.each do |feature_element|
12
13
  feature_element.feature = self
13
14
  end
@@ -23,6 +24,10 @@ module Cucumber
23
24
  end
24
25
  end
25
26
 
27
+ def accept_hook?(hook)
28
+ @tags.accept_hook?(hook)
29
+ end
30
+
26
31
  def next_feature_element(feature_element, &proc)
27
32
  index = @feature_elements.index(feature_element)
28
33
  next_one = @feature_elements[index+1]
@@ -1,5 +1,9 @@
1
+ require 'enumerator'
2
+
1
3
  module Cucumber
2
4
  module FeatureElement
5
+ attr_writer :feature
6
+
3
7
  def attach_steps(steps)
4
8
  steps.each {|step| step.feature_element = self}
5
9
  end
@@ -9,13 +13,27 @@ module Cucumber
9
13
  end
10
14
 
11
15
  def text_length
12
- @keyword.jlength + @name.jlength
16
+ name_line_lengths.max
17
+ end
18
+
19
+ def first_line_length
20
+ name_line_lengths[0]
13
21
  end
14
22
 
15
- def matches_scenario_names?(scenario_names)
16
- scenario_names.detect{|name| name == @name}
23
+ def name_line_lengths
24
+ if @name.empty?
25
+ [@keyword.jlength]
26
+ else
27
+ @name.split("\n").enum_for(:each_with_index).map do |line, line_number|
28
+ line_number == 0 ? @keyword.jlength + line.jlength : line.jlength + Ast::Step::INDENT - 1 # We -1 as names which are not keyword lines are missing a space between keyword and name
29
+ end
30
+ end
17
31
  end
18
32
 
33
+ def matches_scenario_names?(scenario_name_regexps)
34
+ scenario_name_regexps.detect{|name| name =~ @name}
35
+ end
36
+
19
37
  def backtrace_line(name = "#{@keyword} #{@name}", line = @line)
20
38
  @feature.backtrace_line(name, line) if @feature
21
39
  end
@@ -29,14 +47,7 @@ module Cucumber
29
47
  end
30
48
 
31
49
  def accept_hook?(hook)
32
- @tags.accept_hook?(hook)
33
- end
34
-
35
- # TODO: Remove when we use StepCollection everywhere
36
- def previous_step(step)
37
- i = @steps.index(step) || -1
38
- @steps[i-1]
50
+ @tags.accept_hook?(hook) || @feature.accept_hook?(hook)
39
51
  end
40
-
41
52
  end
42
- end
53
+ end