moneta 1.1.1 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +194 -0
  4. data/.travis.yml +65 -25
  5. data/CHANGES +36 -0
  6. data/CONTRIBUTORS +4 -2
  7. data/Gemfile +94 -65
  8. data/README.md +50 -25
  9. data/feature_matrix.yaml +3 -11
  10. data/lib/action_dispatch/middleware/session/moneta_store.rb +1 -0
  11. data/lib/active_support/cache/moneta_store.rb +5 -5
  12. data/lib/moneta.rb +18 -10
  13. data/lib/moneta/adapters/activerecord.rb +35 -19
  14. data/lib/moneta/adapters/activesupportcache.rb +3 -7
  15. data/lib/moneta/adapters/cassandra.rb +24 -16
  16. data/lib/moneta/adapters/client.rb +62 -21
  17. data/lib/moneta/adapters/couch.rb +225 -80
  18. data/lib/moneta/adapters/datamapper.rb +1 -0
  19. data/lib/moneta/adapters/file.rb +9 -6
  20. data/lib/moneta/adapters/hbase.rb +1 -1
  21. data/lib/moneta/adapters/kyotocabinet.rb +8 -7
  22. data/lib/moneta/adapters/leveldb.rb +1 -1
  23. data/lib/moneta/adapters/lmdb.rb +3 -4
  24. data/lib/moneta/adapters/lruhash.rb +29 -62
  25. data/lib/moneta/adapters/memcached.rb +1 -0
  26. data/lib/moneta/adapters/memcached/dalli.rb +1 -1
  27. data/lib/moneta/adapters/memcached/native.rb +10 -8
  28. data/lib/moneta/adapters/mongo.rb +264 -6
  29. data/lib/moneta/adapters/null.rb +1 -2
  30. data/lib/moneta/adapters/pstore.rb +3 -2
  31. data/lib/moneta/adapters/redis.rb +8 -4
  32. data/lib/moneta/adapters/restclient.rb +12 -3
  33. data/lib/moneta/adapters/riak.rb +2 -2
  34. data/lib/moneta/adapters/sequel.rb +68 -494
  35. data/lib/moneta/adapters/sequel/mysql.rb +66 -0
  36. data/lib/moneta/adapters/sequel/postgres.rb +80 -0
  37. data/lib/moneta/adapters/sequel/postgres_hstore.rb +240 -0
  38. data/lib/moneta/adapters/sequel/sqlite.rb +57 -0
  39. data/lib/moneta/adapters/sqlite.rb +10 -10
  40. data/lib/moneta/adapters/tokyotyrant.rb +1 -1
  41. data/lib/moneta/builder.rb +2 -3
  42. data/lib/moneta/create_support.rb +21 -0
  43. data/lib/moneta/dbm_adapter.rb +31 -0
  44. data/lib/moneta/{mixins.rb → defaults.rb} +3 -302
  45. data/lib/moneta/each_key_support.rb +27 -0
  46. data/lib/moneta/enumerable.rb +38 -0
  47. data/lib/moneta/expires.rb +12 -12
  48. data/lib/moneta/expires_support.rb +60 -0
  49. data/lib/moneta/fallback.rb +84 -0
  50. data/lib/moneta/hash_adapter.rb +68 -0
  51. data/lib/moneta/increment_support.rb +16 -0
  52. data/lib/moneta/lock.rb +7 -2
  53. data/lib/moneta/logger.rb +2 -2
  54. data/lib/moneta/nil_values.rb +35 -0
  55. data/lib/moneta/option_support.rb +51 -0
  56. data/lib/moneta/optionmerger.rb +0 -1
  57. data/lib/moneta/pool.rb +312 -30
  58. data/lib/moneta/proxy.rb +3 -3
  59. data/lib/moneta/server.rb +216 -65
  60. data/lib/moneta/shared.rb +13 -7
  61. data/lib/moneta/stack.rb +6 -6
  62. data/lib/moneta/synchronize.rb +3 -3
  63. data/lib/moneta/transformer.rb +68 -24
  64. data/lib/moneta/transformer/config.rb +63 -43
  65. data/lib/moneta/transformer/helper.rb +3 -3
  66. data/lib/moneta/transformer/helper/bson.rb +7 -14
  67. data/lib/moneta/utils.rb +3 -9
  68. data/lib/moneta/version.rb +1 -1
  69. data/lib/moneta/weak_each_key.rb +2 -4
  70. data/lib/rack/cache/moneta.rb +13 -11
  71. data/lib/rack/moneta_rest.rb +2 -2
  72. data/lib/rack/session/moneta.rb +3 -4
  73. data/moneta.gemspec +18 -4
  74. data/script/benchmarks +61 -34
  75. data/script/contributors +11 -6
  76. data/script/start-couchdb +27 -0
  77. data/script/start-hbase +3 -2
  78. data/script/start-services +3 -11
  79. data/spec/active_support/cache_moneta_store_spec.rb +30 -30
  80. data/spec/features/concurrent_create.rb +31 -10
  81. data/spec/features/concurrent_increment.rb +26 -19
  82. data/spec/features/create_expires.rb +15 -15
  83. data/spec/features/default_expires.rb +11 -12
  84. data/spec/features/expires.rb +215 -210
  85. data/spec/features/increment.rb +41 -41
  86. data/spec/features/store.rb +3 -3
  87. data/spec/helper.rb +21 -82
  88. data/spec/moneta/adapters/activerecord/standard_activerecord_spec.rb +1 -1
  89. data/spec/moneta/adapters/activerecord/standard_activerecord_with_expires_spec.rb +1 -1
  90. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_spec.rb +4 -1
  91. data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_with_default_expires_spec.rb +4 -1
  92. data/spec/moneta/adapters/activesupportcache/standard_activesupportcache_spec.rb +14 -0
  93. data/spec/moneta/adapters/cassandra/standard_cassandra_spec.rb +1 -1
  94. data/spec/moneta/adapters/client/adapter_client_spec.rb +6 -6
  95. data/spec/moneta/adapters/client/client_helper.rb +24 -0
  96. data/spec/moneta/adapters/client/standard_client_tcp_spec.rb +8 -8
  97. data/spec/moneta/adapters/client/standard_client_unix_spec.rb +23 -7
  98. data/spec/moneta/adapters/couch/adapter_couch_spec.rb +199 -2
  99. data/spec/moneta/adapters/couch/standard_couch_spec.rb +9 -3
  100. data/spec/moneta/adapters/couch/standard_couch_with_expires_spec.rb +8 -2
  101. data/spec/moneta/adapters/daybreak/standard_daybreak_spec.rb +1 -1
  102. data/spec/moneta/adapters/daybreak/standard_daybreak_with_expires_spec.rb +1 -1
  103. data/spec/moneta/adapters/dbm/standard_dbm_spec.rb +1 -1
  104. data/spec/moneta/adapters/dbm/standard_dbm_with_expires_spec.rb +1 -1
  105. data/spec/moneta/adapters/faraday_helper.rb +9 -0
  106. data/spec/moneta/adapters/file/standard_file_spec.rb +2 -2
  107. data/spec/moneta/adapters/file/standard_file_with_expires_spec.rb +1 -1
  108. data/spec/moneta/adapters/gdbm/standard_gdbm_spec.rb +1 -1
  109. data/spec/moneta/adapters/gdbm/standard_gdbm_with_expires_spec.rb +1 -1
  110. data/spec/moneta/adapters/kyotocabinet/adapter_kyotocabinet_spec.rb +1 -1
  111. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_spec.rb +2 -2
  112. data/spec/moneta/adapters/kyotocabinet/standard_kyotocabinet_with_expires_spec.rb +2 -2
  113. data/spec/moneta/adapters/leveldb/standard_leveldb_spec.rb +1 -1
  114. data/spec/moneta/adapters/leveldb/standard_leveldb_with_expires_spec.rb +1 -1
  115. data/spec/moneta/adapters/lmdb/standard_lmdb_spec.rb +1 -1
  116. data/spec/moneta/adapters/lmdb/standard_lmdb_with_expires_spec.rb +1 -1
  117. data/spec/moneta/adapters/lruhash/adapter_lruhash_spec.rb +2 -2
  118. data/spec/moneta/adapters/lruhash/standard_lruhash_spec.rb +1 -1
  119. data/spec/moneta/adapters/lruhash/standard_lruhash_with_expires_spec.rb +1 -1
  120. data/spec/moneta/adapters/memcached/adapter_memcached_spec.rb +1 -1
  121. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_spec.rb +1 -1
  122. data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_with_default_expires_spec.rb +1 -1
  123. data/spec/moneta/adapters/memcached/dalli/standard_memcached_dalli_spec.rb +1 -1
  124. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_spec.rb +1 -1
  125. data/spec/moneta/adapters/memcached/native/adapter_memcached_native_with_default_expires_spec.rb +1 -1
  126. data/spec/moneta/adapters/memcached/native/standard_memcached_native_spec.rb +1 -1
  127. data/spec/moneta/adapters/memcached/standard_memcached_spec.rb +1 -1
  128. data/spec/moneta/adapters/{memcached/helper.rb → memcached_helper.rb} +0 -0
  129. data/spec/moneta/adapters/memory/standard_memory_spec.rb +1 -1
  130. data/spec/moneta/adapters/memory/standard_memory_with_compress_spec.rb +1 -1
  131. data/spec/moneta/adapters/memory/standard_memory_with_expires_spec.rb +1 -1
  132. data/spec/moneta/adapters/memory/standard_memory_with_json_key_serializer_spec.rb +1 -1
  133. data/spec/moneta/adapters/memory/standard_memory_with_json_serializer_spec.rb +1 -1
  134. data/spec/moneta/adapters/memory/standard_memory_with_json_value_serializer_spec.rb +2 -2
  135. data/spec/moneta/adapters/memory/standard_memory_with_prefix_spec.rb +39 -2
  136. data/spec/moneta/adapters/memory/standard_memory_with_snappy_compress_spec.rb +2 -2
  137. data/spec/moneta/adapters/mongo/adapter_mongo_spec.rb +32 -2
  138. data/spec/moneta/adapters/mongo/adapter_mongo_with_default_expires_spec.rb +5 -3
  139. data/spec/moneta/adapters/mongo/standard_mongo_spec.rb +2 -2
  140. data/spec/moneta/adapters/null/null_adapter_spec.rb +1 -1
  141. data/spec/moneta/adapters/pstore/standard_pstore_spec.rb +1 -1
  142. data/spec/moneta/adapters/pstore/standard_pstore_with_expires_spec.rb +1 -1
  143. data/spec/moneta/adapters/redis/standard_redis_spec.rb +1 -1
  144. data/spec/moneta/adapters/restclient/adapter_restclient_spec.rb +7 -5
  145. data/spec/moneta/adapters/restclient/helper.rb +12 -0
  146. data/spec/moneta/adapters/restclient/standard_restclient_spec.rb +9 -6
  147. data/spec/moneta/adapters/riak/standard_riak_with_expires_spec.rb +4 -0
  148. data/spec/moneta/adapters/sdbm/standard_sdbm_spec.rb +1 -1
  149. data/spec/moneta/adapters/sdbm/standard_sdbm_with_expires_spec.rb +1 -1
  150. data/spec/moneta/adapters/sequel/adapter_sequel_spec.rb +7 -34
  151. data/spec/moneta/adapters/sequel/helper.rb +37 -0
  152. data/spec/moneta/adapters/sequel/standard_sequel_spec.rb +5 -11
  153. data/spec/moneta/adapters/sequel/standard_sequel_with_expires_spec.rb +8 -9
  154. data/spec/moneta/adapters/sqlite/standard_sqlite_spec.rb +1 -1
  155. data/spec/moneta/adapters/sqlite/standard_sqlite_with_expires_spec.rb +1 -1
  156. data/spec/moneta/adapters/tdb/standard_tdb_spec.rb +1 -1
  157. data/spec/moneta/adapters/tdb/standard_tdb_with_expires_spec.rb +1 -1
  158. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_spec.rb +1 -1
  159. data/spec/moneta/adapters/tokyocabinet/standard_tokyocabinet_with_expires_spec.rb +1 -1
  160. data/spec/moneta/adapters/tokyotyrant/adapter_tokyotyrant_spec.rb +6 -2
  161. data/spec/moneta/adapters/tokyotyrant/helper.rb +12 -0
  162. data/spec/moneta/adapters/tokyotyrant/standard_tokyotyrant_spec.rb +5 -2
  163. data/spec/moneta/adapters/tokyotyrant/standard_tokyotyrant_with_expires_spec.rb +5 -1
  164. data/spec/moneta/adapters/yaml/standard_yaml_spec.rb +1 -1
  165. data/spec/moneta/adapters/yaml/standard_yaml_with_expires_spec.rb +1 -1
  166. data/spec/moneta/builder_spec.rb +22 -0
  167. data/spec/moneta/proxies/enumerable/enumerable_spec.rb +26 -0
  168. data/spec/moneta/proxies/expires/expires_file_spec.rb +1 -1
  169. data/spec/moneta/proxies/fallback/fallback_spec.rb +42 -0
  170. data/spec/moneta/proxies/pool/pool_spec.rb +319 -6
  171. data/spec/moneta/proxies/shared/shared_tcp_spec.rb +14 -4
  172. data/spec/moneta/proxies/shared/shared_unix_spec.rb +14 -4
  173. data/spec/moneta/proxies/transformer/transformer_bencode_spec.rb +1 -1
  174. data/spec/moneta/proxies/transformer/transformer_bert_spec.rb +3 -3
  175. data/spec/moneta/proxies/transformer/transformer_bson_spec.rb +2 -2
  176. data/spec/moneta/proxies/transformer/transformer_json_spec.rb +1 -1
  177. data/spec/moneta/proxies/transformer/transformer_key_marshal_spec.rb +1 -1
  178. data/spec/moneta/proxies/transformer/transformer_key_yaml_spec.rb +1 -1
  179. data/spec/moneta/proxies/transformer/transformer_marshal_base64_spec.rb +1 -1
  180. data/spec/moneta/proxies/transformer/transformer_marshal_escape_spec.rb +8 -4
  181. data/spec/moneta/proxies/transformer/transformer_marshal_hex_spec.rb +1 -1
  182. data/spec/moneta/proxies/transformer/transformer_marshal_hmac_spec.rb +1 -1
  183. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_base64_spec.rb +33 -0
  184. data/spec/moneta/proxies/transformer/transformer_marshal_prefix_spec.rb +1 -1
  185. data/spec/moneta/proxies/transformer/transformer_marshal_qp_spec.rb +1 -1
  186. data/spec/moneta/proxies/transformer/transformer_marshal_spec.rb +1 -1
  187. data/spec/moneta/proxies/transformer/transformer_marshal_urlsafe_base64_spec.rb +1 -1
  188. data/spec/moneta/proxies/transformer/transformer_marshal_uuencode_spec.rb +1 -1
  189. data/spec/moneta/proxies/transformer/transformer_msgpack_spec.rb +1 -1
  190. data/spec/moneta/proxies/transformer/transformer_ox_spec.rb +1 -1
  191. data/spec/moneta/proxies/transformer/transformer_php_spec.rb +1 -1
  192. data/spec/moneta/proxies/transformer/transformer_tnet_spec.rb +1 -1
  193. data/spec/moneta/proxies/transformer/transformer_yaml_spec.rb +2 -2
  194. data/spec/moneta/proxies/weak_each_key/weak_each_key_spec.rb +0 -2
  195. data/spec/restserver.rb +55 -0
  196. metadata +136 -32
  197. data/lib/moneta/adapters/mongo/base.rb +0 -103
  198. data/lib/moneta/adapters/mongo/moped.rb +0 -164
  199. data/lib/moneta/adapters/mongo/official.rb +0 -157
  200. data/script/install-kyotocabinet +0 -17
  201. data/spec/moneta/adapters/mongo/adapter_mongo_moped_spec.rb +0 -25
  202. data/spec/moneta/adapters/mongo/adapter_mongo_moped_with_default_expires_spec.rb +0 -12
  203. data/spec/moneta/adapters/mongo/adapter_mongo_official_spec.rb +0 -25
  204. data/spec/moneta/adapters/mongo/adapter_mongo_official_with_default_expires_spec.rb +0 -12
  205. data/spec/moneta/adapters/mongo/standard_mongo_moped_spec.rb +0 -7
  206. data/spec/moneta/adapters/mongo/standard_mongo_official_spec.rb +0 -7
  207. data/spec/quality_spec.rb +0 -51
@@ -2,31 +2,38 @@ shared_examples :concurrent_increment do
2
2
  def increment_thread(name)
3
3
  Thread.new do
4
4
  s = new_store
5
- 100.times do |i|
6
- 100.times do |j|
7
- s.increment("counter#{j}", 1, expires: false)
8
- Thread.pass if rand(1000) >= 995
5
+ begin
6
+ # Create an array where each entry is a list of all the return values
7
+ # from calling increment for a particular key.
8
+ increments = (0...100).map { [] }
9
+ 100.times do
10
+ 100.times do |j|
11
+ increments[j] << s.increment(j.to_s, 1, expires: false)
12
+ Thread.pass if rand(1000) >= 995
13
+ end
9
14
  end
10
- s.store("#{name}#{i}", i.to_s, expires: false)
15
+ increments
16
+ ensure
17
+ s.close
11
18
  end
12
- s.close
13
19
  end
14
20
  end
15
21
 
16
22
  it 'have atomic increment across multiple threads', isolate: true do
17
- a = increment_thread('a')
18
- b = increment_thread('b')
19
- c = increment_thread('c')
20
- a.join
21
- b.join
22
- c.join
23
- 100.times do |i|
24
- store["a#{i}"].should == i.to_s
25
- store["b#{i}"].should == i.to_s
26
- store["c#{i}"].should == i.to_s
27
- end
28
- 100.times do |j|
29
- store.raw["counter#{j}"].should == 300.to_s
23
+ results = %w{a b c}
24
+ .map { |name| increment_thread(name) }
25
+ .map(&:value)
26
+ .transpose # Now the array is indexed by store key instead of thread
27
+
28
+ # Sanity check
29
+ expect(results.length).to eq 100
30
+
31
+ results.each do |ith_values|
32
+ # ensure that for each pair in the triple there are no overlapping values
33
+ expect(ith_values.combination(2).map { |a, b| a & b }).to all be_empty
34
+
35
+ # ensure that when joined together they cover the full 1..300 range
36
+ expect(ith_values.inject(:+)).to contain_exactly(*1..300)
30
37
  end
