timedcache 0.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,16 +1,31 @@
1
- # -*- ruby -*-
1
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
2
2
 
3
3
  require 'rubygems'
4
- require 'hoe'
5
- require './lib/timedcache.rb'
6
-
7
- Hoe.new('timedcache', TimedCache::VERSION) do |p|
8
- p.rubyforge_name = 'timedcache'
9
- p.author = 'Nicholas Dainty'
10
- p.email = 'nick@npad.co.uk'
11
- p.summary = 'A very simple time-based object cache.'
12
- p.description = p.paragraphs_of('README.txt', 3..4).join("\n\n")
13
- p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
14
- p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
- p.remote_rdoc_dir = '' # Place RDocs on project home page.
4
+ require 'rake/gempackagetask'
5
+ require 'rake/testtask'
6
+
7
+ # ============================================================================
8
+
9
+ # If you're using this file as a template to set up a new gem, this constant
10
+ # is the only thing you should need to change in the Rakefile:
11
+ GEM_NAME = 'timedcache'
12
+
13
+ # ============================================================================
14
+
15
+ Rake::TestTask.new do |t|
16
+ t.libs << 'test'
17
+ end
18
+
19
+ # ============================================================================
20
+ # = Gem package and release stuff.
21
+ # ============================================================================
22
+
23
+ spec = eval(File.read(File.join(File.dirname(__FILE__), "#{GEM_NAME}.gemspec")))
24
+
25
+ Rake::GemPackageTask.new(spec) do |pkg|
26
+ pkg.need_tar = true
16
27
  end
28
+
29
+ # ============================================================================
30
+
31
+ task :default => [:test]
@@ -2,59 +2,58 @@ require "pstore"
2
2
  require "monitor"
3
3
 
4
4
  # == TimedCache
5
- #
5
+ #
6
6
  # TimedCache implements a cache in which you can place objects
7
7
  # and specify a timeout value.
8
- #
8
+ #
9
9
  # If you attempt to retrieve the object within the specified timeout
10
10
  # period, the object will be returned. If the timeout period has elapsed,
11
11
  # the TimedCache will return nil.
12
- #
12
+ #
13
13
  # e.g.:
14
14
  # cache = TimedCache.new
15
15
  # cache.put :my_object_key, "Expensive data", 10 # => "Expensive data"
16
- #
16
+ #
17
17
  # cache.get :my_object_key # => "Expensive data"
18
18
  # cache[:my_object_key] # => "Expensive data"
19
- #
19
+ #
20
20
  # ... 10 seconds later:
21
21
  # cache.get :my_object_key # => nil
22
- #
22
+ #
23
23
  # === Default timeout
24
- #
24
+ #
25
25
  # When creating a new TimedCache, a default timeout value can be set. This value
26
26
  # will be used for each object added to the cache, unless a different timeout value
27
27
  # is specifically set for that object.
28
- #
28
+ #
29
29
  # e.g.:
30
- #
30
+ #
31
31
  # cache = TimedCache.new(:default_timeout => 120)
32
32
  # cache.default_timeout # => 120
33
- #
33
+ #
34
34
  # === File-based cache
35
- #
36
- # By default, TimedCache will use an in-memory store. A file-based store (using the
35
+ #
36
+ # By default, TimedCache will use an in-memory store. A file-based store (using the
37
37
  # PStore library) can also be used.
38
- #
38
+ #
39
39
  # e.g.:
40
- #
40
+ #
41
41
  # TimedCache.new(:type => :file, :filename => "my_cache.db")
42
- #
43
- # The file-based cache makes it possible to easily share a cache between several ruby
44
- # processes. However when using the cache in this way, you will probably want to update the
45
- # cache by passing a block to the TimedCache#get method (see below for details).
46
- #
42
+ #
43
+ # The file-based cache makes it possible to easily share a cache between several ruby
44
+ # processes.
45
+ #
47
46
  # Note that objects that cannot be marshalled (e.g. a Proc) can't be stored using the file-based cache.
48
47
  class TimedCache
49
48
  VERSION = "0.3"
50
-
49
+
51
50
  attr_reader :default_timeout
52
-
51
+
53
52
  # Create a new TimedCache. Available options are:
54
53
  # <tt>type</tt>:: <tt>:memory</tt> or <tt>:file</tt> (defaults to <tt>:memory</tt>).
55
54
  # <tt>default_timeout</tt>:: Timeout to use if none is specified when adding an object to the cache.
56
55
  # <tt>filename</tt>:: Must be specified when using the <tt>:file</tt> type store.
57
- #
56
+ #
58
57
  # e.g.:
59
58
  # TimedCache.new(:type => :file, :filename => "cache.db")
60
59
  def initialize(opts = {})
@@ -63,66 +62,73 @@ class TimedCache
63
62
  @store = new_store(opts)
64
63
  @store.extend(MonitorMixin)
65
64
  end
66
-
65
+
67
66
  # Add an object to the cache. e.g.:
68
67
  # cache.put(:session_id, 12345)
69
- #
70
- # The third parameter is an optional timeout value. If not specified, the
68
+ #
69
+ # The third parameter is an optional timeout value. If not specified, the
71
70
  # <tt>:default_timeout</tt> for this TimedCache will be used instead.
72
71
  def put(key, value, timeout = @default_timeout)
73
72
  @store.synchronize do
74
73
  @store.put(key, value, timeout) unless value.nil?
75
74
  end
76
75
  end
77
-
76
+ alias :set :put
77
+
78
+ # Remove an object from the cache. e.g.:
79
+ # cache.del(:session_id)
80
+ def delete(key)
81
+ @store.delete(key)
82
+ end
83
+ alias :del :delete
84
+
78
85
  # Retrieve the object which the given +key+. If the object has expired or
79
86
  # is not present, +nil+ is returned.
80
- #
87
+ #
81
88
  # Optionally, a block can be given. The result of evaluating the block will
82
89
  # be substituted as the cache value, if the cache has expired.
83
- #
90
+ #
84
91
  # e.g.:
85
- #
92
+ #
86
93
  # cache.get("slow_database_query") do
87
94
  # MyDatabase.query("SELECT * FROM bigtable...")
88
95
  # end
89
- #
90
- # The block syntax can also be used with the in-memory cache.
96
+ #
91
97
  def get(key, &block)
92
98
  @store.synchronize do
93
99
  @store.get(key, &block)
94
100
  end
95
101
  end
96
-
102
+
97
103
  # Add to the cache using a hash-like syntax. e.g.:
98
104
  # cache[:name] = "Nick"
99
- #
105
+ #
100
106
  # Note that adding to the cache this way does not allow you to specify timeout values
101
107
  # on a per-object basis.
102
108
  def []=(key, value)
103
109
  put(key, value)
104
110
  end
105
-
111
+
106
112
  # Fetch objects using the hash syntax. e.g.:
107
113
  # cache[:name] # => "Nick"
108
114
  def [](key)
109
115
  get(key)
110
116
  end
111
-
117
+
112
118
  protected
113
-
119
+
114
120
  def new_store(options) #:nodoc:
115
121
  self.class.const_get(options[:type].to_s.capitalize + "Store").new(self, options)
116
122
  end
117
-
123
+
118
124
  class Store #:nodoc:
119
125
  def initialize(timed_cache, options)
120
126
  @timed_cache = timed_cache
121
127
  @options = options
122
128
  end
123
-
129
+
124
130
  protected
125
-
131
+
126
132
  def generic_get(key, timeout, callback, fetch_key = lambda {|k| @cache[key]})
127
133
  if object_store = fetch_key.call(key)
128
134
  if object_store.expired?
@@ -139,40 +145,44 @@ class TimedCache
139
145
  run_callback_and_add_to_cache(key, object_store, callback, timeout)
140
146
  end
141
147
  end
142
-
148
+
143
149
  def run_callback_and_add_to_cache(key, object_store, callback, timeout)
144
150
  object_store.no_expiry! if object_store
145
-
151
+
146
152
  begin
147
153
  result = callback.call
148
154
  rescue
149
155
  object_store.reset_expiry! if object_store
