diff options
Diffstat (limited to 'activerecord/test/cases/persistence_test.rb')
-rw-r--r-- | activerecord/test/cases/persistence_test.rb | 121 |
1 files changed, 92 insertions, 29 deletions
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 688c3ed2b1..6cbe18cc8c 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "cases/helper" require "models/aircraft" require "models/post" @@ -49,7 +51,7 @@ class PersistenceTest < ActiveRecord::TestCase assert !test_update_with_order_succeeds.call("id ASC") # test that this wasn't a fluke and using an incorrect order results in an exception else # test that we're failing because the current Arel's engine doesn't support UPDATE ORDER BY queries is using subselects instead - assert_sql(/\AUPDATE .+ \(SELECT .* ORDER BY id DESC\)\Z/i) do + assert_sql(/\AUPDATE .+ \(SELECT .* ORDER BY id DESC\)\z/i) do test_update_with_order_succeeds.call("id DESC") end end @@ -68,14 +70,23 @@ class PersistenceTest < ActiveRecord::TestCase end def test_update_many - topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } } + topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" }, nil => {} } updated = Topic.update(topic_data.keys, topic_data.values) - assert_equal 2, updated.size + assert_equal [1, 2], updated.map(&:id) assert_equal "1 updated", Topic.find(1).content assert_equal "2 updated", Topic.find(2).content end + def test_class_level_update_is_affected_by_scoping + topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } } + + assert_equal [], Topic.where("1=0").scoping { Topic.update(topic_data.keys, topic_data.values) } + + assert_not_equal "1 updated", Topic.find(1).content + assert_not_equal "2 updated", Topic.find(2).content + end + def test_delete_all assert Topic.count > 0 @@ -90,6 +101,14 @@ class PersistenceTest < ActiveRecord::TestCase assert_equal count, Pet.joins(:toys).where(where_args).delete_all end + def test_delete_all_with_left_joins + where_args = { toys: { name: "Bone" } } + count = Pet.left_joins(:toys).where(where_args).count + + assert_equal count, 1 + assert_equal count, Pet.left_joins(:toys).where(where_args).delete_all + end + def test_delete_all_with_joins_and_where_part_is_not_hash where_args = ["toys.name = ?", "Bone"] count = Pet.joins(:toys).where(where_args).count @@ -131,6 +150,14 @@ class PersistenceTest < ActiveRecord::TestCase assert_equal initial_credit + 2, a1.reload.credit_limit end + def test_increment_updates_timestamps + topic = topics(:first) + topic.update_columns(updated_at: 5.minutes.ago) + previous_updated_at = topic.updated_at + topic.increment!(:replies_count, touch: true) + assert_operator previous_updated_at, :<, topic.reload.updated_at + end + def test_destroy_all conditions = "author_name = 'Mary'" topics_by_mary = Topic.all.merge!(where: conditions, order: "id").to_a @@ -147,7 +174,7 @@ class PersistenceTest < ActiveRecord::TestCase clients = Client.all.merge!(order: "id").find([2, 3]) assert_difference("Client.count", -2) do - destroyed = Client.destroy([2, 3]).sort_by(&:id) + destroyed = Client.destroy([2, 3, nil]).sort_by(&:id) assert_equal clients, destroyed assert destroyed.all?(&:frozen?), "destroyed clients should be frozen" end @@ -222,6 +249,14 @@ class PersistenceTest < ActiveRecord::TestCase assert_equal 41, accounts(:signals37, :reload).credit_limit end + def test_decrement_updates_timestamps + topic = topics(:first) + topic.update_columns(updated_at: 5.minutes.ago) + previous_updated_at = topic.updated_at + topic.decrement!(:replies_count, touch: true) + assert_operator previous_updated_at, :<, topic.reload.updated_at + end + def test_create topic = Topic.new topic.title = "New Topic" @@ -413,6 +448,13 @@ class PersistenceTest < ActiveRecord::TestCase assert_not_nil Topic.find(2) end + def test_delete_isnt_affected_by_scoping + topic = Topic.find(1) + assert_difference("Topic.count", -1) do + Topic.where("1=0").scoping { topic.delete } + end + end + def test_destroy topic = Topic.find(1) assert_equal topic, topic.destroy, "topic.destroy did not return self" @@ -453,6 +495,20 @@ class PersistenceTest < ActiveRecord::TestCase assert_nil Topic.find(2).last_read end + def test_update_all_with_joins + where_args = { toys: { name: "Bone" } } + count = Pet.left_joins(:toys).where(where_args).count + + assert_equal count, Pet.joins(:toys).where(where_args).update_all(name: "Bob") + end + + def test_update_all_with_left_joins + where_args = { toys: { name: "Bone" } } + count = Pet.left_joins(:toys).where(where_args).count + + assert_equal count, Pet.left_joins(:toys).where(where_args).update_all(name: "Bob") + end + def test_update_all_with_non_standard_table_name assert_equal 1, WarehouseThing.where(id: 1).update_all(["value = ?", 0]) assert_equal 0, WarehouseThing.find(1).value @@ -860,18 +916,39 @@ class PersistenceTest < ActiveRecord::TestCase should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world") Topic.find(1).replies << should_be_destroyed_reply - Topic.destroy(1) + topic = Topic.destroy(1) + assert topic.destroyed? + assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) } assert_raise(ActiveRecord::RecordNotFound) { Reply.find(should_be_destroyed_reply.id) } end + def test_class_level_destroy_is_affected_by_scoping + should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world") + Topic.find(1).replies << should_not_be_destroyed_reply + + assert_nil Topic.where("1=0").scoping { Topic.destroy(1) } + + assert_nothing_raised { Topic.find(1) } + assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) } + end + def test_class_level_delete - should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world") - Topic.find(1).replies << should_be_destroyed_reply + should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world") + Topic.find(1).replies << should_not_be_destroyed_reply Topic.delete(1) assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) } - assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) } + assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) } + end + + def test_class_level_delete_is_affected_by_scoping + should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world") + Topic.find(1).replies << should_not_be_destroyed_reply + + Topic.where("1=0").scoping { Topic.delete(1) } + assert_nothing_raised { Topic.find(1) } + assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) } end def test_create_with_custom_timestamps @@ -955,33 +1032,19 @@ class PersistenceTest < ActiveRecord::TestCase end class SaveTest < ActiveRecord::TestCase - self.use_transactional_tests = false - def test_save_touch_false - widget = Class.new(ActiveRecord::Base) do - connection.create_table :widgets, force: true do |t| - t.string :name - t.timestamps null: false - end - - self.table_name = :widgets - end - - instance = widget.create!( + pet = Pet.create!( name: "Bob", created_at: 1.day.ago, updated_at: 1.day.ago) - created_at = instance.created_at - updated_at = instance.updated_at + created_at = pet.created_at + updated_at = pet.updated_at - instance.name = "Barb" - instance.save!(touch: false) - assert_equal instance.created_at, created_at - assert_equal instance.updated_at, updated_at - ensure - ActiveRecord::Base.connection.drop_table widget.table_name - widget.reset_column_information + pet.name = "Barb" + pet.save!(touch: false) + assert_equal pet.created_at, created_at + assert_equal pet.updated_at, updated_at end end |