cucumber 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +7 -9
  3. data/History.md +295 -265
  4. data/README.md +9 -7
  5. data/cucumber.gemspec +2 -2
  6. data/features/docs/cli/dry_run.feature +0 -3
  7. data/features/docs/cli/finding_steps.feature +28 -0
  8. data/features/docs/cli/run_specific_scenarios.feature +3 -1
  9. data/features/docs/cli/specifying_multiple_formatters.feature +22 -1
  10. data/features/docs/defining_steps/nested_steps.feature +0 -1
  11. data/features/docs/defining_steps/printing_messages.feature +4 -4
  12. data/features/docs/defining_steps/skip_scenario.feature +0 -2
  13. data/features/docs/exception_in_around_hook.feature +1 -3
  14. data/features/docs/formatters/html_formatter.feature +1 -0
  15. data/features/docs/formatters/json_formatter.feature +73 -62
  16. data/features/docs/formatters/junit_formatter.feature +130 -38
  17. data/features/docs/formatters/rerun_formatter.feature +60 -8
  18. data/features/docs/formatters/usage_formatter.feature +3 -7
  19. data/features/docs/getting_started.feature +1 -1
  20. data/features/docs/gherkin/background.feature +0 -11
  21. data/features/docs/gherkin/language_help.feature +5 -0
  22. data/features/docs/gherkin/outlines.feature +1 -3
  23. data/features/docs/gherkin/using_descriptions.feature +0 -1
  24. data/features/docs/raketask.feature +1 -1
  25. data/features/docs/writing_support_code/after_hooks.feature +22 -0
  26. data/features/lib/step_definitions/aruba_steps.rb +4 -0
  27. data/features/lib/step_definitions/junit_steps.rb +1 -1
  28. data/features/lib/support/normalise_output.rb +21 -4
  29. data/lib/cucumber/cli/configuration.rb +16 -13
  30. data/lib/cucumber/cli/main.rb +35 -10
  31. data/lib/cucumber/cli/options.rb +33 -9
  32. data/lib/cucumber/cli/rerun_file.rb +29 -0
  33. data/lib/cucumber/filters/prepare_world.rb +2 -3
  34. data/lib/cucumber/formatter/backtrace_filter.rb +40 -0
  35. data/lib/cucumber/formatter/console.rb +2 -3
  36. data/lib/cucumber/formatter/cucumber.css +1 -0
  37. data/lib/cucumber/formatter/duration_extractor.rb +28 -0
  38. data/lib/cucumber/formatter/hook_query_visitor.rb +40 -0
  39. data/lib/cucumber/formatter/html.rb +16 -1
  40. data/lib/cucumber/formatter/json.rb +287 -8
  41. data/lib/cucumber/formatter/junit.rb +92 -143
  42. data/lib/cucumber/formatter/legacy_api/adapter.rb +18 -54
  43. data/lib/cucumber/formatter/legacy_api/ast.rb +13 -0
  44. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +4 -0
  45. data/lib/cucumber/formatter/pretty.rb +2 -1
  46. data/lib/cucumber/formatter/progress.rb +20 -53
  47. data/lib/cucumber/formatter/rerun.rb +2 -1
  48. data/lib/cucumber/formatter/usage.rb +16 -22
  49. data/lib/cucumber/hooks.rb +18 -9
  50. data/lib/cucumber/multiline_argument/data_table.rb +40 -28
  51. data/lib/cucumber/platform.rb +1 -1
  52. data/lib/cucumber/rb_support/rb_hook.rb +4 -0
  53. data/lib/cucumber/running_test_case.rb +13 -4
  54. data/lib/cucumber/runtime/after_hooks.rb +7 -6
  55. data/lib/cucumber/runtime/before_hooks.rb +8 -4
  56. data/lib/cucumber/runtime/step_hooks.rb +5 -4
  57. data/lib/cucumber/runtime/support_code.rb +6 -15
  58. data/lib/cucumber/step_match.rb +1 -1
  59. data/spec/cucumber/cli/configuration_spec.rb +32 -5
  60. data/spec/cucumber/cli/main_spec.rb +3 -3
  61. data/spec/cucumber/cli/options_spec.rb +60 -1
  62. data/spec/cucumber/cli/rerun_spec.rb +89 -0
  63. data/spec/cucumber/formatter/html_spec.rb +84 -5
  64. data/spec/cucumber/formatter/json_spec.rb +757 -0
  65. data/spec/cucumber/formatter/junit_spec.rb +5 -5
  66. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +69 -8
  67. data/spec/cucumber/formatter/pretty_spec.rb +96 -0
  68. data/spec/cucumber/formatter/progress_spec.rb +85 -1
  69. data/spec/cucumber/formatter/rerun_spec.rb +3 -3
  70. data/spec/cucumber/multiline_argument/data_table_spec.rb +89 -0
  71. data/spec/cucumber/running_test_case_spec.rb +57 -1
  72. metadata +70 -60
  73. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +0 -204
  74. data/lib/cucumber/formatter/gpretty.rb +0 -24
@@ -2,7 +2,7 @@ Feature: Rerun formatter
2
2
 
3
3
  The rerun formatter writes an output that's perfect for
4
4
  passing to Cucumber when you want to rerun only the
5
- scenarios that have failed.
5
+ scenarios that prevented the exit code to be zero.
6
6
 
7
7
  You can save off the rerun output to a file by using it like this:
8
8
 
@@ -18,7 +18,28 @@ Feature: Rerun formatter
18
18
  Background:
19
19
  Given the standard step definitions
20
20
 
21
- Scenario: Regular scenarios
21
+ Scenario: Exit code is zero
22
+ Given a file named "features/mixed.feature" with:
23
+ """
24
+ Feature: Mixed
25
+
26
+ Scenario:
27
+ Given this step is undefined
28
+
29
+ Scenario:
30
+ Given this step is pending
31
+
32
+ Scenario:
33
+ Given this step passes
34
+
35
+ """
36
+
37
+ When I run `cucumber -f rerun`
38
+ Then it should pass with exactly:
39
+ """
40
+ """
41
+
42
+ Scenario: Exit code is zero in the dry-run mode
22
43
  Given a file named "features/mixed.feature" with:
23
44
  """
24
45
  Feature: Mixed
@@ -44,13 +65,44 @@ Feature: Rerun formatter
44
65
  Given this step passes
45
66
  """
46
67
 
47
- When I run `cucumber -f rerun`
48
- Then it should fail with:
68
+ When I run `cucumber -f rerun --dry-run`
69
+ Then it should pass with exactly:
70
+ """
71
+ """
72
+
73
+ Scenario: Exit code is not zero, regular scenario
74
+ Given a file named "features/mixed.feature" with:
75
+ """
76
+ Feature: Mixed
77
+
78
+ Scenario:
79
+ Given this step fails
80
+
81
+ Scenario:
82
+ Given this step is undefined
83
+
84
+ Scenario:
85
+ Given this step is pending
86
+
87
+ Scenario:
88
+ Given this step passes
89
+
90
+ """
91
+ And a file named "features/all_good.feature" with:
92
+ """
93
+ Feature: All good
94
+
95
+ Scenario:
96
+ Given this step passes
97
+ """
98
+
99
+ When I run `cucumber -f rerun --strict`
100
+ Then it should fail with exactly:
49
101
  """
50
102
  features/mixed.feature:3:6:9
51
103
  """
52
104
 
53
- Scenario: Scenario outlines
105
+ Scenario: Exit code is not zero, scenario outlines
54
106
  For details see https://github.com/cucumber/cucumber/issues/57
55
107
  Given a file named "features/one_passing_one_failing.feature" with:
56
108
  """
@@ -71,7 +123,7 @@ Feature: Rerun formatter
71
123
  features/one_passing_one_failing.feature:9
72
124
  """
73
125
 
74
- Scenario: Failing background
126
+ Scenario: Exit code is not zero, failing background
75
127
  Given a file named "features/failing_background.feature" with:
76
128
  """
77
129
  Feature: Failing background sample
@@ -91,7 +143,7 @@ Feature: Rerun formatter
91
143
  features/failing_background.feature:6:9
92
144
  """
93
145
 
94
- Scenario: Failing background with scenario outline
146
+ Scenario: Exit code is not zero, failing background with scenario outline
95
147
  Given a file named "features/failing_background_outline.feature" with:
96
148
  """
97
149
  Feature: Failing background sample with scenario outline
@@ -113,7 +165,7 @@ Feature: Rerun formatter
113
165
  features/failing_background_outline.feature:11:12
114
166
  """
115
167
 