150
156
  raise
151
157
  end
152
-
158
+
153
159
  @timed_cache.put(key, result, timeout)
154
160
  result
155
161
  end
156
162
  end
157
-
163
+
158
164
  class MemoryStore < Store #:nodoc:
159
165
  def initialize(*args)
160
166
  super(*args)
161
167
  @cache = Hash.new
162
168
  end
163
-
169
+
164
170
  def put(key, value, timeout)
165
171
  @cache[key] = ObjectContainer.new(value, timeout)
166
172
  # Return just the given value, so that references to the
167
173
  # ObjectStore instance can't be held outside this TimedCache:
168
174
  value
169
175
  end
170
-
176
+
171
177
  def get(key, timeout = @timed_cache.default_timeout, &block)
172
178
  generic_get(key, timeout, block)
173
179
  end
180
+
181
+ def delete(key)
182
+ @cache.delete(key)
183
+ end
174
184
  end
175
-
185
+
176
186
  class FileStore < Store #:nodoc:
177
187
  def initialize(*args)
178
188
  super(*args)
@@ -182,15 +192,15 @@ class TimedCache
182
192
  end
183
193
  @cache = PStore.new(filename)
184
194
  end
185
-
195
+
186
196
  def put(key, value, timeout)
187
197
  @cache.transaction { @cache[key] = ObjectContainer.new(value, timeout) }
188
-
198
+
189
199
  # Return just the given value, so that references to the
190
200
  # ObjectStore instance can't be held outside this TimedCache:
191
201
  value
192
202
  end
193
-
203
+
194
204
  def get(key, timeout = @timed_cache.default_timeout, &block)
195
205
  if block
196
206
  generic_get(key, timeout, block, lambda {|k| @cache.transaction { @cache[key] } })
@@ -198,18 +208,22 @@ class TimedCache
198
208
  @cache.transaction { generic_get(key, timeout, block) }
199
209
  end
200
210
  end
211
+
212
+ def delete(key)
213
+ @cache.transaction { @cache.delete(key) }
214
+ end
201
215
  end
202
-
216
+
203
217
  class ObjectContainer #:nodoc:
204
218
  attr_accessor :object
205
-
219
+
206
220
  def initialize(object, timeout)
207
221
  @created_at = Time.now.utc
208
222
  @timeout = timeout
209
223
  @object = object
210
224
  @frozen = false
211
225
  end
212
-
226
+
213
227
  def expired?
214
228
  if @frozen
215
229
  false
@@ -217,11 +231,11 @@ class TimedCache
217
231
  (Time.now.utc - @timeout) > @created_at
218
232
  end
219
233
  end
220
-
234
+
221
235
  def no_expiry!
222
236
  @frozen = true
223
237
  end
224
-
238
+
225
239
  def reset_expiry!
226
240
  @frozen = false
227
241
  end
@@ -0,0 +1,3 @@
1
+ class TimedCache
2
+ VERSION = "0.4.0"
3
+ end
@@ -1,7 +1,7 @@
1
- require File.join(File.dirname(__FILE__), "../lib/timedcache")
1
+ require File.expand_path('../lib/timedcache', File.dirname(__FILE__))
2
2
 
3
- # This script will almost certainly raise an exception if
4
- # thread safety is not implemented.
3
+ # This script will almost certainly raise an exception if the cache is not
4
+ # thread safe.
5
5
 
6
6
  db = File.join(File.dirname(__FILE__), "thread_test.db")
7
7
 
