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
@@ -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