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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +79 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/lib/itrigga/cache/cache.rb +195 -0
- data/lib/itrigga/cache/filecache.rb +63 -0
- data/lib/itrigga/cache/memcache.rb +55 -0
- data/lib/itrigga/cache.rb +1 -0
- data/spec/filecache_spec.rb +155 -0
- data/spec/itrigga-cache_spec.rb +412 -0
- data/spec/memcache_spec.rb +71 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +15 -0
- data/support/singleton_reset.rb +20 -0
- metadata +203 -0
@@ -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
data/spec/spec_helper.rb
ADDED
@@ -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
|