Skip to content

Instantly share code, notes, and snippets.

@bumi
Created July 16, 2012 13:42
Show Gist options
  • Save bumi/3122795 to your computer and use it in GitHub Desktop.
Save bumi/3122795 to your computer and use it in GitHub Desktop.
rpsec matcher for matching ActiveSupport::Notifications events
# usage:
# expect {}.to publish_notification("object:created").with({:id => 1})
# expect {}.to publish_notification("object:created").with {|actual_payload| actual_payload[:id].present? }
module ActiveSupportNotificationMatchers
class PublishNotifications
def initialize(event_name)
@event_name = event_name
@payload = nil
end
def with(payload=nil,&block)
@payload = payload || block
self
end
def matches?(given_proc)
@verifier = MessageVerifier.new(@event_name, @payload)
ActiveSupport::Notifications.subscribe(@event_name, @verifier)
given_proc.call
@verifier.satisfied?
end
def failure_message
msg = "Expected event '#{@event_name}' with #{@payload.inspect} as payload to get published. "
if @verifier.actual_event_name
msg << "got event '#{@verifier.actual_event_name}' with #{@verifier.actual_payload} as payload."
else
msg << "no message received."
end
end
def description
"Expect #{@event_name} to get published with payload #{@payload.inspect}"
end
end
class MessageVerifier
attr_accessor :actual_event_name, :actual_payload, :expected_event_name, :expected_payload
def initialize(event_name, payload)
@expected_event_name = event_name
@expected_payload = payload
end
def call(event_name, payload)
@actual_event_name = event_name
@actual_payload = payload
end
def payload_satisfied?
return true unless @expected_payload
if @expected_payload.respond_to?(:call)
return @expected_payload.call(@actual_payload)
else
@expected_payload == @actual_payload
end
end
def event_name_satisfied?
@expected_event_name == @actual_event_name
end
def satisfied?
payload_satisfied? && event_name_satisfied?
end
end
def publish_notification(event_name)
PublishNotifications.new(event_name)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment