cucumber 2.0.0.beta.5 → 2.0.0.rc.1

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