31
38
  end
32
39
  end
@@ -1,19 +1,19 @@
1
1
  shared_examples :create_expires do
2
- at_each_usec do
3
- it 'creates the given key and expires it' do
4
- store.create('key','value', expires: min_ttl).should be true
5
- store['key'].should == 'value'
6
- advance min_ttl + t_res
7
- store.key?('key').should be false
8
- end
2
+ it 'creates the given key and expires it' do
3
+ store.create('key','value', expires: min_ttl).should be true
4
+ store['key'].should == 'value'
5
+ advance min_ttl
6
+ 2.times { advance_next_tick }
7
+ store.key?('key').should be false
8
+ end
9
9
 
10
- it 'does not change expires if the key exists' do
11
- store.store('key', 'value', expires: false).should == 'value'
12
- store.create('key','another value', expires: min_ttl).should be false
13
- store['key'].should == 'value'
14
- advance min_ttl + t_res
15
- store['key'].should == 'value'
16
- store.key?('key').should be true
17
- end
10
+ it 'does not change expires if the key exists' do
11
+ store.store('key', 'value', expires: false).should == 'value'
12
+ store.create('key','another value', expires: min_ttl).should be false
13
+ store['key'].should == 'value'
14
+ advance min_ttl
15
+ 2.times { advance_next_tick }
16
+ store['key'].should == 'value'
17
+ store.key?('key').should be true
18
18
  end
19
19
  end
@@ -1,15 +1,14 @@
1
1
  shared_examples :default_expires do
2
- at_each_usec do
3
- it 'sets the default expiration time', default_expires: true do
4
- store['key1'] = 'val1'
5
- advance(t_res / 4.0) # sleep less than a single time-space
6
- store.key?('key1').should be true
7
- store.fetch('key1').should == 'val1'
8
- store.load('key1').should == 'val1'
9
- advance min_ttl + t_res
10
- store.key?('key1').should be false
11
- store.fetch('key1').should be_nil
12
- store.load('key1').should be_nil
13
- end
2
+ it 'sets the default expiration time', default_expires: true do
3
+ store['key1'] = 'val1'
4
+ advance(t_res / 4.0) # sleep less than a single time-space
5
+ store.key?('key1').should be true
6
+ store.fetch('key1').should == 'val1'
7
+ store.load('key1').should == 'val1'
8
+ advance min_ttl
9
+ 2.times { advance_next_tick }
10
+ store.key?('key1').should be false
11
+ store.fetch('key1').should be_nil
12
+ store.load('key1').should be_nil
14
13
  end
15
14
  end
@@ -3,289 +3,294 @@ shared_examples :expires do
3
3
  raise "t_res must be <= min_ttl" unless t_res <= min_ttl
4
4
  end
5
5
 
6
- at_each_usec do
7
- # All methods that are used for updating that include an :expires parameter
8
- shared_examples :updater_expiry do
9
- context "with a positive numeric :expires parameter" do
10
- before do
11
- updater.call(expires: min_ttl)
12
- end
6
+ # All methods that are used for updating that include an :expires parameter
7
+ shared_examples :updater_expiry do
8
+ context "with a positive numeric :expires parameter" do
9
+ before do
10
+ updater.call(expires: min_ttl)
11
+ end
13
12
 
14
- it 'causes the value to expire after the given number of seconds' do
15
- keys.zip(values).each do |key, value|
16
- expect(store.load(key)).to eq value
17
- expect(store[key]).to eq value
18
- end
19
- advance min_ttl + t_res
20
- keys.each do |key, value|
21
- expect(store.load(key)).to be_nil
22
- expect(store[key]).to be_nil
23
- end
13
+ it 'causes the value to expire after the given number of seconds' do
14
+ keys.zip(values).each do |key, value|
15
+ expect(store.load(key)).to eq value
16
+ expect(store[key]).to eq value
17
+ end
18
+ advance min_ttl
19
+ 2.times { advance_next_tick }
20
+ keys.each do |key, value|
21
+ expect(store.load(key)).to be_nil
22
+ expect(store[key]).to be_nil
24
23
  end
25
24
  end
25
+ end
26
26
 
27
- shared_examples :updater_no_expires do
28
- it 'causes the value not to expire after the given number of seconds' do
29
- updater.call(expires: expires)
30
- keys.zip(values).each do |key, value|
31
- expect(store.load(key)).to eq value
32
- expect(store[key]).to eq value
33
- end
34
- advance min_ttl + t_res
35
- keys.zip(values).each do |key, value|
36
- expect(store.load(key)).to eq value
37
- expect(store[key]).to eq value
38
- end
27
+ shared_examples :updater_no_expires do
28
+ it 'causes the value not to expire after the given number of seconds' do
29
+ updater.call(expires: expires)
30
+ keys.zip(values).each do |key, value|
31
+ expect(store.load(key)).to eq value
32
+ expect(store[key]).to eq value
33
+ end
34
+ advance min_ttl
35
+ 2.times { advance_next_tick }
36
+ keys.zip(values).each do |key, value|
37
+ expect(store.load(key)).to eq value
38
+ expect(store[key]).to eq value
39
39
  end
40
40
  end
41
+ end
41
42
 
42
- context "with a zero :expires parameter" do
43
- let(:expires) { 0 }
44
- include_examples :updater_no_expires
45
- end
43
+ context "with a zero :expires parameter" do
44
+ let(:expires) { 0 }
45
+ include_examples :updater_no_expires
46
+ end
46
47
 
47
- context "with a false :expires parameter" do
48
- let(:expires) { false }
49
- include_examples :updater_no_expires
50
- end
48
+ context "with a false :expires parameter" do
49
+ let(:expires) { false }
50
+ include_examples :updater_no_expires
51
51
  end
52
+ end
52
53
 
53
- # All methods that are used to for loading, and that include an expire parameter
54
- shared_examples :loader_expiry do
55
- it "does not affect expiry if the value is not present" do
56
- expect(loader.call(expires: min_ttl)).to be_absent
57
- expect(loader.call).to be_absent
58
- end
54
+ # All methods that are used to for loading, and that include an expire parameter
55
+ shared_examples :loader_expiry do
56
+ it "does not affect expiry if the value is not present" do
57
+ expect(loader.call(expires: min_ttl)).to be_absent
58
+ expect(loader.call).to be_absent
59
+ end
59
60
 
