Skip to content

Instantly share code, notes, and snippets.

@ngty
Created August 20, 2010 06:22
Show Gist options
  • Save ngty/539727 to your computer and use it in GitHub Desktop.
Save ngty/539727 to your computer and use it in GitHub Desktop.
module RailsBestPractices
module Spec
module Support
def within_observable_scope
observer_class = self.description.split('::').inject(Object){|k,c| k.const_get(c) }
has_applied_tweak, tweaks = apply_observer_tweaks(observer_class)
begin
yield(observer_class.instance)
ensure
unapply_observer_tweaks(observer_class, tweaks) if has_applied_tweak
end
end
def apply_observer_tweaks(observer_class)
observer, is_unwanted_observer_initialized = nil
orig_update_meth = :_original_update_observee_xyz_ # some weird name that should never clash with others
if ObjectSpace.each_object(observer_class){|o| observer = o }.zero?
# This is the case when the observer is never meant to exist in this environment
[true, {:method => orig_update_meth}]
elsif observer.respond_to?(orig_update_meth)
# This is the case when the observer is never meant to exist in this environment,
# yet it has already been tampered with, and we want to undo tampering
(class << observer_class.instance; self; end).class_eval do
alias_method :update, orig_update_meth
end
[true, {:method => orig_update_meth}]
end
end
def unapply_observer_tweaks(observer_class, tweaks)
orig_update_meth = tweaks[:method]
(class << observer_class.instance; self; end).class_eval do
alias_method orig_update_meth, :update
def update(*args) ; end
end
end
end
end
end
class TweetObserver < ActiveRecord::Observer
observe :post, :implementation, :question
def after_create(model)
tweet(model.tweet_title, model.tweet_path)
end
private
def tweet(title, path)
# stuff that we only want to run in production environment
end
end
describe TweetObserver do
include RailsBestPractices::Spec::Support
it 'should be observing Post#create' do
Post.delete_all
within_observable_scope do |observer|
instance = Factory.build(:post, :id => 1)
observer.should_receive(:tweet).with(instance.tweet_title, instance.tweet_path)
instance.save
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment