juno 0.1.1 → 0.2.0

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.
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
+