1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
require 'cases/helper'
require 'models/topic'
require 'models/car'
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 = 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(ActiveRecord::StatementInvalid) 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 "counter caches are not updated in memory when not selected" do
car = Car.select(:id).first
assert_nothing_raised do
car.engines << Engine.new
end
end
end
|