116
- Scenario: Scenario outlines with expand
168
+ Scenario: Exit code is not zero, scenario outlines with expand
117
169
  For details see https://github.com/cucumber/cucumber/issues/503
118
170
 
119
171
  Given a file named "features/one_passing_one_failing.feature" with:
@@ -30,12 +30,11 @@ Feature: Usage formatter
30
30
  Given(/D/) { }
31
31
  """
32
32
 
33
- @wip-new-core
34
33
  Scenario: Run with --format usage
35
34
  When I run `cucumber -f usage --dry-run`
36
35
  Then it should pass with exactly:
37
36
  """
38
- --------
37
+ -----------
39
38
 
40
39
  /A/ # features/step_definitions/steps.rb:1
41
40
  Given A # features/f.feature:3
@@ -53,7 +52,6 @@ Feature: Usage formatter
53
52
 
54
53
  4 scenarios (4 skipped)
55
54
  11 steps (11 skipped)
56
- 0m0.012s
57
55
 
58
56
  """
59
57
 
@@ -61,7 +59,7 @@ Feature: Usage formatter
61
59
  When I run `cucumber -x -f usage --dry-run`
62
60
  Then it should pass with exactly:
63
61
  """
64
- ----------
62
+ -----------
65
63
 
66
64
  /A/ # features/step_definitions/steps.rb:1
67
65
  Given A # features/f.feature:3
@@ -79,7 +77,6 @@ Feature: Usage formatter
79
77
 
80
78
  4 scenarios (4 skipped)
81
79
  11 steps (11 skipped)
82
- 0m0.012s
83
80
 
84
81
  """
85
82
 
@@ -87,7 +84,7 @@ Feature: Usage formatter
87
84
  When I run `cucumber -f stepdefs --dry-run`
88
85
  Then it should pass with exactly:
89
86
  """
90
- --------
87
+ -----------
91
88
 
92
89
  /A/ # features/step_definitions/steps.rb:1
93
90
  /B/ # features/step_definitions/steps.rb:2
@@ -97,6 +94,5 @@ Feature: Usage formatter
97
94
 
98
95
  4 scenarios (4 skipped)
99
96
  11 steps (11 skipped)
100
- 0m0.012s
101
97
 
102
98
  """
@@ -19,7 +19,7 @@ Feature: Getting started
19
19
  puts 'this will not be shown'
20
20
  """
21
21
  When I run `cucumber`
22
- Then the exit status should be 1
22
+ Then the exit status should be 2
23
23
  And the output should not contain:
24
24
  """
25
25
  this will not be shown
@@ -222,7 +222,6 @@ Feature: Background
222
222
 
223
223
  1 scenario (1 passed)
224
224
  2 steps (2 passed)
225
- 0m0.012s
226
225
 
227
226
  """
228
227
 
@@ -243,7 +242,6 @@ Feature: Background
243
242
 
244
243
  2 scenarios (2 passed)
245
244
  4 steps (4 passed)
246
- 0m0.012s
247
245
 
248
246
  """
249
247
 
@@ -272,7 +270,6 @@ Feature: Background
272
270
 
273
271
  2 scenarios (2 passed)
274
272
  4 steps (4 passed)
275
- 0m0.012s
276
273
 
277
274
  """
278
275
 
@@ -295,7 +292,6 @@ Feature: Background
295
292
 
296
293
  1 scenario (1 passed)
297
294
  2 steps (2 passed)
298
- 0m0.012s
299
295
 
300
296
  """
301
297
 
@@ -325,7 +321,6 @@ Feature: Background
325
321
 
326
322
  2 scenarios (2 failed)
327
323
  6 steps (2 failed, 4 skipped)
328
- 0m0.012s
329
324
 
330
325
  """
331
326
 
@@ -362,7 +357,6 @@ Feature: Background
362
357
 
363
358
  2 scenarios (2 failed)
364
359
  4 steps (2 failed, 2 skipped)
365
- 0m0.012s
366
360
 
367
361
  """
368
362
 
@@ -386,7 +380,6 @@ Feature: Background
386
380
 
387
381
  2 scenarios (2 pending)
388
382
  4 steps (2 skipped, 2 pending)
389
- 0m0.012s
390
383
 
391
384
  """
392
385
 
@@ -416,7 +409,6 @@ Feature: Background
416
409
 
417
410
  2 scenarios (1 failed, 1 passed)
418
411
  6 steps (1 failed, 1 skipped, 4 passed)
419
- 0m0.012s
420
412
 
421
413
  """
422
414
 
@@ -453,7 +445,6 @@ Feature: Background
453
445
 
454
446
  2 scenarios (1 failed, 1 passed)
455
447
  6 steps (1 failed, 1 skipped, 4 passed)
456
- 0m0.012s
457
448
 
458
449
  """
459
450
 
@@ -493,7 +484,6 @@ Feature: Background
493
484
 
494
485
  2 scenarios (1 failed, 1 passed)
495
486
  6 steps (1 failed, 1 skipped, 4 passed)
496
- 0m0.012s
497
487
 
498
488
  """
499
489
 
@@ -553,7 +543,6 @@ Feature: Background
553
543
 
554
544
  2 scenarios (2 passed)
555
545
  8 steps (8 passed)
556
- 0m0.012s
557
546
 
558
547
  """
559
548
 
@@ -35,3 +35,8 @@ Feature: Language help
35
35
  Scenario: List languages
36
36
  When I run `cucumber --i18n help`
37
37
  Then cucumber lists all the supported languages
38
+
39
+ Scenario: Seek help for invalid language
40
+ When I run `cucumber --i18n foo`
41
+ Then the output includes the message "Invalid language 'foo'"
42
+ And cucumber lists all the supported languages
@@ -138,7 +138,7 @@ Feature: Scenario outlines
138
138
  When I run `cucumber -q --format progress features/outline_sample.feature`
139
139
  Then it should fail with exactly:
140
140
  """
141
- --UU..FF..
141
+ U-..F-..
142
142
 
143
143
  (::) failed steps (::)
144
144
 
@@ -152,7 +152,5 @@ Feature: Scenario outlines
152
152
 
153
153
  5 scenarios (1 failed, 1 undefined, 3 passed)
154
154
  8 steps (1 failed, 2 skipped, 1 undefined, 4 passed)
155
- 0m0.012s
156
155
 
157
156
  """
158
-
@@ -83,6 +83,5 @@ Feature: Using descriptions to give features context
83
83
 
84
84
  2 scenarios (2 passed)
85
85
  4 steps (4 passed)
86
- 0m0.012s
87
86
 
88
87
  """
@@ -40,5 +40,5 @@ Feature: Raketask
40
40
 
41
41
  Scenario: Failing feature
42
42
  When I run `bundle exec rake fail`
43
- Then the exit status should not be 0
43
+ Then the exit status should be 1
44
44
  But the output should not contain "rake aborted!"
@@ -11,6 +11,28 @@ Feature: After Hooks
11
11
  Background:
12
12
  Given the standard step definitions
13
13
 
14
+ Scenario Outline: Retrieve the status of a scenario as a symbol
15
+ Given a file named "features/support/debug_hook.rb" with:
16
+ """
17
+ After do |scenario|
18
+ puts scenario.status.inspect
19
+ end
20
+ """
21
+ And a file named "features/result.feature" with:
22
+ """
23
+ Feature:
24
+ Scenario:
25
+ Given this step <result>
26
+ """
27
+ When I run `cucumber -f progress`
28
+ Then the output should contain "<status symbol>"
29
+
30
+ Examples:
31
+ | result | status symbol |
32
+ | passes | :passed |
33
+ | fails | :failed |
34
+ | is pending | :pending |
35
+
14
36
  Scenario: Check the failed status of a scenario in a hook
15
37
  Given a file named "features/support/debug_hook.rb" with:
16
38
  """
@@ -20,3 +20,7 @@ Then /^it fails before running features with:$/ do |expected|
20
20
  assert_matching_output("\\A#{expected}", all_output)
21
21
  assert_success(false)
22
22
  end
23
+
24
+ Then(/^the output includes the message "(.*)"$/) do |message|
25
+ expect(all_output).to include(message)
26
+ end
@@ -1,7 +1,7 @@
1
1
  Then(/^the junit output file "(.*?)" should contain:$/) do |actual_file, text|
2
2
  actual = IO.read(current_dir + '/' + actual_file)
3
3
  actual = replace_junit_time(actual)
4
- expect(actual).to eq text.to_s
4
+ expect(actual).to eq text
5
5
  end
6
6
 
7
7
  module JUnitHelper
@@ -19,15 +19,32 @@ module NormaliseArubaOutput
19
19
  elements = feature.fetch('elements') { [] }
