2010-08-28 12:47:39 -04:00
require " cases/helper "
require 'models/developer'
require 'models/project'
require 'models/company'
require 'models/topic'
require 'models/reply'
require 'models/computer'
require 'models/customer'
require 'models/order'
require 'models/post'
require 'models/author'
require 'models/tag'
require 'models/tagging'
require 'models/comment'
require 'models/sponsor'
require 'models/member'
require 'models/essay'
require 'models/subscriber'
2010-09-05 21:30:06 -04:00
require " models/pirate "
require " models/bird "
require " models/parrot "
2010-08-28 12:47:39 -04:00
2011-02-18 14:20:15 -05:00
if ActiveRecord :: IdentityMap . enabled?
2010-08-28 12:47:39 -04:00
class IdentityMapTest < ActiveRecord :: TestCase
fixtures :accounts , :companies , :developers , :projects , :topics ,
:developers_projects , :computers , :authors , :author_addresses ,
:posts , :tags , :taggings , :comments , :subscribers
2010-10-03 09:10:35 -04:00
##############################################################################
# Basic tests checking if IM is functioning properly on basic find operations#
##############################################################################
2010-08-28 12:47:39 -04:00
def test_find_id
2010-09-15 10:09:30 -04:00
assert_same ( Client . find ( 3 ) , Client . find ( 3 ) )
end
def test_find_id_without_identity_map
2010-09-15 10:18:34 -04:00
ActiveRecord :: IdentityMap . without do
2010-09-15 10:09:30 -04:00
assert_not_same ( Client . find ( 3 ) , Client . find ( 3 ) )
end
2010-08-28 12:47:39 -04:00
end
2010-10-15 14:44:21 -04:00
def test_find_id_use_identity_map
ActiveRecord :: IdentityMap . enabled = false
ActiveRecord :: IdentityMap . use do
assert_same ( Client . find ( 3 ) , Client . find ( 3 ) )
end
ActiveRecord :: IdentityMap . enabled = true
end
2010-08-28 12:47:39 -04:00
def test_find_pkey
assert_same (
Subscriber . find ( 'swistak' ) ,
Subscriber . find ( 'swistak' )
)
end
def test_find_by_id
assert_same (
Client . find_by_id ( 3 ) ,
Client . find_by_id ( 3 )
)
end
2010-10-14 11:58:47 -04:00
def test_find_by_string_and_numeric_id
assert_same (
Client . find_by_id ( " 3 " ) ,
Client . find_by_id ( 3 )
)
end
2010-08-28 12:47:39 -04:00
def test_find_by_pkey
assert_same (
Subscriber . find_by_nick ( 'swistak' ) ,
Subscriber . find_by_nick ( 'swistak' )
)
end
def test_find_first_id
assert_same (
Client . find ( :first , :conditions = > { :id = > 1 } ) ,
Client . find ( :first , :conditions = > { :id = > 1 } )
)
end
def test_find_first_pkey
assert_same (
Subscriber . find ( :first , :conditions = > { :nick = > 'swistak' } ) ,
Subscriber . find ( :first , :conditions = > { :nick = > 'swistak' } )
)
end
2010-10-03 09:10:35 -04:00
##############################################################################
# Tests checking if IM is functioning properly on more advanced finds #
# and associations #
##############################################################################
def test_owner_object_is_associated_from_identity_map
post = Post . find ( 1 )
comment = post . comments . first
assert_no_queries do
comment . post
end
2011-02-18 13:38:00 -05:00
assert_same post , comment . post
2010-10-03 09:10:35 -04:00
end
def test_associated_object_are_assigned_from_identity_map
post = Post . find ( 1 )
post . comments . each do | comment |
2011-02-18 13:38:00 -05:00
assert_same post , comment . post
assert_equal post . object_id , comment . post . object_id
2010-10-03 09:10:35 -04:00
end
end
2010-08-28 12:47:39 -04:00
def test_creation
t1 = Topic . create ( " title " = > " t1 " )
t2 = Topic . find ( t1 . id )
assert_same ( t1 , t2 )
end
2010-10-03 09:10:35 -04:00
##############################################################################
# Tests checking dirty attribute behaviour with IM #
##############################################################################
2010-09-05 21:30:06 -04:00
def test_loading_new_instance_should_not_update_dirty_attributes
swistak = Subscriber . find ( :first , :conditions = > { :nick = > 'swistak' } )
swistak . name = " Swistak Sreberkowiec "
assert_equal ( [ " name " ] , swistak . changed )
2010-10-03 09:10:35 -04:00
assert_equal ( { " name " = > [ " Marcin Raczkowski " , " Swistak Sreberkowiec " ] } , swistak . changes )
2010-09-05 21:30:06 -04:00
s = Subscriber . find ( 'swistak' )
assert swistak . name_changed?
assert_equal ( " Swistak Sreberkowiec " , swistak . name )
end
2010-10-06 11:09:18 -04:00
def test_loading_new_instance_should_change_dirty_attribute_original_value
2010-10-03 09:10:35 -04:00
swistak = Subscriber . find ( :first , :conditions = > { :nick = > 'swistak' } )
swistak . name = " Swistak Sreberkowiec "
2010-10-06 11:09:18 -04:00
Subscriber . update_all ( { :name = > " Raczkowski Marcin " } , { :name = > " Marcin Raczkowski " } )
2010-10-03 09:10:35 -04:00
s = Subscriber . find ( 'swistak' )
assert_equal ( { 'name' = > [ " Raczkowski Marcin " , " Swistak Sreberkowiec " ] } , swistak . changes )
assert_equal ( " Swistak Sreberkowiec " , swistak . name )
end
2010-09-05 21:30:06 -04:00
def test_loading_new_instance_should_remove_dirt
2010-09-15 09:58:59 -04:00
swistak = Subscriber . find ( :first , :conditions = > { :nick = > 'swistak' } )
swistak . name = " Swistak Sreberkowiec "
2010-10-03 09:10:35 -04:00
assert_equal ( { " name " = > [ " Marcin Raczkowski " , " Swistak Sreberkowiec " ] } , swistak . changes )
Subscriber . update_all ( { :name = > " Swistak Sreberkowiec " } , { :name = > " Marcin Raczkowski " } )
s = Subscriber . find ( 'swistak' )
2010-09-15 09:58:59 -04:00
assert_equal ( " Swistak Sreberkowiec " , swistak . name )
2010-10-03 09:10:35 -04:00
assert_equal ( { } , swistak . changes )
assert ! swistak . name_changed?
2010-09-05 21:30:06 -04:00
end
def test_has_many_associations
pirate = Pirate . create! ( :catchphrase = > " Don' botharrr talkin' like one, savvy? " )
pirate . birds . create! ( :name = > 'Posideons Killer' )
pirate . birds . create! ( :name = > 'Killer bandita Dionne' )
posideons , killer = pirate . birds
pirate . reload
pirate . birds_attributes = [ { :id = > posideons . id , :name = > 'Grace OMalley' } ]
2011-02-18 13:38:17 -05:00
assert_equal 'Grace OMalley' , pirate . birds . to_a . find { | r | r . id == posideons . id } . name
2010-09-05 21:30:06 -04:00
end
2010-08-28 12:47:39 -04:00
def test_changing_associations
2010-09-21 09:54:54 -04:00
post1 = Post . create ( " title " = > " One post " , " body " = > " Posting... " )
post2 = Post . create ( " title " = > " Another post " , " body " = > " Posting... Again... " )
comment = Comment . new ( " body " = > " comment " )
2010-08-28 12:47:39 -04:00
2010-09-21 09:54:54 -04:00
comment . post = post1
assert comment . save
2010-08-28 12:47:39 -04:00
2010-09-21 09:54:54 -04:00
assert_same ( post1 . comments . first , comment )
2010-08-28 12:47:39 -04:00
2010-09-21 09:54:54 -04:00
comment . post = post2
assert comment . save
2010-08-28 12:47:39 -04:00
2010-09-21 09:54:54 -04:00
assert_same ( post2 . comments . first , comment )
assert_equal ( 0 , post1 . comments . size )
2010-08-28 12:47:39 -04:00
end
def test_im_with_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
tag = posts ( :welcome ) . tags . first
tag_with_joins_and_select = posts ( :welcome ) . tags . add_joins_and_select . first
assert_same ( tag , tag_with_joins_and_select )
assert_nothing_raised ( NoMethodError , " Joins/select was not loaded " ) { tag . author_id }
end
2010-10-03 09:10:35 -04:00
##############################################################################
# Tests checking Identity Map behaviour with preloaded associations, joins, #
# includes etc. #
##############################################################################
2010-08-28 12:47:39 -04:00
def test_find_with_preloaded_associations
assert_queries ( 2 ) do
2011-03-18 19:14:45 -04:00
posts = Post . preload ( :comments ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . comments . first
end
# With IM we'll retrieve post object from previous query, it'll have comments
# already preloaded from first call
assert_queries ( 1 ) do
2011-03-18 19:14:45 -04:00
posts = Post . preload ( :comments ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . comments . first
end
assert_queries ( 2 ) do
2011-03-18 19:14:45 -04:00
posts = Post . preload ( :author ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . author
end
# With IM we'll retrieve post object from previous query, it'll have comments
# already preloaded from first call
assert_queries ( 1 ) do
2011-03-18 19:14:45 -04:00
posts = Post . preload ( :author ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . author
end
assert_queries ( 1 ) do
2011-03-18 19:14:45 -04:00
posts = Post . preload ( :author , :comments ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . author
assert posts . first . comments . first
end
end
def test_find_with_included_associations
assert_queries ( 2 ) do
2011-03-18 19:14:45 -04:00
posts = Post . includes ( :comments ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . comments . first
end
assert_queries ( 1 ) do
2011-03-18 19:14:45 -04:00
posts = Post . scoped . includes ( :comments ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . comments . first
end
assert_queries ( 2 ) do
2011-03-18 19:14:45 -04:00
posts = Post . includes ( :author ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . author
end
assert_queries ( 1 ) do
2011-03-18 19:14:45 -04:00
posts = Post . includes ( :author , :comments ) . order ( 'posts.id' )
2010-08-28 12:47:39 -04:00
assert posts . first . author
assert posts . first . comments . first
end
end
def test_eager_loading_with_conditions_on_joined_table_preloads
2010-09-21 16:46:20 -04:00
posts = Post . find ( :all , :select = > 'distinct posts.*' , :include = > :author , :joins = > [ :comments ] , :conditions = > " comments.body like 'Thank you%' " , :order = > 'posts.id' )
2010-08-28 12:47:39 -04:00
assert_equal [ posts ( :welcome ) ] , posts
assert_equal authors ( :david ) , assert_no_queries { posts [ 0 ] . author }
2011-02-18 13:38:00 -05:00
assert_same posts . first . author , Author . first
2010-08-28 12:47:39 -04:00
2010-09-21 16:46:20 -04:00
posts = Post . find ( :all , :select = > 'distinct posts.*' , :include = > :author , :joins = > [ :comments ] , :conditions = > " comments.body like 'Thank you%' " , :order = > 'posts.id' )
2010-08-28 12:47:39 -04:00
assert_equal [ posts ( :welcome ) ] , posts
assert_equal authors ( :david ) , assert_no_queries { posts [ 0 ] . author }
2011-02-18 13:38:00 -05:00
assert_same posts . first . author , Author . first
2010-08-28 12:47:39 -04:00
2010-09-21 16:46:20 -04:00
posts = Post . find ( :all , :include = > :author , :joins = > { :taggings = > :tag } , :conditions = > " tags.name = 'General' " , :order = > 'posts.id' )
2010-08-28 12:47:39 -04:00
assert_equal posts ( :welcome , :thinking ) , posts
2011-02-18 13:38:00 -05:00
assert_same posts . first . author , Author . first
2010-08-28 12:47:39 -04:00
2010-09-21 16:46:20 -04:00
posts = Post . find ( :all , :include = > :author , :joins = > { :taggings = > { :tag = > :taggings } } , :conditions = > " taggings_tags.super_tag_id=2 " , :order = > 'posts.id' )
2010-08-28 12:47:39 -04:00
assert_equal posts ( :welcome , :thinking ) , posts
2011-02-18 13:38:00 -05:00
assert_same posts . first . author , Author . first
2010-08-28 12:47:39 -04:00
end
def test_eager_loading_with_conditions_on_string_joined_table_preloads
posts = assert_queries ( 2 ) do
Post . find ( :all , :select = > 'distinct posts.*' , :include = > :author , :joins = > " INNER JOIN comments on comments.post_id = posts.id " , :conditions = > " comments.body like 'Thank you%' " , :order = > 'posts.id' )
end
assert_equal [ posts ( :welcome ) ] , posts
assert_equal authors ( :david ) , assert_no_queries { posts [ 0 ] . author }
posts = assert_queries ( 1 ) do
Post . find ( :all , :select = > 'distinct posts.*' , :include = > :author , :joins = > [ " INNER JOIN comments on comments.post_id = posts.id " ] , :conditions = > " comments.body like 'Thank you%' " , :order = > 'posts.id' )
end
assert_equal [ posts ( :welcome ) ] , posts
assert_equal authors ( :david ) , assert_no_queries { posts [ 0 ] . author }
end
2010-08-29 06:04:43 -04:00
2010-10-03 09:10:35 -04:00
##############################################################################
2011-03-03 23:54:58 -05:00
# Behaviour related to saving failures
2010-10-03 09:10:35 -04:00
##############################################################################
2010-09-15 10:18:34 -04:00
def test_reload_object_if_save_failed
developer = Developer . first
developer . salary = 0
assert ! developer . save
same_developer = Developer . first
assert_not_same developer , same_developer
assert_not_equal 0 , same_developer . salary
assert_not_equal developer . salary , same_developer . salary
end
2010-09-15 10:22:24 -04:00
def test_reload_object_if_forced_save_failed
developer = Developer . first
developer . salary = 0
assert_raise ( ActiveRecord :: RecordInvalid ) { developer . save! }
same_developer = Developer . first
assert_not_same developer , same_developer
assert_not_equal 0 , same_developer . salary
assert_not_equal developer . salary , same_developer . salary
end
2010-09-15 10:30:15 -04:00
def test_reload_object_if_update_attributes_fails
developer = Developer . first
developer . salary = 0
assert ! developer . update_attributes ( :salary = > 0 )
same_developer = Developer . first
assert_not_same developer , same_developer
assert_not_equal 0 , same_developer . salary
assert_not_equal developer . salary , same_developer . salary
end
2010-10-03 09:10:35 -04:00
##############################################################################
2011-03-03 23:54:58 -05:00
# Behaviour of readonly, frozen, destroyed
2010-10-03 09:10:35 -04:00
##############################################################################
2010-09-17 15:00:06 -04:00
def test_find_using_identity_map_respects_readonly_when_loading_associated_object_first
author = Author . first
readonly_comment = author . readonly_comments . first
comment = Comment . first
assert ! comment . readonly?
assert readonly_comment . readonly?
assert_raise ( ActiveRecord :: ReadOnlyRecord ) { readonly_comment . save }
assert comment . save
end
def test_find_using_identity_map_respects_readonly
comment = Comment . first
assert ! comment . readonly?
author = Author . first
readonly_comment = author . readonly_comments . first
assert readonly_comment . readonly?
assert_raise ( ActiveRecord :: ReadOnlyRecord ) { readonly_comment . save }
assert comment . save
end
2010-10-03 09:10:35 -04:00
2010-11-18 09:03:25 -05:00
def test_find_using_select_and_identity_map
author_id , author = Author . select ( 'id' ) . first , Author . first
assert_equal author_id , author
assert_same author_id , author
assert_not_nil author . name
post , post_id = Post . first , Post . select ( 'id' ) . first
assert_equal post_id , post
assert_same post_id , post
assert_not_nil post . title
end
2010-10-03 09:10:35 -04:00
# Currently AR is not allowing changing primary key (see Persistence#update)
# So we ignore it. If this changes, this test needs to be uncommented.
# def test_updating_of_pkey
# assert client = Client.find(3),
# client.update_attribute(:id, 666)
#
# assert Client.find(666)
# assert_same(client, Client.find(666))
#
# s = Subscriber.find_by_nick('swistak')
# assert s.update_attribute(:nick, 'swistakTheJester')
# assert_equal('swistakTheJester', s.nick)
#
# assert stj = Subscriber.find_by_nick('swistakTheJester')
# assert_same(s, stj)
# end
2010-08-28 12:47:39 -04:00
end
2011-02-18 14:20:15 -05:00
end