cucumber 2.0.0 → 2.0.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 (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
@@ -59,7 +59,7 @@ module Cucumber
59
59
  end
60
60
  end
61
61
 
62
- it { expect(@doc.xpath('//testsuite/system-out').first.content).to match(/\s+boo boo\s+/) }
62
+ it { expect(@doc.xpath('//testsuite/testcase/system-out').first.content).to match(/\s+boo boo\s+/) }
63
63
  end
64
64
 
65
65
  describe "a feature with no name" do
@@ -92,12 +92,12 @@ module Cucumber
92
92
 
93
93
  it { expect(@doc.to_s).to match /One passing scenario, one failing scenario/ }
94
94
 
95
- it 'has a root system-out node' do
96
- expect(@doc.xpath('//testsuite/system-out').size).to eq 1
95
+ it 'has not a root system-out node' do
96
+ expect(@doc.xpath('//testsuite/system-out').size).to eq 0
97
97
  end
98
98
 
99
- it 'has a root system-err node' do
100
- expect(@doc.xpath('//testsuite/system-err').size).to eq 1
99
+ it 'has not a root system-err node' do
100
+ expect(@doc.xpath('//testsuite/system-err').size).to eq 0
101
101
  end
102
102
 
103
103
  it 'has a system-out node under <testcase/>' do
@@ -42,9 +42,23 @@ module Cucumber
42
42
  end
43
43
  end
44
44
 
45
+ class HookWrapper
46
+ def initialize(proc)
47
+ @proc = proc
48
+ end
49
+
50
+ def source_location
51
+ @proc.source_location
52
+ end
53
+
54
+ def invoke(pseudo_method, arguments, &block)
55
+ @proc.call
56
+ end
57
+ end
58
+
45
59
  class AddBeforeAndAfterHooks < Core::Filter.new
46
60
  def test_case(test_case)
47
- steps = before_hooks(test_case.source) +
61
+ steps = before_hooks(test_case.source) +
48
62
  test_case.test_steps +
49
63
  after_hooks(test_case.source)
50
64
  test_case.with_steps(steps).describe_to receiver
@@ -55,12 +69,14 @@ module Cucumber
55
69
  def before_hooks(source)
56
70
  # The adapter is built on the assumption that each test case will have at least one step. This is annoying
57
71
  # for tests, but a safe assumption for production use as we always add one hook to initialize the world.
58
- [ Hooks.before_hook(source) {} ]
72
+ hook = proc {}
73
+ [ Hooks.before_hook(source, Hooks.location(hook), &hook) ]
59
74
  end
60
75
 
61
76
  def after_hooks(source)
62
77
  # We add an after hook to make sure the adapter can cope with it
63
- [ Hooks.after_hook(source) {} ]
78
+ hook = proc {}
79
+ [ Hooks.after_hook(source, Hooks.location(hook), &hook) ]
64
80
  end
65
81
  end
66
82
 
@@ -454,6 +470,8 @@ module Cucumber
454
470
  :after_steps,
455
471
  :before_examples_array,
456
472
  :before_examples,
473
+ :before_tags,
474
+ :after_tags,
457
475
  :examples_name,
458
476
  :before_outline_table,
459
477
  :before_table_row,
@@ -522,6 +540,8 @@ module Cucumber
522
540
  :after_steps,
523
541
  :before_examples_array,
524
542
  :before_examples,
543
+ :before_tags,
544
+ :after_tags,
525
545
  :examples_name,
526
546
  :before_outline_table,
527
547
  :before_table_row,
@@ -606,6 +626,8 @@ module Cucumber
606
626
  :after_steps,
607
627
  :before_examples_array,
608
628
  :before_examples,
629
+ :before_tags,
630
+ :after_tags,
609
631
  :examples_name,
610
632
  :before_outline_table,
611
633
  :before_table_row,
@@ -635,6 +657,8 @@ module Cucumber
635
657
  :after_steps,
636
658
  :before_examples_array,
637
659
  :before_examples,
660
+ :before_tags,
661
+ :after_tags,
638
662
  :examples_name,
639
663
  :before_outline_table,
640
664
  :before_table_row,
@@ -701,6 +725,8 @@ module Cucumber
701
725
  :after_steps,
702
726
  :before_examples_array,
703
727
  :before_examples,
728
+ :before_tags,
729
+ :after_tags,
704
730
  :examples_name,
705
731
  :before_outline_table,
706
732
  :before_table_row,
@@ -775,6 +801,8 @@ module Cucumber
775
801
  :after_steps,
776
802
  :before_examples_array,
777
803
  :before_examples,
804
+ :before_tags,
805
+ :after_tags,
778
806
  :examples_name,
779
807
  :before_outline_table,
780
808
  :before_table_row,
@@ -790,6 +818,8 @@ module Cucumber
790
818
  :after_outline_table,
791
819
  :after_examples,
792
820
  :before_examples,
821
+ :before_tags,
822
+ :after_tags,
793
823
  :examples_name,
794
824
  :before_outline_table,
795
825
  :before_table_row,
@@ -936,6 +966,8 @@ module Cucumber
936
966
  :after_steps,
937
967
  :before_examples_array,
938
968
  :before_examples,
969
+ :before_tags,
970
+ :after_tags,
939
971
  :examples_name,
940
972
  :before_outline_table,
941
973
  :before_table_row,
@@ -1003,6 +1035,8 @@ module Cucumber
1003
1035
  :after_steps,
1004
1036
  :before_examples_array,
1005
1037
  :before_examples,
1038
+ :before_tags,
1039
+ :after_tags,
1006
1040
  :examples_name,
1007
1041
  :before_outline_table,
1008
1042
  :before_table_row,
@@ -1058,6 +1092,8 @@ module Cucumber
1058
1092
  :after_steps,
1059
1093
  :before_examples_array,
1060
1094
  :before_examples,
1095
+ :before_tags,
1096
+ :after_tags,
1061
1097
  :examples_name,
1062
1098
  :before_outline_table,
1063
1099
  :before_table_row,
@@ -1123,6 +1159,8 @@ module Cucumber
1123
1159
  :after_steps,
1124
1160
  :before_examples_array,
1125
1161
  :before_examples,
1162
+ :before_tags,
1163
+ :after_tags,
1126
1164
  :examples_name,
1127
1165
  :before_outline_table,
1128
1166
  :before_table_row,
@@ -1184,6 +1222,8 @@ module Cucumber
1184
1222
  :after_steps,
1185
1223
  :before_examples_array,
1186
1224
  :before_examples,
1225
+ :before_tags,
1226
+ :after_tags,
1187
1227
  :examples_name,
1188
1228
  :before_outline_table,
1189
1229
  :before_table_row,
@@ -1199,6 +1239,8 @@ module Cucumber
1199
1239
  :after_outline_table,
1200
1240
  :after_examples,
1201
1241
  :before_examples,
1242
+ :before_tags,
1243
+ :after_tags,
1202
1244
  :examples_name,
1203
1245
  :before_outline_table,
1204
1246
  :before_table_row,
@@ -1258,6 +1300,8 @@ module Cucumber
1258
1300
  :after_steps,
1259
1301
  :before_examples_array,
1260
1302
  :before_examples,
1303
+ :before_tags,
1304
+ :after_tags,
1261
1305
  :examples_name,
1262
1306
  :before_outline_table,
1263
1307
  :before_table_row,
@@ -1287,6 +1331,8 @@ module Cucumber
1287
1331
  :after_steps,
1288
1332
  :before_examples_array,
1289
1333
  :before_examples,
1334
+ :before_tags,
1335
+ :after_tags,
1290
1336
  :examples_name,
1291
1337
  :before_outline_table,
1292
1338
  :before_table_row,
@@ -1339,6 +1385,8 @@ module Cucumber
1339
1385
  :after_steps,
1340
1386
  :before_examples_array,
1341
1387
  :before_examples,
1388
+ :before_tags,
1389
+ :after_tags,
1342
1390
  :examples_name,
1343
1391
  :before_outline_table,
1344
1392
  :before_table_row,
@@ -1456,6 +1504,8 @@ module Cucumber
1456
1504
  :after_steps,
1457
1505
  :before_examples_array,
1458
1506
  :before_examples,
1507
+ :before_tags,
1508
+ :after_tags,
1459
1509
  :examples_name,
1460
1510
  :before_outline_table,
1461
1511
  :scenario_name,
@@ -1484,7 +1534,8 @@ module Cucumber
1484
1534
 
1485
1535
  class FailingAfterStepHook
1486
1536
  def find_after_step_hooks(test_case)
1487
- Runtime::StepHooks.new [-> { raise Failure }]
1537
+ failing_hook = HookWrapper.new(proc { raise Failure })
1538
+ Runtime::StepHooks.new [failing_hook]
1488
1539
  end
1489
1540
  end
1490
1541
 
@@ -1529,7 +1580,8 @@ module Cucumber
1529
1580
  context 'with exception in a single before hook' do
1530
1581
  class FailingBeforeHook
1531
1582
  def apply_before_hooks(test_case)
1532
- Runtime::BeforeHooks.new([proc { raise Failure }]).apply_to(test_case)
1583
+ failing_hook = HookWrapper.new(proc { raise Failure })
1584
+ Runtime::BeforeHooks.new([failing_hook], RunningTestCase.new(test_case)).apply_to(test_case)
1533
1585
  end
1534
1586
  end
1535
1587
 
@@ -1660,6 +1712,8 @@ module Cucumber
1660
1712
  :after_steps,
1661
1713
  :before_examples_array,
1662
1714
  :before_examples,
1715
+ :before_tags,
1716
+ :after_tags,
1663
1717
  :examples_name,
1664
1718
  :before_outline_table,
1665
1719
  :before_table_row,
@@ -1688,7 +1742,9 @@ module Cucumber
1688
1742
  # the result of the first one.
1689
1743
  class FailingAndPassingBeforeHooks
1690
1744
  def apply_before_hooks(test_case)
1691
- Runtime::BeforeHooks.new([proc { raise Failure }, proc { }]).apply_to(test_case)
1745
+ failing_hook = HookWrapper.new(proc { raise Failure })
1746
+ passing_hook = HookWrapper.new(proc {})
1747
+ Runtime::BeforeHooks.new([failing_hook, passing_hook], RunningTestCase.new(test_case)).apply_to(test_case)
1692
1748
  end
1693
1749
  end
1694
1750
 
@@ -1735,7 +1791,8 @@ module Cucumber
1735
1791
 
1736
1792
  class FailingAfterHook
1737
1793
  def apply_after_hooks(test_case)
1738
- Runtime::AfterHooks.new([proc { raise Failure }]).apply_to(test_case)
1794
+ failing_hook = HookWrapper.new(proc { raise Failure })
1795
+ Runtime::AfterHooks.new([failing_hook], RunningTestCase.new(test_case)).apply_to(test_case)
1739
1796
  end
1740
1797
  end
1741
1798
 
@@ -1814,6 +1871,8 @@ module Cucumber
1814
1871
  :after_steps,
1815
1872
  :before_examples_array,
1816
1873
  :before_examples,
1874
+ :before_tags,
1875
+ :after_tags,
1817
1876
  :examples_name,
1818
1877
  :before_outline_table,
1819
1878
  :before_table_row,
@@ -1840,7 +1899,9 @@ module Cucumber
1840
1899
  context 'with exception in the first of several after hooks' do
1841
1900
  class FailingThenPassingAfterHooks
1842
1901
  def apply_after_hooks(test_case)
1843
- Runtime::AfterHooks.new([proc { raise Failure }, proc {}]).apply_to(test_case)
1902
+ failing_hook = HookWrapper.new(proc { raise Failure })
1903
+ passing_hook = HookWrapper.new(proc {})
1904
+ Runtime::AfterHooks.new([failing_hook, passing_hook], RunningTestCase.new(test_case)).apply_to(test_case)
1844
1905
  end
1845
1906
  end
1846
1907
 
@@ -366,6 +366,102 @@ Feature:
366
366
 
367
367
  1 scenario (1 passed)
368
368
  2 steps (2 passed)
369
+ OUTPUT
370
+ end
371
+ end
372
+
373
+ describe "with tags on all levels" do
374
+ define_feature <<-FEATURE
375
+ @tag1
376
+ Feature:
377
+ @tag2
378
+ Scenario:
379
+ Given this step passes
380
+ @tag3
381
+ Scenario Outline:
382
+ Given this step passes
383
+ @tag4
384
+ Examples:
385
+ | dummy |
386
+ | dummy |
387
+ FEATURE
388
+
389
+
390
+ it "includes the tags in the output " do
391
+ expect( @out.string ).to include <<OUTPUT
392
+ @tag1
393
+ Feature:
394
+
395
+ @tag2
396
+ Scenario:
397
+ Given this step passes
398
+
399
+ @tag3
400
+ Scenario Outline:
401
+ Given this step passes
402
+
403
+ @tag4
404
+ Examples:
405
+ | dummy |
406
+ | dummy |
407
+ OUTPUT
408
+ end
409
+ end
410
+
411
+ describe "with comments on all levels" do
412
+ define_feature <<-FEATURE
413
+ #comment1
414
+ Feature:
415
+ #comment2
416
+ Background:
417
+ #comment3
418
+ Given this step passes
419
+ #comment4
420
+ Scenario:
421
+ #comment5
422
+ Given this step passes
423
+ #comment6
424
+ | dummy |
425
+ #comment7
426
+ Scenario Outline:
427
+ #comment8
428
+ Given this step passes
429
+ #comment9
430
+ Examples:
431
+ #comment10
432
+ | dummy |
433
+ #comment11
434
+ | dummy |
435
+ FEATURE
436
+
437
+
438
+ it "includes the all comments except for data table rows in the output " do
439
+ expect( @out.string ).to include <<OUTPUT
440
+ #comment1
441
+ Feature:
442
+
443
+ #comment2
444
+ Background:
445
+ #comment3
446
+ Given this step passes
447
+
448
+ #comment4
449
+ Scenario:
450
+ #comment5
451
+ Given this step passes
452
+ | dummy |
453
+
454
+ #comment7
455
+ Scenario Outline:
456
+ #comment8
457
+ Given this step passes
458
+
459
+ #comment9
460
+ Examples:
461
+ #comment10
462
+ | dummy |
463
+ #comment11
464
+ | dummy |
369
465
  OUTPUT
370
466
  end
371
467
  end
@@ -12,7 +12,7 @@ module Cucumber
12
12
  before(:each) do
13
13
  Cucumber::Term::ANSIColor.coloring = false
14
14
  @out = StringIO.new
15
- @formatter = Progress.new(runtime, @out, {})
15
+ @formatter = Progress.new(runtime, @out, Cucumber::Cli::Options.new)
16
16
  end
17
17
 
18
18
  describe "given a single feature" do
@@ -79,6 +79,90 @@ module Cucumber
79
79
  end
80
80
 
81
81
  end
82
+
83
+ describe "with hooks" do
84
+
85
+ describe "all hook passes" do
86
+ define_feature <<-FEATURE
87
+ Feature:
88
+ Scenario:
89
+ Given this step passes
90
+ FEATURE
91
+
92
+ define_steps do
93
+ Before do
94
+ end
95
+ AfterStep do
96
+ end
97
+ After do
98
+ end
99
+ Given(/^this step passes$/) {}
100
+ end
101
+
102
+ it "only steps generate output" do
103
+ lines = <<-OUTPUT
104
+ .
105
+ 1 scenario (1 passed)
106
+ 1 step (1 passed)
107
+ OUTPUT
108
+ lines.split("\n").each do |line|
109
+ expect(@out.string).to include line.strip
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "with a failing before hook" do
115
+ define_feature <<-FEATURE
116
+ Feature:
117
+ Scenario:
118
+ Given this step passes
119
+ FEATURE
120
+
121
+ define_steps do
122
+ Before do
123
+ fail "hook failed"
124
+ end
125
+ Given(/^this step passes$/) {}
126
+ end
127
+
128
+ it "the failing hook generate output" do
129
+ lines = <<-OUTPUT
130
+ F-
131
+ 1 scenario (1 failed)
132
+ 1 step (1 skipped)
133
+ OUTPUT
134
+ lines.split("\n").each do |line|
135
+ expect(@out.string).to include line.strip
136
+ end
137
+ end
138
+ end
139
+
140
+ describe "with a failing after hook" do
141
+ define_feature <<-FEATURE
142
+ Feature:
143
+ Scenario:
144
+ Given this step passes
145
+ FEATURE
146
+
147
+ define_steps do
148
+ After do
149
+ fail "hook failed"
150
+ end
151
+ Given(/^this step passes$/) {}
152
+ end
153
+
154
+ it "the failing hook generate output" do
155
+ lines = <<-OUTPUT
156
+ .F
157
+ 1 scenario (1 failed)
158
+ 1 step (1 passed)
159
+ OUTPUT
160
+ lines.split("\n").each do |line|
161
+ expect(@out.string).to include line.strip
162
+ end
163
+ end
164
+ end
165
+ end
82
166
  end
83
167
  end
84
168
  end