cucumber 2.0.0.beta.5 → 2.0.0.rc.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +20 -1
  3. data/Rakefile +0 -2
  4. data/cucumber.gemspec +1 -1
  5. data/features/docs/defining_steps/skip_scenario.feature +31 -2
  6. data/lib/cucumber.rb +6 -0
  7. data/lib/cucumber/ast/facade.rb +117 -0
  8. data/lib/cucumber/cli/configuration.rb +1 -1
  9. data/lib/cucumber/cli/profile_loader.rb +1 -1
  10. data/lib/cucumber/file_specs.rb +1 -1
  11. data/lib/cucumber/filters.rb +9 -0
  12. data/lib/cucumber/filters/activate_steps.rb +34 -0
  13. data/lib/cucumber/filters/apply_after_hooks.rb +9 -0
  14. data/lib/cucumber/filters/apply_after_step_hooks.rb +12 -0
  15. data/lib/cucumber/filters/apply_around_hooks.rb +12 -0
  16. data/lib/cucumber/filters/apply_before_hooks.rb +9 -0
  17. data/lib/cucumber/filters/prepare_world.rb +37 -0
  18. data/lib/cucumber/filters/quit.rb +5 -1
  19. data/lib/cucumber/filters/randomizer.rb +5 -1
  20. data/lib/cucumber/filters/tag_limits.rb +7 -2
  21. data/lib/cucumber/formatter/ansicolor.rb +0 -8
  22. data/lib/cucumber/formatter/html.rb +6 -1
  23. data/lib/cucumber/formatter/legacy_api/adapter.rb +17 -1
  24. data/lib/cucumber/formatter/legacy_api/ast.rb +6 -1
  25. data/lib/cucumber/hooks.rb +97 -0
  26. data/lib/cucumber/platform.rb +2 -3
  27. data/lib/cucumber/rb_support/rb_hook.rb +2 -2
  28. data/lib/cucumber/runtime.rb +18 -15
  29. data/lib/cucumber/runtime/after_hooks.rb +24 -0
  30. data/lib/cucumber/runtime/before_hooks.rb +23 -0
  31. data/lib/cucumber/runtime/step_hooks.rb +22 -0
  32. data/lib/cucumber/runtime/support_code.rb +56 -1
  33. data/lib/cucumber/step_match.rb +26 -2
  34. data/spec/cucumber/cli/configuration_spec.rb +16 -1
  35. data/spec/cucumber/cli/profile_loader_spec.rb +10 -0
  36. data/spec/cucumber/file_specs_spec.rb +10 -2
  37. data/spec/cucumber/filters/activate_steps_spec.rb +57 -0
  38. data/spec/cucumber/formatter/debug_spec.rb +0 -14
  39. data/spec/cucumber/formatter/html_spec.rb +29 -0
  40. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +210 -110
  41. data/spec/cucumber/formatter/pretty_spec.rb +0 -2
  42. data/spec/cucumber/formatter/rerun_spec.rb +17 -16
  43. data/spec/cucumber/formatter/spec_helper.rb +11 -6
  44. data/spec/cucumber/hooks_spec.rb +30 -0
  45. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +11 -4
  46. metadata +22 -16
  47. data/gem_tasks/yard.rake +0 -43
  48. data/gem_tasks/yard/default/layout/html/bubble_32x32.png +0 -0
  49. data/gem_tasks/yard/default/layout/html/footer.erb +0 -5
  50. data/gem_tasks/yard/default/layout/html/index.erb +0 -1
  51. data/gem_tasks/yard/default/layout/html/layout.erb +0 -25
  52. data/gem_tasks/yard/default/layout/html/logo.erb +0 -1
  53. data/gem_tasks/yard/default/layout/html/setup.rb +0 -4
  54. data/lib/cucumber/mappings.rb +0 -238
  55. data/spec/cucumber/mappings_spec.rb +0 -180
@@ -398,7 +398,22 @@ END_OF_MESSAGE
398
398
  expect(config.feature_files).to eq ["cucumber.feature"]
