cucumber 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -6
  3. data/CONTRIBUTING.md +3 -1
  4. data/Gemfile +1 -1
  5. data/History.md +17 -0
  6. data/README.md +3 -3
  7. data/bin/cucumber +1 -2
  8. data/cucumber.gemspec +2 -2
  9. data/examples/i18n/ht/features/adisyon.feature +7 -7
  10. data/features/docs/api/listen_for_events.feature +58 -0
  11. data/features/docs/cli/fail_fast.feature +46 -0
  12. data/features/docs/defining_steps/nested_steps_with_second_arg.feature +3 -22
  13. data/features/docs/extending_cucumber/custom_formatter.feature +40 -4
  14. data/features/docs/gherkin/doc_strings.feature +5 -5
  15. data/features/docs/gherkin/language_help.feature +15 -15
  16. data/features/docs/gherkin/using_descriptions.feature +0 -5
  17. data/lib/cucumber/cli/configuration.rb +10 -92
  18. data/lib/cucumber/cli/main.rb +1 -7
  19. data/lib/cucumber/cli/options.rb +47 -12
  20. data/lib/cucumber/configuration.rb +195 -7
  21. data/lib/cucumber/events.rb +20 -0
  22. data/lib/cucumber/events/after_test_case.rb +25 -0
  23. data/lib/cucumber/events/after_test_step.rb +30 -0
  24. data/lib/cucumber/events/before_test_case.rb +18 -0
  25. data/lib/cucumber/events/before_test_step.rb +23 -0
  26. data/lib/cucumber/events/bus.rb +86 -0
  27. data/lib/cucumber/events/step_match.rb +23 -0
  28. data/lib/cucumber/filters/prepare_world.rb +2 -2
  29. data/lib/cucumber/formatter/backtrace_filter.rb +9 -8
  30. data/lib/cucumber/formatter/console.rb +1 -1
  31. data/lib/cucumber/formatter/event_bus_report.rb +37 -0
  32. data/lib/cucumber/formatter/fail_fast.rb +18 -0
  33. data/lib/cucumber/formatter/html.rb +1 -1
  34. data/lib/cucumber/formatter/io.rb +3 -1
  35. data/lib/cucumber/formatter/json.rb +19 -1
  36. data/lib/cucumber/formatter/legacy_api/adapter.rb +5 -13
  37. data/lib/cucumber/formatter/legacy_api/ast.rb +2 -2
  38. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +3 -1
  39. data/lib/cucumber/formatter/pretty.rb +5 -7
  40. data/lib/cucumber/formatter/progress.rb +1 -1
  41. data/lib/cucumber/formatter/rerun.rb +1 -1
  42. data/lib/cucumber/formatter/steps.rb +1 -1
  43. data/lib/cucumber/formatter/usage.rb +12 -8
  44. data/lib/cucumber/gherkin/data_table_parser.rb +23 -0
  45. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +99 -0
  46. data/lib/cucumber/gherkin/formatter/argument.rb +17 -0
  47. data/lib/cucumber/gherkin/formatter/escaping.rb +17 -0
  48. data/lib/cucumber/gherkin/formatter/hashable.rb +27 -0
  49. data/lib/cucumber/gherkin/i18n.rb +15 -0
  50. data/lib/cucumber/gherkin/steps_parser.rb +41 -0
  51. data/lib/cucumber/language_support/language_methods.rb +6 -5
  52. data/lib/cucumber/multiline_argument.rb +0 -3
  53. data/lib/cucumber/multiline_argument/data_table.rb +6 -5
  54. data/lib/cucumber/multiline_argument/doc_string.rb +1 -2
  55. data/lib/cucumber/platform.rb +1 -1
  56. data/lib/cucumber/rake/task.rb +2 -2
  57. data/lib/cucumber/rb_support/rb_hook.rb +1 -6
  58. data/lib/cucumber/rb_support/rb_language.rb +15 -5
  59. data/lib/cucumber/rb_support/rb_step_definition.rb +11 -17
  60. data/lib/cucumber/rb_support/rb_world.rb +6 -4
  61. data/lib/cucumber/rb_support/regexp_argument_matcher.rb +2 -2
  62. data/lib/cucumber/runtime.rb +36 -16
  63. data/lib/cucumber/runtime/support_code.rb +19 -15
  64. data/lib/cucumber/step_definition_light.rb +5 -5
  65. data/lib/cucumber/step_definitions.rb +2 -2
  66. data/lib/cucumber/step_match.rb +11 -2
  67. data/lib/cucumber/wire_support/wire_protocol/requests.rb +2 -2
  68. data/lib/cucumber/wire_support/wire_step_definition.rb +4 -2
  69. data/{spec → lib}/simplecov_setup.rb +0 -0
  70. data/spec/cucumber/cli/configuration_spec.rb +2 -104
  71. data/spec/cucumber/cli/main_spec.rb +0 -22
  72. data/spec/cucumber/cli/options_spec.rb +3 -1
  73. data/spec/cucumber/configuration_spec.rb +123 -0
  74. data/spec/cucumber/events/bus_spec.rb +94 -0
  75. data/spec/cucumber/formatter/event_bus_report_spec.rb +79 -0
  76. data/spec/cucumber/formatter/fail_fast_spec.rb +88 -0
  77. data/spec/cucumber/formatter/json_spec.rb +43 -1
  78. data/spec/cucumber/formatter/rerun_spec.rb +4 -20
  79. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +29 -0
  80. data/spec/cucumber/runtime_spec.rb +2 -28
  81. data/spec/spec_helper.rb +1 -1
  82. data/spec/support/standard_step_actions.rb +18 -0
  83. metadata +37 -13
  84. data/lib/cucumber/core_ext/proc.rb +0 -36
  85. data/spec/cucumber/core_ext/proc_spec.rb +0 -69
@@ -3,18 +3,18 @@ module Cucumber
3
3
  # in a way that also works for other programming languages (i.e. cuke4duke)
4
4
  # Used for reporting purposes only (usage formatter).
5
5
  class StepDefinitionLight
6
- attr_reader :regexp_source, :file_colon_line
6
+ attr_reader :regexp_source, :location
7
7
 
8
- def initialize(regexp_source, file_colon_line)
9
- @regexp_source, @file_colon_line = regexp_source, file_colon_line
8
+ def initialize(regexp_source, location)
9
+ @regexp_source, @location = regexp_source, location
10
10
  end
11
11
 
12
12
  def eql?(o)
13
- regexp_source == o.regexp_source && file_colon_line == o.file_colon_line
13
+ regexp_source == o.regexp_source && location == o.location
14
14
  end
15
15
 
16
16
  def hash
17
- regexp_source.hash + 31*file_colon_line.hash
17
+ regexp_source.hash + 31*location.to_s.hash
18
18
  end
19
19
  end
20
20
  end
@@ -1,8 +1,8 @@
1
1
  module Cucumber
2
2
  class StepDefinitions
3
3
  def initialize(configuration = Configuration.default)
4
- configuration = Configuration.parse(configuration)
5
- @support_code = Runtime::SupportCode.new(nil, false)
4
+ configuration = Configuration.new(configuration)
5
+ @support_code = Runtime::SupportCode.new(nil, configuration)
6
6
  @support_code.load_files_from_paths(configuration.autoload_code_paths)
7
7
  end
8
8
 
@@ -22,7 +22,7 @@ module Cucumber
22
22
  end
23
23
 
24
24
  def activate(test_step)
25
- test_step.with_action(@step_definition.file_colon_line) do
25
+ test_step.with_action(@step_definition.location) do
26
26
  invoke(MultilineArgument.from_core(test_step.source.last.multiline_arg))
27
27
  end
28
28
  end
@@ -52,8 +52,12 @@ module Cucumber
52
52
  @name_to_report || replace_arguments(@name_to_match, @step_arguments, format, &proc)
53
53
  end
54
54
 
55
+ def location
56
+ @step_definition.location
57
+ end
58
+
55
59
  def file_colon_line
56
- @step_definition.file_colon_line
60
+ location.to_s
57
61
  end
58
62
 
59
63
  def backtrace_line
@@ -113,6 +117,11 @@ module Cucumber
113
117
  @name
114
118
  end
115
119
 
120
+ def location
121
+ raise "No location for #{@step}" unless @step.location
122
+ @step.location
123
+ end
124
+
116
125
  def file_colon_line
117
126
  raise "No file:line for #{@step}" unless @step.file_colon_line
118
127
  @step.file_colon_line
@@ -1,5 +1,5 @@
1
1
  require 'cucumber/wire_support/request_handler'
2
- require 'gherkin/formatter/argument'
2
+ require 'cucumber/gherkin/formatter/argument'
3
3
 
4
4
  module Cucumber
5
5
  module WireSupport
@@ -27,7 +27,7 @@ module Cucumber
27
27
  def create_step_match(raw_step_match)
28
28
  step_definition = WireStepDefinition.new(@connection, raw_step_match)
29
29
  step_args = raw_step_match['args'].map do |raw_arg|
30
- Gherkin::Formatter::Argument.new(raw_arg['pos'], raw_arg['val'])
30
+ Cucumber::Gherkin::Formatter::Argument.new(raw_arg['pos'], raw_arg['val'])
31
31
  end
32
32
  step_match(step_definition, step_args)
33
33
  end
@@ -1,13 +1,15 @@
1
+ require 'cucumber/core/ast/location'
2
+
1
3
  module Cucumber
2
4
  module WireSupport
3
5
  class WireStepDefinition
4
- attr_reader :regexp_source, :file_colon_line
6
+ attr_reader :regexp_source, :location
5
7
 
6
8
  def initialize(connection, data)
7
9
  @connection = connection
8
10
  @id = data['id']
9
11
  @regexp_source = data['regexp'] || "Unknown"
10
- @file_colon_line = data['source'] || "Unknown"
12
+ @location = data['source'] ? Cucumber::Core::Ast::Location.from_file_colon_line(data['source']) : Cucumber::Core::Ast::Location.new("Unknown")
11
13
  end
12
14
 
13
15
  def invoke(args)
File without changes
@@ -37,65 +37,6 @@ module Cli
37
37
 
38
38
  attr_reader :out, :error
39
39
 
40
- it "requires env.rb files first" do
41
- given_the_following_files("/features/support/a_file.rb","/features/support/env.rb")
42
-
43
- config.parse!(%w{--require /features})
44
-
45
- expect(config.support_to_load).to eq [
46
- "/features/support/env.rb",
47
- "/features/support/a_file.rb"
48
- ]
49
- end
50
-
51
- it "does not require env.rb files when --dry-run" do
52
- given_the_following_files("/features/support/a_file.rb","/features/support/env.rb")
53
-
54
- config.parse!(%w{--require /features --dry-run})
55
-
56
- expect(config.support_to_load).to eq [
57
- "/features/support/a_file.rb"
58
- ]
59
- end
60
-
61
- it "requires files in vendor/{plugins,gems}/*/cucumber/*.rb" do
62
- given_the_following_files("/vendor/gems/gem_a/cucumber/bar.rb",
63
- "/vendor/plugins/plugin_a/cucumber/foo.rb")
64
-
65
- config.parse!(%w{--require /features})
66
-
67
- expect(config.step_defs_to_load).to eq [
68
- "/vendor/gems/gem_a/cucumber/bar.rb",
69
- "/vendor/plugins/plugin_a/cucumber/foo.rb"
70
- ]
71
- end
72
-
73
- describe "--exclude" do
74
-
75
- it "excludes a ruby file from requiring when the name matches exactly" do
76
- given_the_following_files("/features/support/a_file.rb","/features/support/env.rb")
77
-
78
- config.parse!(%w{--require /features --exclude a_file.rb})
79
-
80
- expect(config.all_files_to_load).to eq [
81
- "/features/support/env.rb"
82
- ]
83
- end
84
-
85
- it "excludes all ruby files that match the provided patterns from requiring" do
86
- given_the_following_files("/features/support/foof.rb","/features/support/bar.rb",
87
- "/features/support/food.rb","/features/blah.rb",
88
- "/features/support/fooz.rb")
89
-
90
- config.parse!(%w{--require /features --exclude foo[df] --exclude blah})
91
-
92
- expect(config.all_files_to_load).to eq [
93
- "/features/support/bar.rb",
94
- "/features/support/fooz.rb"
95
- ]
96
- end
97
- end
98
-
99
40
  it "uses the default profile when no profile is defined" do
100
41
  given_cucumber_yml_defined_as({'default' => '--require some_file'})
101
42
 
