juno 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +6 -0
  3. data/Gemfile +16 -9
  4. data/README.md +92 -34
  5. data/Rakefile +23 -5
  6. data/benchmarks/run.rb +19 -22
  7. data/juno.gemspec +0 -3
  8. data/lib/juno/adapters/activerecord.rb +58 -0
  9. data/lib/juno/adapters/cassandra.rb +47 -0
  10. data/lib/juno/adapters/couch.rb +43 -0
  11. data/lib/juno/adapters/datamapper.rb +64 -0
  12. data/lib/juno/adapters/dbm.rb +17 -0
  13. data/lib/juno/adapters/file.rb +58 -0
  14. data/lib/juno/adapters/fog.rb +42 -0
  15. data/lib/juno/adapters/gdbm.rb +17 -0
  16. data/lib/juno/adapters/localmemcache.rb +18 -0
  17. data/lib/juno/adapters/memcached.rb +11 -0
  18. data/lib/juno/adapters/memcached_dalli.rb +46 -0
  19. data/lib/juno/adapters/memcached_native.rb +47 -0
  20. data/lib/juno/adapters/memory.rb +30 -0
  21. data/lib/juno/adapters/mongo.rb +43 -0
  22. data/lib/juno/adapters/null.rb +28 -0
  23. data/lib/juno/adapters/pstore.rb +51 -0
  24. data/lib/juno/adapters/redis.rb +43 -0
  25. data/lib/juno/adapters/riak.rb +46 -0
  26. data/lib/juno/adapters/sdbm.rb +27 -0
  27. data/lib/juno/adapters/sequel.rb +50 -0
  28. data/lib/juno/adapters/sqlite.rb +52 -0
  29. data/lib/juno/adapters/tokyocabinet.rb +33 -0
  30. data/lib/juno/adapters/yaml.rb +13 -0
  31. data/lib/juno/base.rb +11 -89
  32. data/lib/juno/builder.rb +30 -0
  33. data/lib/juno/cache.rb +64 -0
  34. data/lib/juno/expires.rb +6 -10
  35. data/lib/juno/proxy.rb +62 -3
  36. data/lib/juno/stack.rb +27 -11
  37. data/lib/juno/transformer.rb +106 -0
  38. data/lib/juno/version.rb +1 -1
  39. data/lib/juno.rb +81 -29
  40. data/spec/adapter_activerecord_spec.rb +41 -0
  41. data/spec/adapter_cassandra_spec.rb +27 -0
  42. data/spec/adapter_couch_spec.rb +27 -0
  43. data/spec/adapter_datamapper_spec.rb +61 -0
  44. data/spec/adapter_dbm_spec.rb +27 -0
  45. data/spec/adapter_file_spec.rb +27 -0
  46. data/spec/adapter_fog_spec.rb +35 -0
  47. data/spec/adapter_gdbm_spec.rb +27 -0
  48. data/spec/adapter_localmemcache_spec.rb +27 -0
  49. data/spec/adapter_memcached_dalli_spec.rb +28 -0
  50. data/spec/adapter_memcached_native_spec.rb +28 -0
  51. data/spec/adapter_memcached_spec.rb +28 -0
  52. data/spec/adapter_memory_spec.rb +42 -0
  53. data/spec/adapter_mongo_spec.rb +27 -0
  54. data/spec/adapter_pstore_spec.rb +30 -0
  55. data/spec/adapter_redis_spec.rb +28 -0
  56. data/spec/adapter_riak_spec.rb +31 -0
  57. data/spec/adapter_sdbm_spec.rb +27 -0
  58. data/spec/adapter_sequel_spec.rb +27 -0
  59. data/spec/adapter_sqlite_spec.rb +27 -0
  60. data/spec/adapter_tokyocabinet_spec.rb +27 -0
  61. data/spec/adapter_yaml_spec.rb +30 -0
  62. data/spec/cache_file_memory_spec.rb +50 -0
  63. data/spec/cache_memory_null_spec.rb +39 -0
  64. data/spec/expires_file_spec.rb +82 -0
  65. data/spec/expires_memory_spec.rb +59 -0
  66. data/spec/generate.rb +736 -0
  67. data/spec/helper.rb +39 -0
  68. data/spec/junospecs.rb +1540 -0
  69. data/spec/null_adapter_spec.rb +33 -0
  70. data/spec/proxy_expires_memory_spec.rb +63 -0
  71. data/spec/proxy_redis_spec.rb +38 -0
  72. data/spec/simple_activerecord_spec.rb +52 -0
  73. data/spec/simple_cassandra_spec.rb +53 -0
  74. data/spec/simple_couch_spec.rb +52 -0
  75. data/spec/simple_datamapper_spec.rb +54 -0
  76. data/spec/simple_datamapper_with_repository_spec.rb +54 -0
  77. data/spec/simple_dbm_spec.rb +52 -0
  78. data/spec/simple_file_spec.rb +52 -0
  79. data/spec/simple_fog_spec.rb +60 -0
  80. data/spec/simple_gdbm_spec.rb +52 -0
  81. data/spec/simple_hashfile_spec.rb +52 -0
  82. data/spec/simple_localmemcache_spec.rb +52 -0
  83. data/spec/simple_memcached_dalli_spec.rb +53 -0
  84. data/spec/simple_memcached_native_spec.rb +53 -0
  85. data/spec/simple_memcached_spec.rb +53 -0
  86. data/spec/simple_memory_spec.rb +52 -0
  87. data/spec/simple_mongo_spec.rb +52 -0
  88. data/spec/simple_null_spec.rb +43 -0
  89. data/spec/simple_pstore_spec.rb +52 -0
  90. data/spec/simple_redis_spec.rb +53 -0
  91. data/spec/simple_riak_spec.rb +56 -0
  92. data/spec/simple_sdbm_spec.rb +52 -0
  93. data/spec/simple_sequel_spec.rb +52 -0
  94. data/spec/simple_sqlite_spec.rb +52 -0
  95. data/spec/simple_tokyocabinet_spec.rb +52 -0
  96. data/spec/simple_yaml_spec.rb +52 -0
  97. data/spec/stack_file_memory_spec.rb +43 -0
  98. data/spec/stack_memory_file_spec.rb +42 -0
  99. data/spec/transformer_bson_spec.rb +44 -0
  100. data/spec/transformer_json_spec.rb +44 -0
  101. data/spec/transformer_marshal_base64_spec.rb +60 -0
  102. data/spec/transformer_marshal_escape_spec.rb +60 -0
  103. data/spec/transformer_marshal_md5_spec.rb +60 -0
  104. data/spec/transformer_marshal_md5_spread_spec.rb +60 -0
  105. data/spec/transformer_msgpack_spec.rb +44 -0
  106. data/spec/transformer_yaml_spec.rb +59 -0
  107. metadata +164 -108
  108. data/lib/juno/activerecord.rb +0 -55
  109. data/lib/juno/cassandra.rb +0 -45
  110. data/lib/juno/couch.rb +0 -43
  111. data/lib/juno/datamapper.rb +0 -63
  112. data/lib/juno/dbm.rb +0 -15
  113. data/lib/juno/file.rb +0 -62
  114. data/lib/juno/fog.rb +0 -48
  115. data/lib/juno/gdbm.rb +0 -15
  116. data/lib/juno/hashfile.rb +0 -12
  117. data/lib/juno/localmemcache.rb +0 -16
  118. data/lib/juno/memcached.rb +0 -7
  119. data/lib/juno/memcached_dalli.rb +0 -55
  120. data/lib/juno/memcached_native.rb +0 -56
  121. data/lib/juno/memory.rb +0 -7
  122. data/lib/juno/mongodb.rb +0 -43
  123. data/lib/juno/null.rb +0 -23
  124. data/lib/juno/pstore.rb +0 -49
  125. data/lib/juno/redis.rb +0 -46
  126. data/lib/juno/riak.rb +0 -45
  127. data/lib/juno/sdbm.rb +0 -15
  128. data/lib/juno/sequel.rb +0 -48
  129. data/lib/juno/sqlite.rb +0 -50
  130. data/lib/juno/tokyocabinet.rb +0 -36
  131. data/lib/juno/yaml.rb +0 -9
  132. data/test/helper.rb +0 -212
  133. data/test/test_activerecord.rb +0 -33
  134. data/test/test_cassandra.rb +0 -13
  135. data/test/test_couch.rb +0 -13
  136. data/test/test_datamapper.rb +0 -64
  137. data/test/test_dbm.rb +0 -13
  138. data/test/test_expires.rb +0 -9
  139. data/test/test_file.rb +0 -9
  140. data/test/test_fog.rb +0 -17
  141. data/test/test_gdbm.rb +0 -13
  142. data/test/test_hashfile.rb +0 -9
  143. data/test/test_localmemcache.rb +0 -13
  144. data/test/test_memcached.rb +0 -14
  145. data/test/test_memcached_dalli.rb +0 -14
  146. data/test/test_memcached_native.rb +0 -14
  147. data/test/test_memory.rb +0 -9
  148. data/test/test_mongodb.rb +0 -13
  149. data/test/test_null.rb +0 -9
  150. data/test/test_proxy.rb +0 -9
  151. data/test/test_pstore.rb +0 -9
  152. data/test/test_redis.rb +0 -13
  153. data/test/test_riak.rb +0 -13
  154. data/test/test_sdbm.rb +0 -13
  155. data/test/test_sequel.rb +0 -13
  156. data/test/test_sqlite.rb +0 -13
  157. data/test/test_stack.rb +0 -10
  158. data/test/test_tokyocabinet.rb +0 -13
  159. data/test/test_yaml.rb +0 -9
  160. data/unsupported/test_tokyotyrant.rb +0 -13
  161. data/unsupported/tokyotyrant.rb +0 -29