399
399
  end
400
400
 
401
- it "allows specifying environment variables on the command line" do
401
+ it "gets the feature files from the rerun file" do
402
+ allow(File).to receive(:directory?).and_return(false)
403
+ allow(File).to receive(:file?).and_return(true)
404
+ allow(IO).to receive(:read).and_return(
405
+ "cucumber.feature:1:3 cucumber space.feature:134 domain folder/cuke.feature:1 domain folder/different cuke:4:5" )
406
+
407
+ config.parse!(%w{@rerun.txt})
408
+
409
+ expect(config.feature_files).to eq [
410
+ "cucumber.feature:1:3",
411
+ "cucumber space.feature:134",
412
+ "domain folder/cuke.feature:1",
413
+ "domain folder/different cuke:4:5"]
414
+ end
415
+
416
+ it "should allow specifying environment variables on the command line" do
402
417
  config.parse!(["foo=bar"])
403
418
 
404
419
  expect(ENV["foo"]).to eq "bar"
@@ -31,6 +31,16 @@ module Cucumber
31
31
 
32
32
  expect(loader.args_from('default')).to eq ['--format','ugly','features/sync_imap_mailbox.feature:16:22']
33
33
  end
34
+
35
+ it "treats percent sign as ERB code block after YAML directive" do
36
+ yml = <<-HERE
37
+ ---
38
+ % x = '--format "pretty" features/sync_imap_mailbox.feature:16:22'
39
+ default: <%= x %>
40
+ HERE
41
+ given_cucumber_yml_defined_as yml
42
+ expect(loader.args_from('default')).to eq ['--format','pretty','features/sync_imap_mailbox.feature:16:22']
43
+ end
34
44
  end
35
45
  end
36
46
  end
@@ -4,6 +4,7 @@ module Cucumber
4
4
  describe FileSpecs do
5
5
  let(:file_specs) { FileSpecs.new(["features/foo.feature:1:2:3", "features/bar.feature:4:5:6"]) }
6
6
  let(:locations) { file_specs.locations }
7
+ let(:files) { file_specs.files }
7
8
 
8
9
  it "parses locations from multiple files" do
9
10
  expect(locations.length).to eq 6
@@ -18,8 +19,6 @@ module Cucumber
18
19
  end
19
20
 
20
21
  it "parses file names from multiple file specs" do
21
- files = file_specs.files
22
-
23
22
  expect(files.length).to eq 2
24
23
  expect(files).to eq [
25
24
  "features/foo.feature",
@@ -27,6 +26,15 @@ module Cucumber
27
26
  ]
28
27
  end
29
28
 
29
+ context "when files are not unique" do
30
+ let(:file_specs) { FileSpecs.new(["features/foo.feature:4", "features/foo.feature:34"]) }
31
+
32
+ it "parses unique file names" do
33
+ expect(files.length).to eq 1
34
+ expect(files).to eq ["features/foo.feature"]
35
+ end
36
+ end
37
+
30
38
  context "when no line number is specified" do
31
39
  let(:file_specs) { FileSpecs.new(["features/foo.feature", "features/bar.feature:34"]) }
32
40
 
