diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2009-09-21 21:14:04 +0100 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2009-09-21 21:14:04 +0100 |
commit | 340be9bddd8e5902e0218a0101a40a17a4afd558 (patch) | |
tree | ef4de25f3f8eb610dc2235f0762b01cb1d464efd /activerecord/test/cases | |
parent | b31cdb55422226cd45a2234a4b54986f1f611151 (diff) | |
parent | 1bbb9b2db05730194edfd7d2cef9f5fcb9d79e50 (diff) | |
download | rails-340be9bddd8e5902e0218a0101a40a17a4afd558.tar.gz rails-340be9bddd8e5902e0218a0101a40a17a4afd558.tar.bz2 rails-340be9bddd8e5902e0218a0101a40a17a4afd558.zip |
Merge commit 'mainstream/master'
Diffstat (limited to 'activerecord/test/cases')
16 files changed, 371 insertions, 255 deletions
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index f7178f2c5e..b193f8d8ba 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -813,7 +813,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase firm = companies(:first_firm) clients = firm.clients assert_equal 2, clients.length - clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end } + clients.last.instance_eval { def overwrite_to_raise() raise "Trigger rollback" end } firm.destroy rescue "do nothing" diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index 7140de77ea..cdac86a3b9 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -36,6 +36,15 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_equal accounts(:rails_core_account), firm.account_using_primary_key end + def test_update_with_foreign_and_primary_keys + firm = companies(:first_firm) + account = firm.account_using_foreign_and_primary_keys + assert_equal Account.find_by_firm_name(firm.name), account + firm.save + firm.reload + assert_equal account, firm.account_using_foreign_and_primary_keys + end + def test_can_marshal_has_one_association_with_nil_target firm = Firm.new assert_nothing_raised do diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 271086af8e..9164701601 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -443,6 +443,70 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa end end +class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase + def test_autosave_new_record_on_belongs_to_can_be_disabled_per_relationship + new_account = Account.new("credit_limit" => 1000) + new_firm = Firm.new("name" => "some firm") + + assert new_firm.new_record? + new_account.firm = new_firm + new_account.save! + + assert !new_firm.new_record? + + new_account = Account.new("credit_limit" => 1000) + new_autosaved_firm = Firm.new("name" => "some firm") + + assert new_autosaved_firm.new_record? + new_account.unautosaved_firm = new_autosaved_firm + new_account.save! + + assert new_autosaved_firm.new_record? + end + + def test_autosave_new_record_on_has_one_can_be_disabled_per_relationship + firm = Firm.new("name" => "some firm") + account = Account.new("credit_limit" => 1000) + + assert account.new_record? + firm.account = account + firm.save! + + assert !account.new_record? + + firm = Firm.new("name" => "some firm") + account = Account.new("credit_limit" => 1000) + + firm.unautosaved_account = account + + assert account.new_record? + firm.unautosaved_account = account + firm.save! + + assert account.new_record? + end + + def test_autosave_new_record_on_has_many_can_be_disabled_per_relationship + firm = Firm.new("name" => "some firm") + account = Account.new("credit_limit" => 1000) + + assert account.new_record? + firm.accounts << account + + firm.save! + assert !account.new_record? + + firm = Firm.new("name" => "some firm") + account = Account.new("credit_limit" => 1000) + + assert account.new_record? + firm.unautosaved_accounts << account + + firm.save! + assert account.new_record? + end +end + class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase self.use_transactional_fixtures = false @@ -480,9 +544,17 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase assert !@pirate.valid? @pirate.ship.mark_for_destruction + @pirate.ship.expects(:valid?).never assert_difference('Ship.count', -1) { @pirate.save! } end + def test_a_child_marked_for_destruction_should_not_be_destroyed_twice + @pirate.ship.mark_for_destruction + assert @pirate.save + @pirate.ship.expects(:destroy).never + assert @pirate.save + end + def test_should_rollback_destructions_if_an_exception_occurred_while_saving_a_child # Stub the save method of the @pirate.ship instance to destroy and then raise an exception class << @pirate.ship @@ -517,9 +589,17 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase assert !@ship.valid? @ship.pirate.mark_for_destruction + @ship.pirate.expects(:valid?).never assert_difference('Pirate.count', -1) { @ship.save! } end + def test_a_parent_marked_for_destruction_should_not_be_destroyed_twice + @ship.pirate.mark_for_destruction + assert @ship.save + @ship.pirate.expects(:destroy).never + assert @ship.save + end + def test_should_rollback_destructions_if_an_exception_occurred_while_saving_a_parent # Stub the save method of the @ship.pirate instance to destroy and then raise an exception class << @ship.pirate @@ -560,9 +640,33 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase children.each { |child| child.name = '' } assert !@pirate.valid? - children.each { |child| child.mark_for_destruction } + children.each do |child| + child.mark_for_destruction + child.expects(:valid?).never + end assert_difference("#{association_name.classify}.count", -2) { @pirate.save! } end + + define_method("test_should_skip_validation_on_the_#{association_name}_association_if_destroyed") do + @pirate.send(association_name).create!(:name => "#{association_name}_1") + children = @pirate.send(association_name) + + children.each { |child| child.name = '' } + assert !@pirate.valid? + + children.each { |child| child.destroy } + assert @pirate.valid? + end + + define_method("test_a_child_marked_for_destruction_should_not_be_destroyed_twice_while_saving_#{association_name}") do + @pirate.send(association_name).create!(:name => "#{association_name}_1") + children = @pirate.send(association_name) + + children.each { |child| child.mark_for_destruction } + assert @pirate.save + children.each { |child| child.expects(:destroy).never } + assert @pirate.save + end define_method("test_should_rollback_destructions_if_an_exception_occurred_while_saving_#{association_name}") do 2.times { |i| @pirate.send(association_name).create!(:name => "#{association_name}_#{i}") } @@ -952,3 +1056,118 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::T include AutosaveAssociationOnACollectionAssociationTests end + +class TestAutosaveAssociationValidationsOnAHasManyAssocication < ActiveRecord::TestCase + self.use_transactional_fixtures = false + + def setup + @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") + @pirate.birds.create(:name => 'cookoo') + end + + test "should automatically validate associations" do + assert @pirate.valid? + @pirate.birds.each { |bird| bird.name = '' } + + assert !@pirate.valid? + end +end + +class TestAutosaveAssociationValidationsOnAHasOneAssocication < ActiveRecord::TestCase + self.use_transactional_fixtures = false + + def setup + @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") + @pirate.create_ship(:name => 'titanic') + end + + test "should automatically validate associations with :validate => true" do + assert @pirate.valid? + @pirate.ship.name = '' + assert !@pirate.valid? + end + + test "should not automatically validate associations without :validate => true" do + assert @pirate.valid? + @pirate.non_validated_ship.name = '' + assert @pirate.valid? + end +end + +class TestAutosaveAssociationValidationsOnABelongsToAssocication < ActiveRecord::TestCase + self.use_transactional_fixtures = false + + def setup + @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") + end + + test "should automatically validate associations with :validate => true" do + assert @pirate.valid? + @pirate.parrot = Parrot.new(:name => '') + assert !@pirate.valid? + end + + test "should not automatically validate associations without :validate => true" do + assert @pirate.valid? + @pirate.non_validated_parrot = Parrot.new(:name => '') + assert @pirate.valid? + end +end + +class TestAutosaveAssociationValidationsOnAHABTMAssocication < ActiveRecord::TestCase + self.use_transactional_fixtures = false + + def setup + @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") + end + + test "should automatically validate associations with :validate => true" do + assert @pirate.valid? + @pirate.parrots = [ Parrot.new(:name => 'popuga') ] + @pirate.parrots.each { |parrot| parrot.name = '' } + assert !@pirate.valid? + end + + test "should not automatically validate associations without :validate => true" do + assert @pirate.valid? + @pirate.non_validated_parrots = [ Parrot.new(:name => 'popuga') ] + @pirate.non_validated_parrots.each { |parrot| parrot.name = '' } + assert @pirate.valid? + end +end + +class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCase + self.use_transactional_fixtures = false + + def setup + @pirate = Pirate.new + end + + test "should generate validation methods for has_many associations" do + assert @pirate.respond_to?(:validate_associated_records_for_birds) + end + + test "should generate validation methods for has_one associations with :validate => true" do + assert @pirate.respond_to?(:validate_associated_records_for_ship) + end + + test "should not generate validation methods for has_one associations without :validate => true" do + assert !@pirate.respond_to?(:validate_associated_records_for_non_validated_ship) + end + + test "should generate validation methods for belongs_to associations with :validate => true" do + assert @pirate.respond_to?(:validate_associated_records_for_parrot) + end + + test "should not generate validation methods for belongs_to associations without :validate => true" do + assert !@pirate.respond_to?(:validate_associated_records_for_non_validated_parrot) + end + + test "should generate validation methods for HABTM associations with :validate => true" do + assert @pirate.respond_to?(:validate_associated_records_for_parrots) + end + + test "should not generate validation methods for HABTM associations without :validate => true" do + assert !@pirate.respond_to?(:validate_associated_records_for_non_validated_parrots) + end +end diff --git a/activerecord/test/cases/callbacks_observers_test.rb b/activerecord/test/cases/callbacks_observers_test.rb index 87de524923..52ce384844 100644 --- a/activerecord/test/cases/callbacks_observers_test.rb +++ b/activerecord/test/cases/callbacks_observers_test.rb @@ -5,7 +5,7 @@ class Comment < ActiveRecord::Base before_validation :record_callers - def after_validation + after_validation do record_callers end @@ -32,7 +32,6 @@ class CallbacksObserversTest < ActiveRecord::TestCase CommentObserver.instance.callers = callers comment.valid? - assert_equal [Comment, Comment, CommentObserver], callers, "model callbacks did not fire before observers were notified" end end diff --git a/activerecord/test/cases/callbacks_test.rb b/activerecord/test/cases/callbacks_test.rb index 95fddaeef6..5a084a611e 100644 --- a/activerecord/test/cases/callbacks_test.rb +++ b/activerecord/test/cases/callbacks_test.rb @@ -13,8 +13,8 @@ class CallbackDeveloper < ActiveRecord::Base end def define_callback_method(callback_method) - define_method("#{callback_method}_method") do |model| - model.history << [callback_method, :method] + define_method(callback_method) do + self.history << [callback_method, :method] end end @@ -27,26 +27,20 @@ class CallbackDeveloper < ActiveRecord::Base end end - ActiveRecord::Callbacks::CALLBACKS.each do |callback_method| - callback_method_sym = callback_method.to_sym - define_callback_method(callback_method_sym) - send(callback_method, callback_method_sym) - send(callback_method, callback_string(callback_method_sym)) - send(callback_method, callback_proc(callback_method_sym)) - send(callback_method, callback_object(callback_method_sym)) - send(callback_method) { |model| model.history << [callback_method_sym, :block] } + ActiveSupport::Deprecation.silence do + ActiveRecord::Callbacks::CALLBACKS.each do |callback_method| + next if callback_method.to_s =~ /^around_/ + define_callback_method(callback_method) + send(callback_method, callback_string(callback_method)) + send(callback_method, callback_proc(callback_method)) + send(callback_method, callback_object(callback_method)) + send(callback_method) { |model| model.history << [callback_method, :block] } + end end def history @history ||= [] end - - # after_initialize and after_find are invoked only if instance methods have been defined. - def after_initialize - end - - def after_find - end end class ParentDeveloper < ActiveRecord::Base @@ -108,12 +102,12 @@ class ImmutableMethodDeveloper < ActiveRecord::Base @cancelled == true end - def before_save + before_save do @cancelled = true false end - def before_destroy + before_destroy do @cancelled = true false end @@ -125,15 +119,15 @@ class CallbackCancellationDeveloper < ActiveRecord::Base attr_reader :after_save_called, :after_create_called, :after_update_called, :after_destroy_called attr_accessor :cancel_before_save, :cancel_before_create, :cancel_before_update, :cancel_before_destroy - def before_save; !@cancel_before_save; end - def before_create; !@cancel_before_create; end - def before_update; !@cancel_before_update; end - def before_destroy; !@cancel_before_destroy; end + before_save { !@cancel_before_save } + before_create { !@cancel_before_create } + before_update { !@cancel_before_update } + before_destroy { !@cancel_before_destroy } - def after_save; @after_save_called = true; end - def after_update; @after_update_called = true; end - def after_create; @after_create_called = true; end - def after_destroy; @after_destroy_called = true; end + after_save { @after_save_called = true } + after_update { @after_update_called = true } + after_create { @after_create_called = true } + after_destroy { @after_destroy_called = true } end class CallbacksTest < ActiveRecord::TestCase @@ -142,6 +136,7 @@ class CallbacksTest < ActiveRecord::TestCase def test_initialize david = CallbackDeveloper.new assert_equal [ + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], @@ -152,10 +147,12 @@ class CallbacksTest < ActiveRecord::TestCase def test_find david = CallbackDeveloper.find(1) assert_equal [ + [ :after_find, :method ], [ :after_find, :string ], [ :after_find, :proc ], [ :after_find, :object ], [ :after_find, :block ], + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], @@ -167,26 +164,21 @@ class CallbacksTest < ActiveRecord::TestCase david = CallbackDeveloper.new david.valid? assert_equal [ + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], [ :after_initialize, :block ], + [ :before_validation, :method ], [ :before_validation, :string ], [ :before_validation, :proc ], [ :before_validation, :object ], [ :before_validation, :block ], - [ :before_validation_on_create, :string ], - [ :before_validation_on_create, :proc ], - [ :before_validation_on_create, :object ], - [ :before_validation_on_create, :block ], + [ :after_validation, :method ], [ :after_validation, :string ], [ :after_validation, :proc ], [ :after_validation, :object ], [ :after_validation, :block ], - [ :after_validation_on_create, :string ], - [ :after_validation_on_create, :proc ], - [ :after_validation_on_create, :object ], - [ :after_validation_on_create, :block ] ], david.history end @@ -194,68 +186,63 @@ class CallbacksTest < ActiveRecord::TestCase david = CallbackDeveloper.find(1) david.valid? assert_equal [ + [ :after_find, :method ], [ :after_find, :string ], [ :after_find, :proc ], [ :after_find, :object ], [ :after_find, :block ], + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], [ :after_initialize, :block ], + [ :before_validation, :method ], [ :before_validation, :string ], [ :before_validation, :proc ], [ :before_validation, :object ], [ :before_validation, :block ], - [ :before_validation_on_update, :string ], - [ :before_validation_on_update, :proc ], - [ :before_validation_on_update, :object ], - [ :before_validation_on_update, :block ], + [ :after_validation, :method ], [ :after_validation, :string ], [ :after_validation, :proc ], [ :after_validation, :object ], [ :after_validation, :block ], - [ :after_validation_on_update, :string ], - [ :after_validation_on_update, :proc ], - [ :after_validation_on_update, :object ], - [ :after_validation_on_update, :block ] ], david.history end def test_create david = CallbackDeveloper.create('name' => 'David', 'salary' => 1000000) assert_equal [ + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], [ :after_initialize, :block ], + [ :before_validation, :method ], [ :before_validation, :string ], [ :before_validation, :proc ], [ :before_validation, :object ], [ :before_validation, :block ], - [ :before_validation_on_create, :string ], - [ :before_validation_on_create, :proc ], - [ :before_validation_on_create, :object ], - [ :before_validation_on_create, :block ], + [ :after_validation, :method ], [ :after_validation, :string ], [ :after_validation, :proc ], [ :after_validation, :object ], [ :after_validation, :block ], - [ :after_validation_on_create, :string ], - [ :after_validation_on_create, :proc ], - [ :after_validation_on_create, :object ], - [ :after_validation_on_create, :block ], + [ :before_save, :method ], [ :before_save, :string ], [ :before_save, :proc ], [ :before_save, :object ], [ :before_save, :block ], + [ :before_create, :method ], [ :before_create, :string ], [ :before_create, :proc ], [ :before_create, :object ], [ :before_create, :block ], + [ :after_create, :method ], [ :after_create, :string ], [ :after_create, :proc ], [ :after_create, :object ], [ :after_create, :block ], + [ :after_save, :method ], [ :after_save, :string ], [ :after_save, :proc ], [ :after_save, :object ], @@ -267,42 +254,42 @@ class CallbacksTest < ActiveRecord::TestCase david = CallbackDeveloper.find(1) david.save assert_equal [ + [ :after_find, :method ], [ :after_find, :string ], [ :after_find, :proc ], [ :after_find, :object ], [ :after_find, :block ], + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], [ :after_initialize, :block ], + [ :before_validation, :method ], [ :before_validation, :string ], [ :before_validation, :proc ], [ :before_validation, :object ], [ :before_validation, :block ], - [ :before_validation_on_update, :string ], - [ :before_validation_on_update, :proc ], - [ :before_validation_on_update, :object ], - [ :before_validation_on_update, :block ], + [ :after_validation, :method ], [ :after_validation, :string ], [ :after_validation, :proc ], [ :after_validation, :object ], [ :after_validation, :block ], - [ :after_validation_on_update, :string ], - [ :after_validation_on_update, :proc ], - [ :after_validation_on_update, :object ], - [ :after_validation_on_update, :block ], + [ :before_save, :method ], [ :before_save, :string ], [ :before_save, :proc ], [ :before_save, :object ], [ :before_save, :block ], + [ :before_update, :method ], [ :before_update, :string ], [ :before_update, :proc ], [ :before_update, :object ], [ :before_update, :block ], + [ :after_update, :method ], [ :after_update, :string ], [ :after_update, :proc ], [ :after_update, :object ], [ :after_update, :block ], + [ :after_save, :method ], [ :after_save, :string ], [ :after_save, :proc ], [ :after_save, :object ], @@ -314,18 +301,22 @@ class CallbacksTest < ActiveRecord::TestCase david = CallbackDeveloper.find(1) david.destroy assert_equal [ + [ :after_find, :method ], [ :after_find, :string ], [ :after_find, :proc ], [ :after_find, :object ], [ :after_find, :block ], + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], [ :after_initialize, :block ], + [ :before_destroy, :method ], [ :before_destroy, :string ], [ :before_destroy, :proc ], [ :before_destroy, :object ], [ :before_destroy, :block ], + [ :after_destroy, :method ], [ :after_destroy, :string ], [ :after_destroy, :proc ], [ :after_destroy, :object ], @@ -337,10 +328,12 @@ class CallbacksTest < ActiveRecord::TestCase david = CallbackDeveloper.find(1) CallbackDeveloper.delete(david.id) assert_equal [ + [ :after_find, :method ], [ :after_find, :string ], [ :after_find, :proc ], [ :after_find, :object ], [ :after_find, :block ], + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], @@ -407,14 +400,17 @@ class CallbacksTest < ActiveRecord::TestCase CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :should_never_get_here] } david.save assert_equal [ + [ :after_find, :method ], [ :after_find, :string ], [ :after_find, :proc ], [ :after_find, :object ], [ :after_find, :block ], + [ :after_initialize, :method ], [ :after_initialize, :string ], [ :after_initialize, :proc ], [ :after_initialize, :object ], [ :after_initialize, :block ], + [ :before_validation, :method ], [ :before_validation, :string ], [ :before_validation, :proc ], [ :before_validation, :object ], diff --git a/activerecord/test/cases/class_inheritable_attributes_test.rb b/activerecord/test/cases/class_inheritable_attributes_test.rb deleted file mode 100644 index abeb63c591..0000000000 --- a/activerecord/test/cases/class_inheritable_attributes_test.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'test/unit' -require "cases/helper" -require 'active_support/core_ext/class/inheritable_attributes' - -class A - include ClassInheritableAttributes -end - -class B < A - write_inheritable_array "first", [ :one, :two ] -end - -class C < A - write_inheritable_array "first", [ :three ] -end - -class D < B - write_inheritable_array "first", [ :four ] -end - - -class ClassInheritableAttributesTest < ActiveRecord::TestCase - def test_first_level - assert_equal [ :one, :two ], B.read_inheritable_attribute("first") - assert_equal [ :three ], C.read_inheritable_attribute("first") - end - - def test_second_level - assert_equal [ :one, :two, :four ], D.read_inheritable_attribute("first") - assert_equal [ :one, :two ], B.read_inheritable_attribute("first") - end -end diff --git a/activerecord/test/cases/connection_test_mysql.rb b/activerecord/test/cases/connection_test_mysql.rb index f79ee2f1f7..8e4842a1b6 100644 --- a/activerecord/test/cases/connection_test_mysql.rb +++ b/activerecord/test/cases/connection_test_mysql.rb @@ -41,6 +41,14 @@ class MysqlConnectionTest < ActiveRecord::TestCase sleep 2 @connection.verify! assert @connection.active? + end + + # Test that MySQL allows multiple results for stored procedures + if Mysql.const_defined?(:CLIENT_MULTI_RESULTS) + def test_multi_results + rows = ActiveRecord::Base.connection.select_rows('CALL ten();') + assert_equal 10, rows[0][0].to_i, "ten() did not return 10 as expected: #{rows.inspect}" + end end private diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index d1e7caed89..aa09c7061f 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -12,8 +12,6 @@ require 'active_record/test_case' require 'active_record/fixtures' require 'connection' -require 'cases/repair_helper' - begin require 'ruby-debug' rescue LoadError diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb index 54fb3d8c39..aa7ce2ecb6 100644 --- a/activerecord/test/cases/lifecycle_test.rb +++ b/activerecord/test/cases/lifecycle_test.rb @@ -1,11 +1,9 @@ -require "cases/helper" +require 'cases/helper' require 'models/topic' require 'models/developer' require 'models/reply' require 'models/minimalistic' -class Topic; def after_find() end end -class Developer; def after_find() end end class SpecialDeveloper < Developer; end class TopicManualObserver @@ -43,6 +41,11 @@ class TopicObserver < ActiveRecord::Observer def after_find(topic) @topic = topic end + + # Create an after_save callback, so a notify_observer hook is created + # on :topic. + def after_save(nothing) + end end class MinimalisticObserver < ActiveRecord::Observer @@ -159,34 +162,6 @@ class LifecycleTest < ActiveRecord::TestCase assert_equal topic, observer.topic end - def test_after_find_is_not_created_if_its_not_used - # use a fresh class so an observer can't have defined an - # after_find on it - model_class = Class.new(ActiveRecord::Base) - observer_class = Class.new(ActiveRecord::Observer) - observer_class.observe(model_class) - - observer = observer_class.instance - - assert !model_class.method_defined?(:after_find) - end - - def test_after_find_is_not_clobbered_if_it_already_exists - # use a fresh observer class so we can instantiate it (Observer is - # a Singleton) - model_class = Class.new(ActiveRecord::Base) do - def after_find; end - end - original_method = model_class.instance_method(:after_find) - observer_class = Class.new(ActiveRecord::Observer) do - def after_find; end - end - observer_class.observe(model_class) - - observer = observer_class.instance - assert_equal original_method, model_class.instance_method(:after_find) - end - def test_invalid_observer assert_raise(ArgumentError) { Topic.observers = Object.new; Topic.instantiate_observers } end diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index d033c1e760..721792132c 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -68,24 +68,38 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase ship = pirate.create_ship(:name => 'Nights Dirty Lightning') assert_no_difference('Ship.count') do - pirate.update_attributes(:ship_attributes => { '_delete' => true }) + pirate.update_attributes(:ship_attributes => { '_destroy' => true }) end end - def test_a_model_should_respond_to_underscore_delete_and_return_if_it_is_marked_for_destruction + def test_a_model_should_respond_to_underscore_destroy_and_return_if_it_is_marked_for_destruction ship = Ship.create!(:name => 'Nights Dirty Lightning') - assert !ship._delete + assert !ship._destroy ship.mark_for_destruction - assert ship._delete + assert ship._destroy + end + + def test_underscore_delete_is_deprecated + ActiveSupport::Deprecation.expects(:warn) + ship = Ship.create!(:name => 'Nights Dirty Lightning') + ship._delete end end class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase + include AssertRaiseWithMessage + def setup @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") @ship = @pirate.create_ship(:name => 'Nights Dirty Lightning') end + def test_should_raise_argument_error_if_trying_to_build_polymorphic_belongs_to + assert_raise_with_message ArgumentError, "Cannot build association looter. Are you trying to build a polymorphic one-to-one association?" do + Treasure.new(:name => 'pearl', :looter_attributes => {:catchphrase => "Arrr"}) + end + end + def test_should_define_an_attribute_writer_method_for_the_association assert_respond_to @pirate, :ship_attributes= end @@ -98,9 +112,9 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name end - def test_should_not_build_a_new_record_if_there_is_no_id_and_delete_is_truthy + def test_should_not_build_a_new_record_if_there_is_no_id_and_destroy_is_truthy @ship.destroy - @pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger', :_delete => '1' } + @pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger', :_destroy => '1' } assert_nil @pirate.ship end @@ -120,8 +134,8 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase assert_equal 'Nights Dirty Lightning', @ship.name end - def test_should_not_replace_an_existing_record_if_there_is_no_id_and_delete_is_truthy - @pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger', :_delete => '1' } + def test_should_not_replace_an_existing_record_if_there_is_no_id_and_destroy_is_truthy + @pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger', :_destroy => '1' } assert_equal @ship, @pirate.ship assert_equal 'Nights Dirty Lightning', @pirate.ship.name @@ -148,29 +162,29 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name end - def test_should_delete_an_existing_record_if_there_is_a_matching_id_and_delete_is_truthy + def test_should_destroy_an_existing_record_if_there_is_a_matching_id_and_destroy_is_truthy @pirate.ship.destroy [1, '1', true, 'true'].each do |truth| @pirate.reload.create_ship(:name => 'Mister Pablo') assert_difference('Ship.count', -1) do - @pirate.update_attribute(:ship_attributes, { :id => @pirate.ship.id, :_delete => truth }) + @pirate.update_attribute(:ship_attributes, { :id => @pirate.ship.id, :_destroy => truth }) end end end - def test_should_not_delete_an_existing_record_if_delete_is_not_truthy + def test_should_not_destroy_an_existing_record_if_destroy_is_not_truthy [nil, '0', 0, 'false', false].each do |not_truth| assert_no_difference('Ship.count') do - @pirate.update_attribute(:ship_attributes, { :id => @pirate.ship.id, :_delete => not_truth }) + @pirate.update_attribute(:ship_attributes, { :id => @pirate.ship.id, :_destroy => not_truth }) end end end - def test_should_not_delete_an_existing_record_if_allow_destroy_is_false + def test_should_not_destroy_an_existing_record_if_allow_destroy_is_false Pirate.accepts_nested_attributes_for :ship, :allow_destroy => false, :reject_if => proc { |attributes| attributes.empty? } assert_no_difference('Ship.count') do - @pirate.update_attribute(:ship_attributes, { :id => @pirate.ship.id, :_delete => '1' }) + @pirate.update_attribute(:ship_attributes, { :id => @pirate.ship.id, :_destroy => '1' }) end Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } @@ -193,7 +207,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase def test_should_not_destroy_the_associated_model_until_the_parent_is_saved assert_no_difference('Ship.count') do - @pirate.attributes = { :ship_attributes => { :id => @ship.id, :_delete => '1' } } + @pirate.attributes = { :ship_attributes => { :id => @ship.id, :_destroy => '1' } } end assert_difference('Ship.count', -1) do @pirate.save @@ -224,9 +238,9 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase assert_equal 'Arr', @ship.pirate.catchphrase end - def test_should_not_build_a_new_record_if_there_is_no_id_and_delete_is_truthy + def test_should_not_build_a_new_record_if_there_is_no_id_and_destroy_is_truthy @pirate.destroy - @ship.reload.pirate_attributes = { :catchphrase => 'Arr', :_delete => '1' } + @ship.reload.pirate_attributes = { :catchphrase => 'Arr', :_destroy => '1' } assert_nil @ship.pirate end @@ -246,8 +260,8 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase assert_equal 'Aye', @pirate.catchphrase end - def test_should_not_replace_an_existing_record_if_there_is_no_id_and_delete_is_truthy - @ship.reload.pirate_attributes = { :catchphrase => 'Arr', :_delete => '1' } + def test_should_not_replace_an_existing_record_if_there_is_no_id_and_destroy_is_truthy + @ship.reload.pirate_attributes = { :catchphrase => 'Arr', :_destroy => '1' } assert_equal @pirate, @ship.pirate assert_equal 'Aye', @ship.pirate.catchphrase @@ -274,29 +288,29 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase assert_equal 'Arr', @ship.pirate.catchphrase end - def test_should_delete_an_existing_record_if_there_is_a_matching_id_and_delete_is_truthy + def test_should_destroy_an_existing_record_if_there_is_a_matching_id_and_destroy_is_truthy @ship.pirate.destroy [1, '1', true, 'true'].each do |truth| @ship.reload.create_pirate(:catchphrase => 'Arr') assert_difference('Pirate.count', -1) do - @ship.update_attribute(:pirate_attributes, { :id => @ship.pirate.id, :_delete => truth }) + @ship.update_attribute(:pirate_attributes, { :id => @ship.pirate.id, :_destroy => truth }) end end end - def test_should_not_delete_an_existing_record_if_delete_is_not_truthy + def test_should_not_destroy_an_existing_record_if_destroy_is_not_truthy [nil, '0', 0, 'false', false].each do |not_truth| assert_no_difference('Pirate.count') do - @ship.update_attribute(:pirate_attributes, { :id => @ship.pirate.id, :_delete => not_truth }) + @ship.update_attribute(:pirate_attributes, { :id => @ship.pirate.id, :_destroy => not_truth }) end end end - def test_should_not_delete_an_existing_record_if_allow_destroy_is_false + def test_should_not_destroy_an_existing_record_if_allow_destroy_is_false Ship.accepts_nested_attributes_for :pirate, :allow_destroy => false, :reject_if => proc { |attributes| attributes.empty? } assert_no_difference('Pirate.count') do - @ship.update_attribute(:pirate_attributes, { :id => @ship.pirate.id, :_delete => '1' }) + @ship.update_attribute(:pirate_attributes, { :id => @ship.pirate.id, :_destroy => '1' }) end Ship.accepts_nested_attributes_for :pirate, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } @@ -312,7 +326,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase def test_should_not_destroy_the_associated_model_until_the_parent_is_saved assert_no_difference('Pirate.count') do - @ship.attributes = { :pirate_attributes => { :id => @ship.pirate.id, '_delete' => true } } + @ship.attributes = { :pirate_attributes => { :id => @ship.pirate.id, '_destroy' => true } } end assert_difference('Pirate.count', -1) { @ship.save } end @@ -380,18 +394,18 @@ module NestedAttributesOnACollectionAssociationTests assert_equal 'Privateers Greed', @pirate.send(@association_name).last.name end - def test_should_not_assign_delete_key_to_a_record + def test_should_not_assign_destroy_key_to_a_record assert_nothing_raised ActiveRecord::UnknownAttributeError do - @pirate.send(association_setter, { 'foo' => { '_delete' => '0' }}) + @pirate.send(association_setter, { 'foo' => { '_destroy' => '0' }}) end end - def test_should_ignore_new_associated_records_with_truthy_delete_attribute + def test_should_ignore_new_associated_records_with_truthy_destroy_attribute @pirate.send(@association_name).destroy_all @pirate.reload.attributes = { association_getter => { 'foo' => { :name => 'Grace OMalley' }, - 'bar' => { :name => 'Privateers Greed', '_delete' => '1' } + 'bar' => { :name => 'Privateers Greed', '_destroy' => '1' } } } @@ -443,7 +457,7 @@ module NestedAttributesOnACollectionAssociationTests ['1', 1, 'true', true].each do |true_variable| record = @pirate.reload.send(@association_name).create!(:name => 'Grace OMalley') @pirate.send(association_setter, - @alternate_params[association_getter].merge('baz' => { :id => record.id, '_delete' => true_variable }) + @alternate_params[association_getter].merge('baz' => { :id => record.id, '_destroy' => true_variable }) ) assert_difference('@pirate.send(@association_name).count', -1) do @@ -454,7 +468,7 @@ module NestedAttributesOnACollectionAssociationTests def test_should_not_destroy_the_associated_model_with_a_non_truthy_argument [nil, '', '0', 0, 'false', false].each do |false_variable| - @alternate_params[association_getter]['foo']['_delete'] = false_variable + @alternate_params[association_getter]['foo']['_destroy'] = false_variable assert_no_difference('@pirate.send(@association_name).count') do @pirate.update_attributes(@alternate_params) end @@ -463,7 +477,7 @@ module NestedAttributesOnACollectionAssociationTests def test_should_not_destroy_the_associated_model_until_the_parent_is_saved assert_no_difference('@pirate.send(@association_name).count') do - @pirate.send(association_setter, @alternate_params[association_getter].merge('baz' => { :id => @child_1.id, '_delete' => true })) + @pirate.send(association_setter, @alternate_params[association_getter].merge('baz' => { :id => @child_1.id, '_destroy' => true })) end assert_difference('@pirate.send(@association_name).count', -1) { @pirate.save } end diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index a164f5e060..0eb2da720e 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -176,9 +176,9 @@ class ReflectionTest < ActiveRecord::TestCase def test_reflection_of_all_associations # FIXME these assertions bust a lot - assert_equal 31, Firm.reflect_on_all_associations.size - assert_equal 24, Firm.reflect_on_all_associations(:has_many).size - assert_equal 7, Firm.reflect_on_all_associations(:has_one).size + assert_equal 35, Firm.reflect_on_all_associations.size + assert_equal 26, Firm.reflect_on_all_associations(:has_many).size + assert_equal 9, Firm.reflect_on_all_associations(:has_one).size assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size end diff --git a/activerecord/test/cases/repair_helper.rb b/activerecord/test/cases/repair_helper.rb deleted file mode 100644 index 80d04010d6..0000000000 --- a/activerecord/test/cases/repair_helper.rb +++ /dev/null @@ -1,46 +0,0 @@ -module ActiveRecord - module Testing - module RepairHelper - extend ActiveSupport::Concern - - module Toolbox - def self.record_validations(*model_classes) - model_classes.inject({}) do |repair, klass| - repair[klass] ||= {} - [:validate, :validate_on_create, :validate_on_update].each do |callback| - the_callback = klass.instance_variable_get("@#{callback.to_s}_callbacks") - repair[klass][callback] = (the_callback.nil? ? nil : the_callback.dup) - end - repair - end - end - - def self.reset_validations(recorded) - recorded.each do |klass, repairs| - [:validate, :validate_on_create, :validate_on_update].each do |callback| - klass.instance_variable_set("@#{callback.to_s}_callbacks", repairs[callback]) - end - end - end - end - - module ClassMethods - def repair_validations(*model_classes) - setup do - @validation_repairs = ActiveRecord::Testing::RepairHelper::Toolbox.record_validations(*model_classes) - end - teardown do - ActiveRecord::Testing::RepairHelper::Toolbox.reset_validations(@validation_repairs) - end - end - end - - def repair_validations(*model_classes, &block) - validation_repairs = ActiveRecord::Testing::RepairHelper::Toolbox.record_validations(*model_classes) - return block.call - ensure - ActiveRecord::Testing::RepairHelper::Toolbox.reset_validations(validation_repairs) - end - end - end -end diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index f6533b5396..aca70b4238 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -382,28 +382,28 @@ class TransactionTest < ActiveRecord::TestCase private def add_exception_raising_after_save_callback_to_topic - Topic.class_eval { def after_save() raise "Make the transaction rollback" end } + Topic.class_eval "def after_save_for_transaction; raise 'Make the transaction rollback' end" end def remove_exception_raising_after_save_callback_to_topic - Topic.class_eval { remove_method :after_save } + Topic.class_eval "def after_save_for_transaction; end" end def add_exception_raising_after_create_callback_to_topic - Topic.class_eval { def after_create() raise "Make the transaction rollback" end } + Topic.class_eval "def after_create_for_transaction; raise 'Make the transaction rollback' end" end def remove_exception_raising_after_create_callback_to_topic - Topic.class_eval { remove_method :after_create } + Topic.class_eval "def after_create_for_transaction; end" end %w(validation save destroy).each do |filter| define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do - Topic.class_eval "def before_#{filter}() Book.create; false end" + Topic.class_eval "def before_#{filter}_for_transaction() Book.create; false end" end define_method("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") do - Topic.class_eval "remove_method :before_#{filter}" + Topic.class_eval "def before_#{filter}_for_transaction; end" end end end diff --git a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb index 29c10de4fe..3794a0ebb9 100644 --- a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb @@ -2,9 +2,9 @@ require "cases/helper" require 'models/topic' require 'models/reply' -class I18nGenerateMessageValidationTest < Test::Unit::TestCase +class I18nGenerateMessageValidationTest < ActiveRecord::TestCase def setup - reset_callbacks Topic + Topic.reset_callbacks(:validate) @topic = Topic.new I18n.backend.store_translations :'en', { :activerecord => { @@ -17,14 +17,6 @@ class I18nGenerateMessageValidationTest < Test::Unit::TestCase } end - def reset_callbacks(*models) - models.each do |model| - model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - end - end - # validates_inclusion_of: generate_message(attr_name, :inclusion, :default => configuration[:message], :value => value) def test_generate_message_inclusion_with_default_message assert_equal 'is not included in the list', @topic.errors.generate_message(:title, :inclusion, :default => nil, :value => 'title') diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb index 73d9c7249c..252138c0d6 100644 --- a/activerecord/test/cases/validations/i18n_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_validation_test.rb @@ -4,7 +4,7 @@ require 'models/reply' class I18nValidationTest < ActiveRecord::TestCase def setup - reset_callbacks Topic + Topic.reset_callbacks(:validate) @topic = Topic.new @old_load_path, @old_backend = I18n.load_path, I18n.backend I18n.load_path.clear @@ -13,7 +13,7 @@ class I18nValidationTest < ActiveRecord::TestCase end def teardown - reset_callbacks Topic + Topic.reset_callbacks(:validate) I18n.load_path.replace @old_load_path I18n.backend = @old_backend end @@ -30,14 +30,6 @@ class I18nValidationTest < ActiveRecord::TestCase end end - def reset_callbacks(*models) - models.each do |model| - model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - end - end - def test_percent_s_interpolation_syntax_in_error_messages_was_deprecated assert_not_deprecated do default = "%s interpolation syntax was deprecated" @@ -710,9 +702,9 @@ class I18nValidationTest < ActiveRecord::TestCase end end -class ActiveRecordValidationsGenerateMessageI18nTests < ActiveSupport::TestCase +class ActiveRecordValidationsGenerateMessageI18nTests < ActiveRecord::TestCase + def setup - reset_callbacks Topic @topic = Topic.new I18n.backend.store_translations :'en', { :activerecord => { @@ -743,14 +735,6 @@ class ActiveRecordValidationsGenerateMessageI18nTests < ActiveSupport::TestCase } end - def reset_callbacks(*models) - models.each do |model| - model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - end - end - # validates_inclusion_of: generate_message(attr_name, :inclusion, :default => configuration[:message], :value => value) def test_generate_message_inclusion_with_default_message assert_equal 'is not included in the list', @topic.errors.generate_message(:title, :inclusion, :default => nil, :value => 'title') diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index a4e874e5e6..5cdb623eef 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -149,24 +149,24 @@ class ValidationsTest < ActiveRecord::TestCase end def test_validates_length_with_globally_modified_error_message - ActiveSupport::Deprecation.silence do - ActiveRecord::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre {{count}}' - end + defaults = ActiveSupport::Deprecation.silence { ActiveRecord::Errors.default_error_messages } + original_message = defaults[:too_short] + defaults[:too_short] = 'tu est trops petit hombre {{count}}' Topic.validates_length_of :title, :minimum => 10 t = Topic.create(:title => 'too short') assert !t.valid? assert_equal ['tu est trops petit hombre 10'], t.errors[:title] + + ensure + defaults[:too_short] = original_message end def test_validates_acceptance_of_as_database_column - repair_validations(Reply) do - Reply.validates_acceptance_of(:author_name) - - reply = Reply.create("author_name" => "Dan Brown") - assert_equal "Dan Brown", reply["author_name"] - end + Topic.validates_acceptance_of(:author_name) + topic = Topic.create("author_name" => "Dan Brown") + assert_equal "Dan Brown", topic["author_name"] end def test_deprecated_validation_instance_methods |