@@ -0,0 +1,115 @@
1
+ require 'test/unit'
2
+ require 'timedcache'
3
+
4
+ class TimedCacheTest < Test::Unit::TestCase
5
+ def setup
6
+ @filename = File.join(File.dirname(__FILE__), "specs.db")
7
+ @memory_cache = TimedCache.new
8
+ @file_cache = TimedCache.new(:type => :file, :filename => @filename)
9
+ @caches = [@memory_cache, @file_cache]
10
+ end
11
+
12
+ def teardown
13
+ File.delete(@filename) if File.exist?(@filename)
14
+ end
15
+
16
+ def test_can_add_an_object_to_the_cache_specifying_a_timeout_value
17
+ @caches.each do |cache|
18
+ assert_equal("This needs caching", cache.put(:myobject, "This needs caching", 10))
19
+ end
20
+ end
21
+
22
+ def test_can_add_an_object_to_the_cache_specifying_a_timeout_value_using_the_set_method
23
+ @caches.each do |cache|
24
+ assert_equal("This needs caching", cache.set(:myobject, "This needs caching", 10))
25
+ end
26
+ end
27
+
28
+ def test_can_remove_objects_from_the_cache
29
+ @caches.each do |cache|
30
+ cache.put(:myobject, "This needs caching", 10)
31
+ assert_equal("This needs caching", cache.get(:myobject))
32
+ cache.del(:myobject)
33
+ assert_nil(cache.get(:myobject))
34
+ end
35
+ end
36
+
37
+ def test_cache_should_hold_seperate_values_for_each_key
38
+ @caches.each do |cache|
39
+ assert_equal("This needs caching", cache.put(:myobject, "This needs caching", 10))
40
+ assert_equal("...and this too", cache.put(:my_other_object, "...and this too", 10))
41
+ assert_equal("This needs caching", cache.get(:myobject))
42
+ assert_equal("...and this too", cache.get(:my_other_object))
43
+ end
44
+ end
45
+
46
+ def test_string_and_symbol_keys_are_not_treated_as_equivalent
47
+ @caches.each do |cache|
48
+ cache[:symbolkey] = "Referenced by symbol"
49
+ cache["stringkey"] = "Referenced by string"
50
+
51
+ assert_equal("Referenced by symbol", cache[:symbolkey])
52
+ assert_nil(cache["symbolkey"])
53
+
54
+ assert_equal("Referenced by string", cache["stringkey"])
55
+ assert_nil(cache[:stringkey])
56
+ end
57
+ end
58
+
59
+ def test_after_the_specified_timeout_value_has_elapsed_nil_should_be_returned
60
+ @caches.each do |cache|
61
+ assert_equal("This needs caching", cache.put(:myobject, "This needs caching", 0))
62
+ assert_nil(cache.get(:myobject))
63
+ end
64
+ end
65
+
66
+ def test_if_no_object_matching_the_given_key_is_found_nil_should_be_returned
67
+ @caches.each do |cache|
68
+ assert_nil(cache.get(:my_nonexistant_object))
69
+ end
70
+ end
71
+
72
+ def test_should_be_able_to_use_an_array_as_a_cache_key
73
+ @caches.each do |cache|
74
+ assert_equal("Array", cache.put([123,234], "Array"))
75
+ assert_equal("Array", cache.get([123,234]))
76
+ end
77
+ end
78
+
79
+ def test_passing_a_block_to_the_get_method_should_substitute_result_of_block_as_value_for_given_key
80
+ @caches.each do |cache|
81
+ cache.put("block_test", 1984, 0)
82
+ assert_equal(2001, cache.get("block_test") { 2001 })
83
+ assert_equal(2001, cache.get("block_test"))
84
+ end
85
+ end
86
+
87
+ def test_passing_block_to_get_should_add_result_of_callback_when_there_is_no_existing_value
88
+ @caches.each do |cache|
89
+ assert_equal(nil, cache.get("new_key_with_block"))
90
+ assert_equal("Nicholas", cache.get("new_key_with_block") { "Nicholas" })
91
+ end
92
+ end
93
+
94
+ def test_is_able_to_specify_default_timeout_when_creating_an_instance
95
+ cache = TimedCache.new(:default_timeout => 20)
96
+ assert_equal(20, cache.default_timeout)
97
+ end
98
+
99
+ def test_if_no_default_timeout_is_set_60_seconds_should_be_used
100
+ cache = TimedCache.new
101
+ assert_equal(60, cache.default_timeout)
102
+ end
103
+
104
+ def test_timeout_specified_when_putting_a_new_object_into_the_cache_should_override_default_timeout
105
+ cache = TimedCache.new(:default_timeout => 20)
106
+ assert_equal(20, cache.default_timeout)
107
+ cache.put("alternative_timeout", "2 minutes", 120)
108
+
109
+ timeout = cache.instance_variable_get(:@store).
110
+ instance_variable_get(:@cache)["alternative_timeout"].
111
+ instance_variable_get(:@timeout)
112
+
113
+ assert_equal(120, timeout)
114
+ end
115
+ end
@@ -0,0 +1,15 @@
1
+ require 'timedcache/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "timedcache"
5
+ s.version = TimedCache::VERSION
6
+ s.summary = %q{TimedCache implements a cache in which you can place objects and specify a timeout value.}
7
+ s.description = %q{TimedCache implements a cache in which you can place objects and specify a timeout value. If you attempt to retrieve the object within the specified timeout, the object will be returned. If the timeout period has elapsed, the TimedCache will return nil.}
8
+ s.files = Dir['**/*']
9
+ s.authors = ["Nicholas Dainty"]
10
+ s.email = "nick@npad.co.uk"
11
+ s.homepage = "http://timedcache.rubyforge.org/"
12
+ s.has_rdoc = true
13
+ s.rdoc_options = ["--charset=UTF-8", "--line-numbers", "--inline-source"]
14
+ s.required_ruby_version = '>= 1.8.6'
15
+ end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timedcache
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.3"
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Nicholas Dainty
@@ -9,64 +15,66 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-03-28 23:00:00 +00:00
18
+ date: 2011-03-24 00:00:00 +00:00
13
19
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: hoe
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 1.8.2
24
- version:
25
- description: TimedCache implements a cache in which you can place objects and specify a timeout value. If you attempt to retrieve the object within the specified timeout period, the object will be returned. If the timeout period has elapsed, the TimedCache will return nil.
20
+ dependencies: []
21
+
22
+ description: TimedCache implements a cache in which you can place objects and specify a timeout value. If you attempt to retrieve the object within the specified timeout, the object will be returned. If the timeout period has elapsed, the TimedCache will return nil.
26
23
  email: nick@npad.co.uk