@@ -0,0 +1,57 @@
1
+ require 'cucumber/filters/activate_steps'
2
+ require 'cucumber/core/gherkin/writer'
3
+ require 'cucumber/core'
4
+
5
+ describe Cucumber::Filters::ActivateSteps do
6
+ include Cucumber::Core::Gherkin::Writer
7
+ include Cucumber::Core
8
+
9
+ let(:step_definitions) { double(find_match: step_match) }
10
+ let(:step_match) { double(activate: activated_test_step) }
11
+ let(:activated_test_step) { double }
12
+ let(:receiver) { double.as_null_object }
13
+
14
+ context "a scenario with a single step" do
15
+ let(:doc) do
16
+ gherkin do
17
+ feature do
18
+ scenario do
19
+ step 'a passing step'
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ it "activates each step" do
26
+ expect(step_match).to receive(:activate) do |test_step|
27
+ expect(test_step.name).to eq 'a passing step'
28
+ end
29
+ compile [doc], receiver, [Cucumber::Filters::ActivateSteps.new(step_definitions)]
30
+ end
31
+ end
32
+
33
+ context "a scenario outline" do
34
+ let(:doc) do
35
+ gherkin do
36
+ feature do
37
+ scenario_outline do
38
+ step 'a <status> step'
39
+
40
+ examples do
41
+ row 'status'
42
+ row 'passing'
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ it "activates each step" do
50
+ expect(step_match).to receive(:activate) do |test_step|
51
+ expect(test_step.name).to eq 'a passing step'
52
+ end
53
+ compile [doc], receiver, [Cucumber::Filters::ActivateSteps.new(step_definitions)]
54
+ end
55
+ end
56
+
57
+ end
@@ -37,14 +37,6 @@ feature_name
37
37
  before_test_step
38
38
  after_test_step
39
39
  before_test_step
40
- after_test_step
41
- before_test_step
42
- after_test_step
43
- before_test_step
44
- after_test_step
45
- before_test_step
46
- after_test_step
47
- before_test_step
48
40
  before_feature_element
49
41
  before_tags
50
42
  after_tags
@@ -56,12 +48,6 @@ step_name
56
48
  after_step_result
57
49
  after_step
58
50
  after_test_step
59
- before_test_step
60
- after_test_step
61
- before_test_step
62
- after_test_step
63
- before_test_step
64
- after_test_step
65
51
  after_steps
66
52
  after_feature_element
67
53
  after_test_case
@@ -29,6 +29,35 @@ module Cucumber
29
29
  }).not_to raise_error
30
30
  end
31
31
 
32
+ describe "when writing the report to a file" do
33
+ before(:each) do
34
+ allow(@out).to receive(:respond_to?).with(:path, false).and_return(true)
35
+ expect(@out).to receive(:respond_to?).with(:path).and_return(true)
36
+ expect(@out).to receive(:path).and_return('out/file.html')
37
+ run_defined_feature
38
+ @doc = Nokogiri.HTML(@out.string)
39
+ end
40
+
41
+ describe "with a step that embeds a snapshot" do
42
+ define_steps do
43
+ Given(/snap/) {
44
+ RSpec::Mocks.allow_message(File, :file?) { true }
45
+ embed('out/snapshot.jpeg', 'image/jpeg')
46
+ }
47
+ end
48
+
49
+ define_feature(<<-FEATURE)
50
+ Feature:
51
+ Scenario:
52
+ Given snap
53
+ FEATURE
54
+
55
+ it "converts the snapshot path to a relative path" do
56
+ expect(@doc.css('.embed img').first.attributes['src'].to_s).to eq "snapshot.jpeg"
57
+ end
58
+ end
59
+ end
60
+
32
61
  describe "given a single feature" do
33
62
  before(:each) do
34
63
  run_defined_feature
@@ -1,7 +1,10 @@
1
1
  require 'cucumber/formatter/legacy_api/adapter'
2
2
  require 'cucumber/core'
3
3
  require 'cucumber/core/gherkin/writer'
4
- require 'cucumber/mappings'
4
+ require 'cucumber/runtime/step_hooks'
5
+ require 'cucumber/runtime/before_hooks'
6
+ require 'cucumber/runtime/after_hooks'
7
+ require 'cucumber/filters'
5
8
 
6
9
  module Cucumber
7
10
  module Formatter::LegacyApi
@@ -12,25 +15,52 @@ module Cucumber
12
15
  let(:report) { Adapter.new(formatter, runtime.results, runtime.support_code, runtime.configuration) }
13
16
  let(:formatter) { double('formatter').as_null_object }
14
17
  let(:runtime) { Runtime.new }
15
- let(:mappings) { mappings = CustomMappings.new }
16
18
 
17
19
  Failure = Class.new(StandardError)
18
20
 
