revo-cache_fu 1.0.0
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.
- data/CHANGELOG +0 -0
- data/LICENSE +18 -0
- data/README +17 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/cache_fu.gemspec +77 -0
- data/defaults/extensions.rb.default +40 -0
- data/defaults/memcached.yml.default +34 -0
- data/defaults/memcached_ctl.default +81 -0
- data/init.rb +34 -0
- data/install.rb +58 -0
- data/lib/acts_as_cached/benchmarking.rb +87 -0
- data/lib/acts_as_cached/cache_methods.rb +305 -0
- data/lib/acts_as_cached/config.rb +97 -0
- data/lib/acts_as_cached/disabled.rb +30 -0
- data/lib/acts_as_cached/fragment_cache.rb +124 -0
- data/lib/acts_as_cached/local_cache.rb +44 -0
- data/lib/acts_as_cached/memcached_rails.rb +17 -0
- data/lib/acts_as_cached/recipes.rb +8 -0
- data/lib/acts_as_cached.rb +51 -0
- data/tasks/memcached.rake +43 -0
- data/test/benchmarking_test.rb +36 -0
- data/test/cache_test.rb +281 -0
- data/test/config_test.rb +128 -0
- data/test/disabled_test.rb +40 -0
- data/test/extensions_test.rb +33 -0
- data/test/fragment_cache_test.rb +250 -0
- data/test/helper.rb +215 -0
- data/test/local_cache_test.rb +43 -0
- data/test/sti_test.rb +36 -0
- metadata +92 -0
@@ -0,0 +1,250 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
require 'test/unit'
|
3
|
+
require 'action_controller/test_process'
|
4
|
+
|
5
|
+
ActionController::Routing::Routes.draw do |map|
|
6
|
+
map.connect ':controller/:action/:id'
|
7
|
+
end
|
8
|
+
|
9
|
+
class FooController < ActionController::Base
|
10
|
+
def url_for(*args)
|
11
|
+
"http://#{Time.now.to_i}.foo.com"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class BarController < ActionController::Base
|
16
|
+
def page
|
17
|
+
render :text => "give me my bongos"
|
18
|
+
end
|
19
|
+
|
20
|
+
def index
|
21
|
+
render :text => "doop!"
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
render :text => "rawk"
|
26
|
+
end
|
27
|
+
|
28
|
+
def trees_are_swell?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def rescue_action(e)
|
33
|
+
raise e
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class FooTemplate
|
38
|
+
include ::ActionView::Helpers::CacheHelper
|
39
|
+
|
40
|
+
attr_reader :controller
|
41
|
+
|
42
|
+
def initialize
|
43
|
+
@controller = FooController.new
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "Fragment caching (when used with memcached)" do
|
48
|
+
include FragmentCacheSpecSetup
|
49
|
+
|
50
|
+
setup do
|
51
|
+
@view = FooTemplate.new
|
52
|
+
end
|
53
|
+
|
54
|
+
specify "should be able to cache with a normal, non-keyed Rails cache calls" do
|
55
|
+
_erbout = ""
|
56
|
+
content = "Caching is fun!"
|
57
|
+
|
58
|
+
ActsAsCached.config[:store].expects(:set).with(@view.controller.url_for.gsub('http://',''), content, ActsAsCached.config[:ttl])
|
59
|
+
|
60
|
+
@view.cache { _erbout << content }
|
61
|
+
end
|
62
|
+
|
63
|
+
specify "should be able to cache with a normal cache call when we don't have a default ttl" do
|
64
|
+
begin
|
65
|
+
_erbout = ""
|
66
|
+
content = "Caching is fun!"
|
67
|
+
|
68
|
+
original_ttl = ActsAsCached.config.delete(:ttl)
|
69
|
+
ActsAsCached.config[:store].expects(:set).with(@view.controller.url_for.gsub('http://',''), content, 25.minutes)
|
70
|
+
|
71
|
+
@view.cache { _erbout << content }
|
72
|
+
ensure
|
73
|
+
ActsAsCached.config[:ttl] = original_ttl
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
specify "should be able to cache with a normal, keyed Rails cache calls" do
|
78
|
+
_erbout = ""
|
79
|
+
content = "Wow, even a key?!"
|
80
|
+
key = "#{Time.now.to_i}_wow_key"
|
81
|
+
|
82
|
+
ActsAsCached.config[:store].expects(:set).with(key, content, ActsAsCached.config[:ttl])
|
83
|
+
|
84
|
+
@view.cache(key) { _erbout << content }
|
85
|
+
end
|
86
|
+
|
87
|
+
specify "should be able to cache with new time-to-live option" do
|
88
|
+
_erbout = ""
|
89
|
+
content = "Time to live? TIME TO DIE!!"
|
90
|
+
key = "#{Time.now.to_i}_death_key"
|
91
|
+
|
92
|
+
ActsAsCached.config[:store].expects(:set).with(key, content, 60)
|
93
|
+
@view.cache(key, { :ttl => 60 }) { _erbout << content }
|
94
|
+
end
|
95
|
+
|
96
|
+
specify "should ignore everything but time-to-live when options are present" do
|
97
|
+
_erbout = ""
|
98
|
+
content = "Don't mess around, here, sir."
|
99
|
+
key = "#{Time.now.to_i}_mess_key"
|
100
|
+
|
101
|
+
ActsAsCached.config[:store].expects(:set).with(key, content, 60)
|
102
|
+
@view.cache(key, { :other_options => "for the kids", :ttl => 60 }) { _erbout << content }
|
103
|
+
end
|
104
|
+
|
105
|
+
specify "should be able to skip cache gets" do
|
106
|
+
ActsAsCached.skip_cache_gets = true
|
107
|
+
ActsAsCached.config[:store].expects(:get).never
|
108
|
+
_erbout = ""
|
109
|
+
@view.cache { _erbout << "Caching is fun!" }
|
110
|
+
ActsAsCached.skip_cache_gets = false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "Action caching (when used with memcached)" do
|
115
|
+
include FragmentCacheSpecSetup
|
116
|
+
page_content = "give me my bongos"
|
117
|
+
index_content = "doop!"
|
118
|
+
edit_content = "rawk"
|
119
|
+
|
120
|
+
setup do
|
121
|
+
@controller = BarController.new
|
122
|
+
@request = ActionController::TestRequest.new
|
123
|
+
@response = ActionController::TestResponse.new
|
124
|
+
end
|
125
|
+
|
126
|
+
teardown do # clear the filter chain between specs to avoid chaos
|
127
|
+
BarController.write_inheritable_attribute('filter_chain', [])
|
128
|
+
end
|
129
|
+
|
130
|
+
# little helper for prettier expections on the cache
|
131
|
+
def cache_expects(method, expected_times = 1)
|
132
|
+
ActsAsCached.config[:store].expects(method).times(expected_times)
|
133
|
+
end
|
134
|
+
|
135
|
+
specify "should cache using default ttl for a normal action cache without ttl" do
|
136
|
+
BarController.caches_action :page
|
137
|
+
|
138
|
+
key = 'test.host/bar/page'
|
139
|
+
cache_expects(:set).with(key, page_content, ActsAsCached.config[:ttl])
|
140
|
+
get :page
|
141
|
+
@response.body.should == page_content
|
142
|
+
|
143
|
+
cache_expects(:read).with(key, nil).returns(page_content)
|
144
|
+
get :page
|
145
|
+
@response.body.should == page_content
|
146
|
+
end
|
147
|
+
|
148
|
+
specify "should cache using defaul ttl for normal, multiple action caches" do
|
149
|
+
BarController.caches_action :page, :index
|
150
|
+
|
151
|
+
cache_expects(:set).with('test.host/bar/page', page_content, ActsAsCached.config[:ttl])
|
152
|
+
get :page
|
153
|
+
cache_expects(:set).with('test.host/bar', index_content, ActsAsCached.config[:ttl])
|
154
|
+
get :index
|
155
|
+
end
|
156
|
+
|
157
|
+
specify "should be able to action cache with ttl" do
|
158
|
+
BarController.caches_action :page => { :ttl => 2.minutes }
|
159
|
+
|
160
|
+
cache_expects(:set).with('test.host/bar/page', page_content, 2.minutes)
|
161
|
+
get :page
|
162
|
+
@response.body.should == page_content
|
163
|
+
end
|
164
|
+
|
165
|
+
specify "should be able to action cache multiple actions with ttls" do
|
166
|
+
BarController.caches_action :index, :page => { :ttl => 5.minutes }
|
167
|
+
|
168
|
+
cache_expects(:set).with('test.host/bar/page', page_content, 5.minutes)
|
169
|
+
cache_expects(:set).with('test.host/bar', index_content, ActsAsCached.config[:ttl])
|
170
|
+
|
171
|
+
get :page
|
172
|
+
@response.body.should == page_content
|
173
|
+
|
174
|
+
get :index
|
175
|
+
@response.body.should == index_content
|
176
|
+
cache_expects(:read).with('test.host/bar', nil).returns(index_content)
|
177
|
+
|
178
|
+
get :index
|
179
|
+
end
|
180
|
+
|
181
|
+
specify "should be able to action cache conditionally when passed something that returns true" do
|
182
|
+
BarController.caches_action :page => { :if => :trees_are_swell? }
|
183
|
+
|
184
|
+
cache_expects(:set).with('test.host/bar/page', page_content, ActsAsCached.config[:ttl])
|
185
|
+
|
186
|
+
get :page
|
187
|
+
@response.body.should == page_content
|
188
|
+
|
189
|
+
cache_expects(:read).with('test.host/bar/page', nil).returns(page_content)
|
190
|
+
|
191
|
+
get :page
|
192
|
+
end
|
193
|
+
|
194
|
+
#check for edginess
|
195
|
+
if [].respond_to?(:extract_options!)
|
196
|
+
specify "should not break cache_path overrides" do
|
197
|
+
BarController.caches_action :page, :cache_path => 'http://test.host/some/custom/path'
|
198
|
+
cache_expects(:set).with('test.host/some/custom/path', page_content, ActsAsCached.config[:ttl])
|
199
|
+
get :page
|
200
|
+
end
|
201
|
+
|
202
|
+
specify "should not break cache_path block overrides" do
|
203
|
+
BarController.caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]}/edit" : "http://test.host/edit" }
|
204
|
+
cache_expects(:set).with('test.host/edit', edit_content, ActsAsCached.config[:ttl])
|
205
|
+
get :edit
|
206
|
+
|
207
|
+
get :index
|
208
|
+
cache_expects(:set).with('test.host/5/edit', edit_content, ActsAsCached.config[:ttl])
|
209
|
+
get :edit, :id => 5
|
210
|
+
end
|
211
|
+
|
212
|
+
specify "should play nice with custom ttls and cache_path overrides" do
|
213
|
+
BarController.caches_action :page => { :ttl => 5.days }, :cache_path => 'http://test.host/my/custom/path'
|
214
|
+
cache_expects(:set).with('test.host/my/custom/path', page_content, 5.days)
|
215
|
+
get :page
|
216
|
+
end
|
217
|
+
|
218
|
+
specify "should play nice with custom ttls and cache_path block overrides" do
|
219
|
+
BarController.caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]}/edit" : "http://test.host/edit" }
|
220
|
+
cache_expects(:set).with('test.host/5/edit', edit_content, ActsAsCached.config[:ttl])
|
221
|
+
get :edit, :id => 5
|
222
|
+
end
|
223
|
+
|
224
|
+
specify "should play nice with the most complicated thing i can throw at it" do
|
225
|
+
BarController.caches_action :index => { :ttl => 24.hours }, :page => { :ttl => 5.seconds }, :edit => { :ttl => 5.days }, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]}/#{c.params[:action]}" : "http://test.host/#{c.params[:action]}" }
|
226
|
+
cache_expects(:set).with('test.host/index', index_content, 24.hours)
|
227
|
+
get :index
|
228
|
+
cache_expects(:set).with('test.host/5/edit', edit_content, 5.days)
|
229
|
+
get :edit, :id => 5
|
230
|
+
cache_expects(:set).with('test.host/5/page', page_content, 5.seconds)
|
231
|
+
get :page, :id => 5
|
232
|
+
|
233
|
+
cache_expects(:read).with('test.host/5/page', nil).returns(page_content)
|
234
|
+
get :page, :id => 5
|
235
|
+
cache_expects(:read).with('test.host/5/edit', nil).returns(edit_content)
|
236
|
+
get :edit, :id => 5
|
237
|
+
cache_expects(:read).with('test.host/index', nil).returns(index_content)
|
238
|
+
get :index
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
specify "should be able to skip action caching when passed something that returns false" do
|
243
|
+
BarController.caches_action :page => { :if => Proc.new {|c| !c.trees_are_swell?} }
|
244
|
+
|
245
|
+
cache_expects(:set, 0).with('test.host/bar/page', page_content, ActsAsCached.config[:ttl])
|
246
|
+
|
247
|
+
get :page
|
248
|
+
@response.body.should == page_content
|
249
|
+
end
|
250
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
##
|
2
|
+
# This file exists to fake out all the Railsisms we use so we can run the
|
3
|
+
# tests in isolation.
|
4
|
+
$LOAD_PATH.unshift 'lib/'
|
5
|
+
#
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'rubygems'
|
9
|
+
gem 'mocha', '>= 0.4.0'
|
10
|
+
require 'mocha'
|
11
|
+
gem 'test-spec', '= 0.3.0'
|
12
|
+
require 'test/spec'
|
13
|
+
require 'multi_rails_init'
|
14
|
+
rescue LoadError
|
15
|
+
puts '=> acts_as_cached tests depend on the following gems: mocha (0.4.0+), test-spec (0.3.0), multi_rails (0.0.2), and rails.'
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
require 'redgreen'
|
20
|
+
rescue LoadError
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
Test::Spec::Should.send :alias_method, :have, :be
|
25
|
+
Test::Spec::ShouldNot.send :alias_method, :have, :be
|
26
|
+
|
27
|
+
##
|
28
|
+
# real men test without mocks
|
29
|
+
if $with_memcache = ARGV.include?('with-memcache')
|
30
|
+
require 'memcache'
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# init.rb hacks
|
35
|
+
RAILS_ROOT = '.' unless defined? RAILS_ROOT
|
36
|
+
RAILS_ENV = 'test' unless defined? RAILS_ENV
|
37
|
+
|
38
|
+
##
|
39
|
+
# get the default config using absolute path, so tests all play nice when run in isolation
|
40
|
+
DEFAULT_CONFIG_FILE = File.expand_path(File.dirname(__FILE__) + '/../defaults/memcached.yml.default')
|
41
|
+
|
42
|
+
##
|
43
|
+
# aac
|
44
|
+
require 'acts_as_cached'
|
45
|
+
Object.send :include, ActsAsCached::Mixin
|
46
|
+
|
47
|
+
##
|
48
|
+
# i need you.
|
49
|
+
module Enumerable
|
50
|
+
def index_by
|
51
|
+
inject({}) do |accum, elem|
|
52
|
+
accum[yield(elem)] = elem
|
53
|
+
accum
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# mocky.
|
60
|
+
class HashStore < Hash
|
61
|
+
alias :get :[]
|
62
|
+
|
63
|
+
def get_multi(*values)
|
64
|
+
reject { |k,v| !values.include? k }
|
65
|
+
end
|
66
|
+
|
67
|
+
def set(key, value, *others)
|
68
|
+
self[key] = value
|
69
|
+
end
|
70
|
+
|
71
|
+
def namespace
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
$cache = HashStore.new
|
77
|
+
|
78
|
+
class Story
|
79
|
+
acts_as_cached($with_memcache ? {} : { :store => $cache })
|
80
|
+
|
81
|
+
attr_accessor :id, :title
|
82
|
+
|
83
|
+
def initialize(attributes = {})
|
84
|
+
attributes.each { |key, value| instance_variable_set("@#{key}", value) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def attributes
|
88
|
+
{ :id => id, :title => title }
|
89
|
+
end
|
90
|
+
|
91
|
+
def ==(other)
|
92
|
+
return false unless other.respond_to? :attributes
|
93
|
+
attributes == other.attributes
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.find(*args)
|
97
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
98
|
+
|
99
|
+
if (ids = args.flatten).size > 1
|
100
|
+
ids.map { |id| $stories[id.to_i] }
|
101
|
+
elsif (id = args.flatten.first).to_i.to_s == id.to_s
|
102
|
+
$stories[id.to_i]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.find_by_title(*args)
|
107
|
+
title = args.shift
|
108
|
+
find(args).select { |s| s.title == title }
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.base_class
|
112
|
+
Story
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.something_cool; :redbull end
|
116
|
+
def something_flashy; :molassy end
|
117
|
+
|
118
|
+
def self.block_on(target = nil)
|
119
|
+
target || :something
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.pass_through(target)
|
123
|
+
target
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.two_params(first, second)
|
127
|
+
"first: #{first} | second: #{second}"
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.find_live(*args) false end
|
131
|
+
end
|
132
|
+
|
133
|
+
class Feature < Story; end
|
134
|
+
class Interview < Story; end
|
135
|
+
|
136
|
+
module ActionController
|
137
|
+
class Base
|
138
|
+
def rendering_runtime(*args) '' end
|
139
|
+
def self.silence; yield end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class MemCache
|
144
|
+
attr_accessor :servers
|
145
|
+
def initialize(*args) end
|
146
|
+
class MemCacheError < StandardError; end unless defined? MemCacheError
|
147
|
+
end unless $with_memcache
|
148
|
+
|
149
|
+
module StoryCacheSpecSetup
|
150
|
+
def self.included(base)
|
151
|
+
base.setup do
|
152
|
+
setup_cache_spec
|
153
|
+
Story.instance_eval { @max_key_length = nil }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def setup_cache_spec
|
158
|
+
@story = Story.new(:id => 1, :title => "acts_as_cached 2 released!")
|
159
|
+
@story2 = Story.new(:id => 2, :title => "BDD is something you can use")
|
160
|
+
@story3 = Story.new(:id => 3, :title => "RailsConf is overrated.")
|
161
|
+
$stories = { 1 => @story, 2 => @story2, 3 => @story3 }
|
162
|
+
|
163
|
+
$with_memcache ? with_memcache : with_mock
|
164
|
+
end
|
165
|
+
|
166
|
+
def with_memcache
|
167
|
+
unless $mc_setup_for_story_cache_spec
|
168
|
+
ActsAsCached.config.clear
|
169
|
+
config = YAML.load_file(DEFAULT_CONFIG_FILE)
|
170
|
+
config['test'] = config['development'].merge('benchmarking' => false, 'disabled' => false)
|
171
|
+
ActsAsCached.config = config
|
172
|
+
$mc_setup_for_story_cache_spec = true
|
173
|
+
end
|
174
|
+
|
175
|
+
Story.send :acts_as_cached
|
176
|
+
Story.expire_cache(1)
|
177
|
+
Story.expire_cache(2)
|
178
|
+
Story.expire_cache(3)
|
179
|
+
Story.expire_cache(:block)
|
180
|
+
Story.set_cache(2, @story2)
|
181
|
+
end
|
182
|
+
|
183
|
+
def with_mock
|
184
|
+
$cache.clear
|
185
|
+
|
186
|
+
Story.send :acts_as_cached, :store => $cache
|
187
|
+
$cache['Story:2'] = @story2
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
module FragmentCacheSpecSetup
|
192
|
+
def self.included(base)
|
193
|
+
base.setup { setup_fragment_spec }
|
194
|
+
end
|
195
|
+
|
196
|
+
def setup_fragment_spec
|
197
|
+
unless $mc_setup_for_fragment_cache_spec
|
198
|
+
ActsAsCached.config.clear
|
199
|
+
config = YAML.load_file(DEFAULT_CONFIG_FILE)
|
200
|
+
|
201
|
+
if $with_memcache
|
202
|
+
other_options = { 'fragments' => true }
|
203
|
+
else
|
204
|
+
Object.const_set(:CACHE, $cache) unless defined? CACHE
|
205
|
+
other_options = { 'fragments' => true, 'store' => $cache }
|
206
|
+
end
|
207
|
+
|
208
|
+
config['test'] = config['development'].merge other_options
|
209
|
+
|
210
|
+
ActsAsCached.config = config
|
211
|
+
ActsAsCached::FragmentCache.setup!
|
212
|
+
$mc_setup_for_fragment_cache_spec = true
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
context "When local_cache_for_request is called" do
|
4
|
+
include StoryCacheSpecSetup
|
5
|
+
|
6
|
+
setup do
|
7
|
+
ActionController::Base.new.local_cache_for_request
|
8
|
+
$cache = CACHE if $with_memcache
|
9
|
+
end
|
10
|
+
|
11
|
+
specify "get_cache should pull from the local cache on a second hit" do
|
12
|
+
$cache.expects(:get).with('Story:2').returns(@story2)
|
13
|
+
@story2.get_cache
|
14
|
+
$cache.expects(:get).never
|
15
|
+
@story2.get_cache
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "set_cache should set to the local cache" do
|
19
|
+
$cache.expects(:set).at_least_once.returns(@story)
|
20
|
+
ActsAsCached::LocalCache.local_cache.expects(:[]=).with('Story:1', @story).returns(@story)
|
21
|
+
@story.set_cache
|
22
|
+
end
|
23
|
+
|
24
|
+
specify "expire_cache should clear from the local cache" do
|
25
|
+
@story2.get_cache
|
26
|
+
$cache.expects(:delete).at_least_once
|
27
|
+
ActsAsCached::LocalCache.local_cache.expects(:delete).with('Story:2')
|
28
|
+
@story2.expire_cache
|
29
|
+
end
|
30
|
+
|
31
|
+
specify "clear_cache should clear from the local cache" do
|
32
|
+
@story2.get_cache
|
33
|
+
$cache.expects(:delete).at_least_once
|
34
|
+
ActsAsCached::LocalCache.local_cache.expects(:delete).with('Story:2')
|
35
|
+
@story2.clear_cache
|
36
|
+
end
|
37
|
+
|
38
|
+
specify "cached? should check the local cache" do
|
39
|
+
@story2.get_cache
|
40
|
+
$cache.expects(:get).never
|
41
|
+
@story2.cached?
|
42
|
+
end
|
43
|
+
end
|
data/test/sti_test.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
context "An STI subclass acting as cached" do
|
4
|
+
include StoryCacheSpecSetup
|
5
|
+
|
6
|
+
setup do
|
7
|
+
@feature = Feature.new(:id => 3, :title => 'Behind the scenes of acts_as_cached')
|
8
|
+
@interview = Interview.new(:id => 4, :title => 'An interview with the Arcade Fire')
|
9
|
+
@feature.expire_cache
|
10
|
+
@interview.expire_cache
|
11
|
+
$stories.update 3 => @feature, 4 => @interview
|
12
|
+
end
|
13
|
+
|
14
|
+
specify "should be just as retrievable as any other cachable Ruby object" do
|
15
|
+
Feature.cached?(3).should.equal false
|
16
|
+
Feature.get_cache(3)
|
17
|
+
Feature.cached?(3).should.equal true
|
18
|
+
end
|
19
|
+
|
20
|
+
specify "should have a key corresponding to its parent class" do
|
21
|
+
@feature.cache_key.should.equal "Story:3"
|
22
|
+
@interview.cache_key.should.equal "Story:4"
|
23
|
+
end
|
24
|
+
|
25
|
+
specify "should be able to get itself from the cache via its parent class" do
|
26
|
+
Story.get_cache(3).should.equal @feature
|
27
|
+
Story.get_cache(4).should.equal @interview
|
28
|
+
end
|
29
|
+
|
30
|
+
specify "should take on its parents cache options but be able to set its own" do
|
31
|
+
@feature.cache_key.should.equal "Story:3"
|
32
|
+
Feature.cache_config[:version] = 1
|
33
|
+
@feature.cache_key.should.equal "Story:1:3"
|
34
|
+
@story.cache_key.should.equal "Story:1"
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: revo-cache_fu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Wanstrath
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-18 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: DESCRIPTION!
|
17
|
+
email: chris@ozmm.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README
|
25
|
+
files:
|
26
|
+
- CHANGELOG
|
27
|
+
- LICENSE
|
28
|
+
- README
|
29
|
+
- Rakefile
|
30
|
+
- VERSION
|
31
|
+
- cache_fu.gemspec
|
32
|
+
- defaults/extensions.rb.default
|
33
|
+
- defaults/memcached.yml.default
|
34
|
+
- defaults/memcached_ctl.default
|
35
|
+
- init.rb
|
36
|
+
- install.rb
|
37
|
+
- lib/acts_as_cached.rb
|
38
|
+
- lib/acts_as_cached/benchmarking.rb
|
39
|
+
- lib/acts_as_cached/cache_methods.rb
|
40
|
+
- lib/acts_as_cached/config.rb
|
41
|
+
- lib/acts_as_cached/disabled.rb
|
42
|
+
- lib/acts_as_cached/fragment_cache.rb
|
43
|
+
- lib/acts_as_cached/local_cache.rb
|
44
|
+
- lib/acts_as_cached/memcached_rails.rb
|
45
|
+
- lib/acts_as_cached/recipes.rb
|
46
|
+
- tasks/memcached.rake
|
47
|
+
- test/benchmarking_test.rb
|
48
|
+
- test/cache_test.rb
|
49
|
+
- test/config_test.rb
|
50
|
+
- test/disabled_test.rb
|
51
|
+
- test/extensions_test.rb
|
52
|
+
- test/fragment_cache_test.rb
|
53
|
+
- test/helper.rb
|
54
|
+
- test/local_cache_test.rb
|
55
|
+
- test/sti_test.rb
|
56
|
+
has_rdoc: false
|
57
|
+
homepage: http://github.com/defunkt/cache_fu
|
58
|
+
licenses:
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --charset=UTF-8
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.3.5
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Summarize your gem
|
83
|
+
test_files:
|
84
|
+
- test/sti_test.rb
|
85
|
+
- test/benchmarking_test.rb
|
86
|
+
- test/local_cache_test.rb
|
87
|
+
- test/config_test.rb
|
88
|
+
- test/extensions_test.rb
|
89
|
+
- test/fragment_cache_test.rb
|
90
|
+
- test/disabled_test.rb
|
91
|
+
- test/cache_test.rb
|
92
|
+
- test/helper.rb
|