diff options
author | Emilio Tagua <miloops@gmail.com> | 2010-12-20 11:23:07 -0300 |
---|---|---|
committer | Emilio Tagua <miloops@gmail.com> | 2010-12-20 11:23:07 -0300 |
commit | 02fc6fbccdd3345e95592cc14e7855e2f1ea14b3 (patch) | |
tree | b26b91e2b2fad62ec382c9cee4ca2ac318f09257 /activerecord/test/cases | |
parent | 2ba06b48defaca940e7c878724e2fb1c090eaa92 (diff) | |
parent | 0cbfd6c28d327304432f7d0c067662b5c1e41a78 (diff) | |
download | rails-02fc6fbccdd3345e95592cc14e7855e2f1ea14b3.tar.gz rails-02fc6fbccdd3345e95592cc14e7855e2f1ea14b3.tar.bz2 rails-02fc6fbccdd3345e95592cc14e7855e2f1ea14b3.zip |
Merge remote branch 'rails/master' into identity_map
Conflicts:
activerecord/lib/active_record/associations/association_proxy.rb
activerecord/lib/active_record/autosave_association.rb
activerecord/lib/active_record/base.rb
activerecord/lib/active_record/persistence.rb
Diffstat (limited to 'activerecord/test/cases')
31 files changed, 682 insertions, 185 deletions
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 1b0c00bd5a..1820f95261 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -486,4 +486,41 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase new_firm = accounts(:signals37).build_firm(:name => 'Apple') assert_equal new_firm.name, "Apple" end + + def test_reassigning_the_parent_id_updates_the_object + original_parent = Firm.create! :name => "original" + updated_parent = Firm.create! :name => "updated" + + client = Client.new("client_of" => original_parent.id) + assert_equal original_parent, client.firm + assert_equal original_parent, client.firm_with_condition + assert_equal original_parent, client.firm_with_other_name + + client.client_of = updated_parent.id + assert_equal updated_parent, client.firm + assert_equal updated_parent, client.firm_with_condition + assert_equal updated_parent, client.firm_with_other_name + end + + def test_polymorphic_reassignment_of_associated_id_updates_the_object + member1 = Member.create! + member2 = Member.create! + + sponsor = Sponsor.new("sponsorable_type" => "Member", "sponsorable_id" => member1.id) + assert_equal member1, sponsor.sponsorable + + sponsor.sponsorable_id = member2.id + assert_equal member2, sponsor.sponsorable + end + + def test_polymorphic_reassignment_of_associated_type_updates_the_object + member1 = Member.create! + + sponsor = Sponsor.new("sponsorable_type" => "Member", "sponsorable_id" => member1.id) + assert_equal member1, sponsor.sponsorable + + sponsor.sponsorable_type = "Firm" + assert_not_equal member1, sponsor.sponsorable + end + end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 16c5176e4f..c064731859 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -17,12 +17,26 @@ require 'models/subscription' require 'models/book' require 'models/developer' require 'models/project' +require 'models/member' +require 'models/membership' +require 'models/club' +require 'models/categorization' class EagerAssociationTest < ActiveRecord::TestCase fixtures :posts, :comments, :authors, :author_addresses, :categories, :categories_posts, - :companies, :accounts, :tags, :taggings, :people, :readers, + :companies, :accounts, :tags, :taggings, :people, :readers, :categorizations, :owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books, - :developers, :projects, :developers_projects + :developers, :projects, :developers_projects, :members, :memberships, :clubs + + def setup + # preheat table existence caches + Comment.find_by_id(1) + end + + def test_eager_with_has_one_through_join_model_with_conditions_on_the_through + member = Member.find(members(:some_other_guy).id, :include => :favourite_club) + assert_nil member.favourite_club + end def test_loading_with_one_association posts = Post.find(:all, :include => :comments) @@ -80,31 +94,31 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_preloading_has_many_in_multiple_queries_with_more_ids_than_database_can_handle - Post.connection.expects(:ids_in_list_limit).at_least_once.returns(5) + Post.connection.expects(:in_clause_length).at_least_once.returns(5) posts = Post.find(:all, :include=>:comments) assert_equal 7, posts.size end def test_preloading_has_many_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle - Post.connection.expects(:ids_in_list_limit).at_least_once.returns(nil) + Post.connection.expects(:in_clause_length).at_least_once.returns(nil) posts = Post.find(:all, :include=>:comments) assert_equal 7, posts.size end def test_preloading_habtm_in_multiple_queries_with_more_ids_than_database_can_handle - Post.connection.expects(:ids_in_list_limit).at_least_once.returns(5) + Post.connection.expects(:in_clause_length).at_least_once.returns(5) posts = Post.find(:all, :include=>:categories) assert_equal 7, posts.size end def test_preloading_habtm_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle - Post.connection.expects(:ids_in_list_limit).at_least_once.returns(nil) + Post.connection.expects(:in_clause_length).at_least_once.returns(nil) posts = Post.find(:all, :include=>:categories) assert_equal 7, posts.size end def test_load_associated_records_in_one_query_when_adapter_has_no_limit - Post.connection.expects(:ids_in_list_limit).at_least_once.returns(nil) + Post.connection.expects(:in_clause_length).at_least_once.returns(nil) Post.expects(:i_was_called).with([1,2,3,4,5,6,7]).returns([1]) associated_records = Post.send(:associated_records, [1,2,3,4,5,6,7]) do |some_ids| Post.i_was_called(some_ids) @@ -113,7 +127,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_load_associated_records_in_several_queries_when_many_ids_passed - Post.connection.expects(:ids_in_list_limit).at_least_once.returns(5) + Post.connection.expects(:in_clause_length).at_least_once.returns(5) Post.expects(:i_was_called).with([1,2,3,4,5]).returns([1]) Post.expects(:i_was_called).with([6,7]).returns([6]) associated_records = Post.send(:associated_records, [1,2,3,4,5,6,7]) do |some_ids| @@ -123,7 +137,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_load_associated_records_in_one_query_when_a_few_ids_passed - Post.connection.expects(:ids_in_list_limit).at_least_once.returns(5) + Post.connection.expects(:in_clause_length).at_least_once.returns(5) Post.expects(:i_was_called).with([1,2,3]).returns([1]) associated_records = Post.send(:associated_records, [1,2,3]) do |some_ids| Post.i_was_called(some_ids) @@ -897,4 +911,10 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_queries(2) { @tagging = Tagging.preload(:taggable).find(t.id) } assert_no_queries { assert ! @tagging.taggable } end + + def test_preloading_has_many_through_with_uniq + mary = Author.includes(:unique_categorized_posts).where(:id => authors(:mary).id).first + assert_equal 1, mary.unique_categorized_posts.length + assert_equal 1, mary.unique_categorized_post_ids.length + end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 33c53e695b..fb772bb8e6 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -67,8 +67,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_no_sql_should_be_fired_if_association_already_loaded - car = Car.create(:name => 'honda') - bulb = car.bulbs.create + Car.create(:name => 'honda') bulbs = Car.first.bulbs bulbs.inspect # to load all instances of bulbs assert_no_queries do diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 94e1eb8c89..77bc369ecc 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -17,11 +17,13 @@ require 'models/developer' require 'models/subscriber' require 'models/book' require 'models/subscription' +require 'models/categorization' +require 'models/category' class HasManyThroughAssociationsTest < ActiveRecord::TestCase fixtures :posts, :readers, :people, :comments, :authors, :owners, :pets, :toys, :jobs, :references, :companies, - :subscribers, :books, :subscriptions, :developers + :subscribers, :books, :subscriptions, :developers, :categorizations # Dummies to force column loads so query counts are clean. def setup @@ -354,7 +356,6 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_has_many_association_through_a_belongs_to_association_where_the_association_doesnt_exist - author = authors(:mary) post = Post.create!(:title => "TITLE", :body => "BODY") assert_equal [], post.author_favorites end @@ -389,6 +390,13 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase ].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) } end + def test_has_many_association_through_a_has_many_association_to_self + sarah = Person.create!(:first_name => 'Sarah', :primary_contact_id => people(:susan).id, :gender => 'F', :number1_fan_id => 1) + john = Person.create!(:first_name => 'John', :primary_contact_id => sarah.id, :gender => 'M', :number1_fan_id => 1) + assert_equal sarah.agents, [john] + assert_equal people(:susan).agents.map(&:agents).flatten, people(:susan).agents_of_agents + end + def test_collection_singular_ids_getter_with_string_primary_keys book = books(:awdr) assert_equal 2, book.subscriber_ids.size @@ -456,4 +464,19 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase post.people << people(:michael) assert_equal readers + 1, post.readers.size end + + def test_has_many_through_with_default_scope_on_join_model + assert_equal posts(:welcome).comments, authors(:david).comments_on_first_posts + end + + def test_create_has_many_through_with_default_scope_on_join_model + category = authors(:david).special_categories.create(:name => "Foo") + assert_equal 1, category.categorizations.where(:special => true).count + end + + def test_joining_has_many_through_with_uniq + mary = Author.joins(:unique_categorized_posts).where(:id => authors(:mary).id).first + assert_equal 1, mary.unique_categorized_posts.length + assert_equal 1, mary.unique_categorized_post_ids.length + end end diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index 6fbeff8aa9..64449df8f5 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -163,7 +163,6 @@ class HasOneAssociationsTest < ActiveRecord::TestCase firm = ExclusivelyDependentFirm.find(9) assert_not_nil firm.account - account_id = firm.account.id assert_equal [], Account.destroyed_account_ids[firm.id] firm.destroy @@ -180,7 +179,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase def test_dependence_with_restrict firm = RestrictedFirm.new(:name => 'restrict') firm.save! - account = firm.create_account(:credit_limit => 10) + firm.create_account(:credit_limit => 10) assert_not_nil firm.account assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy } end @@ -197,8 +196,8 @@ class HasOneAssociationsTest < ActiveRecord::TestCase def test_build_association_twice_without_saving_affects_nothing count_of_account = Account.count firm = Firm.find(:first) - account1 = firm.build_account("credit_limit" => 1000) - account2 = firm.build_account("credit_limit" => 2000) + firm.build_account("credit_limit" => 1000) + firm.build_account("credit_limit" => 2000) assert_equal count_of_account, Account.count end diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb index 5d153147f5..93a4f498d0 100644 --- a/activerecord/test/cases/associations/has_one_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb @@ -9,9 +9,13 @@ require 'models/member_detail' require 'models/minivan' require 'models/dashboard' require 'models/speedometer' +require 'models/author' +require 'models/post' +require 'models/comment' class HasOneThroughAssociationsTest < ActiveRecord::TestCase - fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations, :minivans, :dashboards, :speedometers + fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations, :minivans, + :dashboards, :speedometers, :authors, :posts, :comments def setup @member = members(:groucho) @@ -206,10 +210,31 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase end end + def test_through_belongs_to_after_destroy + @member_detail = MemberDetail.new(:extra_data => 'Extra') + @member.member_detail = @member_detail + @member.save! + + assert_not_nil @member_detail.member_type + @member_detail.destroy + assert_queries(1) do + assert_not_nil @member_detail.member_type(true) + end + + @member_detail.member.destroy + assert_queries(1) do + assert_nil @member_detail.member_type(true) + end + end + def test_value_is_properly_quoted minivan = Minivan.find('m1') assert_nothing_raised do minivan.dashboard end end + + def test_has_one_through_with_default_scope_on_join_model + assert_equal posts(:welcome).comments.first, authors(:david).comment_on_first_posts + end end diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb index 780eabc443..da2a81e98a 100644 --- a/activerecord/test/cases/associations/inner_join_association_test.rb +++ b/activerecord/test/cases/associations/inner_join_association_test.rb @@ -65,21 +65,21 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase authors_with_welcoming_post_titles = Author.calculate(:count, 'authors.id', :joins => :posts, :distinct => true, :conditions => "posts.title like 'Welcome%'") assert_equal real_count, authors_with_welcoming_post_titles, "inner join and conditions should have only returned authors posting titles starting with 'Welcome'" end - + def test_find_with_sti_join scope = Post.joins(:special_comments).where(:id => posts(:sti_comments).id) - + # The join should match SpecialComment and its subclasses only assert scope.where("comments.type" => "Comment").empty? assert !scope.where("comments.type" => "SpecialComment").empty? assert !scope.where("comments.type" => "SubSpecialComment").empty? end - + def test_find_with_conditions_on_reflection assert !posts(:welcome).comments.empty? assert Post.joins(:nonexistant_comments).where(:id => posts(:welcome).id).empty? # [sic!] end - + def test_find_with_conditions_on_through_reflection assert !posts(:welcome).tags.empty? assert Post.joins(:misc_tags).where(:id => posts(:welcome).id).empty? diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb index 081583038f..0491b2d1fa 100644 --- a/activerecord/test/cases/associations/inverse_associations_test.rb +++ b/activerecord/test/cases/associations/inverse_associations_test.rb @@ -484,7 +484,6 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase def test_child_instance_should_be_shared_with_replaced_via_accessor_parent face = faces(:confused) - old_man = face.polymorphic_man new_man = Man.new assert_not_nil face.polymorphic_man @@ -499,7 +498,6 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase def test_child_instance_should_be_shared_with_replaced_via_method_parent face = faces(:confused) - old_man = face.polymorphic_man new_man = Man.new assert_not_nil face.polymorphic_man diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb index 21f61594d7..d6e772e989 100644 --- a/activerecord/test/cases/associations/join_model_test.rb +++ b/activerecord/test/cases/associations/join_model_test.rb @@ -44,16 +44,6 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase assert !authors(:mary).unique_categorized_posts.loaded? end - def test_column_caching - # pre-heat our cache - Post.arel_table.columns - Comment.columns - - Post.connection.column_calls = 0 - 2.times { Post.joins(:comments).to_a } - assert_equal 0, Post.connection.column_calls - end - def test_has_many_uniq_through_find assert_equal 1, authors(:mary).unique_categorized_posts.find(:all).size end @@ -308,6 +298,22 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase assert_equal [authors(:mary)], posts(:authorless).authors end + def test_has_many_going_through_join_model_with_custom_primary_key + assert_equal [authors(:david)], posts(:thinking).authors_using_author_id + end + + def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key + assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id + end + + def test_has_many_through_with_custom_primary_key_on_belongs_to_source + assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk + end + + def test_has_many_through_with_custom_primary_key_on_has_many_source + assert_equal [authors(:david)], posts(:thinking).authors_using_custom_pk + end + def test_both_scoped_and_explicit_joins_should_be_respected assert_nothing_raised do Post.send(:with_scope, :find => {:joins => "left outer join comments on comments.id = posts.id"}) do @@ -642,7 +648,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_preload_nil_polymorphic_belongs_to assert_nothing_raised do - taggings = Tagging.find(:all, :include => :taggable, :conditions => ['taggable_type IS NULL']) + Tagging.find(:all, :include => :taggable, :conditions => ['taggable_type IS NULL']) end end diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 93a51d3606..83c605d2bb 100644 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -270,17 +270,17 @@ class OverridingAssociationsTest < ActiveRecord::TestCase def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited # redeclared association on AR descendant should not inherit callbacks from superclass - callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many) + callbacks = PeopleList.before_add_for_has_and_belongs_to_many assert_equal([:enlist], callbacks) - callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many) + callbacks = DifferentPeopleList.before_add_for_has_and_belongs_to_many assert_equal([], callbacks) end def test_has_many_association_redefinition_callbacks_should_differ_and_not_inherited # redeclared association on AR descendant should not inherit callbacks from superclass - callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_many) + callbacks = PeopleList.before_add_for_has_many assert_equal([:enlist], callbacks) - callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_many) + callbacks = DifferentPeopleList.before_add_for_has_many assert_equal([], callbacks) end diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index bb0166a60c..8214815bde 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -86,6 +86,15 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert !topic.respond_to?(:nothingness) end + # Syck calls respond_to? before actually calling initialize + def test_respond_to_with_allocated_object + topic = Topic.allocate + assert !topic.respond_to?("nothingness") + assert !topic.respond_to?(:nothingness) + assert_respond_to topic, "title" + assert_respond_to topic, :title + end + def test_array_content topic = Topic.new topic.content = %w( one two three ) diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 79cb3884a9..0fd1e62134 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -163,15 +163,15 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas firm.account = Account.find(:first) assert_queries(Firm.partial_updates? ? 0 : 1) { firm.save! } - firm = Firm.find(:first).clone + firm = Firm.find(:first).dup firm.account = Account.find(:first) assert_queries(2) { firm.save! } - firm = Firm.find(:first).clone - firm.account = Account.find(:first).clone + firm = Firm.find(:first).dup + firm.account = Account.find(:first).dup assert_queries(2) { firm.save! } end - + def test_callbacks_firing_order_on_create eye = Eye.create(:iris_attributes => {:color => 'honey'}) assert_equal [true, false], eye.after_create_callbacks_stack @@ -667,10 +667,21 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end end + @ship.pirate.catchphrase = "Changed Catchphrase" + assert_raise(RuntimeError) { assert !@ship.save } assert_not_nil @ship.reload.pirate end + def test_should_save_changed_child_objects_if_parent_is_saved + @pirate = @ship.create_pirate(:catchphrase => "Don' botharrr talkin' like one, savvy?") + @parrot = @pirate.parrots.create!(:name => 'Posideons Killer') + @parrot.name = "NewName" + @ship.save + + assert_equal 'NewName', @parrot.reload.name + end + # has_many & has_and_belongs_to %w{ parrots birds }.each do |association_name| define_method("test_should_destroy_#{association_name}_as_part_of_the_save_transaction_if_they_were_marked_for_destroyal") do diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 26f388ca46..86d4a90fc4 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -669,64 +669,65 @@ class BasicsTest < ActiveRecord::TestCase assert_equal true, Topic.find(1).persisted? end - def test_clone + def test_dup topic = Topic.find(1) - cloned_topic = nil - assert_nothing_raised { cloned_topic = topic.clone } - assert_equal topic.title, cloned_topic.title - assert !cloned_topic.persisted? + duped_topic = nil + assert_nothing_raised { duped_topic = topic.dup } + assert_equal topic.title, duped_topic.title + assert !duped_topic.persisted? - # test if the attributes have been cloned + # test if the attributes have been duped topic.title = "a" - cloned_topic.title = "b" + duped_topic.title = "b" assert_equal "a", topic.title - assert_equal "b", cloned_topic.title + assert_equal "b", duped_topic.title - # test if the attribute values have been cloned + # test if the attribute values have been duped topic.title = {"a" => "b"} - cloned_topic = topic.clone - cloned_topic.title["a"] = "c" + duped_topic = topic.dup + duped_topic.title["a"] = "c" assert_equal "b", topic.title["a"] - # test if attributes set as part of after_initialize are cloned correctly - assert_equal topic.author_email_address, cloned_topic.author_email_address + # test if attributes set as part of after_initialize are duped correctly + assert_equal topic.author_email_address, duped_topic.author_email_address # test if saved clone object differs from original - cloned_topic.save - assert cloned_topic.persisted? - assert_not_equal cloned_topic.id, topic.id + duped_topic.save + assert duped_topic.persisted? + assert_not_equal duped_topic.id, topic.id - cloned_topic.reload + duped_topic.reload # FIXME: I think this is poor behavior, and will fix it with #5686 - assert_equal({'a' => 'c'}.to_s, cloned_topic.title) + assert_equal({'a' => 'c'}.to_s, duped_topic.title) end - def test_clone_with_aggregate_of_same_name_as_attribute + def test_dup_with_aggregate_of_same_name_as_attribute dev = DeveloperWithAggregate.find(1) assert_kind_of DeveloperSalary, dev.salary - clone = nil - assert_nothing_raised { clone = dev.clone } - assert_kind_of DeveloperSalary, clone.salary - assert_equal dev.salary.amount, clone.salary.amount - assert !clone.persisted? + dup = nil + assert_nothing_raised { dup = dev.dup } + assert_kind_of DeveloperSalary, dup.salary + assert_equal dev.salary.amount, dup.salary.amount + assert !dup.persisted? - # test if the attributes have been cloned - original_amount = clone.salary.amount + # test if the attributes have been dupd + original_amount = dup.salary.amount dev.salary.amount = 1 - assert_equal original_amount, clone.salary.amount + assert_equal original_amount, dup.salary.amount - assert clone.save - assert clone.persisted? - assert_not_equal clone.id, dev.id + assert dup.save + assert dup.persisted? + assert_not_equal dup.id, dev.id end - def test_clone_does_not_clone_associations + def test_dup_does_not_copy_associations author = authors(:david) assert_not_equal [], author.posts + author.send(:clear_association_cache) - author_clone = author.clone - assert_equal [], author_clone.posts + author_dup = author.dup + assert_equal [], author_dup.posts end def test_clone_preserves_subtype @@ -765,22 +766,22 @@ class BasicsTest < ActiveRecord::TestCase assert !cloned_developer.salary_changed? # ... and cloned instance should behave same end - def test_clone_of_saved_object_marks_attributes_as_dirty + def test_dup_of_saved_object_marks_attributes_as_dirty developer = Developer.create! :name => 'Bjorn', :salary => 100000 assert !developer.name_changed? assert !developer.salary_changed? - cloned_developer = developer.clone + cloned_developer = developer.dup assert cloned_developer.name_changed? # both attributes differ from defaults assert cloned_developer.salary_changed? end - def test_clone_of_saved_object_marks_as_dirty_only_changed_attributes + def test_dup_of_saved_object_marks_as_dirty_only_changed_attributes developer = Developer.create! :name => 'Bjorn' assert !developer.name_changed? # both attributes of saved object should be threated as not changed assert !developer.salary_changed? - cloned_developer = developer.clone + cloned_developer = developer.dup assert cloned_developer.name_changed? # ... but on cloned object should be assert !cloned_developer.salary_changed? # ... BUT salary has non-nil default which should be threated as not changed on cloned instance end @@ -996,6 +997,22 @@ class BasicsTest < ActiveRecord::TestCase Topic.serialize(:content) end + def test_serialized_boolean_value_true + Topic.serialize(:content) + topic = Topic.new(:content => true) + assert topic.save + topic = topic.reload + assert_equal topic.content, true + end + + def test_serialized_boolean_value_false + Topic.serialize(:content) + topic = Topic.new(:content => false) + assert topic.save + topic = topic.reload + assert_equal topic.content, false + end + def test_quote author_name = "\\ \001 ' \n \\n \"" topic = Topic.create('author_name' => author_name) @@ -1443,10 +1460,6 @@ class BasicsTest < ActiveRecord::TestCase ActiveRecord::Base.logger = original_logger end - def test_dup - assert !Minimalistic.new.freeze.dup.frozen? - end - def test_compute_type_success assert_equal Author, ActiveRecord::Base.send(:compute_type, 'Author') end diff --git a/activerecord/test/cases/clone_test.rb b/activerecord/test/cases/clone_test.rb new file mode 100644 index 0000000000..d91646efca --- /dev/null +++ b/activerecord/test/cases/clone_test.rb @@ -0,0 +1,33 @@ +require "cases/helper" +require 'models/topic' + +module ActiveRecord + class CloneTest < ActiveRecord::TestCase + fixtures :topics + + def test_persisted + topic = Topic.first + cloned = topic.clone + assert topic.persisted?, 'topic persisted' + assert cloned.persisted?, 'topic persisted' + assert !cloned.new_record?, 'topic is not new' + end + + def test_stays_frozen + topic = Topic.first + topic.freeze + + cloned = topic.clone + assert cloned.persisted?, 'topic persisted' + assert !cloned.new_record?, 'topic is not new' + assert cloned.frozen?, 'topic should be frozen' + end + + def test_shallow + topic = Topic.first + cloned = topic.clone + topic.author_name = 'Aaron' + assert_equal 'Aaron', cloned.author_name + end + end +end diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index f0ec5c751c..2e18117895 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -38,9 +38,9 @@ module ActiveRecord assert_not_nil connection end end - + threads.each {|t| t.join} - + Thread.new do threads.each do |t| thread_ids = pool.instance_variable_get(:@reserved_connections).keys diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index b1a54af192..a6738fb654 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -338,13 +338,13 @@ class DirtyTest < ActiveRecord::TestCase assert !pirate.changed? end - def test_cloned_objects_should_not_copy_dirty_flag_from_creator + def test_dup_objects_should_not_copy_dirty_flag_from_creator pirate = Pirate.create!(:catchphrase => "shiver me timbers") - pirate_clone = pirate.clone - pirate_clone.reset_catchphrase! + pirate_dup = pirate.dup + pirate_dup.reset_catchphrase! pirate.catchphrase = "I love Rum" assert pirate.catchphrase_changed? - assert !pirate_clone.catchphrase_changed? + assert !pirate_dup.catchphrase_changed? end def test_reverted_changes_are_not_dirty diff --git a/activerecord/test/cases/dup_test.rb b/activerecord/test/cases/dup_test.rb new file mode 100644 index 0000000000..0236f9b0a1 --- /dev/null +++ b/activerecord/test/cases/dup_test.rb @@ -0,0 +1,103 @@ +require "cases/helper" +require 'models/topic' + +module ActiveRecord + class DupTest < ActiveRecord::TestCase + fixtures :topics + + def test_dup + assert !Topic.new.freeze.dup.frozen? + end + + def test_not_readonly + topic = Topic.first + + duped = topic.dup + assert !duped.readonly?, 'should not be readonly' + end + + def test_is_readonly + topic = Topic.first + topic.readonly! + + duped = topic.dup + assert duped.readonly?, 'should be readonly' + end + + def test_dup_not_persisted + topic = Topic.first + duped = topic.dup + + assert !duped.persisted?, 'topic not persisted' + assert duped.new_record?, 'topic is new' + end + + def test_dup_has_no_id + topic = Topic.first + duped = topic.dup + assert_nil duped.id + end + + def test_dup_with_modified_attributes + topic = Topic.first + topic.author_name = 'Aaron' + duped = topic.dup + assert_equal 'Aaron', duped.author_name + end + + def test_dup_with_changes + dbtopic = Topic.first + topic = Topic.new + + topic.attributes = dbtopic.attributes + + #duped has no timestamp values + duped = dbtopic.dup + + #clear topic timestamp values + topic.send(:clear_timestamp_attributes) + + assert_equal topic.changes, duped.changes + end + + def test_dup_topics_are_independent + topic = Topic.first + topic.author_name = 'Aaron' + duped = topic.dup + + duped.author_name = 'meow' + + assert_not_equal topic.changes, duped.changes + end + + def test_dup_attributes_are_independent + topic = Topic.first + duped = topic.dup + + duped.author_name = 'meow' + topic.author_name = 'Aaron' + + assert_equal 'Aaron', topic.author_name + assert_equal 'meow', duped.author_name + end + + def test_dup_timestamps_are_cleared + topic = Topic.first + assert_not_nil topic.updated_at + assert_not_nil topic.created_at + + # temporary change to the topic object + topic.updated_at -= 3.days + + #dup should not preserve the timestamps if present + new_topic = topic.dup + assert_nil new_topic.updated_at + assert_nil new_topic.created_at + + new_topic.save + assert_not_nil new_topic.updated_at + assert_not_nil new_topic.created_at + end + + end +end diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index 7db55da02a..942a5c048e 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -20,11 +20,6 @@ rescue LoadError require "test/connections/#{connection_type}_sqlite3/connection" end -begin - require 'ruby-debug' -rescue LoadError -end - # Show backtraces for deprecated behavior for quicker cleanup. ActiveSupport::Deprecation.debug = true diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index 31679b2efe..c3da9cdf53 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -16,7 +16,7 @@ class InheritanceTest < ActiveRecord::TestCase def test_class_with_blank_sti_name company = Company.find(:first) - company = company.clone + company = company.dup company.extend(Module.new { def read_attribute(name) return ' ' if name == 'type' diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb index 233338498f..b8c3ffb9cb 100644 --- a/activerecord/test/cases/lifecycle_test.rb +++ b/activerecord/test/cases/lifecycle_test.rb @@ -9,10 +9,19 @@ class SpecialDeveloper < Developer; end class SalaryChecker < ActiveRecord::Observer observe :special_developer + attr_accessor :last_saved def before_save(developer) return developer.salary > 80000 end + + module Implementation + def after_save(developer) + self.last_saved = developer + end + end + include Implementation + end class TopicaAuditor < ActiveRecord::Observer @@ -179,4 +188,11 @@ class LifecycleTest < ActiveRecord::TestCase developer = SpecialDeveloper.new :name => 'Rookie', :salary => 50000 assert !developer.save, "allowed to save a developer with too low salary" end + + test "able to call methods defined with included module" do # https://rails.lighthouseapp.com/projects/8994/tickets/6065-activerecordobserver-is-not-aware-of-method-added-by-including-modules + SalaryChecker.instance # activate + developer = SpecialDeveloper.create! :name => 'Roger', :salary => 100000 + assert_equal developer, SalaryChecker.instance.last_saved + end + end diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index 4ddcdc010b..f9678cb0c5 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -1,3 +1,4 @@ +require 'thread' require "cases/helper" require 'models/person' require 'models/reader' diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 3037d73a1b..1a65045ded 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -5,10 +5,8 @@ require 'models/person' require 'models/topic' require 'models/developer' -require MIGRATIONS_ROOT + "/valid/1_people_have_last_names" require MIGRATIONS_ROOT + "/valid/2_we_need_reminders" require MIGRATIONS_ROOT + "/decimal/1_give_me_big_numbers" -require MIGRATIONS_ROOT + "/interleaved/pass_3/2_i_raise_on_down" if ActiveRecord::Base.connection.supports_migrations? class BigNumber < ActiveRecord::Base; end @@ -21,8 +19,8 @@ if ActiveRecord::Base.connection.supports_migrations? end def puts(text="") - self.class.message_count ||= 0 - self.class.message_count += 1 + ActiveRecord::Migration.message_count ||= 0 + ActiveRecord::Migration.message_count += 1 end end @@ -52,7 +50,7 @@ if ActiveRecord::Base.connection.supports_migrations? def setup ActiveRecord::Migration.verbose = true - PeopleHaveLastNames.message_count = 0 + ActiveRecord::Migration.message_count = 0 end def teardown @@ -1271,51 +1269,56 @@ if ActiveRecord::Base.connection.supports_migrations? def test_finds_migrations migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations - [[1, 'PeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i| + [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i| assert_equal migrations[i].version, pair.first assert_equal migrations[i].name, pair.last end end + def test_finds_migrations_from_two_directories + directories = [MIGRATIONS_ROOT + '/valid_with_timestamps', MIGRATIONS_ROOT + '/to_copy_with_timestamps'] + migrations = ActiveRecord::Migrator.new(:up, directories).migrations + + [[20090101010101, "PeopleHaveHobbies"], + [20090101010202, "PeopleHaveDescriptions"], + [20100101010101, "ValidWithTimestampsPeopleHaveLastNames"], + [20100201010101, "ValidWithTimestampsWeNeedReminders"], + [20100301010101, "ValidWithTimestampsInnocentJointable"]].each_with_index do |pair, i| + assert_equal pair.first, migrations[i].version + assert_equal pair.last, migrations[i].name + end + end + def test_finds_pending_migrations ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2", 1) migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/interleaved/pass_2").pending_migrations assert_equal 1, migrations.size assert_equal migrations[0].version, 3 - assert_equal migrations[0].name, 'InnocentJointable' + assert_equal migrations[0].name, 'InterleavedInnocentJointable' end def test_relative_migrations - $".delete_if do |fname| - fname == (MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb") - end - Object.send(:remove_const, :PeopleHaveLastNames) - - Dir.chdir(MIGRATIONS_ROOT) do + list = Dir.chdir(MIGRATIONS_ROOT) do ActiveRecord::Migrator.up("valid/", 1) end - assert defined?(PeopleHaveLastNames) + migration_proxy = list.find { |item| + item.name == 'ValidPeopleHaveLastNames' + } + assert migration_proxy, 'should find pending migration' end def test_only_loads_pending_migrations # migrate up to 1 ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1) - # now unload the migrations that have been defined - Object.send(:remove_const, :PeopleHaveLastNames) - - ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil) - - assert !defined? PeopleHaveLastNames - - %w(WeNeedReminders, InnocentJointable).each do |migration| - assert defined? migration - end + proxies = ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil) - ensure - load(MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb") + names = proxies.map(&:name) + assert !names.include?('ValidPeopleHaveLastNames') + assert names.include?('WeNeedReminders') + assert names.include?('InnocentJointable') end def test_target_version_zero_should_run_only_once @@ -1325,16 +1328,9 @@ if ActiveRecord::Base.connection.supports_migrations? # migrate down to 0 ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0) - # now unload the migrations that have been defined - PeopleHaveLastNames.unloadable - ActiveSupport::Dependencies.remove_unloadable_constants! - # migrate down to 0 again - ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0) - - assert !defined? PeopleHaveLastNames - ensure - load(MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb") + proxies = ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0) + assert_equal [], proxies end def test_migrator_db_has_no_schema_migrations_table @@ -1351,20 +1347,20 @@ if ActiveRecord::Base.connection.supports_migrations? def test_migrator_verbosity ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1) - assert_operator PeopleHaveLastNames.message_count, :>, 0 - PeopleHaveLastNames.message_count = 0 + assert_not_equal 0, ActiveRecord::Migration.message_count + ActiveRecord::Migration.message_count = 0 ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0) - assert_operator PeopleHaveLastNames.message_count, :>, 0 - PeopleHaveLastNames.message_count = 0 + assert_not_equal 0, ActiveRecord::Migration.message_count + ActiveRecord::Migration.message_count = 0 end def test_migrator_verbosity_off - PeopleHaveLastNames.verbose = false + ActiveRecord::Migration.verbose = false ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1) - assert_equal 0, PeopleHaveLastNames.message_count + assert_equal 0, ActiveRecord::Migration.message_count ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0) - assert_equal 0, PeopleHaveLastNames.message_count + assert_equal 0, ActiveRecord::Migration.message_count end def test_migrator_going_down_due_to_version_target @@ -1658,10 +1654,6 @@ if ActiveRecord::Base.connection.supports_migrations? end # SexyMigrationsTest class MigrationLoggerTest < ActiveRecord::TestCase - def setup - Object.send(:remove_const, :InnocentJointable) - end - def test_migration_should_be_run_without_logger previous_logger = ActiveRecord::Base.logger ActiveRecord::Base.logger = nil @@ -1674,10 +1666,6 @@ if ActiveRecord::Base.connection.supports_migrations? end class InterleavedMigrationsTest < ActiveRecord::TestCase - def setup - Object.send(:remove_const, :PeopleHaveLastNames) - end - def test_migrator_interleaved_migrations ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_1") @@ -1688,10 +1676,12 @@ if ActiveRecord::Base.connection.supports_migrations? Person.reset_column_information assert Person.column_methods_hash.include?(:last_name) - Object.send(:remove_const, :PeopleHaveLastNames) - Object.send(:remove_const, :InnocentJointable) assert_nothing_raised do - ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/interleaved/pass_3") + proxies = ActiveRecord::Migrator.down( + MIGRATIONS_ROOT + "/interleaved/pass_3") + names = proxies.map(&:name) + assert names.include?('InterleavedPeopleHaveLastNames') + assert names.include?('InterleavedInnocentJointable') end end end diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 6ac3e3fc56..ed5e1e0cba 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -141,26 +141,26 @@ class NamedScopeTest < ActiveRecord::TestCase assert_equal 1, Topic.multiple_extensions.extension_one end - def test_has_many_associations_have_access_to_named_scopes + def test_has_many_associations_have_access_to_scopes assert_not_equal Post.containing_the_letter_a, authors(:david).posts assert !Post.containing_the_letter_a.empty? assert_equal authors(:david).posts & Post.containing_the_letter_a, authors(:david).posts.containing_the_letter_a end - def test_named_scope_with_STI + def test_scope_with_STI assert_equal 3,Post.containing_the_letter_a.count assert_equal 1,SpecialPost.containing_the_letter_a.count end - def test_has_many_through_associations_have_access_to_named_scopes + def test_has_many_through_associations_have_access_to_scopes assert_not_equal Comment.containing_the_letter_e, authors(:david).comments assert !Comment.containing_the_letter_e.empty? assert_equal authors(:david).comments & Comment.containing_the_letter_e, authors(:david).comments.containing_the_letter_e end - def test_named_scopes_honor_current_scopes_from_when_defined + def test_scopes_honor_current_scopes_from_when_defined assert !Post.ranked_by_comments.limit_by(5).empty? assert !authors(:david).posts.ranked_by_comments.limit_by(5).empty? assert_not_equal Post.ranked_by_comments.limit_by(5), authors(:david).posts.ranked_by_comments.limit_by(5) @@ -236,7 +236,7 @@ class NamedScopeTest < ActiveRecord::TestCase end end - def test_any_should_not_fire_query_if_named_scope_loaded + def test_any_should_not_fire_query_if_scope_loaded topics = Topic.base topics.collect # force load assert_no_queries { assert topics.any? } @@ -259,7 +259,7 @@ class NamedScopeTest < ActiveRecord::TestCase end end - def test_many_should_not_fire_query_if_named_scope_loaded + def test_many_should_not_fire_query_if_scope_loaded topics = Topic.base topics.collect # force load assert_no_queries { assert topics.many? } @@ -276,27 +276,27 @@ class NamedScopeTest < ActiveRecord::TestCase assert Topic.base.many? end - def test_should_build_on_top_of_named_scope + def test_should_build_on_top_of_scope topic = Topic.approved.build({}) assert topic.approved end - def test_should_build_new_on_top_of_named_scope + def test_should_build_new_on_top_of_scope topic = Topic.approved.new assert topic.approved end - def test_should_create_on_top_of_named_scope + def test_should_create_on_top_of_scope topic = Topic.approved.create({}) assert topic.approved end - def test_should_create_with_bang_on_top_of_named_scope + def test_should_create_with_bang_on_top_of_scope topic = Topic.approved.create!({}) assert topic.approved end - def test_should_build_on_top_of_chained_named_scopes + def test_should_build_on_top_of_chained_scopes topic = Topic.approved.by_lifo.build({}) assert topic.approved assert_equal 'lifo', topic.author_name @@ -310,7 +310,7 @@ class NamedScopeTest < ActiveRecord::TestCase assert_kind_of Topic, Topic.approved.sample end - def test_should_use_where_in_query_for_named_scope + def test_should_use_where_in_query_for_scope assert_equal Developer.find_all_by_name('Jamis').to_set, Developer.find_all_by_id(Developer.jamises).to_set end @@ -361,7 +361,7 @@ class NamedScopeTest < ActiveRecord::TestCase assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).all.uniq end - def test_named_scopes_batch_finders + def test_scopes_batch_finders assert_equal 3, Topic.approved.count assert_queries(4) do @@ -381,7 +381,7 @@ class NamedScopeTest < ActiveRecord::TestCase end end - def test_named_scopes_with_reserved_names + def test_scopes_with_reserved_names class << Topic def public_method; end public :public_method @@ -400,7 +400,7 @@ class NamedScopeTest < ActiveRecord::TestCase end end - def test_named_scopes_on_relations + def test_scopes_on_relations # Topic.replied approved_topics = Topic.scoped.approved.order('id DESC') assert_equal topics(:fourth), approved_topics.first @@ -409,19 +409,19 @@ class NamedScopeTest < ActiveRecord::TestCase assert_equal topics(:third), replied_approved_topics.first end - def test_index_on_named_scope + def test_index_on_scope approved = Topic.approved.order('id ASC') assert_equal topics(:second), approved[0] assert approved.loaded? end - def test_nested_named_scopes_queries_size + def test_nested_scopes_queries_size assert_queries(1) do Topic.approved.by_lifo.replied.written_before(Time.now).all end end - def test_named_scopes_are_cached_on_associations + def test_scopes_are_cached_on_associations post = posts(:welcome) assert_equal post.comments.containing_the_letter_e.object_id, post.comments.containing_the_letter_e.object_id @@ -430,7 +430,7 @@ class NamedScopeTest < ActiveRecord::TestCase assert_no_queries { post.comments.containing_the_letter_e.all } end - def test_named_scopes_with_arguments_are_cached_on_associations + def test_scopes_with_arguments_are_cached_on_associations post = posts(:welcome) one = post.comments.limit_by(1).all @@ -443,7 +443,7 @@ class NamedScopeTest < ActiveRecord::TestCase assert_no_queries { post.comments.limit_by(2).all } end - def test_named_scopes_are_reset_on_association_reload + def test_scopes_are_reset_on_association_reload post = posts(:welcome) [:destroy_all, :reset, :delete_all].each do |method| @@ -453,7 +453,7 @@ class NamedScopeTest < ActiveRecord::TestCase end end - def test_named_scoped_are_lazy_loaded_if_table_still_does_not_exist + def test_scoped_are_lazy_loaded_if_table_still_does_not_exist assert_nothing_raised do require "models/without_table" end diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 92af53d56f..ffcc7a081a 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -827,7 +827,7 @@ class TestNestedAttributesWithNonStandardPrimaryKeys < ActiveRecord::TestCase fixtures :owners, :pets def setup - Owner.accepts_nested_attributes_for :pets + Owner.accepts_nested_attributes_for :pets, :allow_destroy => true @owner = owners(:ashley) @pet1, @pet2 = pets(:chew), pets(:mochi) @@ -844,6 +844,18 @@ class TestNestedAttributesWithNonStandardPrimaryKeys < ActiveRecord::TestCase @owner.update_attributes(@params) assert_equal ['Foo', 'Bar'], @owner.pets.map(&:name) end + + def test_attr_accessor_of_child_should_be_value_provided_during_update_attributes + @owner = owners(:ashley) + @pet1 = pets(:chew) + attributes = {:pets_attributes => { "1"=> { :id => @pet1.id, + :name => "Foo2", + :current_user => "John", + :_destroy=>true }}} + @owner.update_attributes(attributes) + assert_equal 'John', Pet.after_destroy_output + end + end class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRecord::TestCase diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index 3b9e4f42a6..912e3c47bb 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -25,7 +25,7 @@ class ReflectionTest < ActiveRecord::TestCase def test_read_attribute_names assert_equal( %w( id title author_name author_email_address bonus_time written_on last_read content group approved replies_count parent_id parent_title type created_at updated_at ).sort, - @first.attribute_names + @first.attribute_names.sort ) end @@ -191,6 +191,11 @@ class ReflectionTest < ActiveRecord::TestCase assert_kind_of ThroughReflection, Subscriber.reflect_on_association(:books) end + def test_active_record_primary_key + assert_equal "nick", Subscriber.reflect_on_association(:subscriptions).active_record_primary_key.to_s + assert_equal "name", Author.reflect_on_association(:essay).active_record_primary_key.to_s + end + def test_collection_association assert Pirate.reflect_on_association(:birds).collection? assert Pirate.reflect_on_association(:parrots).collection? diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb index dae9721a63..f113a9c516 100644 --- a/activerecord/test/cases/relation_scoping_test.rb +++ b/activerecord/test/cases/relation_scoping_test.rb @@ -422,7 +422,7 @@ class DefaultScopingTest < ActiveRecord::TestCase assert_equal expected, received end - def test_named_scope_overwrites_default + def test_scope_overwrites_default expected = Developer.find(:all, :order => 'salary DESC, name DESC').collect { |dev| dev.name } received = DeveloperOrderedBySalary.by_name.find(:all).collect { |dev| dev.name } assert_equal expected, received @@ -464,6 +464,22 @@ class DefaultScopingTest < ActiveRecord::TestCase assert_equal 50000, PoorDeveloperCalledJamis.create!(:name => 'David').salary end + def test_default_scope_attribute + jamis = PoorDeveloperCalledJamis.new(:name => 'David') + assert_equal 50000, jamis.salary + end + + def test_where_attribute + aaron = PoorDeveloperCalledJamis.where(:salary => 20).new(:name => 'Aaron') + assert_equal 20, aaron.salary + assert_equal 'Aaron', aaron.name + end + + def test_where_attribute_merge + aaron = PoorDeveloperCalledJamis.where(:name => 'foo').new(:name => 'Aaron') + assert_equal 'Aaron', aaron.name + end + def test_scope_composed_by_limit_and_then_offset_is_equal_to_scope_composed_by_offset_and_then_limit posts_limit_offset = Post.limit(3).offset(2) posts_offset_limit = Post.offset(2).limit(3) diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb new file mode 100644 index 0000000000..7bdbd773b6 --- /dev/null +++ b/activerecord/test/cases/relation_test.rb @@ -0,0 +1,139 @@ +require "cases/helper" +require 'models/post' +require 'models/comment' + +module ActiveRecord + class RelationTest < ActiveRecord::TestCase + fixtures :posts, :comments + + class FakeKlass < Struct.new(:table_name) + end + + def test_construction + relation = nil + assert_nothing_raised do + relation = Relation.new :a, :b + end + assert_equal :a, relation.klass + assert_equal :b, relation.table + assert !relation.loaded, 'relation is not loaded' + end + + def test_single_values + assert_equal [:limit, :offset, :lock, :readonly, :create_with, :from].map(&:to_s).sort, + Relation::SINGLE_VALUE_METHODS.map(&:to_s).sort + end + + def test_initialize_single_values + relation = Relation.new :a, :b + Relation::SINGLE_VALUE_METHODS.each do |method| + assert_nil relation.send("#{method}_value"), method.to_s + end + end + + def test_association_methods + assert_equal [:includes, :eager_load, :preload].map(&:to_s).sort, + Relation::ASSOCIATION_METHODS.map(&:to_s).sort + end + + def test_initialize_association_methods + relation = Relation.new :a, :b + Relation::ASSOCIATION_METHODS.each do |method| + assert_equal [], relation.send("#{method}_values"), method.to_s + end + end + + def test_multi_value_methods + assert_equal [:select, :group, :order, :joins, :where, :having, :bind].map(&:to_s).sort, + Relation::MULTI_VALUE_METHODS.map(&:to_s).sort + end + + def test_multi_value_initialize + relation = Relation.new :a, :b + Relation::MULTI_VALUE_METHODS.each do |method| + assert_equal [], relation.send("#{method}_values"), method.to_s + end + end + + def test_extensions + relation = Relation.new :a, :b + assert_equal [], relation.extensions + end + + def test_empty_where_values_hash + relation = Relation.new :a, :b + assert_equal({}, relation.where_values_hash) + + relation.where_values << :hello + assert_equal({}, relation.where_values_hash) + end + + def test_has_values + relation = Relation.new Post, Post.arel_table + relation.where_values << relation.table[:id].eq(10) + assert_equal({:id => 10}, relation.where_values_hash) + end + + def test_values_wrong_table + relation = Relation.new Post, Post.arel_table + relation.where_values << Comment.arel_table[:id].eq(10) + assert_equal({}, relation.where_values_hash) + end + + def test_tree_is_not_traversed + relation = Relation.new Post, Post.arel_table + left = relation.table[:id].eq(10) + right = relation.table[:id].eq(10) + combine = left.and right + relation.where_values << combine + assert_equal({}, relation.where_values_hash) + end + + def test_table_name_delegates_to_klass + relation = Relation.new FakeKlass.new('foo'), :b + assert_equal 'foo', relation.table_name + end + + def test_scope_for_create + relation = Relation.new :a, :b + assert_equal({}, relation.scope_for_create) + end + + def test_create_with_value + relation = Relation.new Post, Post.arel_table + hash = { :hello => 'world' } + relation.create_with_value = hash + assert_equal hash, relation.scope_for_create + end + + def test_create_with_value_with_wheres + relation = Relation.new Post, Post.arel_table + relation.where_values << relation.table[:id].eq(10) + relation.create_with_value = {:hello => 'world'} + assert_equal({:hello => 'world', :id => 10}, relation.scope_for_create) + end + + # FIXME: is this really wanted or expected behavior? + def test_scope_for_create_is_cached + relation = Relation.new Post, Post.arel_table + assert_equal({}, relation.scope_for_create) + + relation.where_values << relation.table[:id].eq(10) + assert_equal({}, relation.scope_for_create) + + relation.create_with_value = {:hello => 'world'} + assert_equal({}, relation.scope_for_create) + end + + def test_empty_eager_loading? + relation = Relation.new :a, :b + assert !relation.eager_loading? + end + + def test_eager_load_values + relation = Relation.new :a, :b + relation.eager_load_values << :b + assert relation.eager_loading? + end + end +end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 2809554e4f..b3d4305f7c 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -14,11 +14,18 @@ require 'models/bird' require 'models/car' require 'models/engine' require 'models/tyre' +require 'models/minivan' class RelationTest < ActiveRecord::TestCase fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments, - :tags, :taggings, :cars + :tags, :taggings, :cars, :minivans + + def test_do_not_double_quote_string_id + van = Minivan.last + assert van + assert_equal van.id, Minivan.where(:minivan_id => van).to_a.first.minivan_id + end def test_bind_values relation = Post.scoped @@ -29,7 +36,7 @@ class RelationTest < ActiveRecord::TestCase assert_equal [], relation.bind_values end - def test_two_named_scopes_with_includes_should_not_drop_any_include + def test_two_scopes_with_includes_should_not_drop_any_include car = Car.incl_engines.incl_tyres.first assert_no_queries { car.tyres.length } assert_no_queries { car.engines.length } @@ -177,6 +184,10 @@ class RelationTest < ActiveRecord::TestCase assert_equal [2, 4, 6, 8, 10], even_ids.sort end + def test_joins_with_nil_argument + assert_nothing_raised { DependentFirm.joins(nil).first } + end + def test_finding_with_hash_conditions_on_joined_table firms = DependentFirm.joins(:account).where({:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}).to_a assert_equal 1, firms.size @@ -241,7 +252,7 @@ class RelationTest < ActiveRecord::TestCase end end - def test_respond_to_class_methods_and_named_scopes + def test_respond_to_class_methods_and_scopes assert DeveloperOrderedBySalary.scoped.respond_to?(:all_ordered_by_name) assert Topic.scoped.respond_to?(:by_lifo) end @@ -749,7 +760,7 @@ class RelationTest < ActiveRecord::TestCase assert_equal 'zyke', FastCar.order('name desc').find(:first, :order => 'id').name end - def test_default_scope_order_with_named_scope_order + def test_default_scope_order_with_scope_order assert_equal 'zyke', CoolCar.order_using_new_style.limit(1).first.name assert_equal 'zyke', CoolCar.order_using_old_style.limit(1).first.name assert_equal 'zyke', FastCar.order_using_new_style.limit(1).first.name diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index b0ccd71836..110a18772f 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -370,23 +370,23 @@ class TransactionTest < ActiveRecord::TestCase assert topic_2.save @first.save @second.destroy - assert_equal true, topic_1.persisted? + assert topic_1.persisted?, 'persisted' assert_not_nil topic_1.id - assert_equal true, topic_2.persisted? + assert topic_2.persisted?, 'persisted' assert_not_nil topic_2.id - assert_equal true, @first.persisted? + assert @first.persisted?, 'persisted' assert_not_nil @first.id - assert_equal true, @second.destroyed? + assert @second.destroyed?, 'destroyed' raise ActiveRecord::Rollback end - assert_equal false, topic_1.persisted? + assert !topic_1.persisted?, 'not persisted' assert_nil topic_1.id - assert_equal false, topic_2.persisted? + assert !topic_2.persisted?, 'not persisted' assert_nil topic_2.id - assert_equal true, @first.persisted? + assert @first.persisted?, 'persisted' assert_not_nil @first.id - assert_equal false, @second.destroyed? + assert !@second.destroyed?, 'not destroyed' end if current_adapter?(:PostgreSQLAdapter) && defined?(PGconn::PQTRANS_IDLE) diff --git a/activerecord/test/cases/xml_serialization_test.rb b/activerecord/test/cases/xml_serialization_test.rb index b11b340e94..a6074b23e7 100644 --- a/activerecord/test/cases/xml_serialization_test.rb +++ b/activerecord/test/cases/xml_serialization_test.rb @@ -4,6 +4,7 @@ require 'models/post' require 'models/author' require 'models/comment' require 'models/company_in_module' +require 'models/toy' class XmlSerializationTest < ActiveRecord::TestCase def test_should_serialize_default_root @@ -83,6 +84,26 @@ class DefaultXmlSerializationTest < ActiveRecord::TestCase end end +class DefaultXmlSerializationTimezoneTest < ActiveRecord::TestCase + def test_should_serialize_datetime_with_timezone + timezone, Time.zone = Time.zone, "Pacific Time (US & Canada)" + + toy = Toy.create(:name => 'Mickey', :updated_at => Time.utc(2006, 8, 1)) + assert_match %r{<updated-at type=\"datetime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml + ensure + Time.zone = timezone + end + + def test_should_serialize_datetime_with_timezone_reloaded + timezone, Time.zone = Time.zone, "Pacific Time (US & Canada)" + + toy = Toy.create(:name => 'Minnie', :updated_at => Time.utc(2006, 8, 1)).reload + assert_match %r{<updated-at type=\"datetime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml + ensure + Time.zone = timezone + end +end + class NilXmlSerializationTest < ActiveRecord::TestCase def setup @xml = Contact.new.to_xml(:root => 'xml_contact') @@ -241,4 +262,10 @@ class DatabaseConnectedXmlSerializationTest < ActiveRecord::TestCase assert array.include? 'github' end + def test_should_support_aliased_attributes + xml = Author.select("name as firstname").to_xml + array = Hash.from_xml(xml)['authors'] + assert_equal array.size, array.select { |author| author.has_key? 'firstname' }.size + end + end diff --git a/activerecord/test/cases/yaml_serialization_test.rb b/activerecord/test/cases/yaml_serialization_test.rb index f221def6b6..0fc9918744 100644 --- a/activerecord/test/cases/yaml_serialization_test.rb +++ b/activerecord/test/cases/yaml_serialization_test.rb @@ -2,10 +2,19 @@ require "cases/helper" require 'models/topic' class YamlSerializationTest < ActiveRecord::TestCase + fixtures :topics + def test_to_yaml_with_time_with_zone_should_not_raise_exception Time.zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"] ActiveRecord::Base.time_zone_aware_attributes = true topic = Topic.new(:written_on => DateTime.now) assert_nothing_raised { topic.to_yaml } end + + def test_roundtrip + topic = Topic.first + assert topic + t = YAML.load YAML.dump topic + assert_equal topic, t + end end |