@@ -397,54 +338,11 @@ END_OF_MESSAGE
397
338
  expect(config.options[:name_regexps]).to include(/User signs up/)
398
339
  end
399
340
 
400
- it "preserves the order of the feature files" do
401
- config.parse!(%w{b.feature c.feature a.feature})
402
-
403
- expect(config.feature_files).to eq ["b.feature", "c.feature", "a.feature"]
404
- end
405
-
406
- it "searchs for all features in the specified directory" do
407
- allow(File).to receive(:directory?) { true }
408
- allow(Dir).to receive(:[]).with("feature_directory/**/*.feature") { ["cucumber.feature"] }
409
-
410
- config.parse!(%w{feature_directory/})
411
-
412
- expect(config.feature_files).to eq ["cucumber.feature"]
413
- end
414
-
415
- it "defaults to the features directory when no feature file are provided" do
416
- allow(File).to receive(:directory?) { true }
417
- allow(Dir).to receive(:[]).with("features/**/*.feature") { ["cucumber.feature"] }
418
-
419
- config.parse!(%w{})
420
-
421
- expect(config.feature_files).to eq ["cucumber.feature"]
422
- end
423
-
424
- it "gets the feature files from the rerun file" do
425
- allow(File).to receive(:directory?).and_return(false)
426
- allow(File).to receive(:file?).and_return(true)
427
- allow(IO).to receive(:read).and_return(
428
- "cucumber.feature:1:3\ncucumber.feature:5 cucumber.feature:10\n"\
429
- "domain folder/different cuke.feature:134 domain folder/cuke.feature:1\n"\
430
- "domain folder/different cuke.feature:4:5 bar.feature")
431
- config.parse!(%w{@rerun.txt})
432
-
433
- expect(config.feature_files).to eq [
434
- "cucumber.feature:1:3",
435
- "cucumber.feature:5",
436
- "cucumber.feature:10",
437
- "domain folder/different cuke.feature:134",
438
- "domain folder/cuke.feature:1",
439
- "domain folder/different cuke.feature:4:5",
440
- "bar.feature"]
441
- end
442
-
443
341
  it "should allow specifying environment variables on the command line" do
444
342
  config.parse!(["foo=bar"])
445
343
 
446
344
  expect(ENV["foo"]).to eq "bar"
447
- expect(config.feature_files).not_to include('foo=bar')
345
+ expect(config.paths).not_to include('foo=bar')
448
346
  end
449
347
 
450
348
  it "allows specifying environment variables in profiles" do
@@ -452,7 +350,7 @@ END_OF_MESSAGE
452
350
  config.parse!(["--profile", "selenium"])
453
351
 
454
352
  expect(ENV["RAILS_ENV"]).to eq "selenium"
455
- expect(config.feature_files).not_to include('RAILS_ENV=selenium')
353
+ expect(config.paths).not_to include('RAILS_ENV=selenium')
456
354
  end
457
355
 
458
356
  describe "#tag_expression" do
@@ -1,6 +1,5 @@
1
1
  require 'spec_helper'
2
2
  require 'yaml'
3
- require 'gherkin/formatter/model'
4
3
 
5
4
  module Cucumber
6
5
  module Cli
@@ -66,27 +65,6 @@ module Cucumber
66
65
  end
67
66
  end
68
67
 
69
- describe "--format with class" do
70
- describe "in module" do
71
- let(:double_module) { double('module') }
72
- let(:formatter) { double('formatter') }
73
-
74
- it "resolves each module until it gets Formatter class" do
75
- cli = Main.new(%w{--format ZooModule::MonkeyFormatterClass}, stdin, stdout, stderr, kernel)
76
-
77
- allow(Object).to receive(:const_defined?) { true }
78
- allow(double_module).to receive(:const_defined?) { true }
79
-
80
- expect(Object).to receive(:const_get).with('ZooModule', false) { double_module }
81
- expect(double_module).to receive(:const_get).with('MonkeyFormatterClass', false) { double('formatter class', :new => formatter) }
82
-
83
- expect(kernel).to receive(:exit).with(0)
84
-
85
- cli.execute!
86
- end
87
- end
88
- end
89
-
90
68
  [ProfilesNotDefinedError, YmlLoadError, ProfileNotFound].each do |exception_klass|
91
69
  it "rescues #{exception_klass}, prints the message to the error stream" do
92
70
  configuration = double('configuration')
@@ -87,7 +87,9 @@ module Cucumber
87
87
 
88
88
  it "displays the language table" do
89
89
  after_parsing '--i18n foo' do
90
- expect(@output_stream.string).to include(Gherkin::I18n.language_table);
90
+ ::Gherkin3::DIALECTS.keys.map do |key|
91
+ expect(@output_stream.string).to include("#{key}");
92
+ end
91
93
  end
92
94
  end
93
95
  end
@@ -19,5 +19,128 @@ module Cucumber
19
19
  expect(subject.autoload_code_paths).to eq ['foo/bar/baz']
20
20
  end
21
21
  end
22
+
23
+ context "selecting files to load" do
24
+
25
+ def given_the_following_files(*files)
26
+ allow(File).to receive(:directory?) { true }
27
+ allow(File).to receive(:file?) { true }
28
+ allow(Dir).to receive(:[]) { files }
29
+ end
30
+
31
+ it "requires env.rb files first" do
32
+ configuration = Configuration.new
33
+ given_the_following_files("/features/support/a_file.rb","/features/support/env.rb")
34
+
35
+ expect(configuration.support_to_load).to eq [
36
+ "/features/support/env.rb",
37
+ "/features/support/a_file.rb"
38
+ ]
39
+ end
40
+
41
+ it "does not require env.rb files when dry run" do
42
+ configuration = Configuration.new(dry_run: true)
43
+ given_the_following_files("/features/support/a_file.rb","/features/support/env.rb")
44
+
45
+ expect(configuration.support_to_load).to eq [
46
+ "/features/support/a_file.rb"
47
+ ]
48
+ end
49
+
50
+ it "requires step defs in vendor/{plugins,gems}/*/cucumber/*.rb" do
51
+ given_the_following_files("/vendor/gems/gem_a/cucumber/bar.rb",
52
+ "/vendor/plugins/plugin_a/cucumber/foo.rb")
53
+
54
+ configuration = Configuration.new
55
+
56
+ expect(configuration.step_defs_to_load).to eq [
57
+ "/vendor/gems/gem_a/cucumber/bar.rb",
58
+ "/vendor/plugins/plugin_a/cucumber/foo.rb"
59
+ ]
60
+ end
61
+
62
+ describe "--exclude" do
63
+
64
+ it "excludes a ruby file from requiring when the name matches exactly" do
65
+ given_the_following_files("/features/support/a_file.rb","/features/support/env.rb")
66
+
67
+ configuration = Configuration.new(excludes: [/a_file.rb/])
68
+
69
+ expect(configuration.all_files_to_load).to eq [
70
+ "/features/support/env.rb"
71
+ ]
72
+ end
73
+
74
+ it "excludes all ruby files that match the provided patterns from requiring" do
75
+ given_the_following_files("/features/support/foof.rb","/features/support/bar.rb",
76
+ "/features/support/food.rb","/features/blah.rb",
77
+ "/features/support/fooz.rb")
78
+
79
+ configuration = Configuration.new(excludes: [/foo[df]/, /blah/])
80
+
81
+ expect(configuration.all_files_to_load).to eq [
82
+ "/features/support/bar.rb",
83
+ "/features/support/fooz.rb"
84
+ ]
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ context "selecting feature files" do
91
+
92
+ it "preserves the order of the feature files" do
93
+ configuration = Configuration.new(paths: %w{b.feature c.feature a.feature})
94
+
95
+ expect(configuration.feature_files).to eq ["b.feature", "c.feature", "a.feature"]
96
+ end
97
+
98
+ it "searchs for all features in the specified directory" do
99
+ allow(File).to receive(:directory?) { true }
100
+ allow(Dir).to receive(:[]).with("feature_directory/**/*.feature") { ["cucumber.feature"] }
101
+
102
+ configuration = Configuration.new(paths: %w{feature_directory/})
103
+
104
+ expect(configuration.feature_files).to eq ["cucumber.feature"]
105
+ end
106
+
107
+ it "defaults to the features directory when no feature file are provided" do
108
+ allow(File).to receive(:directory?) { true }
109
+ allow(Dir).to receive(:[]).with("features/**/*.feature") { ["cucumber.feature"] }
110
+
111
+ configuration = Configuration.new(paths: [])
112
+
113
+ expect(configuration.feature_files).to eq ["cucumber.feature"]
114
+ end
115
+
116
+ it "gets the feature files from the rerun file" do
117
+ allow(File).to receive(:directory?).and_return(false)
118
+ allow(File).to receive(:file?).and_return(true)
119
+ allow(IO).to receive(:read).and_return(
120
+ "cucumber.feature:1:3\ncucumber.feature:5 cucumber.feature:10\n"\
121
+ "domain folder/different cuke.feature:134 domain folder/cuke.feature:1\n"\
122
+ "domain folder/different cuke.feature:4:5 bar.feature")
123
+
124
+ configuration = Configuration.new(paths: %w{@rerun.txt})
125
+
126
+ expect(configuration.feature_files).to eq [
127
+ "cucumber.feature:1:3",
128
+ "cucumber.feature:5",
129
+ "cucumber.feature:10",
130
+ "domain folder/different cuke.feature:134",
131
+ "domain folder/cuke.feature:1",
132
+ "domain folder/different cuke.feature:4:5",
133
+ "bar.feature"]
134
+ end
135
+ end
136
+
137
+ describe "#with_options" do
138
+ it "returns a copy of the configuration with new options" do
139
+ new_out_stream = double
140
+ config = Configuration.new.with_options(out_stream: new_out_stream)
141
+ expect(config.out_stream).to eq new_out_stream
142
+ end
143
+ end
144
+
22
145
  end
23
146
  end
@@ -0,0 +1,94 @@
1
+ require "cucumber/events/bus"
2
+
3
+ module Cucumber
4
+ module Events
5
+ class TestEvent
6
+ end
7
+
8
+ class AnotherTestEvent
9
+ end
10
+
11
+ describe Bus do
12
+ let(:bus) { Bus.new(Cucumber::Events) }
13
+ let(:test_event) { TestEvent.new }
14
+ let(:another_test_event) { AnotherTestEvent.new }
15
+
16
+ it "calls subscriber with event payload" do
17
+ received_payload = nil
18
+ bus.register(TestEvent) do |event|
19
+ received_payload = event
20
+ end
21
+
22
+ bus.notify test_event
23
+
24
+ expect(received_payload).to eq(test_event)
25
+ end
26
+
27
+ it "does not call subscribers for other events" do
28
+ handler_called = false
29
+ bus.register(TestEvent) do |event|
30
+ handler_called = true
31
+ end
32
+
33
+ bus.notify another_test_event
34
+
35
+ expect(handler_called).to eq(false)
36
+ end
37
+
38
+ it "broadcasts to multiple subscribers" do
39
+ received_events = []
40
+ bus.register(TestEvent) do |event|
41
+ received_events << event
42
+ end
43
+ bus.register(TestEvent) do |event|
44
+ received_events << event
45
+ end
46
+
47
+ bus.notify test_event
48
+
49
+ expect(received_events.length).to eq 2
50
+ expect(received_events).to all eq test_event
51
+ end
52
+
53
+ it "allows subscription by string" do
54
+ received_payload = nil
55
+ bus.register('Cucumber::Events::TestEvent') do |event|
56
+ received_payload = event
57
+ end
58
+
59
+ bus.notify test_event
60
+
61
+ expect(received_payload).to eq(test_event)
62
+ end
63
+
64
+ it "allows subscription by symbol (for events in the Cucumber::Events namespace)" do
65
+ received_payload = nil
66
+ bus.register(:test_event) do |event|
67
+ received_payload = event
68
+ end
69
+
70
+ bus.notify test_event
71
+
72
+ expect(received_payload).to eq(test_event)
73
+ end
74
+
75
+ it "allows handlers that are objects with a `call` method" do
76
+ class MyHandler
77
+ attr_reader :received_payload
78
+
79
+ def call(event)
80
+ @received_payload = event
81
+ end
82
+ end
83
+
84
+ handler = MyHandler.new
85
+ bus.register(TestEvent, handler)
86
+
87
+ bus.notify test_event
88
+
89
+ expect(handler.received_payload).to eq test_event
90
+ end
91
+
92
+ end
93
+ end
94
+ end