60
- shared_examples :loader_expires do
61
- context 'when passed a positive numeric :expires parameter' do
62
- it 'changes the expiry of the value(s) to the given number of seconds' do
63
- expect(loader.call).to be_present
64
- expect(loader.call(expires: min_ttl + 2 * t_res)).to be_present
65
- advance min_ttl + t_res
66
- expect(loader.call).to be_present
67
- advance 2 * t_res
68
- expect(loader.call).to be_absent
69
- end
61
+ shared_examples :loader_expires do
62
+ context 'when passed a positive numeric :expires parameter' do
63
+ it 'changes the expiry of the value(s) to the given number of seconds' do
64
+ expect(loader.call).to be_present
65
+ expect(loader.call(expires: min_ttl + 2 * t_res)).to be_present
66
+ advance min_ttl
67
+ advance_next_tick
68
+ expect(loader.call).to be_present
69
+ 2.times { advance_next_tick }
70
+ expect(loader.call).to be_absent
70
71
  end
71
72
  end
73
+ end
72
74
 
73
- context 'with previously stored expiring value(s)' do
74
- before do
75
- keys.zip(values).each do |key, value|
76
- store.store(key, value, expires: min_ttl)
77
- end
75
+ context 'with previously stored expiring value(s)' do
76
+ before do
77
+ keys.zip(values).each do |key, value|
78
+ store.store(key, value, expires: min_ttl)
78
79
  end
79
- include_examples :loader_expires
80
-
81
- shared_examples :loader_no_expires do
82
- it "changes the expiry of the value(s) so that they don't expire" do
83
- expect(loader.call(expires: expires)).to be_present
84
- advance min_ttl + t_res
85
- expect(loader.call).to be_present
86
- end
80
+ end
81
+ include_examples :loader_expires
82
+
83
+ shared_examples :loader_no_expires do
84
+ it "changes the expiry of the value(s) so that they don't expire" do
85
+ expect(loader.call(expires: expires)).to be_present
86
+ advance min_ttl
87
+ advance_next_tick
88
+ expect(loader.call).to be_present
87
89
  end
90
+ end
88
91
 
89
- context "when passed a zero :expires parameter" do
90
- let(:expires) { 0 }
91
- include_examples :loader_no_expires
92
- end
92
+ context "when passed a zero :expires parameter" do
93
+ let(:expires) { 0 }
94
+ include_examples :loader_no_expires
95
+ end
93
96
 
94
- context "when passed false :expires parameter" do
95
- let(:expires) { false }
96
- include_examples :loader_no_expires
97
- end
97
+ context "when passed false :expires parameter" do
98
+ let(:expires) { false }
99
+ include_examples :loader_no_expires
100
+ end
98
101
 
99
- shared_examples :loader_no_effect do
100
- it 'does not affect the expiry time' do
101
- expect(loader_no_effect.call).to be_present
102
- advance min_ttl + t_res
103
- expect(loader.call).to be_absent
104
- end
102
+ shared_examples :loader_no_effect do
103
+ it 'does not affect the expiry time' do
104
+ expect(loader_no_effect.call).to be_present
105
+ advance min_ttl
106
+ advance_next_tick
107
+ expect(loader.call).to be_absent
105
108
  end
109
+ end
106
110
 
107
- context 'when passed a nil :expires parameter' do
108
- let(:loader_no_effect) { lambda { loader.call(expires: nil) } }
109
- include_examples :loader_no_effect
110
- end
111
+ context 'when passed a nil :expires parameter' do
112
+ let(:loader_no_effect) { lambda { loader.call(expires: nil) } }
113
+ include_examples :loader_no_effect
114
+ end
111
115
 
112
- context 'when not passed an :expires parameter' do
113
- let(:loader_no_effect) { loader }
114
- include_examples :loader_no_effect
115
- end
116
+ context 'when not passed an :expires parameter' do
117
+ let(:loader_no_effect) { loader }
118
+ include_examples :loader_no_effect
116
119
  end
120
+ end
117
121
 
118
- context "with previously stored not expiring value(s)" do
119
- before do
120
- keys.zip(values).each do |key, value|
121
- store.store(key, value, expires: false)
122
- end
122
+ context "with previously stored not expiring value(s)" do
123
+ before do
124
+ keys.zip(values).each do |key, value|
125
+ store.store(key, value, expires: false)
123
126
  end
124
- include_examples :loader_expires
125
127
  end
128
+ include_examples :loader_expires
126
129
  end
130
+ end
127
131
 
128
- describe '#store' do
129
- let(:keys) { ['key1'] }
130
- let(:values) { ['value1'] }
131
- let(:updater) do
132
- lambda do |**options|
133
- expect(store.store(keys[0], values[0], options)).to eq values[0]
134
- end
132
+ describe '#store' do
133
+ let(:keys) { ['key1'] }
134
+ let(:values) { ['value1'] }
135
+ let(:updater) do
136
+ lambda do |**options|
137
+ expect(store.store(keys[0], values[0], options)).to eq values[0]
135
138
  end
