cached-models 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,90 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ require 'active_record/fixtures'
4
+
5
+ path_to_fixtures = File.dirname(__FILE__) + '/../test/fixtures'
6
+ fixtures = %w( authors blogs posts comments tags )
7
+
8
+ desc 'Run default task (test)'
9
+ task :cached_models => 'cached_models:test'
10
+
11
+ namespace :cached_models do
12
+ desc 'Reset the CachedModels data'
13
+ task :reset => [ :teardown, :setup ]
14
+
15
+ desc 'Create CachedModels test database tables and load fixtures'
16
+ task :setup => [ :create_tables, :load_fixtures ]
17
+
18
+ desc 'Remove all CachedModels data'
19
+ task :teardown => :drop_tables
20
+
21
+ desc 'Create CachedModels test database tables'
22
+ task :create_tables => :environment do
23
+ ActiveRecord::Schema.define do
24
+ create_table :authors, :force => true do |t|
25
+ t.integer :blog_id
26
+ t.string :first_name
27
+ t.string :last_name
28
+ t.integer :age
29
+
30
+ t.timestamps
31
+ end
32
+
33
+ create_table :blogs, :force => true do |t|
34
+ t.string :title
35
+
36
+ t.timestamps
37
+ end
38
+
39
+ create_table :posts, :force => true do |t|
40
+ t.integer :author_id
41
+ t.integer :blog_id
42
+ t.string :title
43
+ t.text :text
44
+ t.datetime :published_at
45
+
46
+ t.timestamps
47
+ end
48
+
49
+ create_table :comments, :force => true do |t|
50
+ t.integer :post_id
51
+ t.string :email
52
+ t.text :text
53
+
54
+ t.timestamps
55
+ end
56
+
57
+ create_table :tags, :force => true do |t|
58
+ t.integer :taggable_id
59
+ t.string :taggable_type
60
+ t.string :name
61
+
62
+ t.timestamps
63
+ end
64
+ end
65
+ end
66
+
67
+ desc 'Drops CachedModels test database tables'
68
+ task :drop_tables => :environment do
69
+ ActiveRecord::Base.connection.drop_table :authors
70
+ ActiveRecord::Base.connection.drop_table :posts
71
+ ActiveRecord::Base.connection.drop_table :comments
72
+ ActiveRecord::Base.connection.drop_table :tags
73
+ end
74
+
75
+ desc 'Load fixtures'
76
+ task :load_fixtures => :environment do
77
+ fixtures.each { |f| Fixtures.create_fixtures(path_to_fixtures, f) }
78
+ end
79
+
80
+ desc 'Test CachedModels'
81
+ task :test => [ :setup, 'test:all' ]
82
+
83
+ namespace :test do
84
+ desc 'Run CachedModels tests'
85
+ Rake::TestTask.new(:all) do |t|
86
+ t.test_files = FileList["#{File.dirname( __FILE__ )}/../test/**/*_test.rb"]
87
+ t.verbose = true
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,401 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+ require 'active_record/associations/has_many_association'
3
+
4
+ class HasManyAssociationTest < Test::Unit::TestCase
5
+ include ActiveRecord::Associations
6
+
7
+ def setup
8
+ cache.clear rescue nil
9
+ end
10
+
11
+ uses_mocha 'HasManyAssociationTest' do
12
+ def test_should_always_use_cache_for_all_instances_which_reference_the_same_record
13
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
14
+ expected = authors(:luca).cached_posts
15
+ actual = Author.first.cached_posts
16
+ assert_equal expected, actual
17
+ end
18
+
19
+ def test_should_expire_cache_on_update
20
+ author = authors(:luca)
21
+ old_cache_key = author.cache_key
22
+
23
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
24
+ cache.expects(:delete).with("#{cache_key}/cached_posts").returns true
25
+
26
+ author.cached_posts # force cache loading
27
+ author.update_attributes :first_name => author.first_name.upcase
28
+
29
+ # assert_not_equal old_cache_key, author.cache_key
30
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
31
+ end
32
+
33
+ def test_should_not_expire_cache_on_update_on_missing_updated_at
34
+ author = authors(:luca)
35
+ old_cache_key = author.cache_key
36
+
37
+ author.stubs(:[]).with(:updated_at).returns nil
38
+ author.expects(:[]).with('blog_id').returns author.blog_id
39
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
40
+ cache.expects(:delete).with("#{cache_key}/cached_posts").never
41
+ cache.expects(:delete).with("#{cache_key}/cached_comments").never
42
+ cache.expects(:delete).with("#{cache_key}/cached_posts_with_comments").never
43
+
44
+ author.cached_posts # force cache loading
45
+ author.update_attributes :first_name => author.first_name.upcase
46
+
47
+ # assert_not_equal old_cache_key, author.cache_key
48
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
49
+ end
50
+
51
+ def test_should_use_cache_when_find_with_scope
52
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").returns association_proxy
53
+
54
+ post = authors(:luca).cached_posts.find(posts(:welcome).id)
55
+ assert_equal posts(:welcome), post
56
+ end
57
+
58
+ def test_should_use_cache_when_find_with_scope_using_multiple_ids
59
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").returns association_proxy
60
+
61
+ ids = posts_by_author(:luca).map(&:id)
62
+ assert_equal posts_by_author(:luca),
63
+ authors(:luca).cached_posts.find(ids)
64
+ end
65
+
66
+ def test_should_use_cache_when_fetch_first_from_collection
67
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").returns association_proxy
68
+ # cache.expects(:read).with("#{cache_key}/cached_posts").returns posts_by_author(:luca)
69
+
70
+ assert_equal [ posts_by_author(:luca).first ],
71
+ authors(:luca).cached_posts.first(1)
72
+ end
73
+
74
+ def test_should_use_cache_when_fetch_last_from_collection
75
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").returns association_proxy
76
+ # cache.expects(:read).with("#{cache_key}/cached_posts").returns posts_by_author(:luca)
77
+
78
+ assert_equal [ posts_by_author(:luca).last ],
79
+ authors(:luca).cached_posts.last(1)
80
+ end
81
+
82
+ def test_should_use_cache_when_reset_collection
83
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
84
+
85
+ assert_false authors(:luca).cached_posts.reset
86
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
87
+ end
88
+
89
+ def test_should_expire_cache_when_delete_all_elements_from_collection
90
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
91
+ # cache.expects(:read).with("#{cache_key}/cached_posts").returns posts_by_author(:luca)
92
+
93
+ authors(:luca).cached_posts.delete_all
94
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
95
+ end
96
+
97
+ def test_should_expire_cache_when_destroy_all_elements_from_collection
98
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
99
+ # cache.expects(:read).with("#{cache_key}/cached_posts").returns posts_by_author(:luca)
100
+
101
+ authors(:luca).cached_posts.destroy_all
102
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
103
+ end
104
+
105
+ def test_should_use_cache_on_collection_sum
106
+ cache.expects(:fetch).with("#{blogs(:weblog).cache_key}/authors").returns authors_association_proxy
107
+
108
+ assert_equal authors_by_blog(:weblog).map(&:age).sum,
109
+ blogs(:weblog).authors.sum(:age)
110
+ end
111
+
112
+ def test_should_not_use_cache_on_false_cached_option
113
+ cache.expects(:fetch).never
114
+ authors(:luca).posts
115
+ authors(:luca).posts(true) # force reload
116
+ end
117
+
118
+ def test_should_cache_associated_objects
119
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns(posts_by_author(:luca))
120
+
121
+ posts = authors(:luca).cached_posts
122
+ assert_equal posts, authors(:luca).cached_posts
123
+ end
124
+
125
+ def test_should_reload_association_and_refresh_the_cache_on_force_reload
126
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns(posts_by_author(:luca))
127
+
128
+ reloaded_posts = authors(:luca).cached_posts(true)
129
+ assert_equal reloaded_posts, authors(:luca).cached_posts
130
+ end
131
+
132
+ def test_should_cache_associated_ids
133
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
134
+ cache.expects(:fetch).with("#{cache_key}/cached_post_ids").times(2).returns(posts_by_author(:luca).map(&:id))
135
+ ids = authors(:luca).cached_post_ids
136
+ assert_equal ids, authors(:luca).cached_post_ids
137
+ end
138
+
139
+ def test_should_not_cache_associated_ids_on_false_cached_option
140
+ cache.expects(:fetch).never
141
+ authors(:luca).post_ids
142
+ end
143
+
144
+ def test_should_cache_all_eager_loaded_objects
145
+ cache.expects(:fetch).with("#{cache_key}/cached_posts_with_comments").times(2).returns(posts_by_author(:luca, true))
146
+ posts = authors(:luca).cached_posts_with_comments
147
+ assert_equal posts, authors(:luca).cached_posts_with_comments
148
+ end
149
+
150
+ def test_should_not_cache_eager_loaded_objects_on_false_cached_option
151
+ cache.expects(:fetch).never
152
+ authors(:luca).posts_with_comments
153
+ end
154
+
155
+ def test_should_cache_polymorphic_associations
156
+ cache.expects(:fetch).with("#{posts(:cached_models).cache_key}/cached_tags").times(2).returns(tags_by_post(:cached_models))
157
+ tags = posts(:cached_models).cached_tags
158
+ assert_equal tags, posts(:cached_models).cached_tags
159
+ end
160
+
161
+ def test_should_not_cache_polymorphic_associations_on_false_cached_option
162
+ cache.expects(:fetch).never
163
+ posts(:cached_models).tags
164
+ end
165
+
166
+ def test_should_cache_habtm_associations
167
+ cache.expects(:fetch).with("#{cache_key}/cached_comments").times(2).returns(comments_by_author(:luca))
168
+ comments = authors(:luca).cached_comments
169
+ assert_equal comments, authors(:luca).cached_comments
170
+ end
171
+
172
+ def test_should_not_cache_habtm_associations_on_false_cached_option
173
+ cache.expects(:fetch).never
174
+ authors(:luca).comments
175
+ end
176
+
177
+ def test_should_refresh_cache_when_associated_elements_change
178
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
179
+
180
+ post = authors(:luca).cached_posts.last # force cache loading and fetch a post
181
+ post.update_attributes :title => 'Cached Models!'
182
+
183
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
184
+ end
185
+
186
+ def test_should_refresh_cache_when_pushing_element_to_association
187
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
188
+ cache.expects(:write).with("#{cache_key}/cached_posts", association_proxy).returns true
189
+
190
+ post = create_post :author_id => nil
191
+ authors(:luca).cached_posts << post
192
+
193
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
194
+ end
195
+
196
+ def test_should_refresh_caches_when_pushing_element_to_association_belonging_to_another_model
197
+ cache.expects(:fetch).with("#{authors(:chuck).cache_key}/cached_posts").times(2).returns association_proxy(:chuck)
198
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
199
+
200
+ post = authors(:chuck).cached_posts.last
201
+ authors(:luca).cached_posts << post
202
+
203
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
204
+ assert_equal posts_by_author(:chuck), authors(:chuck).cached_posts
205
+ end
206
+
207
+ def test_should_refresh_caches_when_pushing_element_to_polymorphic_association_belonging_to_another_model
208
+ cache.expects(:fetch).with("#{posts(:welcome).cache_key}/cached_tags").times(2).returns tags_association_proxy
209
+ cache.expects(:fetch).with("#{posts(:cached_models).cache_key}/cached_tags").times(2).returns tags_association_proxy(:cached_models)
210
+ tag = posts(:welcome).cached_tags.last
211
+
212
+ posts(:cached_models).cached_tags << tag
213
+
214
+ # NOTE for some weird reason the assertion fails, even if the collections are equals.
215
+ # I forced the comparision between the ids.
216
+ assert_equal tags_by_post(:cached_models).map(&:id).sort,
217
+ posts(:cached_models).cached_tags.map(&:id).sort
218
+ assert_equal tags_by_post(:welcome), posts(:welcome).cached_tags
219
+ end
220
+
221
+ def test_should_not_use_cache_when_pushing_element_to_association_on_false_cached_option
222
+ cache.expects(:write).never
223
+
224
+ post = create_post :author_id => nil
225
+ authors(:luca).posts << post
226
+ end
227
+
228
+ def test_should_not_use_cache_when_pushing_element_to_association_belonging_to_anotner_model_on_false_cached_option
229
+ cache.expects(:delete).with("#{blogs(:weblog).cache_key}/posts").never
230
+ post = blogs(:weblog).posts.last
231
+ blogs(:blog).posts << post
232
+
233
+ assert_equal posts_by_blog(:blog), blogs(:blog).posts
234
+ end
235
+
236
+ def test_should_not_use_cache_when_pushing_element_to_polymorphic_association_belonging_to_another_model_on_false_cached_option
237
+ cache.expects(:delete).never
238
+ tag = posts(:welcome).tags.last
239
+ posts(:cached_models).tags << tag
240
+
241
+ assert_equal tags_by_post(:cached_models), posts(:cached_models).tags
242
+ end
243
+
244
+ def test_should_update_cache_when_pushing_element_with_build
245
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
246
+
247
+ author = authors(:luca)
248
+ post = author.cached_posts.build post_options
249
+ post.save
250
+
251
+ assert_equal posts_by_author(:luca), author.cached_posts
252
+ end
253
+
254
+ def test_should_update_cache_when_pushing_element_with_create
255
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
256
+
257
+ author = authors(:luca)
258
+ author.cached_posts.create post_options(:title => "CM Overview")
259
+
260
+ assert_equal posts_by_author(:luca), author.cached_posts
261
+ end
262
+
263
+ def test_should_update_cache_when_pushing_element_with_create_bang_method
264
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
265
+
266
+ author = authors(:luca)
267
+ author.cached_posts.create! post_options(:title => "CM Overview!!")
268
+
269
+ assert_equal posts_by_author(:luca), author.cached_posts
270
+ end
271
+
272
+ def test_should_update_cache_when_deleting_element_from_collection
273
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
274
+
275
+ authors(:luca).cached_posts.delete(posts_by_author(:luca).first)
276
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
277
+ end
278
+
279
+ def test_should_update_cache_when_clearing_collection
280
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
281
+ authors(:luca).cached_posts.clear
282
+
283
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
284
+ end
285
+
286
+ def test_should_update_cache_when_clearing_collection_with_dependent_destroy_option
287
+ cache.expects(:fetch).with("#{cache_key}/cached_dependent_posts").times(2).returns association_proxy
288
+ authors(:luca).cached_dependent_posts.clear
289
+
290
+ assert_equal posts_by_author(:luca), authors(:luca).cached_dependent_posts
291
+ end
292
+
293
+ def test_should_update_cache_when_directly_assigning_a_new_collection
294
+ posts = [ posts_by_author(:luca).first ]
295
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
296
+ authors(:luca).cached_posts = posts
297
+
298
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
299
+ end
300
+
301
+ def test_should_update_cache_when_replace_collection
302
+ post = create_post; post.save
303
+ posts = [ posts_by_author(:luca).first, post ]
304
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
305
+ authors(:luca).cached_posts.replace(posts)
306
+
307
+ assert_equal posts_by_author(:luca), authors(:luca).cached_posts
308
+ end
309
+
310
+ def test_should_use_cache_for_collection_size
311
+ # cache.expects(:fetch).with("#{cache_key}/cached_posts").times(2).returns association_proxy
312
+
313
+ assert_equal posts_by_author(:luca).size,
314
+ authors(:luca).cached_posts.size
315
+ end
316
+
317
+ def test_should_use_cache_for_collection_length
318
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").returns association_proxy
319
+
320
+ assert_equal posts_by_author(:luca).length,
321
+ authors(:luca).cached_posts.length
322
+ end
323
+
324
+ def test_should_use_cache_for_collection_empty
325
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").returns association_proxy
326
+
327
+ assert_equal posts_by_author(:luca).empty?,
328
+ authors(:luca).cached_posts.empty?
329
+ end
330
+
331
+ def test_should_use_cache_for_collection_any
332
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").returns association_proxy
333
+
334
+ assert_equal posts_by_author(:luca).any?,
335
+ authors(:luca).cached_posts.any?
336
+ end
337
+
338
+ def test_should_use_cache_for_collection_include
339
+ cache.expects(:fetch).with("#{cache_key}/cached_posts").returns association_proxy
340
+
341
+ post = posts_by_author(:luca).first
342
+ assert authors(:luca).cached_posts.include?(post)
343
+ end
344
+ end
345
+
346
+ private
347
+ def posts_by_author(author, include_comments = false)
348
+ conditions = include_comments ? { :include => :comments } : { }
349
+ Post.find_all_by_author_id(authors(author).id, conditions)
350
+ end
351
+
352
+ def posts_by_blog(blog)
353
+ Post.find_all_by_blog_id(blogs(blog).id)
354
+ end
355
+
356
+ def tags_by_post(post)
357
+ Tag.find_all_by_taggable_id(posts(post).id)
358
+ end
359
+
360
+ def comments_by_author(author)
361
+ Comment.find(:all, :conditions => ["post_id IN (?)", authors(author).post_ids])
362
+ end
363
+
364
+ def authors_by_blog(blog)
365
+ Author.find_all_by_blog_id(blogs(blog).id)
366
+ end
367
+
368
+ def association_proxy(author = :luca)
369
+ HasManyAssociation.new(authors(author), Author.reflect_on_association(:cached_posts))
370
+ end
371
+
372
+ def authors_association_proxy(blog = :weblog)
373
+ HasManyAssociation.new(blogs(blog), Blog.reflect_on_association(:authors))
374
+ end
375
+
376
+ def tags_association_proxy(post = :welcome)
377
+ HasManyAssociation.new(posts(post), Post.reflect_on_association(:cached_tags))
378
+ end
379
+
380
+ def comments_association_proxy(author = :luca)
381
+ HasManyThroughAssociation.new(authors(author), Author.reflect_on_association(:cached_comments))
382
+ end
383
+
384
+ def create_post(options = {})
385
+ Post.new({ :author_id => 1,
386
+ :title => 'CachedModels',
387
+ :text => 'Introduction to CachedModels plugin',
388
+ :published_at => 1.week.ago }.merge(options))
389
+ end
390
+
391
+ def post_options(options = {})
392
+ { :blog_id => blogs(:weblog).id,
393
+ :title => "Cached models review",
394
+ :text => "Cached models review..",
395
+ :published_at => 1.week.ago }.merge(options)
396
+ end
397
+
398
+ def cache_key
399
+ @cache_key ||= authors(:luca).cache_key
400
+ end
401
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class BaseTest < Test::Unit::TestCase
4
+ fixtures :authors
5
+
6
+ def test_should_have_cache
7
+ assert_equal RAILS_CACHE, ActiveRecord::Base.rails_cache if defined? Rails
8
+ assert_kind_of ActiveSupport::Cache::Store, ActiveRecord::Base.rails_cache
9
+ end
10
+
11
+ def test_should_wrap_rails_cache
12
+ assert_equal RAILS_CACHE, Post.new.send(:rails_cache) if defined? Rails
13
+ assert_kind_of ActiveSupport::Cache::Store, Post.new.send(:rails_cache)
14
+ end
15
+
16
+ def test_reflection_cache_key
17
+ author = authors(:luca)
18
+ actual = author.send(:reflection_cache_key, Author.reflections[:cached_posts])
19
+ assert_equal "#{author.cache_key}/cached_posts", actual
20
+ end
21
+
22
+ def test_cached_association
23
+ author = authors(:luca)
24
+ assert_equal({}, author.send(:cached_associations))
25
+
26
+ author.cached_posts # force cache loading
27
+ assert_equal({:cached_posts => true}, author.send(:cached_associations))
28
+
29
+ author.send(:cache_delete, Author.reflections[:cached_posts])
30
+ assert_equal({:cached_posts => false}, author.send(:cached_associations))
31
+ end
32
+ end
@@ -0,0 +1,13 @@
1
+ luca:
2
+ id: 1
3
+ blog_id: 1
4
+ first_name: Luca
5
+ last_name: Guidi
6
+ age: <%= Time.now.year - 1982 %>
7
+
8
+ chuck:
9
+ id: 2
10
+ blog_id: 1
11
+ first_name: Chuck
12
+ last_name: Palahniuk
13
+ age: <%= Time.now.year - 1962 %>
@@ -0,0 +1,7 @@
1
+ weblog:
2
+ id: 1
3
+ title: "Luca Guidi weblog"
4
+
5
+ blog:
6
+ id: 2
7
+ title: "TDC"
@@ -0,0 +1,19 @@
1
+ comment:
2
+ post_id: 1
3
+ email: john@doe.com
4
+ text: Good luck for your blog.
5
+
6
+ positive_comment:
7
+ post_id: 2
8
+ email: john@doe.com
9
+ text: Very nice plugin, thank you!
10
+
11
+ negative_comment:
12
+ post_id: 2
13
+ email: doe@john.com
14
+ text: Crappy stuff!
15
+
16
+ comment_for_fight_club:
17
+ post_id: 3
18
+ email: john@doe.com
19
+ text: Awsome book!
@@ -0,0 +1,23 @@
1
+ welcome:
2
+ id: 1
3
+ blog_id: 1
4
+ author_id: 1
5
+ title: Welcome
6
+ text: Welcome to my blog
7
+ published_at: <%= 3.years.ago %>
8
+
9
+ cached_models:
10
+ id: 2
11
+ blog_id: 1
12
+ author_id: 1
13
+ title: Cached Models
14
+ text: Cached Models plugin overview
15
+ published_at: <%= 2.weeks.ago %>
16
+
17
+ fight_club:
18
+ id: 3
19
+ blog_id: 2
20
+ author_id: 2
21
+ title: Fight Club
22
+ text: This is a Fight Club review
23
+ published_at: <%= 1.week.ago %>
@@ -0,0 +1,14 @@
1
+ announcements_on_welcome:
2
+ taggable_id: 1
3
+ taggable_type: Post
4
+ name: announcements
5
+
6
+ plugin_on_cached_models:
7
+ taggable_id: 2
8
+ taggable_type: Post
9
+ name: plugin
10
+
11
+ rails_on_cached_models:
12
+ taggable_id: 2
13
+ taggable_type: Post
14
+ name: rails
@@ -0,0 +1,10 @@
1
+ class Author < ActiveRecord::Base
2
+ belongs_to :blog, :cached => true
3
+ has_many :posts
4
+ has_many :cached_posts, :cached => true, :class_name => 'Post'
5
+ has_many :cached_dependent_posts, :cached => true, :class_name => 'Post', :dependent => :destroy
6
+ has_many :posts_with_comments, :class_name => 'Post', :include => :comments
7
+ has_many :cached_posts_with_comments, :class_name => 'Post', :include => :comments, :cached => true
8
+ has_many :comments, :through => :posts
9
+ has_many :cached_comments, :through => :posts, :source => :comments, :cached => true
10
+ end
@@ -0,0 +1,4 @@
1
+ class Blog < ActiveRecord::Base
2
+ has_many :authors, :cached => true
3
+ has_many :posts
4
+ end
@@ -0,0 +1,3 @@
1
+ class Comment < ActiveRecord::Base
2
+ belongs_to :post
3
+ end
@@ -0,0 +1,7 @@
1
+ class Post < ActiveRecord::Base
2
+ belongs_to :author, :cached => true
3
+ belongs_to :blog
4
+ has_many :comments
5
+ has_many :tags, :as => :taggable
6
+ has_many :cached_tags, :as => :taggable, :class_name => 'Tag', :cached => true
7
+ end
@@ -0,0 +1,3 @@
1
+ class Tag < ActiveRecord::Base
2
+ belongs_to :taggable, :polymorphic => true
3
+ end
@@ -0,0 +1,42 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ require 'test/unit'
4
+ require 'rubygems'
5
+ require 'active_support'
6
+ require 'action_controller'
7
+ require 'active_support/test_case'
8
+ require 'active_record/fixtures'
9
+ require 'action_controller/integration'
10
+
11
+ # FIXME load path
12
+ require File.dirname(__FILE__) + '/../../../../config/environment'
13
+ $:.unshift File.dirname(__FILE__) + '/models'
14
+ require 'author'
15
+ require 'post'
16
+
17
+ Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures"
18
+ ActionController::IntegrationTest.fixture_path = Test::Unit::TestCase.fixture_path
19
+
20
+ class Test::Unit::TestCase
21
+ self.use_transactional_fixtures = true
22
+ self.use_instantiated_fixtures = false
23
+ fixtures :all
24
+
25
+ # Assert the given condition is false
26
+ def assert_false(condition, message = nil)
27
+ assert !condition, message
28
+ end
29
+
30
+ private
31
+ def cache
32
+ ActiveRecord::Base.rails_cache
33
+ end
34
+ end
35
+
36
+ def uses_mocha(description)
37
+ require 'rubygems'
38
+ require 'mocha'
39
+ yield
40
+ rescue LoadError
41
+ $stderr.puts "Skipping #{description} tests. `gem install mocha` and try again."
42
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here