itrigga-cache 0.2.1

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