Skip to content

Commit

Permalink
Support class reloading for Event Subscribers
Browse files Browse the repository at this point in the history
Before this change, editing an instance of Spree::Event::Subscriber
would result in not being reloaded or being subscribed twice.

With this change each includer of Event::Subscriber is registered by its
name and later unsubscribed just before class unload (using old module
instance), then resubscribed after the new code is loaded.
  • Loading branch information
elia committed Jul 9, 2019
1 parent 08053be commit 64ce0d8
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 2 deletions.
11 changes: 9 additions & 2 deletions core/lib/spree/core/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,15 @@ class Engine < ::Rails::Engine
Migrations.new(config, engine_name).check
end

initializer 'spree.core.mailer_subscriber' do
Spree::MailerSubscriber.subscribe!
# Setup Event Subscribers
initializer 'spree.core.initialize_subscribers' do |app|
app.reloader.to_prepare do
Spree::Event.subscribers.each(&:subscribe!)
end

app.reloader.before_class_unload do
Spree::Event.subscribers.each(&:unsubscribe!)
end
end

# Load in mailer previews for apps to use in development.
Expand Down
6 changes: 6 additions & 0 deletions core/lib/spree/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ def suffix
Spree::Config.events.suffix
end

# @!attribute [r] subscribers
# @return [Array<Spree::Event::Subscriber>] A list of subscribers used to support class reloading for Spree::Event::Subscriber instances
def subscribers
Spree::Config.events.subscribers
end

private

def name_with_suffix(name)
Expand Down
8 changes: 8 additions & 0 deletions core/lib/spree/event/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# frozen_string_literal: true

require 'spree/core/class_constantizer'

module Spree
module Event
class Configuration
def subscribers
@subscribers ||= ::Spree::Core::ClassConstantizer::Set.new.tap do |set|
set << 'Spree::MailerSubscriber'
end
end

attr_writer :adapter, :suffix

def adapter
Expand Down
26 changes: 26 additions & 0 deletions core/spec/lib/spree/event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,30 @@
end
end
end

describe '.subscribers' do
let(:subscriber) { instance_double(Module, 'Subscriber') }
let(:subscriber_name) { instance_double(String, 'Subscriber name') }

before do
described_class.subscribers.clear
allow(subscriber).to receive(:name).and_return(subscriber_name)
allow(subscriber_name).to receive(:constantize).and_return(subscriber)
allow(subscriber_name).to receive(:to_s).and_return(subscriber_name)
end

it 'accepts the names of constants' do
Spree::Config.events.subscribers << subscriber_name

expect(described_class.subscribers.to_a).to eq([subscriber])
end

it 'discards duplicates' do
described_class.subscribers << subscriber_name
described_class.subscribers << subscriber_name
described_class.subscribers << subscriber_name

expect(described_class.subscribers.to_a).to eq([subscriber])
end
end
end

0 comments on commit 64ce0d8

Please sign in to comment.