20
20
  elements.each do |scenario|
21
21
  scenario['steps'].each do |step|
22
- if step['result']
23
- expect(step['result']['duration']).to be >= 0
24
- step['result']['duration'] = 1
22
+ ['steps', 'before', 'after'].each do |type|
23
+ if scenario[type]
24
+ scenario[type].each do |step_or_hook|
25
+ normalise_json_step_or_hook(step_or_hook)
26
+ if step_or_hook['after']
27
+ step_or_hook['after'].each do |hook|
28
+ normalise_json_step_or_hook(hook)
29
+ end
30
+ end
31
+ end
32
+ end
25
33
  end
26
34
  end
27
35
  end
28
36
  end
29
37
  end
38
+
39
+ def normalise_json_step_or_hook(step_or_hook)
40
+ if step_or_hook['result']
41
+ if step_or_hook['result']['duration']
42
+ expect(step_or_hook['result']['duration']).to be >= 0
43
+ step_or_hook['result']['duration'] = 1
44
+ end
45
+ end
46
+ end
47
+
30
48
  end
31
49
 
32
50
  World(NormaliseArubaOutput)
33
-
@@ -1,5 +1,6 @@
1
1
  require 'logger'
2
2
  require 'cucumber/cli/options'
3
+ require 'cucumber/cli/rerun_file'
3
4
  require 'cucumber/constantize'
4
5
  require 'gherkin/tag_expression'
5
6
 
@@ -75,8 +76,7 @@ module Cucumber
75
76
  end
76
77
 
77
78
  def all_files_to_load
78
- requires = @options[:require].empty? ? require_dirs : @options[:require]
79
- files = requires.map do |path|
79
+ files = require_dirs.map do |path|
80
80
  path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
81
81
  path = path.gsub(/\/$/, '') # Strip trailing slash.
82
82
  File.directory?(path) ? Dir["#{path}/**/*"] : path
@@ -105,9 +105,8 @@ module Cucumber
105
105
  path = path.chomp('/')
106
106
  if File.directory?(path)
107
107
  Dir["#{path}/**/*.feature"].sort
108
- elsif path[0..0] == '@' and # @listfile.txt
109
- File.file?(path[1..-1]) # listfile.txt is a file
110
- IO.read(path[1..-1]).split(/(.*?\.feature.*?) /).collect(&:strip).reject(&:empty?)
108
+ elsif RerunFile.can_read?(path)
109
+ RerunFile.new(path).features
111
110
  else
112
111
  path
113
112
  end
@@ -116,6 +115,7 @@ module Cucumber
116
115
  potential_feature_files
117
116
  end
118
117
 
118
+
119
119
  def feature_dirs
120
120
  dirs = paths.map { |f| File.directory?(f) ? f : File.dirname(f) }.uniq
121
121
  dirs.delete('.') unless paths.include?('.')
@@ -180,8 +180,12 @@ module Cucumber
180
180
 
181
181
  private
182
182
 
183
+ def default_features_paths
184
+ ["features"]
185
+ end
186
+
183
187
  def with_default_features_path(paths)
184
- return ['features'] if paths.empty?
188
+ return default_features_paths if paths.empty?
185
189
  paths
186
190
  end
187
191
 
@@ -201,10 +205,7 @@ module Cucumber
201
205
  @options[:formats] << ['pretty', @out_stream] if @options[:formats].empty?
202
206
  @options[:formats] = @options[:formats].sort_by{|f| f[1] == @out_stream ? -1 : 1}
203
207
  @options[:formats].uniq!
204
- streams = @options[:formats].map { |(_, stream)| stream }
205
- if streams != streams.uniq
206
- raise "All but one formatter must use --out, only one can print to each stream (or STDOUT)"
207
- end
208
+ @options.check_formatter_stream_conflicts()
208
209
  end
209
210
 
210
211
  def remove_excluded_files_from(files)
@@ -212,10 +213,12 @@ module Cucumber
212
213
  end
213
214
 
214
215
  def require_dirs
215
- feature_dirs + Dir['vendor/{gems,plugins}/*/cucumber']
216
+ if @options[:require].empty?
217
+ default_features_paths + Dir['vendor/{gems,plugins}/*/cucumber']
218
+ else
219
+ @options[:require]
220
+ end
216
221
  end
217
-
218
222
  end
219
-
220
223
  end
221
224
  end