139
+ end
136
140
 
137
- include_examples :updater_expiry
141
+ include_examples :updater_expiry
142
+ end
143
+
144
+ describe '#load' do
145
+ let(:keys) { ['key1'] }
146
+ let(:values) { ['value1'] }
147
+ let(:loader) do
148
+ lambda { |**options| store.load('key1', options) }
149
+ end
150
+ let(:be_present) { eq 'value1' }
151
+ let(:be_absent) { be_nil }
152
+
153
+ include_examples :loader_expiry
154
+ end
155
+
156
+ describe '#key?' do
157
+ let(:keys) { ['key1'] }
158
+ let(:values) { ['value1'] }
159
+ let(:loader) do
160
+ lambda { |**options| store.key?('key1', options) }
138
161
  end
162
+ let(:be_present) { be true }
163
+ let(:be_absent) { be false }
164
+
165
+ include_examples :loader_expiry
166
+ end
139
167
 
140
- describe '#load' do
141
- let(:keys) { ['key1'] }
142
- let(:values) { ['value1'] }
168
+ describe '#fetch' do
169
+ let(:keys) { ['key1'] }
170
+ let(:values) { ['value1'] }
171
+ let(:be_present) { eq 'value1' }
172
+
173
+ context "with default given as second parameter" do
143
174
  let(:loader) do
144
- lambda { |**options| store.load('key1', options) }
175
+ lambda { |**options| store.fetch('key1', 'missing', options) }
145
176
  end
146
- let(:be_present) { eq 'value1' }
147
- let(:be_absent) { be_nil }
177
+ let(:be_absent) { eq 'missing' }
148
178
 
149
179
  include_examples :loader_expiry
150
180
  end
151
181
 
152
- describe '#key?' do
153
- let(:keys) { ['key1'] }
154
- let(:values) { ['value1'] }
182
+ context "with default given as a block" do
155
183
  let(:loader) do
156
- lambda { |**options| store.key?('key1', options) }
184
+ lambda { |**options| store.fetch('key1', options) { 'missing' } }
157
185
  end
158
- let(:be_present) { be true }
159
- let(:be_absent) { be false }
186
+ let(:be_absent) { eq 'missing' }
160
187
 
161
188
  include_examples :loader_expiry
162
189
  end
163
190
 
164
- describe '#fetch' do
165
- let(:keys) { ['key1'] }
166
- let(:values) { ['value1'] }
167
- let(:be_present) { eq 'value1' }
168
-
169
- context "with default given as second parameter" do
170
- let(:loader) do
171
- lambda { |**options| store.fetch('key1', 'missing', options) }
172
- end
173
- let(:be_absent) { eq 'missing' }
174
-
175
- include_examples :loader_expiry
191
+ context "with nil default given" do
192
+ let(:loader) do
193
+ lambda { |**options| store.fetch('key1', nil, options) }
176
194
  end
195
+ let(:be_absent) { be_nil }
177
196
 
178
- context "with default given as a block" do
179
- let(:loader) do
180
- lambda { |**options| store.fetch('key1', options) { 'missing' } }
181
- end
182
- let(:be_absent) { eq 'missing' }
197
+ include_examples :loader_expiry
198
+ end
199
+ end
183
200
 
184
- include_examples :loader_expiry
201
+ describe '#delete' do
202
+ context 'with an already expired value' do
203
+ before do
204
+ store.store('key2', 'val2', expires: min_ttl)
205
+ expect(store['key2']).to eq 'val2'
206
+ advance min_ttl
207
+ advance_next_tick
185
208
  end
186
209
 
187
- context "with nil default given" do
188
- let(:loader) do
189
- lambda { |**options| store.fetch('key1', nil, options) }
190
- end
191
- let(:be_absent) { be_nil }
192
-
193
- include_examples :loader_expiry
210
+ it 'does not return the expired value' do
211
+ expect(store.delete('key2')).to be_nil
194
212
  end
195
213
  end
214
+ end
196
215
 
197
- describe '#delete' do
198
- context 'with an already expired value' do
199
- before do
200
- store.store('key2', 'val2', expires: min_ttl)
201
- expect(store['key2']).to eq 'val2'
202
- advance min_ttl + t_res
203
- end
216
+ describe '#expires' do
217
+ it "returns a store with access to the same items" do
218
+ store.store('persistent_key', 'persistent_value', expires: false)
219
+ store_expires = store.expires(min_ttl)
220
+ expect(store_expires['persistent_key']).to eq 'persistent_value'
221
+ end
204
222
 
205
- it 'does not return the expired value' do
206
- expect(store.delete('key2')).to be_nil
207
- end
208
- end
223
+ it "returns a store with default expiry set" do
224
+ store_expires = store.expires(min_ttl)
225
+ expect(store_expires.store('key1', 'val1')).to eq 'val1'
226
+ expect(store_expires['key1']).to eq 'val1'
227
+ advance min_ttl
228
+ advance_next_tick
229
+ expect(store['key1']).to be_nil
209
230
  end