19
- class CustomMappings
20
- def test_case(test_case, mapper)
21
- # The adapter is built on the assumption that each test case will have at least one step. This is annoying
22
- # for tests, but a safe assumption for production use as we always add one hook to initialize the world.
23
- mapper.before {}
21
+ class SimpleStepMatch
22
+ def initialize(&block)
23
+ @block = block
24
+ end
25
+
26
+ def activate(test_step)
27
+ test_step.with_action &@block
24
28
  end
29
+ end
25
30
 
26
- def test_step(test_step, mapper)
31
+ class SimpleStepDefinitions
32
+ def find_match(test_step)
27
33
  if test_step.name =~ /pass/
28
- mapper.map {}
34
+ return SimpleStepMatch.new {}
29
35
  end
30
36
 
31
37
  if test_step.name =~ /fail/
32
- mapper.map { raise Failure }
38
+ return SimpleStepMatch.new { raise Failure }
33
39
  end
40
+
41
+ NoStepMatch.new test_step.source.last, test_step.name
42
+ end
43
+ end
44
+
45
+ class AddBeforeAndAfterHooks < Core::Filter.new
46
+ def test_case(test_case)
47
+ steps = before_hooks(test_case.source) +
48
+ test_case.test_steps +
49
+ after_hooks(test_case.source)
50
+ test_case.with_steps(steps).describe_to receiver
51
+ end
52
+
53
+ private
54
+
55
+ def before_hooks(source)
56
+ # The adapter is built on the assumption that each test case will have at least one step. This is annoying
57
+ # for tests, but a safe assumption for production use as we always add one hook to initialize the world.
58
+ [ Hooks.before_hook(source) {} ]
59
+ end
60
+
61
+ def after_hooks(source)
62
+ # We add an after hook to make sure the adapter can cope with it
63
+ [ Hooks.after_hook(source) {} ]
34
64
  end
35
65
  end
36
66
 
@@ -54,44 +84,45 @@ module Cucumber
54
84
  end
55
85
  end,
56
86
  ]
57
- execute gherkin_docs, mappings, report
87
+ runner = Core::Test::Runner.new(report)
88
+ compile gherkin_docs, runner, default_filters
58
89
  expect( formatter.legacy_messages ).to eq [
59
- :before_features,
60
- :before_feature,
90
+ :before_features,
91
+ :before_feature,
92
+ :before_tags,
93
+ :after_tags,
94
+ :feature_name,
95
+ :before_feature_element,
61
96
  :before_tags,
62
97
  :after_tags,
63
- :feature_name,
64
- :before_feature_element,
65
- :before_tags,
66
- :after_tags,
67
- :scenario_name,
68
- :before_steps,
69
- :before_step,
70
- :before_step_result,
71
- :step_name,
72
- :after_step_result,
73
- :after_step,
74
- :after_steps,
75
- :after_feature_element,
76
- :after_feature,
77
- :before_feature,
98
+ :scenario_name,
99
+ :before_steps,
100
+ :before_step,
101
+ :before_step_result,
102
+ :step_name,
103
+ :after_step_result,
104
+ :after_step,
105
+ :after_steps,
106
+ :after_feature_element,
107
+ :after_feature,
108
+ :before_feature,
109
+ :before_tags,
110
+ :after_tags,
111
+ :feature_name,
112
+ :before_feature_element,
78
113
  :before_tags,
79
114
  :after_tags,
80
- :feature_name,
81
- :before_feature_element,
82
- :before_tags,
83
- :after_tags,
84
- :scenario_name,
85
- :before_steps,
86
- :before_step,
87
- :before_step_result,
88
- :step_name,
89
- :after_step_result,
90
- :after_step,
91
- :after_steps,
92
- :after_feature_element,
93
- :after_feature,
94
- :after_features,
115
+ :scenario_name,
116
+ :before_steps,
117
+ :before_step,
118
+ :before_step_result,
119
+ :step_name,
120
+ :after_step_result,
121
+ :after_step,
122
+ :after_steps,
123
+ :after_feature_element,
124
+ :after_feature,
125
+ :after_features,
95
126
  ]
