Skip to content

Commit

Permalink
Fix publishing events responding to #to_hash on Ruby 2.7
Browse files Browse the repository at this point in the history
When a method accepts both splatted positional & keyword parameters and
a single argument responding to `#to_hash` is given, the argument is
coerced to hash and assigned to the keyword arguments.

E.g.:

class Hashable
  def to_hash
    { im: :a_hash }
  end
end

def method_with_splat_on_the_positional_argument(*args, **kwargs) # method_with_splat_on_the_positional_argument(Hashable.new)
  puts args.inspect # =>  []
  puts kwargs.inspect # => {:im=>:a_hash}
end

However,

def method_without_splat_on_the_positional_argument(args, **kwargs) # method_without_splat_on_the_positional_argument(Hashable.new)
  puts args.inspect # => #<Hashable:0x000055cfe8b072b0>
  puts kwargs.inspect # => {}
end

We fix the problem on the Spree::Bus override by being explicit about
the expected parameters.

References solidusio/solidus_stripe#157 (comment)

(cherry picked from commit d69f8d7)
  • Loading branch information
waiting-for-dev committed Feb 1, 2023
1 parent 531d60a commit 0f3adac
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
6 changes: 3 additions & 3 deletions core/lib/spree/bus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ module Spree
# It has some modifications to support internal usage of the legacy event
# system {see Spree::AppConfiguration#use_legacy_events}.
Bus = Omnes::Bus.new
Bus.define_singleton_method(:publish) do |*args, **kwargs, &block|
def Bus.publish(event, **kwargs)
if Spree::Config.use_legacy_events
Spree::Event.fire(*args, **kwargs, &block)
Spree::Event.fire(event, **kwargs)
else
# Override caller_location to point to the actual event publisher
super(*args, **kwargs, caller_location: caller_locations(1)[0], &block)
super(event, **kwargs, caller_location: caller_locations(1)[0])
end
end
end
25 changes: 25 additions & 0 deletions core/spec/lib/spree/bus_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Spree::Bus do
describe '.publish' do
it "doesn't coerce events responding to #to_hash",
if: (Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.0")) && !Spree::Config.use_legacy_events do
described_class.register(:foo)
event = Class.new do
def omnes_event_name
:foo
end

def to_hash
{ foo: 'bar' }
end
end.new

expect { described_class.publish(event) }.not_to raise_error
ensure
described_class.registry.unregister(:foo)
end
end
end

0 comments on commit 0f3adac

Please sign in to comment.