cached-models 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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