Skip to content

Instantly share code, notes, and snippets.

@zef
Created December 24, 2009 03:47
Show Gist options
  • Save zef/262994 to your computer and use it in GitHub Desktop.
Save zef/262994 to your computer and use it in GitHub Desktop.
require 'test_helper'
module CallbackModelTemplate
def self.included(model)
model.class_eval do
key :name, String
has_many :sons, :class_name => 'CallbacksTest::Son'
[ :before_validation_on_create, :before_validation_on_update,
:before_validation, :after_validation,
:before_create, :after_create,
:before_update, :after_update,
:before_save, :after_save,
:before_destroy, :after_destroy ].each do |callback|
callback_method = "#{callback}_callback"
send(callback, callback_method)
define_method(callback_method) do
history << callback.to_sym
end
end
end
end
def history
@history ||= []
end
def clear_history
@history = nil
sons.each { |son| son.clear_history }
begin
wife.clear_history
rescue
end
end
end
class CallbacksTest < Test::Unit::TestCase
CreateOrder = [:before_validation, :before_validation_on_create, :after_validation, :before_save, :before_create, :after_create, :after_save]
UpdateOrder = [:before_validation, :before_validation_on_update, :after_validation, :before_save, :before_update, :after_update, :after_save]
class Wife
include MongoMapper::EmbeddedDocument
include CallbackModelTemplate
end
class Father
include MongoMapper::Document
include CallbackModelTemplate
key :wife, Wife
end
class Son
include MongoMapper::EmbeddedDocument
include CallbackModelTemplate
end
context "Defining and running callbacks" do
setup do
grandson = Son.new(:name => 'John Nunemaker III')
@son = Son.new(:name => 'John Nunemaker Jr.', :sons => [grandson])
@wife = Wife.new(:name => 'Stephanie')
clear_all_collections
end
context ": Creating a document" do
setup do
@father = Father.create(:name => 'John Nunemaker', :wife => @wife, :sons => [@son])
@order
end
should "get the order right for documents" do
@father.history.should == CreateOrder
@father.wife.history.should == CreateOrder
@father.sons.first.history.should == CreateOrder
@father.sons.first.sons.first.history.should == CreateOrder
end
end
context ": Updating a document" do
setup do
@father = Father.create(:name => 'John Nunemaker', :sons => [@son])
@father.clear_history
@father.name = "John"
@father.save
end
should "get the order right for all documents" do
@father.history.should == UpdateOrder
@father.sons.first.history.should == UpdateOrder
@father.sons.first.sons.first.history.should == UpdateOrder
end
context ": With a new embedded document" do
setup do
@father.clear_history
@father.wife = @wife
grandson = Son.new(:name => 'Jimmy Nunemaker Jr.')
@father.sons << Son.new(:name => 'Jimmy Nunemaker', :sons => [grandson])
@father.save
end
should "perform create callbacks on new embedded docs" do
@father.wife.history.should == CreateOrder
@father.sons.last.history.should == CreateOrder
@father.sons.last.sons.first.history.should == CreateOrder
end
should "perform update callbacks on old embedded docs" do
@father.sons.first.history.should == UpdateOrder
@father.sons.first.sons.first.history.should == UpdateOrder
end
end
end
should "work for before and after validation" do
doc = Father.new(:name => 'John Nunemaker')
doc.valid?
doc.history.should include(:before_validation)
doc.history.should include(:after_validation)
end
should "work for before and after create" do
doc = Father.create(:name => 'John Nunemaker')
doc.history.should include(:before_create)
doc.history.should include(:after_create)
end
should "work for before and after update" do
doc = Father.create(:name => 'John Nunemaker')
doc.name = 'John Doe'
doc.save
doc.history.should include(:before_update)
doc.history.should include(:after_update)
end
should "work for before and after save" do
doc = Father.new
doc.name = 'John Doe'
doc.save
doc.history.should include(:before_save)
doc.history.should include(:after_save)
end
should "work for before and after destroy" do
doc = Father.create(:name => 'John Nunemaker')
doc.destroy
doc.history.should include(:before_destroy)
doc.history.should include(:after_destroy)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment