Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/cucumber/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
module Cucumber
module Core

def execute(gherkin_documents, filters = [], event_bus = EventBus.new)
def execute(gherkin_documents, filters = [], event_bus = create_and_start_event_bus)
yield event_bus if block_given?
receiver = Test::Runner.new(event_bus)
compile gherkin_documents, receiver, filters
Expand Down Expand Up @@ -39,5 +39,10 @@ def compose(filters, last_receiver)
end
end

def create_and_start_event_bus
event_bus = EventBus.new
event_bus.start
event_bus
end
end
end
30 changes: 28 additions & 2 deletions lib/cucumber/core/event_bus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,22 @@ module Core
# to subscribe to events that fire as your tests are executed.
#
class EventBus
attr_reader :event_types
attr_reader :event_types, :started
private :started

# @param [Hash{Symbol => Class}] a hash of event types to use on the bus
def initialize(registry = Events.registry)
@event_types = registry.freeze
@handlers = {}
@started = false
end

def start
event_queue.each do |event|
do_broadcast(event)
end
reset_event_queue
@started = true
end

# Register for an event. The handler proc will be called back with each of the attributes
Expand All @@ -29,7 +39,11 @@ def on(event_id, handler_object = nil, &handler_proc)
# Broadcast an event
def broadcast(event)
raise ArgumentError, "Event type #{event.class} is not registered. Try one of these:\n#{event_types.values.join("\n")}" unless is_registered_type?(event.class)
handlers_for(event.class).each { |handler| handler.call(event) }
if started
do_broadcast(event)
else
event_queue << event
end
end

def method_missing(event_id, *args)
Expand All @@ -45,6 +59,10 @@ def handlers_for(event_class)
@handlers[event_class.to_s] ||= []
end

def do_broadcast(event)
handlers_for(event.class).each { |handler| handler.call(event) }
end

def is_registered_id?(event_id)
event_types.keys.include?(event_id)
end
Expand All @@ -58,6 +76,14 @@ def validate_handler_and_event_id!(handler, event_id)
raise ArgumentError, "Please use a symbol for the event_id" unless event_id.is_a?(Symbol)
raise ArgumentError, "Event ID #{event_id} is not recognised. Try one of these:\n#{event_types.keys.join("\n")}" unless is_registered_id?(event_id)
end

def event_queue
@event_queue ||= []
end

def reset_event_queue
@event_queue = []
end
end

end
Expand Down
35 changes: 29 additions & 6 deletions spec/cucumber/core/event_bus_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class TestEvent < Core::Event.new(:some_attribute)

context "broadcasting events" do

before(:each) { event_bus.start }

it "can broadcast by calling a method named after the event ID" do
called = false
event_bus.on(:test_event) {called = true }
Expand Down Expand Up @@ -82,7 +84,23 @@ class TestEvent < Core::Event.new(:some_attribute)

end

context "queuing events" do

it "before the event bus is started, events are queued and broadcasted when started" do
called = false
event_bus.on(:test_event) {called = true }
event_bus.test_event
expect(called).to be false
event_bus.start
expect(called).to be true
end

end

context "subscribing to events" do

before(:each) { event_bus.start }

it "allows subscription by symbol (Event ID)" do
received_payload = nil
event_bus.on(:test_event) do |event|
Expand Down Expand Up @@ -138,14 +156,19 @@ def on_test_event(event)

end

it "will let you inspect the registry" do
expect(event_bus.event_types[:test_event]).to eq Events::TestEvent
end
context "event registry" do

it "won't let you modify the registry" do
expect { event_bus.event_types[:foo] = :bar }.to raise_error(RuntimeError)
end
before(:each) { event_bus.start }

it "will let you inspect the registry" do
expect(event_bus.event_types[:test_event]).to eq Events::TestEvent
end

it "won't let you modify the registry" do
expect { event_bus.event_types[:foo] = :bar }.to raise_error(RuntimeError)
end

end
end
end
end
5 changes: 4 additions & 1 deletion spec/cucumber/core/report/summary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ module Cucumber::Core::Report
let(:duration) { double }
let(:exception) { double }

before(:each) { @summary = Summary.new(event_bus) }
before(:each) do
@summary = Summary.new(event_bus)
event_bus.start
end

context "test case summary" do
let(:test_case) { double }
Expand Down
7 changes: 3 additions & 4 deletions spec/cucumber/core_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ def expect_tag_excess(error_message)
end

describe "executing a test suite" do
let(:event_bus) { Core::EventBus.new }

before(:each) { event_bus.start }

it "fires events" do
gherkin = gherkin do
Expand Down Expand Up @@ -273,7 +276,6 @@ def expect_tag_excess(error_message)
end
end

event_bus = Core::EventBus.new
report = Core::Report::Summary.new(event_bus)
execute [gherkin], [Core::Test::Filters::ActivateStepsForSelfTest.new], event_bus

Expand Down Expand Up @@ -317,7 +319,6 @@ def test_case(test_case)
end
logger = []

event_bus = Core::EventBus.new
report = Core::Report::Summary.new(event_bus)
execute [gherkin], [WithAroundHooks.new(logger)], event_bus

Expand Down Expand Up @@ -352,7 +353,6 @@ def test_case(test_case)
end
end

event_bus = Core::EventBus.new
report = Core::Report::Summary.new(event_bus)
execute [gherkin], [ Cucumber::Core::Test::TagFilter.new(['@a']) ], event_bus

Expand All @@ -371,7 +371,6 @@ def test_case(test_case)
end
end

event_bus = Core::EventBus.new
report = Core::Report::Summary.new(event_bus)
execute [gherkin], [ Cucumber::Core::Test::NameFilter.new([/scenario/]) ], event_bus

Expand Down