96
127
  end
97
128
 
@@ -270,6 +301,41 @@ module Cucumber
270
301
  ]
271
302
  end
272
303
 
304
+ it 'a feature with a background and an empty scenario' do
305
+ execute_gherkin do
306
+ feature do
307
+ background do
308
+ step 'passing'
309
+ end
310
+ scenario
311
+ end
312
+ end
313
+ expect( formatter.legacy_messages ).to eq [
314
+ :before_features,
315
+ :before_feature,
316
+ :before_tags,
317
+ :after_tags,
318
+ :feature_name,
319
+ :before_background,
320
+ :background_name,
321
+ :before_steps,
322
+ :before_step,
323
+ :before_step_result,
324
+ :step_name,
325
+ :after_step_result,
326
+ :after_step,
327
+ :after_steps,
328
+ :after_background,
329
+ :before_feature_element,
330
+ :before_tags,
331
+ :after_tags,
332
+ :scenario_name,
333
+ :after_feature_element,
334
+ :after_feature,
335
+ :after_features,
336
+ ]
337
+ end
338
+
273
339
  it 'a feature with a background and two scenarios' do
274
340
  execute_gherkin do
275
341
  feature do
@@ -1416,17 +1482,19 @@ module Cucumber
1416
1482
 
1417
1483
  context 'with exception in after step hook' do
1418
1484
 
1419
- class CustomMappingsWithAfterStepHook < CustomMappings
1420
- def test_step(test_step, mappings)
1421
- super
1422
- mappings.after { raise Failure }
1485
+ class FailingAfterStepHook
1486
+ def find_after_step_hooks(test_case)
1487
+ Runtime::StepHooks.new [-> { raise Failure }]
1423
1488
  end
1424
1489
  end
1425
1490
 
1426
- let(:mappings) { CustomMappingsWithAfterStepHook.new }
1427
-
1428
1491
  it 'prints the exception within the step' do
1429
- execute_gherkin do
1492
+ filters = [
1493
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1494
+ Filters::ApplyAfterStepHooks.new(FailingAfterStepHook.new),
1495
+ AddBeforeAndAfterHooks.new
1496
+ ]
1497
+ execute_gherkin(filters) do
1430
1498
  feature do
1431
1499
  scenario do
1432
1500
  step 'passing'
@@ -1459,17 +1527,19 @@ module Cucumber
1459
1527
  end
1460
1528
 
1461
1529
  context 'with exception in a single before hook' do
1462
- class CustomMappingsWithBeforeHook < CustomMappings
1463
- def test_case(test_case, mappings)
1464
- super
1465
- mappings.before { raise Failure }
1530
+ class FailingBeforeHook
1531
+ def apply_before_hooks(test_case)
1532
+ Runtime::BeforeHooks.new([proc { raise Failure }]).apply_to(test_case)
1466
1533
  end
1467
1534
  end
1468
1535
 
1469
- let(:mappings) { CustomMappingsWithBeforeHook.new }
1470
-
1471
1536
  it 'prints the exception after the scenario name' do
1472
- execute_gherkin do
1537
+ filters = [
1538
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1539
+ Filters::ApplyBeforeHooks.new(FailingBeforeHook.new),
1540
+ AddBeforeAndAfterHooks.new
1541
+ ]
1542
+ execute_gherkin(filters) do
1473
1543
  feature do
1474
1544
  scenario do
1475
1545
  step 'passing'
@@ -1502,13 +1572,12 @@ module Cucumber
1502
1572
  end
1503
1573
 
1504
1574
  it 'prints the exception after the background name' do
1505
- mappings = Class.new(CustomMappings) {
1506
- def test_case(test_case, mapper)
1507
- mapper.before { raise Failure }
1508
- end
1509
- }.new
1510
-
1511
- execute_gherkin(mappings) do
1575
+ filters = [
1576
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1577
+ Filters::ApplyBeforeHooks.new(FailingBeforeHook.new),
1578
+ AddBeforeAndAfterHooks.new
1579
+ ]
1580
+ execute_gherkin(filters) do
1512
1581
  feature do
