cucumber 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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