data/spec/junospecs.rb ADDED
@@ -0,0 +1,1540 @@
1
+ #################### null_stringkey_stringvalue ####################
2
+
3
+ shared_examples_for 'null_stringkey_stringvalue' do
4
+ it "reads from keys that are Strings like a Hash" do
5
+ @store["strkey1"].should == nil
6
+ @store.load("strkey1").should == nil
7
+ end
8
+
9
+ it "guarantees that the same String value is returned when setting a String key" do
10
+ value = "strval1"
11
+ (@store["strkey1"] = value).should equal(value)
12
+ end
13
+
14
+ it "returns false from key? if a String key is not available" do
15
+ @store.key?("strkey1").should == false
16
+ end
17
+
18
+ it "returns nil from delete if an element for a String key does not exist" do
19
+ @store.delete("strkey1").should == nil
20
+ end
21
+
22
+ it "removes all String keys from the store with clear" do
23
+ @store["strkey1"] = "strval1"
24
+ @store["strkey2"] = "strval2"
25
+ @store.clear.should equal(@store)
26
+ @store.key?("strkey1").should_not == true
27
+ @store.key?("strkey2").should_not == true
28
+ end
29
+
30
+ it "fetches a String key with a default value with fetch, if the key is not available" do
31
+ @store.fetch("strkey1", "strval1").should == "strval1"
32
+ end
33
+
34
+ it "fetches a String key with a block with fetch, if the key is not available" do
35
+ key = "strkey1"
36
+ value = "strval1"
37
+ @store.fetch(key) do |k|
38
+ k.should equal(key)
39
+ value
40
+ end.should equal(value)
41
+ end
42
+
43
+ it 'should accept options' do
44
+ @store.key?("strkey1", :option1 => 1).should == false
45
+ @store.load("strkey1", :option2 => 2).should == nil
46
+ @store.fetch("strkey1", nil, :option3 => 3).should == nil
47
+ @store.delete("strkey1", :option4 => 4).should == nil
48
+ @store.clear(:option5 => 5).should equal(@store)
49
+ @store.store("strkey1", "strval1", :option6 => 6).should == "strval1"
50
+ end
51
+ end
52
+
53
+ #################### store_stringkey_stringvalue ####################
54
+
55
+ shared_examples_for 'store_stringkey_stringvalue' do
56
+ it "writes String values to keys that are Strings like a Hash" do
57
+ @store["strkey1"] = "strval1"
58
+ @store["strkey1"].should == "strval1"
59
+ @store.load("strkey1").should == "strval1"
60
+ end
61
+
62
+ it "returns true from key? if a String key is available" do
63
+ @store["strkey1"] = "strval1"
64
+ @store.key?("strkey1").should == true
65
+ end
66
+
67
+ it "stores String values with String keys with #store" do
68
+ value = "strval1"
69
+ @store.store("strkey1", value).should equal(value)
70
+ @store["strkey1"].should == "strval1"
71
+ @store.load("strkey1").should == "strval1"
72
+ end
73
+
74
+ it "removes and returns a String element with a String key from the backing store via delete if it exists" do
75
+ @store["strkey1"] = "strval1"
76
+ @store.delete("strkey1").should == "strval1"
77
+ @store.key?("strkey1").should == false
78
+ end
79
+
80
+ it "does not run the block if the String key is available" do
81
+ @store["strkey1"] = "strval1"
82
+ unaltered = "unaltered"
83
+ @store.fetch("strkey1") { unaltered = "altered" }
84
+ unaltered.should == "unaltered"
85
+ end
86
+
87
+ it "fetches a String key with a default value with fetch, if the key is available" do
88
+ @store["strkey1"] = "strval1"
89
+ @store.fetch("strkey1", "strval2").should == "strval1"
90
+ end
91
+ end
92
+
93
+ #################### returndifferent_stringkey_stringvalue ####################
94
+
95
+ shared_examples_for 'returndifferent_stringkey_stringvalue' do
96
+ it "guarantees that a different String value is retrieved from the String key" do
97
+ value = "strval1"
98
+ @store["strkey1"] = "strval1"
99
+ @store["strkey1"].should_not be_equal("strval1")
100
+ end
101
+ end
102
+
103
+ #################### expires_stringkey_stringvalue ####################
104
+
105
+ shared_examples_for 'expires_stringkey_stringvalue' do
106
+ it 'should support expires on store and #[]' do
107
+ @store.store("strkey1", "strval1", :expires => 2)
108
+ @store["strkey1"].should == "strval1"
109
+ sleep 1
110
+ @store["strkey1"].should == "strval1"
111
+ sleep 2
112
+ @store["strkey1"].should == nil
113
+ end
114
+
115
+ it 'should support expires on store and load' do
116
+ @store.store("strkey1", "strval1", :expires => 2)
117
+ @store.load("strkey1").should == "strval1"
118
+ sleep 1
119
+ @store.load("strkey1").should == "strval1"
120
+ sleep 2
121
+ @store.load("strkey1").should == nil
122
+ end
123
+
124
+ it 'should support expires on store and key?' do
125
+ @store.store("strkey1", "strval1", :expires => 2)
126
+ @store.key?("strkey1").should == true
127
+ sleep 1
128
+ @store.key?("strkey1").should == true
129
+ sleep 2
130
+ @store.key?("strkey1").should == false
131
+ end
132
+
133
+ it 'should support updating the expiration time in load' do
134
+ @store.store("strkey2", "strval2", :expires => 2)
135
+ @store["strkey2"].should == "strval2"
136
+ sleep 1
137
+ @store.load("strkey2", :expires => 3).should == "strval2"
138
+ @store["strkey2"].should == "strval2"
139
+ sleep 1
140
+ @store["strkey2"].should == "strval2"
141
+ sleep 3
142
+ @store["strkey2"].should == nil
143
+ end
144
+
145
+ it 'should support updating the expiration time in fetch' do
146
+ @store.store("strkey1", "strval1", :expires => 2)
147
+ @store["strkey1"].should == "strval1"
148
+ sleep 1
149
+ @store.fetch("strkey1", nil, :expires => 3).should == "strval1"
150
+ @store["strkey1"].should == "strval1"
151
+ sleep 1
152
+ @store["strkey1"].should == "strval1"
153
+ sleep 3
154
+ @store["strkey1"].should == nil
155
+ end
156
+
157
+ it 'should respect expires in delete' do
158
+ @store.store("strkey2", "strval2", :expires => 2)
159
+ @store["strkey2"].should == "strval2"
160
+ sleep 1
161
+ @store["strkey2"].should == "strval2"
162
+ sleep 2
163
+ @store.delete("strkey2").should == nil
164
+ end
165
+ end
166
+
167
+ #################### null_stringkey_objectvalue ####################
168
+
169
+ shared_examples_for 'null_stringkey_objectvalue' do
170
+ it "reads from keys that are Strings like a Hash" do
171
+ @store["strkey1"].should == nil
172
+ @store.load("strkey1").should == nil
173
+ end
174
+
175
+ it "guarantees that the same Object value is returned when setting a String key" do
176
+ value = Value.new(:objval1)
177
+ (@store["strkey1"] = value).should equal(value)
178
+ end
179
+
180
+ it "returns false from key? if a String key is not available" do
181
+ @store.key?("strkey1").should == false
182
+ end
183
+
184
+ it "returns nil from delete if an element for a String key does not exist" do
185
+ @store.delete("strkey1").should == nil
186
+ end
187
+
188
+ it "removes all String keys from the store with clear" do
189
+ @store["strkey1"] = Value.new(:objval1)
190
+ @store["strkey2"] = Value.new(:objval2)
191
+ @store.clear.should equal(@store)
192
+ @store.key?("strkey1").should_not == true
193
+ @store.key?("strkey2").should_not == true
194
+ end
195
+
196
+ it "fetches a String key with a default value with fetch, if the key is not available" do
197
+ @store.fetch("strkey1", Value.new(:objval1)).should == Value.new(:objval1)
198
+ end
199
+
200
+ it "fetches a String key with a block with fetch, if the key is not available" do
201
+ key = "strkey1"
202
+ value = Value.new(:objval1)
203
+ @store.fetch(key) do |k|
204
+ k.should equal(key)
205
+ value
206
+ end.should equal(value)
207
+ end
208
+
209
+ it 'should accept options' do
210
+ @store.key?("strkey1", :option1 => 1).should == false
211
+ @store.load("strkey1", :option2 => 2).should == nil
212
+ @store.fetch("strkey1", nil, :option3 => 3).should == nil
213
+ @store.delete("strkey1", :option4 => 4).should == nil
214
+ @store.clear(:option5 => 5).should equal(@store)
215
+ @store.store("strkey1", Value.new(:objval1), :option6 => 6).should == Value.new(:objval1)
216
+ end
217
+ end
218
+
219
+ #################### store_stringkey_objectvalue ####################
220
+
221
+ shared_examples_for 'store_stringkey_objectvalue' do
222
+ it "writes Object values to keys that are Strings like a Hash" do
223
+ @store["strkey1"] = Value.new(:objval1)
224
+ @store["strkey1"].should == Value.new(:objval1)
225
+ @store.load("strkey1").should == Value.new(:objval1)
226
+ end
227
+
228
+ it "returns true from key? if a String key is available" do
229
+ @store["strkey1"] = Value.new(:objval1)
230
+ @store.key?("strkey1").should == true
231
+ end
232
+
233
+ it "stores Object values with String keys with #store" do
234
+ value = Value.new(:objval1)
235
+ @store.store("strkey1", value).should equal(value)
236
+ @store["strkey1"].should == Value.new(:objval1)
237
+ @store.load("strkey1").should == Value.new(:objval1)
238
+ end
239
+
240
+ it "removes and returns a Object element with a String key from the backing store via delete if it exists" do
241
+ @store["strkey1"] = Value.new(:objval1)
242
+ @store.delete("strkey1").should == Value.new(:objval1)
243
+ @store.key?("strkey1").should == false
244
+ end
245
+
246
+ it "does not run the block if the String key is available" do
247
+ @store["strkey1"] = Value.new(:objval1)
248
+ unaltered = "unaltered"
249
+ @store.fetch("strkey1") { unaltered = "altered" }
250
+ unaltered.should == "unaltered"
251
+ end
252
+
253
+ it "fetches a String key with a default value with fetch, if the key is available" do
254
+ @store["strkey1"] = Value.new(:objval1)
255
+ @store.fetch("strkey1", Value.new(:objval2)).should == Value.new(:objval1)
256
+ end
257
+ end
258
+
259
+ #################### returndifferent_stringkey_objectvalue ####################
260
+
261
+ shared_examples_for 'returndifferent_stringkey_objectvalue' do
262
+ it "guarantees that a different Object value is retrieved from the String key" do
263
+ value = Value.new(:objval1)
264
+ @store["strkey1"] = Value.new(:objval1)
265
+ @store["strkey1"].should_not be_equal(Value.new(:objval1))
266
+ end
267
+ end
268
+
269
+ #################### expires_stringkey_objectvalue ####################
270
+
271
+ shared_examples_for 'expires_stringkey_objectvalue' do
272
+ it 'should support expires on store and #[]' do
273
+ @store.store("strkey1", Value.new(:objval1), :expires => 2)
274
+ @store["strkey1"].should == Value.new(:objval1)
275
+ sleep 1
276
+ @store["strkey1"].should == Value.new(:objval1)
277
+ sleep 2
278
+ @store["strkey1"].should == nil
279
+ end
280
+
281
+ it 'should support expires on store and load' do
282
+ @store.store("strkey1", Value.new(:objval1), :expires => 2)
283
+ @store.load("strkey1").should == Value.new(:objval1)
284
+ sleep 1
285
+ @store.load("strkey1").should == Value.new(:objval1)
286
+ sleep 2
287
+ @store.load("strkey1").should == nil
288
+ end
289
+
290
+ it 'should support expires on store and key?' do
291
+ @store.store("strkey1", Value.new(:objval1), :expires => 2)
292
+ @store.key?("strkey1").should == true
293
+ sleep 1
294
+ @store.key?("strkey1").should == true
295
+ sleep 2
296
+ @store.key?("strkey1").should == false
297
+ end
298
+
299
+ it 'should support updating the expiration time in load' do
300
+ @store.store("strkey2", Value.new(:objval2), :expires => 2)
301
+ @store["strkey2"].should == Value.new(:objval2)
302
+ sleep 1
303
+ @store.load("strkey2", :expires => 3).should == Value.new(:objval2)
304
+ @store["strkey2"].should == Value.new(:objval2)
305
+ sleep 1
306
+ @store["strkey2"].should == Value.new(:objval2)
307
+ sleep 3
308
+ @store["strkey2"].should == nil
309
+ end
310
+
311
+ it 'should support updating the expiration time in fetch' do
312
+ @store.store("strkey1", Value.new(:objval1), :expires => 2)
313
+ @store["strkey1"].should == Value.new(:objval1)
314
+ sleep 1
315
+ @store.fetch("strkey1", nil, :expires => 3).should == Value.new(:objval1)
316
+ @store["strkey1"].should == Value.new(:objval1)
317
+ sleep 1
318
+ @store["strkey1"].should == Value.new(:objval1)
319
+ sleep 3
320
+ @store["strkey1"].should == nil
321
+ end
322
+
323
+ it 'should respect expires in delete' do
324
+ @store.store("strkey2", Value.new(:objval2), :expires => 2)
325
+ @store["strkey2"].should == Value.new(:objval2)
326
+ sleep 1
327
+ @store["strkey2"].should == Value.new(:objval2)
328
+ sleep 2
329
+ @store.delete("strkey2").should == nil
330
+ end
331
+ end
332
+
333
+ #################### null_stringkey_hashvalue ####################
334
+
335
+ shared_examples_for 'null_stringkey_hashvalue' do
336
+ it "reads from keys that are Strings like a Hash" do
337
+ @store["strkey1"].should == nil
338
+ @store.load("strkey1").should == nil
339
+ end
340
+
341
+ it "guarantees that the same Hash value is returned when setting a String key" do
342
+ value = {"hashval1"=>"hashval2"}
343
+ (@store["strkey1"] = value).should equal(value)
344
+ end
345
+
346
+ it "returns false from key? if a String key is not available" do
347
+ @store.key?("strkey1").should == false
348
+ end
349
+
350
+ it "returns nil from delete if an element for a String key does not exist" do
351
+ @store.delete("strkey1").should == nil
352
+ end
353
+
354
+ it "removes all String keys from the store with clear" do
355
+ @store["strkey1"] = {"hashval1"=>"hashval2"}
356
+ @store["strkey2"] = {"hashval3"=>"hashval4"}
357
+ @store.clear.should equal(@store)
358
+ @store.key?("strkey1").should_not == true
359
+ @store.key?("strkey2").should_not == true
360
+ end
361
+
362
+ it "fetches a String key with a default value with fetch, if the key is not available" do
363
+ @store.fetch("strkey1", {"hashval1"=>"hashval2"}).should == {"hashval1"=>"hashval2"}
364
+ end
365
+
366
+ it "fetches a String key with a block with fetch, if the key is not available" do
367
+ key = "strkey1"
368
+ value = {"hashval1"=>"hashval2"}
369
+ @store.fetch(key) do |k|
370
+ k.should equal(key)
371
+ value
372
+ end.should equal(value)
373
+ end
374
+
375
+ it 'should accept options' do
376
+ @store.key?("strkey1", :option1 => 1).should == false
377
+ @store.load("strkey1", :option2 => 2).should == nil
378
+ @store.fetch("strkey1", nil, :option3 => 3).should == nil
379
+ @store.delete("strkey1", :option4 => 4).should == nil
380
+ @store.clear(:option5 => 5).should equal(@store)
381
+ @store.store("strkey1", {"hashval1"=>"hashval2"}, :option6 => 6).should == {"hashval1"=>"hashval2"}
382
+ end
383
+ end
384
+
385
+ #################### store_stringkey_hashvalue ####################
386
+
387
+ shared_examples_for 'store_stringkey_hashvalue' do
388
+ it "writes Hash values to keys that are Strings like a Hash" do
389
+ @store["strkey1"] = {"hashval1"=>"hashval2"}
390
+ @store["strkey1"].should == {"hashval1"=>"hashval2"}
391
+ @store.load("strkey1").should == {"hashval1"=>"hashval2"}
392
+ end
393
+
394
+ it "returns true from key? if a String key is available" do
395
+ @store["strkey1"] = {"hashval1"=>"hashval2"}
396
+ @store.key?("strkey1").should == true
397
+ end
398
+
399
+ it "stores Hash values with String keys with #store" do
400
+ value = {"hashval1"=>"hashval2"}
401
+ @store.store("strkey1", value).should equal(value)
402
+ @store["strkey1"].should == {"hashval1"=>"hashval2"}
403
+ @store.load("strkey1").should == {"hashval1"=>"hashval2"}
404
+ end
405
+
406
+ it "removes and returns a Hash element with a String key from the backing store via delete if it exists" do
407
+ @store["strkey1"] = {"hashval1"=>"hashval2"}
408
+ @store.delete("strkey1").should == {"hashval1"=>"hashval2"}
409
+ @store.key?("strkey1").should == false
410
+ end
411
+
412
+ it "does not run the block if the String key is available" do
413
+ @store["strkey1"] = {"hashval1"=>"hashval2"}
414
+ unaltered = "unaltered"
415
+ @store.fetch("strkey1") { unaltered = "altered" }
416
+ unaltered.should == "unaltered"
417
+ end
418
+
419
+ it "fetches a String key with a default value with fetch, if the key is available" do
420
+ @store["strkey1"] = {"hashval1"=>"hashval2"}
421
+ @store.fetch("strkey1", {"hashval3"=>"hashval4"}).should == {"hashval1"=>"hashval2"}
422
+ end
423
+ end
424
+
425
+ #################### returndifferent_stringkey_hashvalue ####################
426
+
427
+ shared_examples_for 'returndifferent_stringkey_hashvalue' do
428
+ it "guarantees that a different Hash value is retrieved from the String key" do
429
+ value = {"hashval1"=>"hashval2"}
430
+ @store["strkey1"] = {"hashval1"=>"hashval2"}
431
+ @store["strkey1"].should_not be_equal({"hashval1"=>"hashval2"})
432
+ end
433
+ end
434
+
435
+ #################### expires_stringkey_hashvalue ####################
436
+
437
+ shared_examples_for 'expires_stringkey_hashvalue' do
438
+ it 'should support expires on store and #[]' do
439
+ @store.store("strkey1", {"hashval1"=>"hashval2"}, :expires => 2)
440
+ @store["strkey1"].should == {"hashval1"=>"hashval2"}
441
+ sleep 1
442
+ @store["strkey1"].should == {"hashval1"=>"hashval2"}
443
+ sleep 2
444
+ @store["strkey1"].should == nil
445
+ end
446
+
447
+ it 'should support expires on store and load' do
448
+ @store.store("strkey1", {"hashval1"=>"hashval2"}, :expires => 2)
449
+ @store.load("strkey1").should == {"hashval1"=>"hashval2"}
450
+ sleep 1
451
+ @store.load("strkey1").should == {"hashval1"=>"hashval2"}
452
+ sleep 2
453
+ @store.load("strkey1").should == nil
454
+ end
455
+
456
+ it 'should support expires on store and key?' do
457
+ @store.store("strkey1", {"hashval1"=>"hashval2"}, :expires => 2)
458
+ @store.key?("strkey1").should == true
459
+ sleep 1
460
+ @store.key?("strkey1").should == true
461
+ sleep 2
462
+ @store.key?("strkey1").should == false
463
+ end
464
+
465
+ it 'should support updating the expiration time in load' do
466
+ @store.store("strkey2", {"hashval3"=>"hashval4"}, :expires => 2)
467
+ @store["strkey2"].should == {"hashval3"=>"hashval4"}
468
+ sleep 1
469
+ @store.load("strkey2", :expires => 3).should == {"hashval3"=>"hashval4"}
470
+ @store["strkey2"].should == {"hashval3"=>"hashval4"}
471
+ sleep 1
472
+ @store["strkey2"].should == {"hashval3"=>"hashval4"}
473
+ sleep 3
474
+ @store["strkey2"].should == nil
475
+ end
476
+
477
+ it 'should support updating the expiration time in fetch' do
478
+ @store.store("strkey1", {"hashval1"=>"hashval2"}, :expires => 2)
479
+ @store["strkey1"].should == {"hashval1"=>"hashval2"}
480
+ sleep 1
481
+ @store.fetch("strkey1", nil, :expires => 3).should == {"hashval1"=>"hashval2"}
482
+ @store["strkey1"].should == {"hashval1"=>"hashval2"}
483
+ sleep 1
484
+ @store["strkey1"].should == {"hashval1"=>"hashval2"}
485
+ sleep 3
486
+ @store["strkey1"].should == nil
487
+ end
488
+
489
+ it 'should respect expires in delete' do
490
+ @store.store("strkey2", {"hashval3"=>"hashval4"}, :expires => 2)
491
+ @store["strkey2"].should == {"hashval3"=>"hashval4"}
492
+ sleep 1
493
+ @store["strkey2"].should == {"hashval3"=>"hashval4"}
494
+ sleep 2
495
+ @store.delete("strkey2").should == nil
496
+ end
497
+ end
498
+
499
+ #################### null_objectkey_stringvalue ####################
500
+
501
+ shared_examples_for 'null_objectkey_stringvalue' do
502
+ it "reads from keys that are Objects like a Hash" do
503
+ @store[Value.new(:objkey1)].should == nil
504
+ @store.load(Value.new(:objkey1)).should == nil
505
+ end
506
+
507
+ it "guarantees that the same String value is returned when setting a Object key" do
508
+ value = "strval1"
509
+ (@store[Value.new(:objkey1)] = value).should equal(value)
510
+ end
511
+
512
+ it "returns false from key? if a Object key is not available" do
513
+ @store.key?(Value.new(:objkey1)).should == false
514
+ end
515
+
516
+ it "returns nil from delete if an element for a Object key does not exist" do
517
+ @store.delete(Value.new(:objkey1)).should == nil
518
+ end
519
+
520
+ it "removes all Object keys from the store with clear" do
521
+ @store[Value.new(:objkey1)] = "strval1"
522
+ @store[Value.new(:objkey2)] = "strval2"
523
+ @store.clear.should equal(@store)
524
+ @store.key?(Value.new(:objkey1)).should_not == true
525
+ @store.key?(Value.new(:objkey2)).should_not == true
526
+ end
527
+
528
+ it "fetches a Object key with a default value with fetch, if the key is not available" do
529
+ @store.fetch(Value.new(:objkey1), "strval1").should == "strval1"
530
+ end
531
+
532
+ it "fetches a Object key with a block with fetch, if the key is not available" do
533
+ key = Value.new(:objkey1)
534
+ value = "strval1"
535
+ @store.fetch(key) do |k|
536
+ k.should equal(key)
537
+ value
538
+ end.should equal(value)
539
+ end
540
+
541
+ it 'should accept options' do
542
+ @store.key?(Value.new(:objkey1), :option1 => 1).should == false
543
+ @store.load(Value.new(:objkey1), :option2 => 2).should == nil
544
+ @store.fetch(Value.new(:objkey1), nil, :option3 => 3).should == nil
545
+ @store.delete(Value.new(:objkey1), :option4 => 4).should == nil
546
+ @store.clear(:option5 => 5).should equal(@store)
547
+ @store.store(Value.new(:objkey1), "strval1", :option6 => 6).should == "strval1"
548
+ end
549
+ end
550
+
551
+ #################### store_objectkey_stringvalue ####################
552
+
553
+ shared_examples_for 'store_objectkey_stringvalue' do
554
+ it "writes String values to keys that are Objects like a Hash" do
555
+ @store[Value.new(:objkey1)] = "strval1"
556
+ @store[Value.new(:objkey1)].should == "strval1"
557
+ @store.load(Value.new(:objkey1)).should == "strval1"
558
+ end
559
+
560
+ it "returns true from key? if a Object key is available" do
561
+ @store[Value.new(:objkey1)] = "strval1"
562
+ @store.key?(Value.new(:objkey1)).should == true
563
+ end
564
+
565
+ it "stores String values with Object keys with #store" do
566
+ value = "strval1"
567
+ @store.store(Value.new(:objkey1), value).should equal(value)
568
+ @store[Value.new(:objkey1)].should == "strval1"
569
+ @store.load(Value.new(:objkey1)).should == "strval1"
570
+ end
571
+
572
+ it "removes and returns a String element with a Object key from the backing store via delete if it exists" do
573
+ @store[Value.new(:objkey1)] = "strval1"
574
+ @store.delete(Value.new(:objkey1)).should == "strval1"
575
+ @store.key?(Value.new(:objkey1)).should == false
576
+ end
577
+
578
+ it "does not run the block if the Object key is available" do
579
+ @store[Value.new(:objkey1)] = "strval1"
580
+ unaltered = "unaltered"
581
+ @store.fetch(Value.new(:objkey1)) { unaltered = "altered" }
582
+ unaltered.should == "unaltered"
583
+ end
584
+
585
+ it "fetches a Object key with a default value with fetch, if the key is available" do
586
+ @store[Value.new(:objkey1)] = "strval1"
587
+ @store.fetch(Value.new(:objkey1), "strval2").should == "strval1"
588
+ end
589
+ end
590
+
591
+ #################### returndifferent_objectkey_stringvalue ####################
592
+
593
+ shared_examples_for 'returndifferent_objectkey_stringvalue' do
594
+ it "guarantees that a different String value is retrieved from the Object key" do
595
+ value = "strval1"
596
+ @store[Value.new(:objkey1)] = "strval1"
597
+ @store[Value.new(:objkey1)].should_not be_equal("strval1")
598
+ end
599
+ end
600
+
601
+ #################### expires_objectkey_stringvalue ####################
602
+
603
+ shared_examples_for 'expires_objectkey_stringvalue' do
604
+ it 'should support expires on store and #[]' do
605
+ @store.store(Value.new(:objkey1), "strval1", :expires => 2)
606
+ @store[Value.new(:objkey1)].should == "strval1"
607
+ sleep 1
608
+ @store[Value.new(:objkey1)].should == "strval1"
609
+ sleep 2
610
+ @store[Value.new(:objkey1)].should == nil
611
+ end
612
+
613
+ it 'should support expires on store and load' do
614
+ @store.store(Value.new(:objkey1), "strval1", :expires => 2)
615
+ @store.load(Value.new(:objkey1)).should == "strval1"
616
+ sleep 1
617
+ @store.load(Value.new(:objkey1)).should == "strval1"
618
+ sleep 2
619
+ @store.load(Value.new(:objkey1)).should == nil
620
+ end
621
+
622
+ it 'should support expires on store and key?' do
623
+ @store.store(Value.new(:objkey1), "strval1", :expires => 2)
624
+ @store.key?(Value.new(:objkey1)).should == true
625
+ sleep 1
626
+ @store.key?(Value.new(:objkey1)).should == true
627
+ sleep 2
628
+ @store.key?(Value.new(:objkey1)).should == false
629
+ end
630
+
631
+ it 'should support updating the expiration time in load' do
632
+ @store.store(Value.new(:objkey2), "strval2", :expires => 2)
633
+ @store[Value.new(:objkey2)].should == "strval2"
634
+ sleep 1
635
+ @store.load(Value.new(:objkey2), :expires => 3).should == "strval2"
636
+ @store[Value.new(:objkey2)].should == "strval2"
637
+ sleep 1
638
+ @store[Value.new(:objkey2)].should == "strval2"
639
+ sleep 3
640
+ @store[Value.new(:objkey2)].should == nil
641
+ end
642
+
643
+ it 'should support updating the expiration time in fetch' do
644
+ @store.store(Value.new(:objkey1), "strval1", :expires => 2)
645
+ @store[Value.new(:objkey1)].should == "strval1"
646
+ sleep 1
647
+ @store.fetch(Value.new(:objkey1), nil, :expires => 3).should == "strval1"
648
+ @store[Value.new(:objkey1)].should == "strval1"
649
+ sleep 1
650
+ @store[Value.new(:objkey1)].should == "strval1"
651
+ sleep 3
652
+ @store[Value.new(:objkey1)].should == nil
653
+ end
654
+
655
+ it 'should respect expires in delete' do
656
+ @store.store(Value.new(:objkey2), "strval2", :expires => 2)
657
+ @store[Value.new(:objkey2)].should == "strval2"
658
+ sleep 1
659
+ @store[Value.new(:objkey2)].should == "strval2"
660
+ sleep 2
661
+ @store.delete(Value.new(:objkey2)).should == nil
662
+ end
663
+ end
664
+
665
+ #################### null_objectkey_objectvalue ####################
666
+
667
+ shared_examples_for 'null_objectkey_objectvalue' do
668
+ it "reads from keys that are Objects like a Hash" do
669
+ @store[Value.new(:objkey1)].should == nil
670
+ @store.load(Value.new(:objkey1)).should == nil
671
+ end
672
+
673
+ it "guarantees that the same Object value is returned when setting a Object key" do
674
+ value = Value.new(:objval1)
675
+ (@store[Value.new(:objkey1)] = value).should equal(value)
676
+ end
677
+
678
+ it "returns false from key? if a Object key is not available" do
679
+ @store.key?(Value.new(:objkey1)).should == false
680
+ end
681
+
682
+ it "returns nil from delete if an element for a Object key does not exist" do
683
+ @store.delete(Value.new(:objkey1)).should == nil
684
+ end
685
+
686
+ it "removes all Object keys from the store with clear" do
687
+ @store[Value.new(:objkey1)] = Value.new(:objval1)
688
+ @store[Value.new(:objkey2)] = Value.new(:objval2)
689
+ @store.clear.should equal(@store)
690
+ @store.key?(Value.new(:objkey1)).should_not == true
691
+ @store.key?(Value.new(:objkey2)).should_not == true
692
+ end
693
+
694
+ it "fetches a Object key with a default value with fetch, if the key is not available" do
695
+ @store.fetch(Value.new(:objkey1), Value.new(:objval1)).should == Value.new(:objval1)
696
+ end
697
+
698
+ it "fetches a Object key with a block with fetch, if the key is not available" do
699
+ key = Value.new(:objkey1)
700
+ value = Value.new(:objval1)
701
+ @store.fetch(key) do |k|
702
+ k.should equal(key)
703
+ value
704
+ end.should equal(value)
705
+ end
706
+
707
+ it 'should accept options' do
708
+ @store.key?(Value.new(:objkey1), :option1 => 1).should == false
709
+ @store.load(Value.new(:objkey1), :option2 => 2).should == nil
710
+ @store.fetch(Value.new(:objkey1), nil, :option3 => 3).should == nil
711
+ @store.delete(Value.new(:objkey1), :option4 => 4).should == nil
712
+ @store.clear(:option5 => 5).should equal(@store)
713
+ @store.store(Value.new(:objkey1), Value.new(:objval1), :option6 => 6).should == Value.new(:objval1)
714
+ end
715
+ end
716
+
717
+ #################### store_objectkey_objectvalue ####################
718
+
719
+ shared_examples_for 'store_objectkey_objectvalue' do
720
+ it "writes Object values to keys that are Objects like a Hash" do
721
+ @store[Value.new(:objkey1)] = Value.new(:objval1)
722
+ @store[Value.new(:objkey1)].should == Value.new(:objval1)
723
+ @store.load(Value.new(:objkey1)).should == Value.new(:objval1)
724
+ end
725
+
726
+ it "returns true from key? if a Object key is available" do
727
+ @store[Value.new(:objkey1)] = Value.new(:objval1)
728
+ @store.key?(Value.new(:objkey1)).should == true
729
+ end
730
+
731
+ it "stores Object values with Object keys with #store" do
732
+ value = Value.new(:objval1)
733
+ @store.store(Value.new(:objkey1), value).should equal(value)
734
+ @store[Value.new(:objkey1)].should == Value.new(:objval1)
735
+ @store.load(Value.new(:objkey1)).should == Value.new(:objval1)
736
+ end
737
+
738
+ it "removes and returns a Object element with a Object key from the backing store via delete if it exists" do
739
+ @store[Value.new(:objkey1)] = Value.new(:objval1)
740
+ @store.delete(Value.new(:objkey1)).should == Value.new(:objval1)
741
+ @store.key?(Value.new(:objkey1)).should == false
742
+ end
743
+
744
+ it "does not run the block if the Object key is available" do
745
+ @store[Value.new(:objkey1)] = Value.new(:objval1)
746
+ unaltered = "unaltered"
747
+ @store.fetch(Value.new(:objkey1)) { unaltered = "altered" }
748
+ unaltered.should == "unaltered"
749
+ end
750
+
751
+ it "fetches a Object key with a default value with fetch, if the key is available" do
752
+ @store[Value.new(:objkey1)] = Value.new(:objval1)
753
+ @store.fetch(Value.new(:objkey1), Value.new(:objval2)).should == Value.new(:objval1)
754
+ end
755
+ end
756
+
757
+ #################### returndifferent_objectkey_objectvalue ####################
758
+
759
+ shared_examples_for 'returndifferent_objectkey_objectvalue' do
760
+ it "guarantees that a different Object value is retrieved from the Object key" do
761
+ value = Value.new(:objval1)
762
+ @store[Value.new(:objkey1)] = Value.new(:objval1)
763
+ @store[Value.new(:objkey1)].should_not be_equal(Value.new(:objval1))
764
+ end
765
+ end
766
+
767
+ #################### expires_objectkey_objectvalue ####################
768
+
769
+ shared_examples_for 'expires_objectkey_objectvalue' do
770
+ it 'should support expires on store and #[]' do
771
+ @store.store(Value.new(:objkey1), Value.new(:objval1), :expires => 2)
772
+ @store[Value.new(:objkey1)].should == Value.new(:objval1)
773
+ sleep 1
774
+ @store[Value.new(:objkey1)].should == Value.new(:objval1)
775
+ sleep 2
776
+ @store[Value.new(:objkey1)].should == nil
777
+ end
778
+
779
+ it 'should support expires on store and load' do
780
+ @store.store(Value.new(:objkey1), Value.new(:objval1), :expires => 2)
781
+ @store.load(Value.new(:objkey1)).should == Value.new(:objval1)
782
+ sleep 1
783
+ @store.load(Value.new(:objkey1)).should == Value.new(:objval1)
784
+ sleep 2
785
+ @store.load(Value.new(:objkey1)).should == nil
786
+ end
787
+
788
+ it 'should support expires on store and key?' do
789
+ @store.store(Value.new(:objkey1), Value.new(:objval1), :expires => 2)
790
+ @store.key?(Value.new(:objkey1)).should == true
791
+ sleep 1
792
+ @store.key?(Value.new(:objkey1)).should == true
793
+ sleep 2
794
+ @store.key?(Value.new(:objkey1)).should == false
795
+ end
796
+
797
+ it 'should support updating the expiration time in load' do
798
+ @store.store(Value.new(:objkey2), Value.new(:objval2), :expires => 2)
799
+ @store[Value.new(:objkey2)].should == Value.new(:objval2)
800
+ sleep 1
801
+ @store.load(Value.new(:objkey2), :expires => 3).should == Value.new(:objval2)
802
+ @store[Value.new(:objkey2)].should == Value.new(:objval2)
803
+ sleep 1
804
+ @store[Value.new(:objkey2)].should == Value.new(:objval2)
805
+ sleep 3
806
+ @store[Value.new(:objkey2)].should == nil
807
+ end
808
+
809
+ it 'should support updating the expiration time in fetch' do
810
+ @store.store(Value.new(:objkey1), Value.new(:objval1), :expires => 2)
811
+ @store[Value.new(:objkey1)].should == Value.new(:objval1)
812
+ sleep 1
813
+ @store.fetch(Value.new(:objkey1), nil, :expires => 3).should == Value.new(:objval1)
814
+ @store[Value.new(:objkey1)].should == Value.new(:objval1)
815
+ sleep 1
816
+ @store[Value.new(:objkey1)].should == Value.new(:objval1)
817
+ sleep 3
818
+ @store[Value.new(:objkey1)].should == nil
819
+ end
820
+
821
+ it 'should respect expires in delete' do
822
+ @store.store(Value.new(:objkey2), Value.new(:objval2), :expires => 2)
823
+ @store[Value.new(:objkey2)].should == Value.new(:objval2)
824
+ sleep 1
825
+ @store[Value.new(:objkey2)].should == Value.new(:objval2)
826
+ sleep 2
827
+ @store.delete(Value.new(:objkey2)).should == nil
828
+ end
829
+ end
830
+
831
+ #################### null_objectkey_hashvalue ####################
832
+
833
+ shared_examples_for 'null_objectkey_hashvalue' do
834
+ it "reads from keys that are Objects like a Hash" do
835
+ @store[Value.new(:objkey1)].should == nil
836
+ @store.load(Value.new(:objkey1)).should == nil
837
+ end
838
+
839
+ it "guarantees that the same Hash value is returned when setting a Object key" do
840
+ value = {"hashval1"=>"hashval2"}
841
+ (@store[Value.new(:objkey1)] = value).should equal(value)
842
+ end
843
+
844
+ it "returns false from key? if a Object key is not available" do
845
+ @store.key?(Value.new(:objkey1)).should == false
846
+ end
847
+
848
+ it "returns nil from delete if an element for a Object key does not exist" do
849
+ @store.delete(Value.new(:objkey1)).should == nil
850
+ end
851
+
852
+ it "removes all Object keys from the store with clear" do
853
+ @store[Value.new(:objkey1)] = {"hashval1"=>"hashval2"}
854
+ @store[Value.new(:objkey2)] = {"hashval3"=>"hashval4"}
855
+ @store.clear.should equal(@store)
856
+ @store.key?(Value.new(:objkey1)).should_not == true
857
+ @store.key?(Value.new(:objkey2)).should_not == true
858
+ end
859
+
860
+ it "fetches a Object key with a default value with fetch, if the key is not available" do
861
+ @store.fetch(Value.new(:objkey1), {"hashval1"=>"hashval2"}).should == {"hashval1"=>"hashval2"}
862
+ end
863
+
864
+ it "fetches a Object key with a block with fetch, if the key is not available" do
865
+ key = Value.new(:objkey1)
866
+ value = {"hashval1"=>"hashval2"}
867
+ @store.fetch(key) do |k|
868
+ k.should equal(key)
869
+ value
870
+ end.should equal(value)
871
+ end
872
+
873
+ it 'should accept options' do
874
+ @store.key?(Value.new(:objkey1), :option1 => 1).should == false
875
+ @store.load(Value.new(:objkey1), :option2 => 2).should == nil
876
+ @store.fetch(Value.new(:objkey1), nil, :option3 => 3).should == nil
877
+ @store.delete(Value.new(:objkey1), :option4 => 4).should == nil
878
+ @store.clear(:option5 => 5).should equal(@store)
879
+ @store.store(Value.new(:objkey1), {"hashval1"=>"hashval2"}, :option6 => 6).should == {"hashval1"=>"hashval2"}
880
+ end
881
+ end
882
+
883
+ #################### store_objectkey_hashvalue ####################
884
+
885
+ shared_examples_for 'store_objectkey_hashvalue' do
886
+ it "writes Hash values to keys that are Objects like a Hash" do
887
+ @store[Value.new(:objkey1)] = {"hashval1"=>"hashval2"}
888
+ @store[Value.new(:objkey1)].should == {"hashval1"=>"hashval2"}
889
+ @store.load(Value.new(:objkey1)).should == {"hashval1"=>"hashval2"}
890
+ end
891
+
892
+ it "returns true from key? if a Object key is available" do
893
+ @store[Value.new(:objkey1)] = {"hashval1"=>"hashval2"}
894
+ @store.key?(Value.new(:objkey1)).should == true
895
+ end
896
+
897
+ it "stores Hash values with Object keys with #store" do
898
+ value = {"hashval1"=>"hashval2"}
899
+ @store.store(Value.new(:objkey1), value).should equal(value)
900
+ @store[Value.new(:objkey1)].should == {"hashval1"=>"hashval2"}
901
+ @store.load(Value.new(:objkey1)).should == {"hashval1"=>"hashval2"}
902
+ end
903
+
904
+ it "removes and returns a Hash element with a Object key from the backing store via delete if it exists" do
905
+ @store[Value.new(:objkey1)] = {"hashval1"=>"hashval2"}
906
+ @store.delete(Value.new(:objkey1)).should == {"hashval1"=>"hashval2"}
907
+ @store.key?(Value.new(:objkey1)).should == false
908
+ end
909
+
910
+ it "does not run the block if the Object key is available" do
911
+ @store[Value.new(:objkey1)] = {"hashval1"=>"hashval2"}
912
+ unaltered = "unaltered"
913
+ @store.fetch(Value.new(:objkey1)) { unaltered = "altered" }
914
+ unaltered.should == "unaltered"
915
+ end
916
+
917
+ it "fetches a Object key with a default value with fetch, if the key is available" do
918
+ @store[Value.new(:objkey1)] = {"hashval1"=>"hashval2"}
919
+ @store.fetch(Value.new(:objkey1), {"hashval3"=>"hashval4"}).should == {"hashval1"=>"hashval2"}
920
+ end
921
+ end
922
+
923
+ #################### returndifferent_objectkey_hashvalue ####################
924
+
925
+ shared_examples_for 'returndifferent_objectkey_hashvalue' do
926
+ it "guarantees that a different Hash value is retrieved from the Object key" do
927
+ value = {"hashval1"=>"hashval2"}
928
+ @store[Value.new(:objkey1)] = {"hashval1"=>"hashval2"}
929
+ @store[Value.new(:objkey1)].should_not be_equal({"hashval1"=>"hashval2"})
930
+ end
931
+ end
932
+
933
+ #################### expires_objectkey_hashvalue ####################
934
+
935
+ shared_examples_for 'expires_objectkey_hashvalue' do
936
+ it 'should support expires on store and #[]' do
937
+ @store.store(Value.new(:objkey1), {"hashval1"=>"hashval2"}, :expires => 2)
938
+ @store[Value.new(:objkey1)].should == {"hashval1"=>"hashval2"}
939
+ sleep 1
940
+ @store[Value.new(:objkey1)].should == {"hashval1"=>"hashval2"}
941
+ sleep 2
942
+ @store[Value.new(:objkey1)].should == nil
943
+ end
944
+
945
+ it 'should support expires on store and load' do
946
+ @store.store(Value.new(:objkey1), {"hashval1"=>"hashval2"}, :expires => 2)
947
+ @store.load(Value.new(:objkey1)).should == {"hashval1"=>"hashval2"}
948
+ sleep 1
949
+ @store.load(Value.new(:objkey1)).should == {"hashval1"=>"hashval2"}
950
+ sleep 2
951
+ @store.load(Value.new(:objkey1)).should == nil
952
+ end
953
+
954
+ it 'should support expires on store and key?' do
955
+ @store.store(Value.new(:objkey1), {"hashval1"=>"hashval2"}, :expires => 2)
956
+ @store.key?(Value.new(:objkey1)).should == true
957
+ sleep 1
958
+ @store.key?(Value.new(:objkey1)).should == true
959
+ sleep 2
960
+ @store.key?(Value.new(:objkey1)).should == false
961
+ end
962
+
963
+ it 'should support updating the expiration time in load' do
964
+ @store.store(Value.new(:objkey2), {"hashval3"=>"hashval4"}, :expires => 2)
965
+ @store[Value.new(:objkey2)].should == {"hashval3"=>"hashval4"}
966
+ sleep 1
967
+ @store.load(Value.new(:objkey2), :expires => 3).should == {"hashval3"=>"hashval4"}
968
+ @store[Value.new(:objkey2)].should == {"hashval3"=>"hashval4"}
969
+ sleep 1
970
+ @store[Value.new(:objkey2)].should == {"hashval3"=>"hashval4"}
971
+ sleep 3
972
+ @store[Value.new(:objkey2)].should == nil
973
+ end
974
+
975
+ it 'should support updating the expiration time in fetch' do
976
+ @store.store(Value.new(:objkey1), {"hashval1"=>"hashval2"}, :expires => 2)
977
+ @store[Value.new(:objkey1)].should == {"hashval1"=>"hashval2"}
978
+ sleep 1
979
+ @store.fetch(Value.new(:objkey1), nil, :expires => 3).should == {"hashval1"=>"hashval2"}
980
+ @store[Value.new(:objkey1)].should == {"hashval1"=>"hashval2"}
981
+ sleep 1
982
+ @store[Value.new(:objkey1)].should == {"hashval1"=>"hashval2"}
983
+ sleep 3
984
+ @store[Value.new(:objkey1)].should == nil
985
+ end
986
+
987
+ it 'should respect expires in delete' do
988
+ @store.store(Value.new(:objkey2), {"hashval3"=>"hashval4"}, :expires => 2)
989
+ @store[Value.new(:objkey2)].should == {"hashval3"=>"hashval4"}
990
+ sleep 1
991
+ @store[Value.new(:objkey2)].should == {"hashval3"=>"hashval4"}
992
+ sleep 2
993
+ @store.delete(Value.new(:objkey2)).should == nil
994
+ end
995
+ end
996
+
997
+ #################### null_hashkey_stringvalue ####################
998
+
999
+ shared_examples_for 'null_hashkey_stringvalue' do
1000
+ it "reads from keys that are Hashs like a Hash" do
1001
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1002
+ @store.load({"hashkey1"=>"hashkey2"}).should == nil
1003
+ end
1004
+
1005
+ it "guarantees that the same String value is returned when setting a Hash key" do
1006
+ value = "strval1"
1007
+ (@store[{"hashkey1"=>"hashkey2"}] = value).should equal(value)
1008
+ end
1009
+
1010
+ it "returns false from key? if a Hash key is not available" do
1011
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1012
+ end
1013
+
1014
+ it "returns nil from delete if an element for a Hash key does not exist" do
1015
+ @store.delete({"hashkey1"=>"hashkey2"}).should == nil
1016
+ end
1017
+
1018
+ it "removes all Hash keys from the store with clear" do
1019
+ @store[{"hashkey1"=>"hashkey2"}] = "strval1"
1020
+ @store[{"hashkey3"=>"hashkey4"}] = "strval2"
1021
+ @store.clear.should equal(@store)
1022
+ @store.key?({"hashkey1"=>"hashkey2"}).should_not == true
1023
+ @store.key?({"hashkey3"=>"hashkey4"}).should_not == true
1024
+ end
1025
+
1026
+ it "fetches a Hash key with a default value with fetch, if the key is not available" do
1027
+ @store.fetch({"hashkey1"=>"hashkey2"}, "strval1").should == "strval1"
1028
+ end
1029
+
1030
+ it "fetches a Hash key with a block with fetch, if the key is not available" do
1031
+ key = {"hashkey1"=>"hashkey2"}
1032
+ value = "strval1"
1033
+ @store.fetch(key) do |k|
1034
+ k.should equal(key)
1035
+ value
1036
+ end.should equal(value)
1037
+ end
1038
+
1039
+ it 'should accept options' do
1040
+ @store.key?({"hashkey1"=>"hashkey2"}, :option1 => 1).should == false
1041
+ @store.load({"hashkey1"=>"hashkey2"}, :option2 => 2).should == nil
1042
+ @store.fetch({"hashkey1"=>"hashkey2"}, nil, :option3 => 3).should == nil
1043
+ @store.delete({"hashkey1"=>"hashkey2"}, :option4 => 4).should == nil
1044
+ @store.clear(:option5 => 5).should equal(@store)
1045
+ @store.store({"hashkey1"=>"hashkey2"}, "strval1", :option6 => 6).should == "strval1"
1046
+ end
1047
+ end
1048
+
1049
+ #################### store_hashkey_stringvalue ####################
1050
+
1051
+ shared_examples_for 'store_hashkey_stringvalue' do
1052
+ it "writes String values to keys that are Hashs like a Hash" do
1053
+ @store[{"hashkey1"=>"hashkey2"}] = "strval1"
1054
+ @store[{"hashkey1"=>"hashkey2"}].should == "strval1"
1055
+ @store.load({"hashkey1"=>"hashkey2"}).should == "strval1"
1056
+ end
1057
+
1058
+ it "returns true from key? if a Hash key is available" do
1059
+ @store[{"hashkey1"=>"hashkey2"}] = "strval1"
1060
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1061
+ end
1062
+
1063
+ it "stores String values with Hash keys with #store" do
1064
+ value = "strval1"
1065
+ @store.store({"hashkey1"=>"hashkey2"}, value).should equal(value)
1066
+ @store[{"hashkey1"=>"hashkey2"}].should == "strval1"
1067
+ @store.load({"hashkey1"=>"hashkey2"}).should == "strval1"
1068
+ end
1069
+
1070
+ it "removes and returns a String element with a Hash key from the backing store via delete if it exists" do
1071
+ @store[{"hashkey1"=>"hashkey2"}] = "strval1"
1072
+ @store.delete({"hashkey1"=>"hashkey2"}).should == "strval1"
1073
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1074
+ end
1075
+
1076
+ it "does not run the block if the Hash key is available" do
1077
+ @store[{"hashkey1"=>"hashkey2"}] = "strval1"
1078
+ unaltered = "unaltered"
1079
+ @store.fetch({"hashkey1"=>"hashkey2"}) { unaltered = "altered" }
1080
+ unaltered.should == "unaltered"
1081
+ end
1082
+
1083
+ it "fetches a Hash key with a default value with fetch, if the key is available" do
1084
+ @store[{"hashkey1"=>"hashkey2"}] = "strval1"
1085
+ @store.fetch({"hashkey1"=>"hashkey2"}, "strval2").should == "strval1"
1086
+ end
1087
+ end
1088
+
1089
+ #################### returndifferent_hashkey_stringvalue ####################
1090
+
1091
+ shared_examples_for 'returndifferent_hashkey_stringvalue' do
1092
+ it "guarantees that a different String value is retrieved from the Hash key" do
1093
+ value = "strval1"
1094
+ @store[{"hashkey1"=>"hashkey2"}] = "strval1"
1095
+ @store[{"hashkey1"=>"hashkey2"}].should_not be_equal("strval1")
1096
+ end
1097
+ end
1098
+
1099
+ #################### expires_hashkey_stringvalue ####################
1100
+
1101
+ shared_examples_for 'expires_hashkey_stringvalue' do
1102
+ it 'should support expires on store and #[]' do
1103
+ @store.store({"hashkey1"=>"hashkey2"}, "strval1", :expires => 2)
1104
+ @store[{"hashkey1"=>"hashkey2"}].should == "strval1"
1105
+ sleep 1
1106
+ @store[{"hashkey1"=>"hashkey2"}].should == "strval1"
1107
+ sleep 2
1108
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1109
+ end
1110
+
1111
+ it 'should support expires on store and load' do
1112
+ @store.store({"hashkey1"=>"hashkey2"}, "strval1", :expires => 2)
1113
+ @store.load({"hashkey1"=>"hashkey2"}).should == "strval1"
1114
+ sleep 1
1115
+ @store.load({"hashkey1"=>"hashkey2"}).should == "strval1"
1116
+ sleep 2
1117
+ @store.load({"hashkey1"=>"hashkey2"}).should == nil
1118
+ end
1119
+
1120
+ it 'should support expires on store and key?' do
1121
+ @store.store({"hashkey1"=>"hashkey2"}, "strval1", :expires => 2)
1122
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1123
+ sleep 1
1124
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1125
+ sleep 2
1126
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1127
+ end
1128
+
1129
+ it 'should support updating the expiration time in load' do
1130
+ @store.store({"hashkey3"=>"hashkey4"}, "strval2", :expires => 2)
1131
+ @store[{"hashkey3"=>"hashkey4"}].should == "strval2"
1132
+ sleep 1
1133
+ @store.load({"hashkey3"=>"hashkey4"}, :expires => 3).should == "strval2"
1134
+ @store[{"hashkey3"=>"hashkey4"}].should == "strval2"
1135
+ sleep 1
1136
+ @store[{"hashkey3"=>"hashkey4"}].should == "strval2"
1137
+ sleep 3
1138
+ @store[{"hashkey3"=>"hashkey4"}].should == nil
1139
+ end
1140
+
1141
+ it 'should support updating the expiration time in fetch' do
1142
+ @store.store({"hashkey1"=>"hashkey2"}, "strval1", :expires => 2)
1143
+ @store[{"hashkey1"=>"hashkey2"}].should == "strval1"
1144
+ sleep 1
1145
+ @store.fetch({"hashkey1"=>"hashkey2"}, nil, :expires => 3).should == "strval1"
1146
+ @store[{"hashkey1"=>"hashkey2"}].should == "strval1"
1147
+ sleep 1
1148
+ @store[{"hashkey1"=>"hashkey2"}].should == "strval1"
1149
+ sleep 3
1150
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1151
+ end
1152
+
1153
+ it 'should respect expires in delete' do
1154
+ @store.store({"hashkey3"=>"hashkey4"}, "strval2", :expires => 2)
1155
+ @store[{"hashkey3"=>"hashkey4"}].should == "strval2"
1156
+ sleep 1
1157
+ @store[{"hashkey3"=>"hashkey4"}].should == "strval2"
1158
+ sleep 2
1159
+ @store.delete({"hashkey3"=>"hashkey4"}).should == nil
1160
+ end
1161
+ end
1162
+
1163
+ #################### null_hashkey_objectvalue ####################
1164
+
1165
+ shared_examples_for 'null_hashkey_objectvalue' do
1166
+ it "reads from keys that are Hashs like a Hash" do
1167
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1168
+ @store.load({"hashkey1"=>"hashkey2"}).should == nil
1169
+ end
1170
+
1171
+ it "guarantees that the same Object value is returned when setting a Hash key" do
1172
+ value = Value.new(:objval1)
1173
+ (@store[{"hashkey1"=>"hashkey2"}] = value).should equal(value)
1174
+ end
1175
+
1176
+ it "returns false from key? if a Hash key is not available" do
1177
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1178
+ end
1179
+
1180
+ it "returns nil from delete if an element for a Hash key does not exist" do
1181
+ @store.delete({"hashkey1"=>"hashkey2"}).should == nil
1182
+ end
1183
+
1184
+ it "removes all Hash keys from the store with clear" do
1185
+ @store[{"hashkey1"=>"hashkey2"}] = Value.new(:objval1)
1186
+ @store[{"hashkey3"=>"hashkey4"}] = Value.new(:objval2)
1187
+ @store.clear.should equal(@store)
1188
+ @store.key?({"hashkey1"=>"hashkey2"}).should_not == true
1189
+ @store.key?({"hashkey3"=>"hashkey4"}).should_not == true
1190
+ end
1191
+
1192
+ it "fetches a Hash key with a default value with fetch, if the key is not available" do
1193
+ @store.fetch({"hashkey1"=>"hashkey2"}, Value.new(:objval1)).should == Value.new(:objval1)
1194
+ end
1195
+
1196
+ it "fetches a Hash key with a block with fetch, if the key is not available" do
1197
+ key = {"hashkey1"=>"hashkey2"}
1198
+ value = Value.new(:objval1)
1199
+ @store.fetch(key) do |k|
1200
+ k.should equal(key)
1201
+ value
1202
+ end.should equal(value)
1203
+ end
1204
+
1205
+ it 'should accept options' do
1206
+ @store.key?({"hashkey1"=>"hashkey2"}, :option1 => 1).should == false
1207
+ @store.load({"hashkey1"=>"hashkey2"}, :option2 => 2).should == nil
1208
+ @store.fetch({"hashkey1"=>"hashkey2"}, nil, :option3 => 3).should == nil
1209
+ @store.delete({"hashkey1"=>"hashkey2"}, :option4 => 4).should == nil
1210
+ @store.clear(:option5 => 5).should equal(@store)
1211
+ @store.store({"hashkey1"=>"hashkey2"}, Value.new(:objval1), :option6 => 6).should == Value.new(:objval1)
1212
+ end
1213
+ end
1214
+
1215
+ #################### store_hashkey_objectvalue ####################
1216
+
1217
+ shared_examples_for 'store_hashkey_objectvalue' do
1218
+ it "writes Object values to keys that are Hashs like a Hash" do
1219
+ @store[{"hashkey1"=>"hashkey2"}] = Value.new(:objval1)
1220
+ @store[{"hashkey1"=>"hashkey2"}].should == Value.new(:objval1)
1221
+ @store.load({"hashkey1"=>"hashkey2"}).should == Value.new(:objval1)
1222
+ end
1223
+
1224
+ it "returns true from key? if a Hash key is available" do
1225
+ @store[{"hashkey1"=>"hashkey2"}] = Value.new(:objval1)
1226
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1227
+ end
1228
+
1229
+ it "stores Object values with Hash keys with #store" do
1230
+ value = Value.new(:objval1)
1231
+ @store.store({"hashkey1"=>"hashkey2"}, value).should equal(value)
1232
+ @store[{"hashkey1"=>"hashkey2"}].should == Value.new(:objval1)
1233
+ @store.load({"hashkey1"=>"hashkey2"}).should == Value.new(:objval1)
1234
+ end
1235
+
1236
+ it "removes and returns a Object element with a Hash key from the backing store via delete if it exists" do
1237
+ @store[{"hashkey1"=>"hashkey2"}] = Value.new(:objval1)
1238
+ @store.delete({"hashkey1"=>"hashkey2"}).should == Value.new(:objval1)
1239
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1240
+ end
1241
+
1242
+ it "does not run the block if the Hash key is available" do
1243
+ @store[{"hashkey1"=>"hashkey2"}] = Value.new(:objval1)
1244
+ unaltered = "unaltered"
1245
+ @store.fetch({"hashkey1"=>"hashkey2"}) { unaltered = "altered" }
1246
+ unaltered.should == "unaltered"
1247
+ end
1248
+
1249
+ it "fetches a Hash key with a default value with fetch, if the key is available" do
1250
+ @store[{"hashkey1"=>"hashkey2"}] = Value.new(:objval1)
1251
+ @store.fetch({"hashkey1"=>"hashkey2"}, Value.new(:objval2)).should == Value.new(:objval1)
1252
+ end
1253
+ end
1254
+
1255
+ #################### returndifferent_hashkey_objectvalue ####################
1256
+
1257
+ shared_examples_for 'returndifferent_hashkey_objectvalue' do
1258
+ it "guarantees that a different Object value is retrieved from the Hash key" do
1259
+ value = Value.new(:objval1)
1260
+ @store[{"hashkey1"=>"hashkey2"}] = Value.new(:objval1)
1261
+ @store[{"hashkey1"=>"hashkey2"}].should_not be_equal(Value.new(:objval1))
1262
+ end
1263
+ end
1264
+
1265
+ #################### expires_hashkey_objectvalue ####################
1266
+
1267
+ shared_examples_for 'expires_hashkey_objectvalue' do
1268
+ it 'should support expires on store and #[]' do
1269
+ @store.store({"hashkey1"=>"hashkey2"}, Value.new(:objval1), :expires => 2)
1270
+ @store[{"hashkey1"=>"hashkey2"}].should == Value.new(:objval1)
1271
+ sleep 1
1272
+ @store[{"hashkey1"=>"hashkey2"}].should == Value.new(:objval1)
1273
+ sleep 2
1274
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1275
+ end
1276
+
1277
+ it 'should support expires on store and load' do
1278
+ @store.store({"hashkey1"=>"hashkey2"}, Value.new(:objval1), :expires => 2)
1279
+ @store.load({"hashkey1"=>"hashkey2"}).should == Value.new(:objval1)
1280
+ sleep 1
1281
+ @store.load({"hashkey1"=>"hashkey2"}).should == Value.new(:objval1)
1282
+ sleep 2
1283
+ @store.load({"hashkey1"=>"hashkey2"}).should == nil
1284
+ end
1285
+
1286
+ it 'should support expires on store and key?' do
1287
+ @store.store({"hashkey1"=>"hashkey2"}, Value.new(:objval1), :expires => 2)
1288
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1289
+ sleep 1
1290
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1291
+ sleep 2
1292
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1293
+ end
1294
+
1295
+ it 'should support updating the expiration time in load' do
1296
+ @store.store({"hashkey3"=>"hashkey4"}, Value.new(:objval2), :expires => 2)
1297
+ @store[{"hashkey3"=>"hashkey4"}].should == Value.new(:objval2)
1298
+ sleep 1
1299
+ @store.load({"hashkey3"=>"hashkey4"}, :expires => 3).should == Value.new(:objval2)
1300
+ @store[{"hashkey3"=>"hashkey4"}].should == Value.new(:objval2)
1301
+ sleep 1
1302
+ @store[{"hashkey3"=>"hashkey4"}].should == Value.new(:objval2)
1303
+ sleep 3
1304
+ @store[{"hashkey3"=>"hashkey4"}].should == nil
1305
+ end
1306
+
1307
+ it 'should support updating the expiration time in fetch' do
1308
+ @store.store({"hashkey1"=>"hashkey2"}, Value.new(:objval1), :expires => 2)
1309
+ @store[{"hashkey1"=>"hashkey2"}].should == Value.new(:objval1)
1310
+ sleep 1
1311
+ @store.fetch({"hashkey1"=>"hashkey2"}, nil, :expires => 3).should == Value.new(:objval1)
1312
+ @store[{"hashkey1"=>"hashkey2"}].should == Value.new(:objval1)
1313
+ sleep 1
1314
+ @store[{"hashkey1"=>"hashkey2"}].should == Value.new(:objval1)
1315
+ sleep 3
1316
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1317
+ end
1318
+
1319
+ it 'should respect expires in delete' do
1320
+ @store.store({"hashkey3"=>"hashkey4"}, Value.new(:objval2), :expires => 2)
1321
+ @store[{"hashkey3"=>"hashkey4"}].should == Value.new(:objval2)
1322
+ sleep 1
1323
+ @store[{"hashkey3"=>"hashkey4"}].should == Value.new(:objval2)
1324
+ sleep 2
1325
+ @store.delete({"hashkey3"=>"hashkey4"}).should == nil
1326
+ end
1327
+ end
1328
+
1329
+ #################### null_hashkey_hashvalue ####################
1330
+
1331
+ shared_examples_for 'null_hashkey_hashvalue' do
1332
+ it "reads from keys that are Hashs like a Hash" do
1333
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1334
+ @store.load({"hashkey1"=>"hashkey2"}).should == nil
1335
+ end
1336
+
1337
+ it "guarantees that the same Hash value is returned when setting a Hash key" do
1338
+ value = {"hashval1"=>"hashval2"}
1339
+ (@store[{"hashkey1"=>"hashkey2"}] = value).should equal(value)
1340
+ end
1341
+
1342
+ it "returns false from key? if a Hash key is not available" do
1343
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1344
+ end
1345
+
1346
+ it "returns nil from delete if an element for a Hash key does not exist" do
1347
+ @store.delete({"hashkey1"=>"hashkey2"}).should == nil
1348
+ end
1349
+
1350
+ it "removes all Hash keys from the store with clear" do
1351
+ @store[{"hashkey1"=>"hashkey2"}] = {"hashval1"=>"hashval2"}
1352
+ @store[{"hashkey3"=>"hashkey4"}] = {"hashval3"=>"hashval4"}
1353
+ @store.clear.should equal(@store)
1354
+ @store.key?({"hashkey1"=>"hashkey2"}).should_not == true
1355
+ @store.key?({"hashkey3"=>"hashkey4"}).should_not == true
1356
+ end
1357
+
1358
+ it "fetches a Hash key with a default value with fetch, if the key is not available" do
1359
+ @store.fetch({"hashkey1"=>"hashkey2"}, {"hashval1"=>"hashval2"}).should == {"hashval1"=>"hashval2"}
1360
+ end
1361
+
1362
+ it "fetches a Hash key with a block with fetch, if the key is not available" do
1363
+ key = {"hashkey1"=>"hashkey2"}
1364
+ value = {"hashval1"=>"hashval2"}
1365
+ @store.fetch(key) do |k|
1366
+ k.should equal(key)
1367
+ value
1368
+ end.should equal(value)
1369
+ end
1370
+
1371
+ it 'should accept options' do
1372
+ @store.key?({"hashkey1"=>"hashkey2"}, :option1 => 1).should == false
1373
+ @store.load({"hashkey1"=>"hashkey2"}, :option2 => 2).should == nil
1374
+ @store.fetch({"hashkey1"=>"hashkey2"}, nil, :option3 => 3).should == nil
1375
+ @store.delete({"hashkey1"=>"hashkey2"}, :option4 => 4).should == nil
1376
+ @store.clear(:option5 => 5).should equal(@store)
1377
+ @store.store({"hashkey1"=>"hashkey2"}, {"hashval1"=>"hashval2"}, :option6 => 6).should == {"hashval1"=>"hashval2"}
1378
+ end
1379
+ end
1380
+
1381
+ #################### store_hashkey_hashvalue ####################
1382
+
1383
+ shared_examples_for 'store_hashkey_hashvalue' do
1384
+ it "writes Hash values to keys that are Hashs like a Hash" do
1385
+ @store[{"hashkey1"=>"hashkey2"}] = {"hashval1"=>"hashval2"}
1386
+ @store[{"hashkey1"=>"hashkey2"}].should == {"hashval1"=>"hashval2"}
1387
+ @store.load({"hashkey1"=>"hashkey2"}).should == {"hashval1"=>"hashval2"}
1388
+ end
1389
+
1390
+ it "returns true from key? if a Hash key is available" do
1391
+ @store[{"hashkey1"=>"hashkey2"}] = {"hashval1"=>"hashval2"}
1392
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1393
+ end
1394
+
1395
+ it "stores Hash values with Hash keys with #store" do
1396
+ value = {"hashval1"=>"hashval2"}
1397
+ @store.store({"hashkey1"=>"hashkey2"}, value).should equal(value)
1398
+ @store[{"hashkey1"=>"hashkey2"}].should == {"hashval1"=>"hashval2"}
1399
+ @store.load({"hashkey1"=>"hashkey2"}).should == {"hashval1"=>"hashval2"}
1400
+ end
1401
+
1402
+ it "removes and returns a Hash element with a Hash key from the backing store via delete if it exists" do
1403
+ @store[{"hashkey1"=>"hashkey2"}] = {"hashval1"=>"hashval2"}
1404
+ @store.delete({"hashkey1"=>"hashkey2"}).should == {"hashval1"=>"hashval2"}
1405
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1406
+ end
1407
+
1408
+ it "does not run the block if the Hash key is available" do
1409
+ @store[{"hashkey1"=>"hashkey2"}] = {"hashval1"=>"hashval2"}
1410
+ unaltered = "unaltered"
1411
+ @store.fetch({"hashkey1"=>"hashkey2"}) { unaltered = "altered" }
1412
+ unaltered.should == "unaltered"
1413
+ end
1414
+
1415
+ it "fetches a Hash key with a default value with fetch, if the key is available" do
1416
+ @store[{"hashkey1"=>"hashkey2"}] = {"hashval1"=>"hashval2"}
1417
+ @store.fetch({"hashkey1"=>"hashkey2"}, {"hashval3"=>"hashval4"}).should == {"hashval1"=>"hashval2"}
1418
+ end
1419
+ end
1420
+
1421
+ #################### returndifferent_hashkey_hashvalue ####################
1422
+
1423
+ shared_examples_for 'returndifferent_hashkey_hashvalue' do
1424
+ it "guarantees that a different Hash value is retrieved from the Hash key" do
1425
+ value = {"hashval1"=>"hashval2"}
1426
+ @store[{"hashkey1"=>"hashkey2"}] = {"hashval1"=>"hashval2"}
1427
+ @store[{"hashkey1"=>"hashkey2"}].should_not be_equal({"hashval1"=>"hashval2"})
1428
+ end
1429
+ end
1430
+
1431
+ #################### expires_hashkey_hashvalue ####################
1432
+
1433
+ shared_examples_for 'expires_hashkey_hashvalue' do
1434
+ it 'should support expires on store and #[]' do
1435
+ @store.store({"hashkey1"=>"hashkey2"}, {"hashval1"=>"hashval2"}, :expires => 2)
1436
+ @store[{"hashkey1"=>"hashkey2"}].should == {"hashval1"=>"hashval2"}
1437
+ sleep 1
1438
+ @store[{"hashkey1"=>"hashkey2"}].should == {"hashval1"=>"hashval2"}
1439
+ sleep 2
1440
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1441
+ end
1442
+
1443
+ it 'should support expires on store and load' do
1444
+ @store.store({"hashkey1"=>"hashkey2"}, {"hashval1"=>"hashval2"}, :expires => 2)
1445
+ @store.load({"hashkey1"=>"hashkey2"}).should == {"hashval1"=>"hashval2"}
1446
+ sleep 1
1447
+ @store.load({"hashkey1"=>"hashkey2"}).should == {"hashval1"=>"hashval2"}
1448
+ sleep 2
1449
+ @store.load({"hashkey1"=>"hashkey2"}).should == nil
1450
+ end
1451
+
1452
+ it 'should support expires on store and key?' do
1453
+ @store.store({"hashkey1"=>"hashkey2"}, {"hashval1"=>"hashval2"}, :expires => 2)
1454
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1455
+ sleep 1
1456
+ @store.key?({"hashkey1"=>"hashkey2"}).should == true
1457
+ sleep 2
1458
+ @store.key?({"hashkey1"=>"hashkey2"}).should == false
1459
+ end
1460
+
1461
+ it 'should support updating the expiration time in load' do
1462
+ @store.store({"hashkey3"=>"hashkey4"}, {"hashval3"=>"hashval4"}, :expires => 2)
1463
+ @store[{"hashkey3"=>"hashkey4"}].should == {"hashval3"=>"hashval4"}
1464
+ sleep 1
1465
+ @store.load({"hashkey3"=>"hashkey4"}, :expires => 3).should == {"hashval3"=>"hashval4"}
1466
+ @store[{"hashkey3"=>"hashkey4"}].should == {"hashval3"=>"hashval4"}
1467
+ sleep 1
1468
+ @store[{"hashkey3"=>"hashkey4"}].should == {"hashval3"=>"hashval4"}
1469
+ sleep 3
1470
+ @store[{"hashkey3"=>"hashkey4"}].should == nil
1471
+ end
1472
+
1473
+ it 'should support updating the expiration time in fetch' do
1474
+ @store.store({"hashkey1"=>"hashkey2"}, {"hashval1"=>"hashval2"}, :expires => 2)
1475
+ @store[{"hashkey1"=>"hashkey2"}].should == {"hashval1"=>"hashval2"}
1476
+ sleep 1
1477
+ @store.fetch({"hashkey1"=>"hashkey2"}, nil, :expires => 3).should == {"hashval1"=>"hashval2"}
1478
+ @store[{"hashkey1"=>"hashkey2"}].should == {"hashval1"=>"hashval2"}
1479
+ sleep 1
1480
+ @store[{"hashkey1"=>"hashkey2"}].should == {"hashval1"=>"hashval2"}
1481
+ sleep 3
1482
+ @store[{"hashkey1"=>"hashkey2"}].should == nil
1483
+ end
1484
+
1485
+ it 'should respect expires in delete' do
1486
+ @store.store({"hashkey3"=>"hashkey4"}, {"hashval3"=>"hashval4"}, :expires => 2)
1487
+ @store[{"hashkey3"=>"hashkey4"}].should == {"hashval3"=>"hashval4"}
1488
+ sleep 1
1489
+ @store[{"hashkey3"=>"hashkey4"}].should == {"hashval3"=>"hashval4"}
1490
+ sleep 2
1491
+ @store.delete({"hashkey3"=>"hashkey4"}).should == nil
1492
+ end
1493
+ end
1494
+
1495
+ #################### marshallable_key ####################
1496
+
1497
+ shared_examples_for 'marshallable_key' do
1498
+ it "refuses to #[] from keys that cannot be marshalled" do
1499
+ expect do
1500
+ @store[Struct.new(:foo).new(:bar)]
1501
+ end.to raise_error(marshal_error)
1502
+ end
1503
+
1504
+ it "refuses to load from keys that cannot be marshalled" do
1505
+ expect do
1506
+ @store.load(Struct.new(:foo).new(:bar))
1507
+ end.to raise_error(marshal_error)
1508
+ end
1509
+
1510
+ it "refuses to fetch from keys that cannot be marshalled" do
1511
+ expect do
1512
+ @store.fetch(Struct.new(:foo).new(:bar), true)
1513
+ end.to raise_error(marshal_error)
1514
+ end
1515
+
1516
+ it "refuses to #[]= to keys that cannot be marshalled" do
1517
+ expect do
1518
+ @store[Struct.new(:foo).new(:bar)] = 'value'
1519
+ end.to raise_error(marshal_error)
1520
+ end
1521
+
1522
+ it "refuses to store to keys that cannot be marshalled" do
1523
+ expect do
1524
+ @store.store Struct.new(:foo).new(:bar), 'value'
1525
+ end.to raise_error(marshal_error)
1526
+ end
1527
+
1528
+ it "refuses to check for key? if the key cannot be marshalled" do
1529
+ expect do
1530
+ @store.key? Struct.new(:foo).new(:bar)
1531
+ end.to raise_error(marshal_error)
1532
+ end
1533
+
1534
+ it "refuses to delete a key if the key cannot be marshalled" do
1535
+ expect do
1536
+ @store.delete Struct.new(:foo).new(:bar)
1537
+ end.to raise_error(marshal_error)
1538
+ end
1539
+ end
1540
+