forked from solidusio/solidus
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce Spree::Event's test interface to run only selected listeners
Given the global nature of our event bus, we need a system to scope the execution of a block to a selected list of subscribers. That's useful for testing purposes, as we need to be sure that others subscribers are not interfering with our expectations. This commit introduces a `Spree::Event.performing_only(listeners)` method. It takes a block during the execution of which only the provided listeners are subscribed: ```ruby listener1 = Spree::Event.subscribe('foo') { do_something } listener2 = Spree::Event.subscribe('foo') { do_something_else } Spree::Event.performing_only(listener1) do Spree::Event.fire('foo') # only listener1 will run end Spree::Event.fire('foo') # both listener1 & listener2 will run ``` This behavior is only available for the new `Spree::Event::Adapters::Default` adapter. We only need that for testing purposes, so the method is made available after calling `Spree::Event.enable_test_interface`. It prevents the main `Spree::Event` API from being bloated and sends a more explicit message to users. We also add a `Spree::Subscriber#listeners` method, which returns the set of generated listeners for a given subscriber module. It's called automatically by `Spree::Event.performing_only` so that users can directly specify that they only want the listeners for a given subscriber module to be run. `Spree::Subscriber#listeners` accepts an array of event names as arguments in case more fine-grained control is required. ```ruby module EmailSubscriber include Spree::Event::Subscriber event_action :foo event_action :bar def foo(_event) do_something end def bar(_event) do_something_else end end Spree::Event.performing_only(EmailSubscriber) do Spree::Event.fire('foo') # both foo & bar methods will run end Spree::Event.performing_only(EmailSubscriber.listeners('foo')) do Spree::Event.fire('foo') # only foo method will run end ``` A specialized `Spree::Event.performing_nothing` method calls `Spree::Event.performing_only` with no listeners at all.
- Loading branch information
1 parent
9dbcad1
commit 7d9b4e9
Showing
11 changed files
with
452 additions
and
4 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
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
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
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
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
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,93 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spree/event' | ||
|
||
module Spree | ||
module Event | ||
# Test helpers for {Spree::Event} | ||
# | ||
# This module defines test helpers methods for {Spree::Event}. They can be | ||
# made available to {Spree::Event} when {Spree::Event.enable_test_interface} | ||
# is called. | ||
# | ||
# If you prefer, you can directly call them from | ||
# `Spree::Event::TestInterface}. | ||
module TestInterface | ||
# @see {Spree::Event::TestInterface} | ||
module Methods | ||
# Perform only given listeners for the duration of the block | ||
# | ||
# Temporarily deactivate all subscribed listeners and listen only to the | ||
# provided ones for the duration of the block. | ||
# | ||
# @example | ||
# Spree::Event.enable_test_interface | ||
# | ||
# listener1 = Spree::Event.subscribe('foo') { do_something } | ||
# listener2 = Spree::Event.subscribe('foo') { do_something_else } | ||
# | ||
# Spree::Event.performing_only(listener1) do | ||
# Spree::Event.fire('foo') # This will run only `listener1` | ||
# end | ||
# | ||
# Spree::Event.fire('foo') # This will run both `listener1` & `listener2` | ||
# | ||
# {Spree::Event::Subscriber} modules can also be given to unsubscribe from | ||
# all listeners generated from it: | ||
# | ||
# @example | ||
# Spree::Event.performing_only(EmailSubscriber) {} | ||
# | ||
# You can gain more fine-grained control thanks to | ||
# {Spree::Event::Subscribe#listeners}: | ||
# | ||
# @example | ||
# Spree::Event.performing_only(EmailSubscriber.listeners('order_finalized')) {} | ||
# | ||
# You can mix different ways of specifying listeners without problems: | ||
# | ||
# @example | ||
# Spree::Event.performing_only(EmailSubscriber, listener1) {} | ||
# | ||
# @param listeners_and_subscribers [Spree::Event::Listener, | ||
# Array<Spree::Event::Listener>, Spree::Event::Subscriber] | ||
# @yield While the block executes only provided listeners will run | ||
def performing_only(*listeners_and_subscribers) | ||
adapter_in_use = Spree::Event.default_adapter | ||
listeners = listeners_and_subscribers.flatten.map(&:listeners) | ||
Spree::Config.events.adapter = adapter_in_use.with_listeners(listeners.flatten) | ||
yield | ||
ensure | ||
Spree::Config.events.adapter = adapter_in_use | ||
end | ||
|
||
# Perform no listeners for the duration of the block | ||
# | ||
# It's a specialized version of {#performing_only} that provides no | ||
# listeners. | ||
# | ||
# @yield While the block executes no listeners will run | ||
# | ||
# @see Spree::Event::TestInterface#performing_only | ||
def performing_nothing(&block) | ||
performing_only(&block) | ||
end | ||
end | ||
|
||
extend Methods | ||
end | ||
|
||
# Adds test methods to {Spree::Event} | ||
# | ||
# @raise [RuntimeError] when {Spree::Event::Configuration#adapter} is set to | ||
# the legacy adapter {Spree::Event::Adapters::ActiveSupportNotifications}. | ||
def enable_test_interface | ||
raise <<~MSG if deprecation_handler.legacy_adapter?(default_adapter) | ||
Spree::Event's test interface is not supported when using the deprecated | ||
adapter 'Spree::Event::Adapters::ActiveSupportNotifications'. | ||
MSG | ||
|
||
extend(TestInterface::Methods) | ||
end | ||
end | ||
end |
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
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
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
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
Oops, something went wrong.