27
24
  executables: []
28
25
 
29
26
  extensions: []
30
27
 
31
- extra_rdoc_files:
32
- - History.txt
33
- - Manifest.txt
34
- - README.txt
28
+ extra_rdoc_files: []
29
+
35
30
  files:
36
31
  - History.txt
37
- - Manifest.txt
38
- - README.txt
39
- - Rakefile
40
32
  - lib/timed_cache.rb
33
+ - lib/timedcache/version.rb
41
34
  - lib/timedcache.rb
35
+ - Manifest.txt
42
36
  - misc/thread_test.rb
43
- - spec/timed_cache_spec.rb
37
+ - Rakefile
38
+ - README.txt
39
+ - test/test_timed_cache.rb
40
+ - timedcache.gemspec
44
41
  has_rdoc: true
45
- homepage:
42
+ homepage: http://timedcache.rubyforge.org/
43
+ licenses: []
44
+
46
45
  post_install_message:
47
46
  rdoc_options:
48
- - --main
49
- - README.txt
47
+ - --charset=UTF-8
48
+ - --line-numbers
49
+ - --inline-source
50
50
  require_paths:
51
51
  - lib
52
52
  required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
53
54
  requirements:
54
55
  - - ">="
55
56
  - !ruby/object:Gem::Version
56
- version: "0"
57
- version:
57
+ hash: 59
58
+ segments:
59
+ - 1
60
+ - 8
61
+ - 6
62
+ version: 1.8.6
58
63
  required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
59
65
  requirements:
60
66
  - - ">="
61
67
  - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
62
71
  version: "0"
63
- version:
64
72
  requirements: []
65
73
 
66
- rubyforge_project: timedcache
67
- rubygems_version: 1.3.1
74
+ rubyforge_project:
75
+ rubygems_version: 1.5.3
68
76
  signing_key:
69
- specification_version: 2
70
- summary: A very simple time-based object cache.
77
+ specification_version: 3
78
+ summary: TimedCache implements a cache in which you can place objects and specify a timeout value.
71
79
  test_files: []
72
80
 
@@ -1,102 +0,0 @@
1
- require File.join(File.dirname(__FILE__), "../lib/timedcache")
2
-
3
- $filename = File.join(File.dirname(__FILE__), "specs.db")
4
-
5
- describe "Adding and retrieving objects from the cache" do
6
- before(:each) do
7
- @memory_cache = TimedCache.new
8
- @file_cache = TimedCache.new(:type => :file, :filename => $filename)
9
- @caches = [@memory_cache, @file_cache]
10
- end
11
-
12
- after do
13
- File.delete($filename)
14
- end
15
-
16
- it "Can add an object to the cache, specifying a timeout value" do
17
- @caches.each do |cache|
18
- cache.put(:myobject, "This needs caching", 10).should == "This needs caching"
19
- end
20
- end
21
-
22
- it "Cache should hold seperate values for each key" do
23
- @caches.each do |cache|
24
- cache.put(:myobject, "This needs caching", 10).should == "This needs caching"
25
- cache.put(:my_other_object, "...and this too", 10).should == "...and this too"
26
- cache.get(:myobject).should == "This needs caching"
27
- cache.get(:my_other_object).should == "...and this too"
28
- end
29
- end
30
-
31
- it "String and symbol keys are not treated as equivalent" do
32
- @caches.each do |cache|
33
- cache[:symbolkey] = "Referenced by symbol"
34
- cache["stringkey"] = "Referenced by string"
35
-
36
- cache[:symbolkey].should == "Referenced by symbol"
37
- cache["symbolkey"].should == nil
38
-
39
- cache["stringkey"].should == "Referenced by string"
40
- cache[:stringkey].should == nil
41
- end
42
- end
43
-
44
- it "After the specified timeout value has elapsed, nil should be returned" do
45
- @caches.each do |cache|
46
- cache.put(:myobject, "This needs caching", 0).should == "This needs caching"
47
- cache.get(:myobject).should == nil
48
- end
49
- end
50
-
51
- it "If no object matching the given key is found, nil should be returned" do
52
- @caches.each do |cache|
53
- cache.get(:my_nonexistant_object).should == nil
54
- end
55
- end
56
-
57
- it "Should be able to use an array as a cache key" do
58
- @caches.each do |cache|
59
- cache.put([123,234], "Array").should == "Array"
60
- cache.get([123,234]).should == "Array"
61
- end
62
- end
63
-
64
- it "Passing a block to the TimedCache#get method should substitute the " +
65
- "result of the block as the value for the given key" do
66
- @caches.each do |cache|
67
- cache.put("block_test", 1984, 0)
68
- cache.get("block_test") { 2001 }.should == 2001
69
- cache.get("block_test").should == 2001
70
- end
71
- end
72
-
73
- it "Passing a block to TimedCache#get should add the result of the callback " +
74
- "when there is no existing value for the key given" do
75
- @caches.each do |cache|
76
- cache.get("new_key_with_block").should == nil
77
- cache.get("new_key_with_block") { "Nicholas" }.should == "Nicholas"
78
- end
79
- end
80
- end
81
-
82
- describe "Specifying a default timeout" do
83
- it "Should be able to it a default timeout when creating a TimedCache" do
84
- cache = TimedCache.new(:default_timeout => 20)
85
- cache.should be_kind_of(TimedCache)
86
- cache.default_timeout.should == 20
87
- end
88
-
89
- it "If no default timeout is set, 60 seconds should be used" do
90
- cache = TimedCache.new
91
- cache.should be_kind_of(TimedCache)
92
- cache.default_timeout.should == 60
93
- end
94
-
95
- it "Timeout specified when putting a new object into the cache should override default timeout" do
96
- cache = TimedCache.new(:default_timeout => 20)
97
- cache.default_timeout.should == 20
98
- cache.put("alternative_timeout", "2 minutes", 120)
99
- cache.instance_variable_get(:@store).instance_variable_get(:@cache)["alternative_timeout"].
100
- instance_variable_get(:@timeout).should == 120
101
- end
102
- end