itrigga-cache 0.2.1

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,412 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ class TriggaCacheTestClass
4
+ include Itrigga::Cache
5
+ end
6
+
7
+ unless defined?(ActionController::Base) # for testing outside rails
8
+ module ActionController
9
+ class Base
10
+ def render_to_string; "content"; end
11
+ end
12
+ end
13
+ end
14
+
15
+ class TriggaCacheControllerTestClass < ActionController::Base
16
+ include Itrigga::Cache
17
+ end
18
+
19
+
20
+
21
+ describe Itrigga::Cache do
22
+ before do
23
+ @klass = TriggaCacheTestClass.new
24
+ @klass.stub!(:cache_log) # stub out the logging method in tests
25
+ end
26
+
27
+ describe "included" do
28
+ it "should include InstanceMethods" do
29
+ TriggaCacheTestClass.should include Itrigga::Cache::InstanceMethods
30
+ TriggaCacheControllerTestClass.should include Itrigga::Cache::InstanceMethods
31
+ end
32
+
33
+ it "should include ParamFu" do
34
+ TriggaCacheTestClass.should include Trigga::ParamFu
35
+ end
36
+
37
+ it "should not include the controller methods" do
38
+ TriggaCacheTestClass.should_not include Itrigga::Cache::ControllerMethods
39
+ end
40
+
41
+ it "should include the controller methods" do
42
+ TriggaCacheControllerTestClass.should include Itrigga::Cache::ControllerMethods
43
+ end
44
+ end
45
+
46
+ describe "setup" do
47
+ before do
48
+ end
49
+
50
+ it "should initialize the memcache client" do
51
+ @opts = {:abc => 123, :backend => :memcached}
52
+ Itrigga::Cache::Memcache.should_receive(:setup!).with(@opts)
53
+ Itrigga::Cache.setup!(@opts)
54
+ end
55
+
56
+ it "should initialize the filecache client" do
57
+ @opts = {:abc => 123, :backend => :filecached}
58
+ Itrigga::Cache::Filecache.should_receive(:setup!).with(@opts)
59
+ Itrigga::Cache.setup!(@opts)
60
+ end
61
+ end
62
+
63
+ describe "instance" do
64
+ it "should initialize the memcache client" do
65
+ Itrigga::Cache::Memcache.should_receive(:instance).and_return(@instance = mock("Instance"))
66
+ Itrigga::Cache.instance(:backend => :memcached).should == @instance
67
+ end
68
+
69
+ it "should initialize the filecache client" do
70
+ Itrigga::Cache::Filecache.should_receive(:instance).and_return(@instance = mock("Instance"))
71
+ Itrigga::Cache.instance(:backend => :filecache).should == @instance
72
+ end
73
+
74
+
75
+ it "should return the default @@ITRIGGA_CACHE_TYPE" do
76
+ Itrigga::Cache::Filecache.should_receive(:instance).and_return(@instance = mock("Instance", :cache => "a cache"))
77
+ Itrigga::Cache.instance().should == @instance
78
+ end
79
+ end
80
+
81
+
82
+
83
+
84
+ describe "with_cache" do
85
+ before do
86
+
87
+ @klass.class.stub!(:get_from_cache)
88
+ @klass.class.stub!(:set_to_cache)
89
+ @klass.stub!(:require_param)
90
+ @opts = {:key => "monkeys"}
91
+ end
92
+
93
+ it "should call require_param" do
94
+ @klass.class.should_receive(:require_param).with(@opts, :key)
95
+ @klass.with_cache(@opts){ nil }
96
+ end
97
+
98
+ describe "when caching not enabled" do
99
+ before do
100
+ @klass.class.stub!(:caching_enabled?).and_return(false)
101
+ end
102
+
103
+ it "should not call get_from_cache" do
104
+ @klass.class.should_not_receive(:get_from_cache)
105
+ @klass.with_cache(@opts){ nil }
106
+ end
107
+
108
+ it "should return the block output" do
109
+ @klass.with_cache(@opts){ "blart" }.should == "blart"
110
+ end
111
+ end
112
+
113
+ describe "with cache enabled" do
114
+ before do
115
+ @klass.class.stub!(:caching_enabled?).and_return(true)
116
+ end
117
+
118
+
119
+ describe "when key no in cache" do
120
+ it "should call get_from_cache" do
121
+ @klass.class.should_receive(:get_from_cache).with("monkeys",@opts)
122
+ @klass.with_cache(@opts){ nil }
123
+ end
124
+
125
+ it "should call the block" do
126
+ value = 1
127
+ @klass.with_cache(@opts){ value = 2 }
128
+ value.should == 2
129
+ end
130
+
131
+ it "should call set_to_cache" do
132
+ @klass.class.should_receive(:set_to_cache).with("monkeys",2,{})
133
+ @klass.with_cache(@opts){ 2 }
134
+ end
135
+
136
+ it "should return the value" do
137
+ @klass.with_cache(@opts){ 2 }.should == 2
138
+ end
139
+
140
+ end
141
+
142
+ describe "when key is already in cache" do
143
+ before do
144
+ @klass.class.stub!(:get_from_cache).and_return("funkiness")
145
+ end
146
+
147
+ it "should not call the block" do
148
+ value = 1
149
+ @klass.with_cache(@opts){ value = 2 }
150
+ value.should == 1
151
+ end
152
+
153
+ it "should not call set_to_cache" do
154
+ @klass.class.should_not_receive(:set_to_cache)
155
+ @klass.with_cache(@opts){ 2 }
156
+ end
157
+
158
+ it "should return the original value" do
159
+ @klass.with_cache(@opts){ 2 }.should == "funkiness"
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+
166
+
167
+
168
+ describe "get_from_cache" do
169
+ before do
170
+ Itrigga::Cache.stub!(:instance).and_return(@cache = mock("Cache"))
171
+ @cache.stub!(:get).and_return("funky")
172
+ end
173
+
174
+ it "should return nil if caching disabled" do
175
+ Itrigga::Cache.should_receive(:instance).and_return(nil)
176
+ @klass.class.send("get_from_cache","monkeys").should == nil
177
+ end
178
+
179
+ it "should call get with the key" do
180
+ @cache.should_receive(:get).with("monkeys")
181
+ @klass.class.send("get_from_cache","monkeys")
182
+ end
183
+
184
+ it "should return the value" do
185
+ @klass.class.send("get_from_cache","monkeys").should == "funky"
186
+ end
187
+
188
+ it "should catch Memcached::NotFound and return nil" do
189
+ @cache.stub!(:get).and_raise(Memcached::NotFound)
190
+ lambda { @klass.class.send("get_from_cache","monkeys") }.should_not raise_error
191
+ @klass.class.send("get_from_cache","monkeys").should == nil
192
+ end
193
+ end
194
+
195
+
196
+
197
+ describe "set_to_cache" do
198
+ before do
199
+ Itrigga::Cache.stub!(:instance).and_return(@cache = mock("Cache"))
200
+ @cache.stub!(:set)
201
+ end
202
+
203
+ describe "when no timeout" do
204
+ before do
205
+ @opts = {}
206
+ end
207
+
208
+ it "should call $cache.set" do
209
+ @cache.should_receive(:set).with("monky","funky",@opts)
210
+ @klass.class.send("set_to_cache","monky","funky", @opts)
211
+ end
212
+
213
+ it "should return the value" do
214
+ @klass.class.send("set_to_cache","monky","funky").should == "funky"
215
+ end
216
+ end
217
+
218
+ describe "when given a timeout" do
219
+ before do
220
+ @opts = {:timeout => 42}
221
+ end
222
+
223
+ it "should call $cache.set" do
224
+ @cache.should_receive(:set).with("monky","funky",@opts)
225
+ @klass.class.send("set_to_cache","monky","funky",@opts)
226
+ end
227
+
228
+ it "should return the value" do
229
+ @klass.class.send("set_to_cache","monky","funky", @opts).should == "funky"
230
+ end
231
+ end
232
+ end
233
+
234
+
235
+ describe "delete_from_cache" do
236
+ before do
237
+ Itrigga::Cache.stub!(:instance).and_return(@cache = mock("Cache"))
238
+ @cache.stub!(:delete)
239
+ @klass.class.stub!(:caching_enabled?).and_return(true)
240
+ end
241
+
242
+ it "should return nil if caching disabled" do
243
+ @klass.class.stub!(:caching_enabled?).and_return(false)
244
+ @klass.class.send("delete_from_cache","monkeys").should == nil
245
+ end
246
+
247
+ it "should call delete with the key" do
248
+ @cache.should_receive(:delete).with("monkeys")
249
+ @klass.class.send("delete_from_cache","monkeys")
250
+ end
251
+
252
+ it "should catch Memcached::NotFound and return nil" do
253
+ @cache.stub!(:delete).and_raise(Memcached::NotFound)
254
+ lambda { @klass.class.send("delete_from_cache","monkeys") }.should_not raise_error
255
+ @klass.class.send("delete_from_cache","monkeys").should == nil
256
+ end
257
+ end
258
+
259
+
260
+
261
+
262
+
263
+ describe "with_controller_cache" do
264
+ before do
265
+ @controller = TriggaCacheControllerTestClass.new
266
+ @controller.stub!(:delete_from_cache)
267
+ @controller.stub!(:with_cache)
268
+ @controller.stub!(:cache_log) # stub out the logging method in tests
269
+ @controller.stub!(:render)
270
+ @controller.stub!(:performed?).and_return(false)
271
+ @controller.stub!(:request => mock("Request", :format => mock("Format", :html? => true)))
272
+ @controller.stub!(:params).and_return({})
273
+ @controller.stub!(:caching_enabled?).and_return(true)
274
+ @abc = 1
275
+ end
276
+
277
+ describe "when caching disabled" do
278
+ before do
279
+ @controller.stub!(:caching_enabled?).and_return(false)
280
+ end
281
+
282
+ it "should log a message" do
283
+ @controller.should_receive(:cache_log).with("Cache not enabled!",{})
284
+ @controller.with_controller_cache(){ @abc = 2 }
285
+ end
286
+
287
+ it "should call the block" do
288
+ @controller.with_controller_cache(){ @abc = 2 }
289
+ @abc.should == 2
290
+ end
291
+
292
+ it "should save the output from the block into the @content instance variable" do
293
+ @controller.with_controller_cache(){ @abc = 2 }
294
+ @controller.instance_variable_get("@content").should == 2
295
+ end
296
+
297
+ describe "when performed? is false" do
298
+ it "should not call render_to_string" do
299
+ @controller.stub!(:performed?).and_return(false)
300
+ @controller.should_receive(:render_to_string)
301
+ @controller.with_controller_cache(){ nil }
302
+ end
303
+ end
304
+
305
+ describe "when performed? is true" do
306
+ it "should not call render_to_string" do
307
+ @controller.stub!(:performed?).and_return(true)
308
+ @controller.should_not_receive(:render_to_string)
309
+ @controller.with_controller_cache(){ nil }
310
+ end
311
+ end
312
+ end
313
+
314
+
315
+ describe "when caching enabled" do
316
+ before do
317
+ @controller.stub!(:caching_enabled?).and_return(true)
318
+ @opts = {:key => "key"}
319
+ end
320
+
321
+ it "should raise an error if :key not given" do
322
+ expect{ @controller.with_controller_cache(){ nil } }.to raise_error
323
+ end
324
+
325
+ it "should call delete_from_cache if the freshen key is given" do
326
+ @controller.should_receive(:delete_from_cache).with("key", @opts)
327
+ @controller.stub!(:params).and_return("freshen" => true)
328
+ @controller.with_controller_cache(@opts){ nil }
329
+ end
330
+
331
+ it "should not call delete_from_cache" do
332
+ @controller.should_not_receive(:delete_from_cache)
333
+ @controller.with_controller_cache(@opts.merge("freshen" => true)){ nil }
334
+ end
335
+
336
+ it "should call with_cache" do
337
+ @controller.should_receive(:with_cache).and_return("content")
338
+ @controller.with_controller_cache(@opts) { "content" }
339
+ end
340
+
341
+ it "should call render_to_string" do
342
+ @controller.should_receive(:render_to_string).and_return("content")
343
+ @controller.stub!(:performed?).and_return(false)
344
+ @controller.with_controller_cache(@opts) { nil }
345
+ end
346
+
347
+ it "should call not render_to_string" do
348
+ @controller.should_not_receive(:render_to_string).and_return("content")
349
+ @controller.stub!(:performed?).and_return(true)
350
+ @controller.with_controller_cache(@opts) { "content" }
351
+ end
352
+
353
+ it "should call not render_to_string" do
354
+ @controller.should_not_receive(:render_to_string).and_return("content")
355
+ @controller.stub!(:performed?).and_return(true)
356
+ @controller.with_controller_cache(@opts) { nil }
357
+ end
358
+
359
+ it "should call render" do
360
+ @controller.should_receive(:render).with(:text => "content", :content_type => "text/html")
361
+ @controller.with_controller_cache(@opts) { "content" }
362
+ end
363
+
364
+ it "should return the content" do
365
+ @controller.with_controller_cache(@opts) { "content" }.should == "content"
366
+ end
367
+
368
+ describe "when an error occurs" do
369
+ before do
370
+ @controller.stub!(:with_cache).and_raise("An error")
371
+ end
372
+
373
+ it "should handle the error" do
374
+ lambda { @controller.with_controller_cache(@opts) { "content" } }.should_not raise_error
375
+ end
376
+
377
+ it "should log the error" do
378
+ @controller.should_receive(:cache_log).with("Error when rendering cache block: An error", {:key=>"key"})
379
+ @controller.with_controller_cache(@opts) { "content" }
380
+ end
381
+
382
+ it "should call the block and set the output into @content" do
383
+ @controller.with_controller_cache(@opts) { "content" }
384
+ @controller.instance_variable_get("@content").should == "content"
385
+ end
386
+
387
+ it "should call render_to_string" do
388
+ @controller.stub!(:performed?).and_return(false)
389
+ @controller.should_receive(:render_to_string).and_return("string")
390
+ @controller.with_controller_cache(@opts) { nil }
391
+ end
392
+
393
+ it "should not call render_to_string" do
394
+ @controller.stub!(:performed?).and_return(true)
395
+ @controller.should_not_receive(:render_to_string).and_return("string")
396
+ @controller.with_controller_cache(@opts) { nil }
397
+ end
398
+
399
+ it "should not call render_to_string" do
400
+ @controller.stub!(:performed?).and_return(false)
401
+ @controller.should_not_receive(:render_to_string).and_return("string")
402
+ @controller.with_controller_cache(@opts) { "content" }
403
+ end
404
+ end
405
+
406
+ end
407
+
408
+
409
+ end
410
+
411
+
412
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Itrigga::Cache::Memcache do
4
+ before do
5
+ Itrigga::Cache::Memcache.reset_instance
6
+ ::Memcached.stub!(:new).and_return(@memcached = mock("Memcached"))
7
+ @instance = Itrigga::Cache::Memcache.instance
8
+ end
9
+
10
+ it "should include Singleton" do
11
+ Itrigga::Cache::Memcache.should include Singleton
12
+ end
13
+
14
+ describe "setup!" do
15
+ it "should call Memcached.new with default server" do
16
+ Memcached.should_receive(:new).with("localhost:11211",{})
17
+ Itrigga::Cache::Memcache.setup!
18
+ end
19
+
20
+ it "should call Memcached.new with given server" do
21
+ Memcached.should_receive(:new).with("funky monkeys",{:abc => 123})
22
+ Itrigga::Cache::Memcache.setup!(:servers => "funky monkeys", :abc => 123)
23
+ end
24
+
25
+ it "should call Memcached.new with timeout" do
26
+ Memcached.should_receive(:new).with("funky monkeys",{:default_ttl => 42})
27
+ Itrigga::Cache::Memcache.setup!(:servers => "funky monkeys", :timeout => 42)
28
+ end
29
+
30
+ it "should call Memcached.new with timeout" do
31
+ Memcached.should_receive(:new).with("funky monkeys",{:default_ttl => 42})
32
+ Itrigga::Cache::Memcache.setup!(:servers => "funky monkeys", :default_ttl => 42)
33
+ end
34
+
35
+ it "should assign the memcached instance" do
36
+ Itrigga::Cache::Memcache.setup!(:servers => "funky monkeys", :default_ttl => 42)
37
+ Itrigga::Cache::Memcache.instance.cache.should == @memcached
38
+ end
39
+ end
40
+
41
+
42
+ describe "instance_methods" do
43
+ before do
44
+ @instance.stub!(:cache).and_return(@cache = mock("Memcached"))
45
+ end
46
+
47
+
48
+ describe "get" do
49
+ it "should call cache.get" do
50
+ @cache.should_receive(:get).with("key")
51
+ @instance.get("key")
52
+ end
53
+ end
54
+
55
+ describe "set" do
56
+ it "should call cache.set" do
57
+ @cache.should_receive(:set).with("key","content",42)
58
+ @instance.set("key","content",{:timeout => 42})
59
+ end
60
+ end
61
+
62
+ describe "delete" do
63
+ it "should call cache.delete" do
64
+ @cache.should_receive(:delete).with("key")
65
+ @instance.delete("key")
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
5
+ --backtrace
@@ -0,0 +1,15 @@
1
+ RAILS_ENV = 'test'
2
+ ENV['RAILS_ENV'] = 'test'
3
+ RAILS_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
4
+
5
+ $LOAD_PATH.unshift(File.join(RAILS_ROOT, 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'memcached'
8
+
9
+ # Requires supporting files with custom matchers and macros, etc,
10
+ # in ./support/ and its subdirectories.
11
+ Dir["#{RAILS_ROOT}/support/**/*.rb"].each {|f| require f }
12
+
13
+ require 'lib/itrigga/cache'
14
+
15
+
@@ -0,0 +1,20 @@
1
+ # http://blog.ardes.com/2006/12/11/testing-singletons-with-ruby
2
+ #
3
+ # Allows unit testing of a Singleton, resetting state between each test
4
+ # MySingleton.restart_instance
5
+ #
6
+ require 'singleton'
7
+ puts "SINGLETON TESTING"
8
+ class << Singleton
9
+ def included_with_reset(klass)
10
+ included_without_reset(klass)
11
+ class << klass
12
+ def reset_instance
13
+ Singleton.send :__init__, self
14
+ self
15
+ end
16
+ end
17
+ end
18
+ alias_method :included_without_reset, :included
19
+ alias_method :included, :included_with_reset
20
+ end