1513
1582
  background do
1514
1583
  step 'passing'
@@ -1555,13 +1624,12 @@ module Cucumber
1555
1624
 
1556
1625
 
1557
1626
  it 'prints the exception before the examples table row' do
1558
- mappings = Class.new(CustomMappings) {
1559
- def test_case(test_case, mapper)
1560
- mapper.before { raise Failure }
1561
- end
1562
- }.new
1563
-
1564
- execute_gherkin(mappings) do
1627
+ filters = [
1628
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1629
+ Filters::ApplyBeforeHooks.new(FailingBeforeHook.new),
1630
+ AddBeforeAndAfterHooks.new
1631
+ ]
1632
+ execute_gherkin(filters) do
1565
1633
  feature do
1566
1634
  scenario_outline do
1567
1635
  step '<status>ing'
@@ -1618,15 +1686,19 @@ module Cucumber
1618
1686
  context 'with exception in the first of several before hooks' do
1619
1687
  # This proves that the second before hook's result doesn't overwrite
1620
1688
  # the result of the first one.
1621
- it 'prints the exception after the scenario name' do
1622
- mappings = Class.new(CustomMappings) {
1623
- def test_case(test_case, mapper)
1624
- mapper.before { raise Failure }
1625
- mapper.before { }
1626
- end
1627
- }.new
1689
+ class FailingAndPassingBeforeHooks
1690
+ def apply_before_hooks(test_case)
1691
+ Runtime::BeforeHooks.new([proc { raise Failure }, proc { }]).apply_to(test_case)
1692
+ end
1693
+ end
1628
1694
 
1629
- execute_gherkin(mappings) do
1695
+ it 'prints the exception after the scenario name' do
1696
+ filters = [
1697
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1698
+ Filters::ApplyBeforeHooks.new(FailingAndPassingBeforeHooks.new),
1699
+ AddBeforeAndAfterHooks.new
1700
+ ]
1701
+ execute_gherkin(filters) do
1630
1702
  feature do
1631
1703
  scenario do
1632
1704
  step 'passing'
@@ -1660,17 +1732,20 @@ module Cucumber
1660
1732
  end
1661
1733
 
1662
1734
  context 'with exception in after hooks' do
1663
- let(:mappings) do
1664
- Class.new(CustomMappings) {
1665
- def test_case(test_case, mapper)
1666
- mapper.after { raise Failure }
1667
- end
1668
- }.new
1735
+
1736
+ class FailingAfterHook
1737
+ def apply_after_hooks(test_case)
1738
+ Runtime::AfterHooks.new([proc { raise Failure }]).apply_to(test_case)
1739
+ end
1669
1740
  end
1670
1741
 
1671
1742
  it 'prints the exception after the steps' do
1672
-
1673
- execute_gherkin(mappings) do
1743
+ filters = [
1744
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1745
+ Filters::ApplyAfterHooks.new(FailingAfterHook.new),
1746
+ AddBeforeAndAfterHooks.new
1747
+ ]
1748
+ execute_gherkin(filters) do
1674
1749
  feature do
1675
1750
  scenario do
1676
1751
  step 'passing'
@@ -1703,7 +1778,12 @@ module Cucumber
1703
1778
  end
1704
1779
 
1705
1780
  it 'prints the exception after the examples table row' do
1706
- execute_gherkin do
1781
+ filters = [
1782
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1783
+ Filters::ApplyAfterHooks.new(FailingAfterHook.new),
1784
+ AddBeforeAndAfterHooks.new
1785
+ ]
1786
+ execute_gherkin(filters) do
1707
1787
  feature do
1708
1788
  scenario_outline do
1709
1789
  step '<status>ing'
@@ -1758,17 +1838,19 @@ module Cucumber
1758
1838
  end
1759
1839
 
1760
1840
  context 'with exception in the first of several after hooks' do
