-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4214 from solidusio/waiting-for-dev/events_stubs
Add stubbing test helpers for the event bus
- Loading branch information
Showing
2 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spree/event' | ||
|
||
module Spree | ||
module TestingSupport | ||
# RSpec test helpers for the event bus | ||
# | ||
# If you want to use the methods defined in this module, include it in your | ||
# specs: | ||
# | ||
# @example | ||
# require 'rails_helper' | ||
# require 'spree/testing_support/event_helpers' | ||
# | ||
# RSpec.describe MyClass do | ||
# include Spree::TestingSupport::EventHelpers | ||
# end | ||
# | ||
# or, globally, in your `spec_helper.rb`: | ||
# | ||
# @example | ||
# require 'spree/testing_support/event_helpers' | ||
# | ||
# RSpec.configure do |config| | ||
# config.include Spree::TestingSupport::EventHelpers | ||
# end | ||
module EventHelpers | ||
extend RSpec::Matchers::DSL | ||
|
||
# Stubs {Spree::Event} | ||
# | ||
# After you have called this method in an example, {Spree::Event} will no | ||
# longer listen to any event for the duration of that example. All the | ||
# method invocations on it will be spied but not performed. | ||
# | ||
# Internally, it stubs {Spree::Event} to a class spy of itself. | ||
# | ||
# After you call this method, probably you'll want to call some of the | ||
# matchers defined in this module. | ||
def stub_spree_events | ||
stub_const('Spree::Event', class_spy(Spree::Event)) | ||
end | ||
|
||
# @!method have_been_fired(event_name) | ||
# Matcher to test that an event has been fired via {Spree::Event#fire} | ||
# | ||
# Before using this matcher, you need to call {#stub_spree_events}. | ||
# | ||
# Remember that the event listeners won't be performed. | ||
# | ||
# @example | ||
# it 'fires foo event' do | ||
# stub_spree_events | ||
# | ||
# Spree::Event.fire 'foo' | ||
# | ||
# expect('foo').to have_been_fired | ||
# end | ||
# | ||
# It can be chain through `with` to match with the published payload: | ||
# | ||
# @example | ||
# it 'fires foo event with the expected payload' do | ||
# stub_spree_events | ||
# | ||
# Spree::Event.fire 'foo', bar: :baz, qux: :quux | ||
# | ||
# expect('foo').to have_been_fired.with(a_hash_including(bar: :baz)) | ||
# end | ||
# | ||
# @param [String, Symbol] event_name | ||
matcher :have_been_fired do | ||
chain :with, :payload | ||
|
||
match do |expected_event| | ||
expected_event = normalize_name(expected_event) | ||
arguments = payload ? [expected_event, payload] : [expected_event, any_args] | ||
expect(Spree::Event).to have_received(:fire).with(*arguments) | ||
end | ||
|
||
failure_message do |expected_event| | ||
<<~MSG | ||
expected #{expected_event.inspect} to have been fired. | ||
Make sure that provided payload, if any, also matches. | ||
MSG | ||
end | ||
|
||
def normalize_name(event_name) | ||
if event_name.is_a?(String) | ||
eq(event_name).or(eq(event_name.to_sym)) | ||
elsif event_name.is_a?(Symbol) | ||
eq(event_name).or(eq(event_name.to_s)) | ||
else | ||
raise ArgumentError, <<~MSG | ||
"#{event_name.inspect} is not a valid event name. It must be a String or a Symbol." | ||
MSG | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
110 changes: 110 additions & 0 deletions
110
core/spec/lib/spree/core/testing_support/event_helpers_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spec_helper' | ||
require 'spree/testing_support/event_helpers' | ||
|
||
RSpec.describe Spree::TestingSupport::EventHelpers do | ||
include described_class | ||
|
||
describe '#stub_spree_events' do | ||
it 'creates a spy class from Spree::Event and assigns to itself' do | ||
stub_spree_events | ||
|
||
expect(Spree::Event.inspect).to include('ClassDouble') | ||
|
||
Spree::Event.fire 'foo' | ||
|
||
expect(Spree::Event).to have_received(:fire) | ||
end | ||
end | ||
|
||
describe '#have_been_fired' do | ||
it "matches when the event has been fired without payload and there's no expectation on it" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire 'foo' | ||
|
||
expect('foo').to have_been_fired | ||
end | ||
|
||
it "matches when the event has been fired with payload but there's no expectation on it" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire 'foo', bar: :baz | ||
|
||
expect('foo').to have_been_fired | ||
end | ||
|
||
it "matches when the event has been fired with payload and the expectation on it matches" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire 'foo', bar: :baz | ||
|
||
expect('foo').to have_been_fired.with(bar: :baz) | ||
end | ||
|
||
it "matches when fired as string and matched as string" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire 'foo' | ||
|
||
expect('foo').to have_been_fired | ||
end | ||
|
||
it "matches when fired as string but matched as symbol" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire 'foo' | ||
|
||
expect(:foo).to have_been_fired | ||
end | ||
|
||
it "matches when fired as symbol but matched as string" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire :foo | ||
|
||
expect('foo').to have_been_fired | ||
end | ||
|
||
it "matches when fired as symbol and matched as symbol" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire :foo | ||
|
||
expect(:foo).to have_been_fired | ||
end | ||
|
||
it "can match payload with an inner matcher" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire 'foo', bar: :baz, tar: :tar | ||
|
||
expect('foo').to have_been_fired.with(a_hash_including(bar: :baz)) | ||
end | ||
|
||
it "doesn't match when the event hasn't been fired" do | ||
stub_spree_events | ||
|
||
expect { | ||
expect('foo').to have_been_fired | ||
}.to raise_error /expected "foo" to have been fired/ | ||
end | ||
|
||
it "doesn't match when the event has been fired but the payload doesn't match" do | ||
stub_spree_events | ||
|
||
Spree::Event.fire 'foo', foo: :bar | ||
|
||
expect { | ||
expect('foo').to have_been_fired.with(bar: :baz) | ||
}.to raise_error /Make sure that provided payload.*also matches/ | ||
end | ||
|
||
it "raises when expected event is not a valid name" do | ||
expect { | ||
expect([]).to have_been_fired.with(bar: :baz) | ||
}.to raise_error /not a valid event name/ | ||
end | ||
end | ||
end |