Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 6cc0b28

Browse files
committed
allow the reporter to send custom events to registered formatters
1 parent 9d12a30 commit 6cc0b28

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

lib/rspec/core/notifications.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,5 +599,19 @@ def self.from_hash(data)
599599
# currently require no information, but we may wish to extend in future.
600600
class NullNotification
601601
end
602+
603+
# `CustomNotification` is used when sending custom events to formatters /
604+
# other registered listeners, it creates attributes based on supplied hash
605+
# of options.
606+
class CustomNotification < Struct
607+
# @param options [Hash] A hash of method / value pairs to create on this notification
608+
# @return [CustomNotification]
609+
#
610+
# Build a custom notification based on the supplied option key / values.
611+
def self.for(options={})
612+
return NullNotification if options.keys.empty?
613+
new(*options.keys).new(*options.values)
614+
end
615+
end
602616
end
603617
end

lib/rspec/core/reporter.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ module RSpec::Core
22
# A reporter will send notifications to listeners, usually formatters for the
33
# spec suite run.
44
class Reporter
5+
# @private
6+
NOTIFICATIONS =
7+
[
8+
:close, :deprecation, :deprecation_summary, :dump_failures, :dump_pending,
9+
:dump_profile, :dump_summary, :example_failed, :example_group_finished,
10+
:example_group_started, :example_passed, :example_pending, :example_started,
11+
:message, :seed, :start, :start_dump, :stop
12+
]
13+
514
def initialize(configuration)
615
@configuration = configuration
716
@listeners = Hash.new { |h, k| h[k] = Set.new }
@@ -79,6 +88,19 @@ def message(message)
7988
notify :message, Notifications::MessageNotification.new(message)
8089
end
8190

91+
# @param event [Symbol] Name of the custom event to trigger on formatters
92+
# @param options [Hash] Hash of arguments to provide via `CustomNotification`
93+
#
94+
# Publish a custom event to supporting registered formatters.
95+
# @see RSpec::Core::Notifications::CustomNotification
96+
def publish(event, options={})
97+
if NOTIFICATIONS.include? event
98+
raise "RSpec::Core::Reporter#publish is intended for sending custom " \
99+
"events not internal RSpec ones, please rename your custom event."
100+
end
101+
notify event, Notifications::CustomNotification.for(options)
102+
end
103+
82104
# @private
83105
def example_group_started(group)
84106
notify :example_group_started, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty?

spec/rspec/core/reporter_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,33 @@ module RSpec::Core
172172
end
173173
end
174174

175+
describe "#publish" do
176+
let(:listener) { double("listener", :custom => nil) }
177+
before do
178+
reporter.register_listener listener, :custom, :start
179+
end
180+
181+
it 'will send custom events to registered listeners' do
182+
expect(listener).to receive(:custom).with(RSpec::Core::Notifications::NullNotification)
183+
reporter.publish :custom
184+
end
185+
186+
it 'will raise when encountering RSpec standard events' do
187+
expect { reporter.publish :start }.to raise_error
188+
end
189+
190+
it 'will ignore event names sent as strings' do
191+
expect(listener).not_to receive(:custom)
192+
reporter.publish "custom"
193+
end
194+
195+
it 'will provide a custom notification object based on the options hash' do
196+
expect(listener).to receive(:custom)
197+
.with(an_object_having_attributes(:my_data => :value))
198+
reporter.publish :custom, :my_data => :value
199+
end
200+
end
201+
175202
describe "timing" do
176203
before do
177204
config.start_time = start_time

0 commit comments

Comments
 (0)