1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/activerecord/test/cases/counter_cache_test.rb
Ryuta Kamizono ea65d92f19
Enable Lint/UselessAssignment cop to avoid unused variable warnings (#34904)
* Enable `Lint/UselessAssignment` cop to avoid unused variable warnings

Since we've addressed the warning "assigned but unused variable"
frequently.

370537de05
3040446cec
5ed618e192
76ebafe594

And also, I've found the unused args in c1b14ad which raises no warnings
by the cop, it shows the value of the cop.
2019-01-09 18:09:01 +09:00

367 lines
12 KiB
Ruby

# frozen_string_literal: true
require "cases/helper"
require "models/topic"
require "models/car"
require "models/aircraft"
require "models/wheel"
require "models/engine"
require "models/reply"
require "models/category"
require "models/categorization"
require "models/dog"
require "models/dog_lover"
require "models/person"
require "models/friendship"
require "models/subscriber"
require "models/subscription"
require "models/book"
class CounterCacheTest < ActiveRecord::TestCase
fixtures :topics, :categories, :categorizations, :cars, :dogs, :dog_lovers, :people, :friendships, :subscribers, :subscriptions, :books
class ::SpecialTopic < ::Topic
has_many :special_replies, foreign_key: "parent_id"
has_many :lightweight_special_replies, -> { select("topics.id, topics.title") }, foreign_key: "parent_id", class_name: "SpecialReply"
end
class ::SpecialReply < ::Reply
belongs_to :special_topic, foreign_key: "parent_id", counter_cache: "replies_count"
end
setup do
@topic = Topic.find(1)
end
test "increment counter" do
assert_difference "@topic.reload.replies_count" do
Topic.increment_counter(:replies_count, @topic.id)
end
end
test "decrement counter" do
assert_difference "@topic.reload.replies_count", -1 do
Topic.decrement_counter(:replies_count, @topic.id)
end
end
test "reset counters" do
# throw the count off by 1
Topic.increment_counter(:replies_count, @topic.id)
# check that it gets reset
assert_difference "@topic.reload.replies_count", -1 do
Topic.reset_counters(@topic.id, :replies)
end
end
test "reset counters by counter name" do
# throw the count off by 1
Topic.increment_counter(:replies_count, @topic.id)
# check that it gets reset
assert_difference "@topic.reload.replies_count", -1 do
Topic.reset_counters(@topic.id, :replies_count)
end
end
test "reset multiple counters" do
Topic.update_counters @topic.id, replies_count: 1, unique_replies_count: 1
assert_difference ["@topic.reload.replies_count", "@topic.reload.unique_replies_count"], -1 do
Topic.reset_counters(@topic.id, :replies, :unique_replies)
end
end
test "reset counters with string argument" do
Topic.increment_counter("replies_count", @topic.id)
assert_difference "@topic.reload.replies_count", -1 do
Topic.reset_counters(@topic.id, "replies")
end
end
test "reset counters with modularized and camelized classnames" do
special = SpecialTopic.create!(title: "Special")
SpecialTopic.increment_counter(:replies_count, special.id)
assert_difference "special.reload.replies_count", -1 do
SpecialTopic.reset_counters(special.id, :special_replies)
end
end
test "reset counter with belongs_to which has class_name" do
car = cars(:honda)
assert_nothing_raised do
Car.reset_counters(car.id, :engines)
end
assert_nothing_raised do
Car.reset_counters(car.id, :wheels)
end
end
test "reset the right counter if two have the same class_name" do
david = dog_lovers(:david)
DogLover.increment_counter(:bred_dogs_count, david.id)
DogLover.increment_counter(:trained_dogs_count, david.id)
assert_difference "david.reload.bred_dogs_count", -1 do
DogLover.reset_counters(david.id, :bred_dogs)
end
assert_difference "david.reload.trained_dogs_count", -1 do
DogLover.reset_counters(david.id, :trained_dogs)
end
end
test "update counter with initial null value" do
category = categories(:general)
assert_equal 2, category.categorizations.count
assert_nil category.categorizations_count
Category.update_counters(category.id, categorizations_count: category.categorizations.count)
assert_equal 2, category.reload.categorizations_count
end
test "update counter for decrement" do
assert_difference "@topic.reload.replies_count", -3 do
Topic.update_counters(@topic.id, replies_count: -3)
end
end
test "update counters of multiple records" do
t1, t2 = topics(:first, :second)
assert_difference ["t1.reload.replies_count", "t2.reload.replies_count"], 2 do
Topic.update_counters([t1.id, t2.id], replies_count: 2)
end
end
test "update multiple counters" do
assert_difference ["@topic.reload.replies_count", "@topic.reload.unique_replies_count"], 2 do
Topic.update_counters @topic.id, replies_count: 2, unique_replies_count: 2
end
end
test "update other counters on parent destroy" do
david, joanna = dog_lovers(:david, :joanna)
_ = joanna # squelch a warning
assert_difference "joanna.reload.dogs_count", -1 do
david.destroy
end
end
test "reset the right counter if two have the same foreign key" do
michael = people(:michael)
assert_nothing_raised do
Person.reset_counters(michael.id, :friends_too)
end
end
test "reset counter of has_many :through association" do
subscriber = subscribers("second")
Subscriber.reset_counters(subscriber.id, "books")
Subscriber.increment_counter("books_count", subscriber.id)
assert_difference "subscriber.reload.books_count", -1 do
Subscriber.reset_counters(subscriber.id, "books")
end
end
test "the passed symbol needs to be an association name or counter name" do
e = assert_raises(ArgumentError) do
Topic.reset_counters(@topic.id, :undefined_count)
end
assert_equal "'Topic' has no association called 'undefined_count'", e.message
end
test "reset counter works with select declared on association" do
special = SpecialTopic.create!(title: "Special")
SpecialTopic.increment_counter(:replies_count, special.id)
assert_difference "special.reload.replies_count", -1 do
SpecialTopic.reset_counters(special.id, :lightweight_special_replies)
end
end
test "counters are updated both in memory and in the database on create" do
car = Car.new(engines_count: 0)
car.engines = [Engine.new, Engine.new]
car.save!
assert_equal 2, car.engines_count
assert_equal 2, car.reload.engines_count
end
test "counter caches are updated in memory when the default value is nil" do
car = Car.new(engines_count: nil)
car.engines = [Engine.new, Engine.new]
car.save!
assert_equal 2, car.engines_count
assert_equal 2, car.reload.engines_count
end
test "update counters in a polymorphic relationship" do
aircraft = Aircraft.create!
assert_difference "aircraft.reload.wheels_count" do
aircraft.wheels << Wheel.create!
end
assert_difference "aircraft.reload.wheels_count", -1 do
aircraft.wheels.first.destroy
end
end
test "update counters doesn't touch timestamps by default" do
@topic.update_column :updated_at, 5.minutes.ago
previously_updated_at = @topic.updated_at
Topic.update_counters(@topic.id, replies_count: -1)
assert_equal previously_updated_at, @topic.updated_at
end
test "update counters doesn't touch timestamps with touch: []" do
@topic.update_column :updated_at, 5.minutes.ago
previously_updated_at = @topic.updated_at
Topic.update_counters(@topic.id, replies_count: -1, touch: [])
assert_equal previously_updated_at, @topic.updated_at
end
test "update counters with touch: true" do
assert_touching @topic, :updated_at do
Topic.update_counters(@topic.id, replies_count: -1, touch: true)
end
end
test "update counters of multiple records with touch: true" do
t1, t2 = topics(:first, :second)
assert_touching t1, :updated_at do
assert_difference ["t1.reload.replies_count", "t2.reload.replies_count"], 2 do
Topic.update_counters([t1.id, t2.id], replies_count: 2, touch: true)
end
end
end
test "update multiple counters with touch: true" do
assert_touching @topic, :updated_at do
Topic.update_counters(@topic.id, replies_count: 2, unique_replies_count: 2, touch: true)
end
end
test "reset counters with touch: true" do
assert_touching @topic, :updated_at do
Topic.reset_counters(@topic.id, :replies, touch: true)
end
end
test "reset multiple counters with touch: true" do
assert_touching @topic, :updated_at do
Topic.update_counters(@topic.id, replies_count: 1, unique_replies_count: 1)
Topic.reset_counters(@topic.id, :replies, :unique_replies, touch: true)
end
end
test "increment counters with touch: true" do
assert_touching @topic, :updated_at do
Topic.increment_counter(:replies_count, @topic.id, touch: true)
end
end
test "decrement counters with touch: true" do
assert_touching @topic, :updated_at do
Topic.decrement_counter(:replies_count, @topic.id, touch: true)
end
end
test "update counters with touch: :written_on" do
assert_touching @topic, :updated_at, :written_on do
Topic.update_counters(@topic.id, replies_count: -1, touch: :written_on)
end
end
test "update multiple counters with touch: :written_on" do
assert_touching @topic, :updated_at, :written_on do
Topic.update_counters(@topic.id, replies_count: 2, unique_replies_count: 2, touch: :written_on)
end
end
test "reset counters with touch: :written_on" do
assert_touching @topic, :updated_at, :written_on do
Topic.reset_counters(@topic.id, :replies, touch: :written_on)
end
end
test "reset multiple counters with touch: :written_on" do
assert_touching @topic, :updated_at, :written_on do
Topic.update_counters(@topic.id, replies_count: 1, unique_replies_count: 1)
Topic.reset_counters(@topic.id, :replies, :unique_replies, touch: :written_on)
end
end
test "increment counters with touch: :written_on" do
assert_touching @topic, :updated_at, :written_on do
Topic.increment_counter(:replies_count, @topic.id, touch: :written_on)
end
end
test "decrement counters with touch: :written_on" do
assert_touching @topic, :updated_at, :written_on do
Topic.decrement_counter(:replies_count, @topic.id, touch: :written_on)
end
end
test "update counters with touch: %i( updated_at written_on )" do
assert_touching @topic, :updated_at, :written_on do
Topic.update_counters(@topic.id, replies_count: -1, touch: %i( updated_at written_on ))
end
end
test "update multiple counters with touch: %i( updated_at written_on )" do
assert_touching @topic, :updated_at, :written_on do
Topic.update_counters(@topic.id, replies_count: 2, unique_replies_count: 2, touch: %i( updated_at written_on ))
end
end
test "reset counters with touch: %i( updated_at written_on )" do
assert_touching @topic, :updated_at, :written_on do
Topic.reset_counters(@topic.id, :replies, touch: %i( updated_at written_on ))
end
end
test "reset multiple counters with touch: %i( updated_at written_on )" do
assert_touching @topic, :updated_at, :written_on do
Topic.update_counters(@topic.id, replies_count: 1, unique_replies_count: 1)
Topic.reset_counters(@topic.id, :replies, :unique_replies, touch: %i( updated_at written_on ))
end
end
test "increment counters with touch: %i( updated_at written_on )" do
assert_touching @topic, :updated_at, :written_on do
Topic.increment_counter(:replies_count, @topic.id, touch: %i( updated_at written_on ))
end
end
test "decrement counters with touch: %i( updated_at written_on )" do
assert_touching @topic, :updated_at, :written_on do
Topic.decrement_counter(:replies_count, @topic.id, touch: %i( updated_at written_on ))
end
end
private
def assert_touching(record, *attributes)
record.update_columns attributes.map { |attr| [ attr, 5.minutes.ago ] }.to_h
touch_times = attributes.map { |attr| [ attr, record.public_send(attr) ] }.to_h
yield
touch_times.each do |attr, previous_touch_time|
assert_operator previous_touch_time, :<, record.reload.public_send(attr)
end
end
end