231
+ end
210
232
 
211
- describe '#expires' do
212
- it "returns a store with access to the same items" do
213
- store.store('persistent_key', 'persistent_value', expires: false)
214
- store_expires = store.expires(min_ttl)
215
- expect(store_expires['persistent_key']).to eq 'persistent_value'
233
+ describe '#merge!' do
234
+ let(:keys) { ['key1', 'key2'] }
235
+ let(:values) { ['value1', 'value2'] }
236
+ let(:updater) do
237
+ lambda do |**options|
238
+ expect(store.merge!(keys.zip(values), options)).to eq store
216
239
  end
240
+ end
217
241
 
218
- it "returns a store with default expiry set" do
219
- store_expires = store.expires(min_ttl)
220
- expect(store_expires.store('key1', 'val1')).to eq 'val1'
221
- expect(store_expires['key1']).to eq 'val1'
222
- advance min_ttl + t_res
223
- expect(store['key1']).to be_nil
224
- end
242
+ include_examples :updater_expiry
243
+ end
244
+
245
+ describe '#values_at' do
246
+ let(:keys) { ['key1', 'key2'] }
247
+ let(:values) { ['value1', 'value2'] }
248
+ let(:loader) do
249
+ lambda { |**options| store.values_at('key1', 'key2', **options) }
225
250
  end
251
+ let(:be_present) { eq ['value1', 'value2'] }
252
+ let(:be_absent) { eq [nil, nil] }
226
253
 
227
- describe '#merge!' do
228
- let(:keys) { ['key1', 'key2'] }
229
- let(:values) { ['value1', 'value2'] }
230
- let(:updater) do
254
+ include_examples :loader_expiry
255
+ end
256
+
257
+ describe '#fetch_values' do
258
+ let(:keys) { ['key1', 'key2'] }
259
+ let(:values) { ['value1', 'value2'] }
260
+ let(:be_present) { eq ['value1', 'value2'] }
261
+
262
+ context 'with default values given via a block' do
263
+ let(:loader) do
231
264
  lambda do |**options|
232
- expect(store.merge!(keys.zip(values), options)).to eq store
265
+ store.fetch_values('key1', 'key2', **options) { |k| "#{k} missing" }
233
266
  end
234
267
  end
268
+ let(:be_absent) { eq ['key1 missing', 'key2 missing'] }
235
269
 
236
- include_examples :updater_expiry
270
+ include_examples :loader_expiry
237
271
  end
238
272
 
239
- describe '#values_at' do
240
- let(:keys) { ['key1', 'key2'] }
241
- let(:values) { ['value1', 'value2'] }
273
+ context 'without default values given' do
242
274
  let(:loader) do
243
- lambda { |**options| store.values_at('key1', 'key2', **options) }
275
+ lambda do |**options|
276
+ store.fetch_values('key1', 'key2', **options)
277
+ end
244
278
  end
245
- let(:be_present) { eq ['value1', 'value2'] }
246
279
  let(:be_absent) { eq [nil, nil] }
247
280
 
248
281
  include_examples :loader_expiry
249
282
  end
283
+ end
250
284
 
251
- describe '#fetch_values' do
252
- let(:keys) { ['key1', 'key2'] }
253
- let(:values) { ['value1', 'value2'] }
254
- let(:be_present) { eq ['value1', 'value2'] }
255
-
256
- context 'with default values given via a block' do
257
- let(:loader) do
258
- lambda do |**options|
259
- store.fetch_values('key1', 'key2', **options) { |k| "#{k} missing" }
260
- end
261
- end
262
- let(:be_absent) { eq ['key1 missing', 'key2 missing'] }
263
-
264
- include_examples :loader_expiry
265
- end
266
-
267
- context 'without default values given' do
268
- let(:loader) do
269
- lambda do |**options|
270
- store.fetch_values('key1', 'key2', **options)
271
- end
272
- end
273
- let(:be_absent) { eq [nil, nil] }
274
-
275
- include_examples :loader_expiry
276
- end
285
+ describe '#slice' do
286
+ let(:keys) { ['key1', 'key2'] }
287
+ let(:values) { ['value1', 'value2'] }
288
+ let(:loader) do
289
+ lambda { |**options| store.slice('key1', 'key2', **options) }
277
290
  end
291
+ let(:be_present) { contain_exactly(['key1', 'value1'], ['key2', 'value2']) }
292
+ let(:be_absent) { be_empty }
278
293
 
279
- describe '#slice' do
280
- let(:keys) { ['key1', 'key2'] }
281
- let(:values) { ['value1', 'value2'] }
282
- let(:loader) do
283
- lambda { |**options| store.slice('key1', 'key2', **options) }
284
- end
285
- let(:be_present) { contain_exactly(['key1', 'value1'], ['key2', 'value2']) }
286
- let(:be_absent) { be_empty }
287
-
288
- include_examples :loader_expiry
289
- end
294
+ include_examples :loader_expiry
290
295
  end
291
296
  end