1761
- let(:mappings) do
1762
- Class.new(CustomMappings) {
1763
- def test_case(test_case, mapper)
1764
- mapper.after { raise Failure }
1765
- mapper.after { }
1766
- end
1767
- }.new
1841
+ class FailingThenPassingAfterHooks
1842
+ def apply_after_hooks(test_case)
1843
+ Runtime::AfterHooks.new([proc { raise Failure }, proc {}]).apply_to(test_case)
1844
+ end
1768
1845
  end
1769
1846
 
1770
1847
  it 'prints the exception after the steps' do
1771
- execute_gherkin do
1848
+ filters = [
1849
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1850
+ Filters::ApplyAfterHooks.new(FailingThenPassingAfterHooks.new),
1851
+ AddBeforeAndAfterHooks.new
1852
+ ]
1853
+ execute_gherkin(filters) do
1772
1854
  feature do
1773
1855
  scenario do
1774
1856
  step 'passing'
@@ -1802,16 +1884,13 @@ module Cucumber
1802
1884
  end
1803
1885
 
1804
1886
  context 'with an exception in an after hook but no steps' do
1805
- let(:mappings) do
1806
- Class.new(CustomMappings) {
1807
- def test_case(test_case, mapper)
1808
- mapper.after { raise Failure }
1809
- end
1810
- }.new
1811
- end
1812
-
1813
1887
  it 'prints the exception after the steps' do
1814
- execute_gherkin do
1888
+ filters = [
1889
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1890
+ Filters::ApplyAfterHooks.new(FailingAfterHook.new),
1891
+ AddBeforeAndAfterHooks.new
1892
+ ]
1893
+ execute_gherkin(filters) do
1815
1894
  feature do
1816
1895
  scenario do
1817
1896
  end
@@ -1837,6 +1916,19 @@ module Cucumber
1837
1916
  end
1838
1917
  end
1839
1918
 
1919
+ it 'passes nil as the multiline arg when there is none' do
1920
+ expect(formatter).to receive(:after_step_result) do |keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line|
1921
+ expect(multiline_arg).to be_nil
1922
+ end
1923
+ execute_gherkin do
1924
+ feature do
1925
+ scenario do
1926
+ step 'passing'
1927
+ end
1928
+ end
1929
+ end
1930
+ end
1931
+
1840
1932
  it 'passes an object responding to failed? with the after_feature_element message' do
1841
1933
  expect( formatter ).to receive(:after_feature_element) do |scenario|
1842
1934
  expect( scenario ).to be_failed
@@ -1854,9 +1946,9 @@ module Cucumber
1854
1946
  let(:runtime) { Runtime.new strict: true }
1855
1947
 
1856
1948
  it 'passes an exception to the formatter for undefined steps' do
1857
- expect( formatter ).to receive(:exception) do |exception|
1858
- expect( exception.message ).to eq %{Undefined step: "this step is undefined"}
1859
- end
1949
+ expect( formatter ).to receive(:exception) do |exception|
1950
+ expect( exception.message ).to eq %{Undefined step: "this step is undefined"}
1951
+ end
1860
1952
  execute_gherkin do
1861
1953
  feature do
1862
1954
  scenario do
@@ -1893,8 +1985,16 @@ module Cucumber
1893
1985
  end
1894
1986
  end
1895
1987
 
1896
- def execute_gherkin(custom_mappings = mappings, &gherkin)
1897
- execute [gherkin(&gherkin)], custom_mappings, report
1988
+ def execute_gherkin(filters = default_filters, &gherkin)
1989
+ runner = Core::Test::Runner.new(report)
1990
+ compile [gherkin(&gherkin)], runner, filters
1991
+ end
1992
+
1993
+ def default_filters
1994
+ [
1995
+ Filters::ActivateSteps.new(SimpleStepDefinitions.new),
1996
+ AddBeforeAndAfterHooks.new
1997
+ ]
1898
1998
  end
1899
1999
 
1900
2000
  end