moneta 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +1 -0
- data/CHANGES +21 -10
- data/README.md +1 -1
- data/SPEC.md +4 -12
- data/lib/moneta.rb +7 -5
- data/lib/moneta/adapters/activerecord.rb +9 -3
- data/lib/moneta/adapters/cassandra.rb +9 -4
- data/lib/moneta/adapters/client.rb +9 -3
- data/lib/moneta/adapters/cookie.rb +3 -0
- data/lib/moneta/adapters/couch.rb +8 -3
- data/lib/moneta/adapters/datamapper.rb +8 -3
- data/lib/moneta/adapters/dbm.rb +1 -2
- data/lib/moneta/adapters/file.rb +9 -4
- data/lib/moneta/adapters/fog.rb +8 -3
- data/lib/moneta/adapters/gdbm.rb +1 -2
- data/lib/moneta/adapters/hbase.rb +10 -3
- data/lib/moneta/adapters/leveldb.rb +3 -2
- data/lib/moneta/adapters/localmemcache.rb +4 -4
- data/lib/moneta/adapters/lruhash.rb +8 -4
- data/lib/moneta/adapters/memcached/dalli.rb +10 -4
- data/lib/moneta/adapters/memcached/native.rb +9 -4
- data/lib/moneta/adapters/memory.rb +8 -3
- data/lib/moneta/adapters/mongo.rb +7 -3
- data/lib/moneta/adapters/null.rb +8 -1
- data/lib/moneta/adapters/pstore.rb +9 -3
- data/lib/moneta/adapters/redis.rb +10 -4
- data/lib/moneta/adapters/riak.rb +12 -7
- data/lib/moneta/adapters/sdbm.rb +1 -2
- data/lib/moneta/adapters/sequel.rb +9 -3
- data/lib/moneta/adapters/sqlite.rb +10 -4
- data/lib/moneta/adapters/tokyocabinet.rb +2 -2
- data/lib/moneta/builder.rb +11 -7
- data/lib/moneta/cache.rb +16 -6
- data/lib/moneta/expires.rb +12 -6
- data/lib/moneta/lock.rb +0 -2
- data/lib/moneta/logger.rb +0 -2
- data/lib/moneta/mixins.rb +175 -47
- data/lib/moneta/optionmerger.rb +2 -0
- data/lib/moneta/proxy.rb +14 -30
- data/lib/moneta/server.rb +0 -2
- data/lib/moneta/shared.rb +1 -3
- data/lib/moneta/stack.rb +20 -10
- data/lib/moneta/transformer.rb +84 -61
- data/lib/moneta/version.rb +1 -1
- data/lib/rack/moneta_rest.rb +56 -0
- data/moneta.gemspec +1 -1
- data/spec/active_support/cache_moneta_store_spec.rb +4 -4
- data/spec/generate.rb +216 -203
- data/spec/helper.rb +0 -6
- data/spec/moneta/adapter_cassandra_spec.rb +2 -2
- data/spec/moneta/adapter_datamapper_spec.rb +1 -1
- data/spec/moneta/adapter_lruhash_spec.rb +1 -1
- data/spec/moneta/adapter_memcached_dalli_spec.rb +2 -2
- data/spec/moneta/adapter_memcached_native_spec.rb +2 -2
- data/spec/moneta/adapter_memcached_spec.rb +2 -2
- data/spec/moneta/adapter_redis_spec.rb +2 -2
- data/spec/moneta/cache_file_memory_spec.rb +3 -3
- data/spec/moneta/expires_file_spec.rb +4 -4
- data/spec/moneta/expires_memory_spec.rb +2 -2
- data/spec/moneta/optionmerger_spec.rb +6 -6
- data/spec/moneta/shared_spec.rb +1 -1
- data/spec/moneta/simple_client_tcp_spec.rb +1 -1
- data/spec/moneta/transformer_key_marshal_spec.rb +109 -0
- data/spec/moneta/transformer_key_yaml_spec.rb +109 -0
- data/spec/moneta/transformer_marshal_spec.rb +109 -0
- data/spec/moneta/transformer_value_marshal_spec.rb +109 -0
- data/spec/moneta/transformer_value_yaml_spec.rb +109 -0
- data/spec/monetaspecs.rb +14460 -3956
- metadata +16 -6
- data/lib/moneta/base.rb +0 -98
- data/lib/moneta/net.rb +0 -22
data/lib/moneta/transformer.rb
CHANGED
@@ -10,19 +10,17 @@ module Moneta
|
|
10
10
|
#
|
11
11
|
# @example Bypass serialization
|
12
12
|
# store.store('key', 'value', :raw => true)
|
13
|
-
# store['key']
|
14
|
-
# store.load('key', :raw => true)
|
13
|
+
# store['key'] # raises an Exception
|
14
|
+
# store.load('key', :raw => true) # returns 'value'
|
15
15
|
#
|
16
16
|
# store['key'] = 'value'
|
17
|
-
# store.load('key', :raw => true)
|
17
|
+
# store.load('key', :raw => true) # returns "\x04\bI\"\nvalue\x06:\x06ET"
|
18
18
|
#
|
19
19
|
# @api public
|
20
20
|
class Transformer < Proxy
|
21
21
|
class << self
|
22
22
|
alias_method :original_new, :new
|
23
23
|
|
24
|
-
# Constructor
|
25
|
-
#
|
26
24
|
# @param [Moneta store] adapter The underlying store
|
27
25
|
# @param [Hash] options
|
28
26
|
# @return [Transformer] new Moneta transformer
|
@@ -31,28 +29,25 @@ module Moneta
|
|
31
29
|
# @option options [String] :prefix Prefix string for key namespacing (Used by the :prefix key transformer)
|
32
30
|
# @option options [String] :secret HMAC secret to verify values (Used by the :hmac value transformer)
|
33
31
|
# @option options [Integer] :maxlen Maximum key length (Used by the :truncate key transformer)
|
34
|
-
# @option options [Boolean] :quiet Disable error message
|
35
32
|
def new(adapter, options = {})
|
36
33
|
keys = [options[:key]].flatten.compact
|
37
34
|
values = [options[:value]].flatten.compact
|
38
35
|
raise ArgumentError, 'Option :key or :value is required' if keys.empty? && values.empty?
|
39
36
|
options[:prefix] ||= '' if keys.include?(:prefix)
|
40
|
-
name = class_name(
|
41
|
-
const_set(name, compile(
|
37
|
+
name = class_name(keys, values)
|
38
|
+
const_set(name, compile(keys, values)) unless const_defined?(name)
|
42
39
|
const_get(name).original_new(adapter, options)
|
43
40
|
end
|
44
41
|
|
45
42
|
private
|
46
43
|
|
47
|
-
def compile(
|
44
|
+
def compile(keys, values)
|
48
45
|
@key_validator ||= compile_validator(KEY_TRANSFORMER)
|
49
46
|
@value_validator ||= compile_validator(VALUE_TRANSFORMER)
|
50
47
|
|
51
48
|
raise ArgumentError, 'Invalid key transformer chain' if @key_validator !~ keys.map(&:inspect).join
|
52
49
|
raise ArgumentError, 'Invalid value transformer chain' if @value_validator !~ values.map(&:inspect).join
|
53
50
|
|
54
|
-
key = compile_transformer(keys, 'key')
|
55
|
-
|
56
51
|
klass = Class.new(self)
|
57
52
|
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
58
53
|
def initialize(adapter, options = {})
|
@@ -60,62 +55,90 @@ module Moneta
|
|
60
55
|
#{compile_initializer('key', keys)}
|
61
56
|
#{compile_initializer('value', values)}
|
62
57
|
end
|
58
|
+
end_eval
|
59
|
+
|
60
|
+
key = compile_transformer(keys, 'key')
|
61
|
+
dump = compile_transformer(values, 'value')
|
62
|
+
load = compile_transformer(values.reverse, 'value', 1)
|
63
|
+
|
64
|
+
if values.empty?
|
65
|
+
compile_key_transformer(klass, key)
|
66
|
+
elsif keys.empty?
|
67
|
+
compile_value_transformer(klass, load, dump)
|
68
|
+
else
|
69
|
+
compile_key_value_transformer(klass, key, load, dump)
|
70
|
+
end
|
71
|
+
|
72
|
+
klass
|
73
|
+
end
|
74
|
+
|
75
|
+
def compile_key_transformer(klass, key)
|
76
|
+
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
63
77
|
def key?(key, options = {})
|
64
78
|
@adapter.key?(#{key}, options)
|
65
79
|
end
|
66
80
|
def increment(key, amount = 1, options = {})
|
67
81
|
@adapter.increment(#{key}, amount, options)
|
68
82
|
end
|
83
|
+
def load(key, options = {})
|
84
|
+
options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
85
|
+
@adapter.load(#{key}, options)
|
86
|
+
end
|
87
|
+
def store(key, value, options = {})
|
88
|
+
options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
89
|
+
@adapter.store(#{key}, value, options)
|
90
|
+
end
|
91
|
+
def delete(key, options = {})
|
92
|
+
options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
93
|
+
@adapter.delete(#{key}, options)
|
94
|
+
end
|
69
95
|
end_eval
|
96
|
+
end
|
70
97
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
116
|
-
end_eval
|
117
|
-
end
|
118
|
-
klass
|
98
|
+
def compile_value_transformer(klass, load, dump)
|
99
|
+
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
100
|
+
def load(key, options = {})
|
101
|
+
raw = options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
102
|
+
value = @adapter.load(key, options)
|
103
|
+
value && !raw ? #{load} : value
|
104
|
+
end
|
105
|
+
def store(key, value, options = {})
|
106
|
+
raw = options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
107
|
+
@adapter.store(key, raw ? value : #{dump}, options)
|
108
|
+
value
|
109
|
+
end
|
110
|
+
def delete(key, options = {})
|
111
|
+
raw = options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
112
|
+
value = @adapter.delete(key, options)
|
113
|
+
value && !raw ? #{load} : value
|
114
|
+
end
|
115
|
+
end_eval
|
116
|
+
end
|
117
|
+
|
118
|
+
def compile_key_value_transformer(klass, key, load, dump)
|
119
|
+
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
120
|
+
def key?(key, options = {})
|
121
|
+
@adapter.key?(#{key}, options)
|
122
|
+
end
|
123
|
+
def increment(key, amount = 1, options = {})
|
124
|
+
@adapter.increment(#{key}, amount, options)
|
125
|
+
end
|
126
|
+
def load(key, options = {})
|
127
|
+
raw = options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
128
|
+
value = @adapter.load(#{key}, options)
|
129
|
+
value && !raw ? #{load} : value
|
130
|
+
end
|
131
|
+
def store(key, value, options = {})
|
132
|
+
raw = options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
133
|
+
@adapter.store(#{key}, raw ? value : #{dump}, options)
|
134
|
+
value
|
135
|
+
end
|
136
|
+
def delete(key, options = {})
|
137
|
+
raw = options.include?(:raw) && (options = options.dup; options.delete(:raw))
|
138
|
+
value = @adapter.delete(#{key}, options)
|
139
|
+
value && !raw ? #{load} : value
|
140
|
+
end
|
141
|
+
end_eval
|
119
142
|
end
|
120
143
|
|
121
144
|
# Compile option initializer
|
@@ -149,8 +172,8 @@ module Moneta
|
|
149
172
|
end
|
150
173
|
end
|
151
174
|
|
152
|
-
def class_name(
|
153
|
-
|
175
|
+
def class_name(keys, values)
|
176
|
+
(keys.empty? ? '' : keys.map(&:to_s).map(&:capitalize).join << 'Key') <<
|
154
177
|
(values.empty? ? '' : values.map(&:to_s).map(&:capitalize).join << 'Value')
|
155
178
|
end
|
156
179
|
end
|
data/lib/moneta/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'moneta'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class MonetaRest
|
5
|
+
def initialize(store = nil, options = {}, &block)
|
6
|
+
if block
|
7
|
+
raise ArgumentError, 'Use either block or options' unless options.emtpy?
|
8
|
+
@store = ::Moneta.build(&block)
|
9
|
+
else
|
10
|
+
raise ArgumentError, 'Option :store is required' unless @store = store
|
11
|
+
@store = ::Moneta.new(@store, options) if Symbol === @store
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
key = env['PATH_INFO'][1..-1]
|
17
|
+
case env['REQUEST_METHOD']
|
18
|
+
when 'HEAD'
|
19
|
+
if @store.key?(key)
|
20
|
+
respond(200)
|
21
|
+
else
|
22
|
+
empty(404)
|
23
|
+
end
|
24
|
+
when 'GET'
|
25
|
+
if value = @store[key]
|
26
|
+
respond(200, value)
|
27
|
+
else
|
28
|
+
empty(404)
|
29
|
+
end
|
30
|
+
when 'POST', 'PUT'
|
31
|
+
respond(200, @store[key] = env['rack.input'].read)
|
32
|
+
when 'DELETE'
|
33
|
+
if key.empty?
|
34
|
+
@store.clear
|
35
|
+
empty(200)
|
36
|
+
else
|
37
|
+
respond(200, @store.delete(key))
|
38
|
+
end
|
39
|
+
else
|
40
|
+
empty(400)
|
41
|
+
end
|
42
|
+
rescue => ex
|
43
|
+
respond(500, ex.message)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def empty(status)
|
49
|
+
[status, {'Content-Type'=>'application/octet-stream', 'Content-Length' => '0'}, []]
|
50
|
+
end
|
51
|
+
|
52
|
+
def respond(status, value)
|
53
|
+
[status, {'Content-Type'=>'application/octet-stream', 'Content-Length' => value.bytesize.to_s}, [value]]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/moneta.gemspec
CHANGED
@@ -15,5 +15,5 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
16
|
s.homepage = 'http://github.com/minad/moneta'
|
17
17
|
s.require_paths = ['lib']
|
18
|
-
s.summary = %{A unified interface to key/value stores, including
|
18
|
+
s.summary = %{A unified interface to key/value stores, including Redis, Memcached, TokyoCabinet, ActiveRecord and many more}
|
19
19
|
end
|
@@ -76,24 +76,24 @@ describe ActiveSupport::Cache::MonetaStore do
|
|
76
76
|
|
77
77
|
it 'increments a key' do
|
78
78
|
3.times { @store.increment 'counter' }
|
79
|
-
@store.read('counter').should == '3'
|
79
|
+
@store.read('counter', :raw => true).should == '3'
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'decrements a key' do
|
83
83
|
3.times { @store.increment 'counter' }
|
84
84
|
2.times { @store.decrement 'counter' }
|
85
|
-
@store.read('counter').should == '1'
|
85
|
+
@store.read('counter', :raw => true).should == '1'
|
86
86
|
end
|
87
87
|
|
88
88
|
it 'increments a key by given value' do
|
89
89
|
@store.increment 'counter', 3
|
90
|
-
@store.read('counter').should == '3'
|
90
|
+
@store.read('counter', :raw => true).should == '3'
|
91
91
|
end
|
92
92
|
|
93
93
|
it 'decrements a key by given value' do
|
94
94
|
3.times { @store.increment 'counter' }
|
95
95
|
@store.decrement 'counter', 2
|
96
|
-
@store.read('counter').should == '1'
|
96
|
+
@store.read('counter', :raw => true).should == '1'
|
97
97
|
end
|
98
98
|
|
99
99
|
describe 'notifications' do
|
data/spec/generate.rb
CHANGED
@@ -3,24 +3,24 @@ class Specs
|
|
3
3
|
|
4
4
|
def initialize(specs, key = nil, value = nil)
|
5
5
|
@specs = specs
|
6
|
-
@key = key || %w(
|
7
|
-
@value = value || %w(
|
6
|
+
@key = key || %w(object string hash boolean nil integer)
|
7
|
+
@value = value || %w(object string hash boolean nil integer)
|
8
8
|
end
|
9
9
|
|
10
10
|
def stringkeys_only
|
11
|
-
Specs.new(specs, %w(
|
11
|
+
Specs.new(specs, %w(string), value)
|
12
12
|
end
|
13
13
|
|
14
14
|
def stringvalues_only
|
15
|
-
Specs.new(specs, key, %w(
|
15
|
+
Specs.new(specs, key, %w(string))
|
16
16
|
end
|
17
17
|
|
18
18
|
def simplekeys_only
|
19
|
-
Specs.new(specs, %w(
|
19
|
+
Specs.new(specs, %w(string hash integer), value)
|
20
20
|
end
|
21
21
|
|
22
22
|
def simplevalues_only
|
23
|
-
Specs.new(specs, key, %w(
|
23
|
+
Specs.new(specs, key, %w(string hash integer))
|
24
24
|
end
|
25
25
|
|
26
26
|
def without_increment
|
@@ -95,7 +95,7 @@ class Specs
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
ADAPTER_SPECS = Specs.new([:null, :store, :returndifferent, :increment, :persist], %w(
|
98
|
+
ADAPTER_SPECS = Specs.new([:null, :store, :returndifferent, :increment, :persist], %w(string), %w(string))
|
99
99
|
STANDARD_SPECS = Specs.new([:null, :store, :returndifferent, :marshallable_key, :marshallable_value, :transform_value, :increment, :persist])
|
100
100
|
TRANSFORMER_SPECS = Specs.new([:null, :store, :returndifferent, :transform_value, :increment])
|
101
101
|
|
@@ -107,7 +107,7 @@ TESTS = {
|
|
107
107
|
:store => :Client,
|
108
108
|
:specs => STANDARD_SPECS,
|
109
109
|
:tests => %{
|
110
|
-
it '
|
110
|
+
it 'supports multiple clients' do
|
111
111
|
client = Moneta.new(:Client)
|
112
112
|
client['shared_key'] = 'shared_val'
|
113
113
|
(1..100).each do |i|
|
@@ -449,7 +449,7 @@ end
|
|
449
449
|
end},
|
450
450
|
:specs => STANDARD_SPECS.without_transform.with_expires.without_persist,
|
451
451
|
:tests => %{
|
452
|
-
it '
|
452
|
+
it 'supports default expiration time' do
|
453
453
|
store = Moneta.new(:Memory, :expires => 2)
|
454
454
|
store.store('key1', 'val1')
|
455
455
|
store.store('key2', 'val2', :expires => 60)
|
@@ -457,7 +457,7 @@ it 'should support default expiration time' do
|
|
457
457
|
sleep 1
|
458
458
|
store.load('key1').should == 'val1'
|
459
459
|
sleep 2
|
460
|
-
store.load('key1').should
|
460
|
+
store.load('key1').should be_nil
|
461
461
|
store['key2'].should == 'val2'
|
462
462
|
end}
|
463
463
|
},
|
@@ -469,15 +469,15 @@ end}
|
|
469
469
|
end},
|
470
470
|
:specs => STANDARD_SPECS.with_expires.stringvalues_only,
|
471
471
|
:tests => %{
|
472
|
-
it '
|
472
|
+
it 'deletes expired value in underlying file storage' do
|
473
473
|
store.store('foo', 'bar', :expires => 2)
|
474
474
|
store['foo'].should == 'bar'
|
475
475
|
sleep 1
|
476
476
|
store['foo'].should == 'bar'
|
477
477
|
sleep 2
|
478
|
-
store['foo'].should
|
479
|
-
store.adapter['foo'].should
|
480
|
-
store.adapter.adapter['foo'].should
|
478
|
+
store['foo'].should be_nil
|
479
|
+
store.adapter['foo'].should be_nil
|
480
|
+
store.adapter.adapter['foo'].should be_nil
|
481
481
|
end
|
482
482
|
}
|
483
483
|
},
|
@@ -507,15 +507,15 @@ end},
|
|
507
507
|
end},
|
508
508
|
:specs => ADAPTER_SPECS,
|
509
509
|
:tests => %{
|
510
|
-
it '
|
510
|
+
it 'stores loaded values in cache' do
|
511
511
|
store.backend['foo'] = 'bar'
|
512
|
-
store.cache['foo'].should
|
512
|
+
store.cache['foo'].should be_nil
|
513
513
|
store['foo'].should == 'bar'
|
514
514
|
store.cache['foo'].should == 'bar'
|
515
515
|
store.backend.delete('foo')
|
516
516
|
store['foo'].should == 'bar'
|
517
517
|
store.delete('foo')
|
518
|
-
store['foo'].should
|
518
|
+
store['foo'].should be_nil
|
519
519
|
end
|
520
520
|
}
|
521
521
|
},
|
@@ -536,7 +536,7 @@ end},
|
|
536
536
|
end},
|
537
537
|
:specs => ADAPTER_SPECS.without_persist,
|
538
538
|
:tests => %{
|
539
|
-
it '
|
539
|
+
it 'shares values' do
|
540
540
|
store['shared_key'] = 'shared_value'
|
541
541
|
second = new_store
|
542
542
|
second.key?('shared_key').should be_true
|
@@ -678,10 +678,50 @@ end},
|
|
678
678
|
:specs => TRANSFORMER_SPECS.simplekeys_only.simplevalues_only,
|
679
679
|
:load_value => '::MessagePack.unpack(value)'
|
680
680
|
},
|
681
|
+
'transformer_marshal' => {
|
682
|
+
:build => %{Moneta.build do
|
683
|
+
use :Transformer, :key => :marshal, :value => :marshal
|
684
|
+
adapter :Memory
|
685
|
+
end},
|
686
|
+
:specs => TRANSFORMER_SPECS,
|
687
|
+
:load_value => '::Marshal.load(value)'
|
688
|
+
},
|
689
|
+
'transformer_key_marshal' => {
|
690
|
+
:build => %{Moneta.build do
|
691
|
+
use :Transformer, :key => :marshal
|
692
|
+
adapter :Memory
|
693
|
+
end},
|
694
|
+
:specs => TRANSFORMER_SPECS,
|
695
|
+
:load_value => 'value'
|
696
|
+
},
|
697
|
+
'transformer_value_marshal' => {
|
698
|
+
:build => %{Moneta.build do
|
699
|
+
use :Transformer, :value => :marshal
|
700
|
+
adapter :Memory
|
701
|
+
end},
|
702
|
+
:specs => TRANSFORMER_SPECS,
|
703
|
+
:load_value => '::Marshal.load(value)'
|
704
|
+
},
|
681
705
|
'transformer_yaml' => {
|
682
706
|
:build => %{Moneta.build do
|
683
707
|
use :Transformer, :key => :yaml, :value => :yaml
|
684
708
|
adapter :Memory
|
709
|
+
end},
|
710
|
+
:specs => TRANSFORMER_SPECS,
|
711
|
+
:load_value => '::YAML.load(value)'
|
712
|
+
},
|
713
|
+
'transformer_key_yaml' => {
|
714
|
+
:build => %{Moneta.build do
|
715
|
+
use :Transformer, :key => :yaml
|
716
|
+
adapter :Memory
|
717
|
+
end},
|
718
|
+
:specs => TRANSFORMER_SPECS,
|
719
|
+
:load_value => 'value'
|
720
|
+
},
|
721
|
+
'transformer_value_yaml' => {
|
722
|
+
:build => %{Moneta.build do
|
723
|
+
use :Transformer, :value => :yaml
|
724
|
+
adapter :Memory
|
685
725
|
end},
|
686
726
|
:specs => TRANSFORMER_SPECS,
|
687
727
|
:load_value => '::YAML.load(value)'
|
@@ -808,7 +848,7 @@ end
|
|
808
848
|
:build => "Moneta::Adapters::Cassandra.new(:keyspace => 'adapter_cassandra')",
|
809
849
|
:specs => ADAPTER_SPECS.without_increment.with_expires,
|
810
850
|
:tests => %{
|
811
|
-
it '
|
851
|
+
it 'supports default expiration time' do
|
812
852
|
store = Moneta::Adapters::Cassandra.new(:expires => 2, :keyspace => 'adapter_cassandra')
|
813
853
|
store.store('key1', 'val1')
|
814
854
|
store.store('key2', 'val2', :expires => 60)
|
@@ -816,7 +856,7 @@ it 'should support default expiration time' do
|
|
816
856
|
sleep 1
|
817
857
|
store.load('key1').should == 'val1'
|
818
858
|
sleep 2
|
819
|
-
store.load('key1').should
|
859
|
+
store.load('key1').should be_nil
|
820
860
|
store['key2'].should == 'val2'
|
821
861
|
end}
|
822
862
|
},
|
@@ -863,7 +903,7 @@ it 'does not cross contaminate when deleting' do
|
|
863
903
|
second['key'] = 'value2'
|
864
904
|
|
865
905
|
first.delete('key').should == 'value'
|
866
|
-
first.key?('key').should
|
906
|
+
first.key?('key').should be_false
|
867
907
|
second['key'].should == 'value2'
|
868
908
|
end
|
869
909
|
}
|
@@ -897,7 +937,7 @@ end
|
|
897
937
|
:build => 'Moneta::Adapters::MemcachedDalli.new(:namespace => "adapter_memcached_dalli")',
|
898
938
|
:specs => ADAPTER_SPECS.with_expires,
|
899
939
|
:tests => %{
|
900
|
-
it '
|
940
|
+
it 'supports default expiration time' do
|
901
941
|
store = Moneta::Adapters::MemcachedDalli.new(:expires => 2, :namespace => "adapter_memcached_dalli")
|
902
942
|
store.store('key1', 'val1')
|
903
943
|
store.store('key2', 'val2', :expires => 60)
|
@@ -905,7 +945,7 @@ it 'should support default expiration time' do
|
|
905
945
|
sleep 1
|
906
946
|
store.load('key1').should == 'val1'
|
907
947
|
sleep 2
|
908
|
-
store.load('key1').should
|
948
|
+
store.load('key1').should be_nil
|
909
949
|
store['key2'].should == 'val2'
|
910
950
|
end}
|
911
951
|
},
|
@@ -913,7 +953,7 @@ end}
|
|
913
953
|
:build => 'Moneta::Adapters::MemcachedNative.new(:namespace => "adapter_memcached_native")',
|
914
954
|
:specs => ADAPTER_SPECS.with_expires,
|
915
955
|
:tests => %{
|
916
|
-
it '
|
956
|
+
it 'supports default expiration time' do
|
917
957
|
store = Moneta::Adapters::MemcachedNative.new(:expires => 2, :namespace => "adapter_memcached_native")
|
918
958
|
store.store('key1', 'val1')
|
919
959
|
store.store('key2', 'val2', :expires => 60)
|
@@ -921,7 +961,7 @@ it 'should support default expiration time' do
|
|
921
961
|
sleep 1
|
922
962
|
store.load('key1').should == 'val1'
|
923
963
|
sleep 2
|
924
|
-
store.load('key1').should
|
964
|
+
store.load('key1').should be_nil
|
925
965
|
store['key2'].should == 'val2'
|
926
966
|
end
|
927
967
|
}
|
@@ -930,7 +970,7 @@ end
|
|
930
970
|
:build => 'Moneta::Adapters::Memcached.new(:namespace => "adapter_memcached")',
|
931
971
|
:specs => ADAPTER_SPECS.with_expires,
|
932
972
|
:tests => %{
|
933
|
-
it '
|
973
|
+
it 'supports default expiration time' do
|
934
974
|
store = Moneta::Adapters::Memcached.new(:expires => 2, :namespace => "adapter_memcached")
|
935
975
|
store.store('key1', 'val1')
|
936
976
|
store.store('key2', 'val2', :expires => 60)
|
@@ -938,7 +978,7 @@ it 'should support default expiration time' do
|
|
938
978
|
sleep 1
|
939
979
|
store.load('key1').should == 'val1'
|
940
980
|
sleep 2
|
941
|
-
store.load('key1').should
|
981
|
+
store.load('key1').should be_nil
|
942
982
|
store['key2'].should == 'val2'
|
943
983
|
end}
|
944
984
|
},
|
@@ -950,7 +990,7 @@ end}
|
|
950
990
|
:build => 'Moneta::Adapters::LRUHash.new',
|
951
991
|
:specs => ADAPTER_SPECS.without_persist,
|
952
992
|
:tests => %{
|
953
|
-
it '
|
993
|
+
it 'deletes oldest' do
|
954
994
|
store = Moneta::Adapters::LRUHash.new(:max_size => 10)
|
955
995
|
store[0] = 'y'
|
956
996
|
(1..1000).each do |i|
|
@@ -976,7 +1016,7 @@ end}
|
|
976
1016
|
:build => 'Moneta::Adapters::Redis.new',
|
977
1017
|
:specs => ADAPTER_SPECS.with_expires,
|
978
1018
|
:tests => %{
|
979
|
-
it '
|
1019
|
+
it 'supports default expiration time' do
|
980
1020
|
store = Moneta::Adapters::Redis.new(:expires => 2)
|
981
1021
|
store.store('key1', 'val1')
|
982
1022
|
store.store('key2', 'val2', :expires => 60)
|
@@ -984,7 +1024,7 @@ it 'should support default expiration time' do
|
|
984
1024
|
sleep 1
|
985
1025
|
store.load('key1').should == 'val1'
|
986
1026
|
sleep 2
|
987
|
-
store.load('key1').should
|
1027
|
+
store.load('key1').should be_nil
|
988
1028
|
store['key2'].should == 'val2'
|
989
1029
|
end}
|
990
1030
|
},
|
@@ -1033,7 +1073,7 @@ it '#with should return OptionMerger' do
|
|
1033
1073
|
merger.should be_instance_of(Moneta::OptionMerger)
|
1034
1074
|
end
|
1035
1075
|
|
1036
|
-
it '
|
1076
|
+
it 'saves default options' do
|
1037
1077
|
options = {:optionname => :optionvalue}
|
1038
1078
|
merger = store.with(options)
|
1039
1079
|
Moneta::OptionMerger::METHODS.each do |method|
|
@@ -1043,14 +1083,14 @@ end
|
|
1043
1083
|
|
1044
1084
|
PREFIX = [['alpha', nil], ['beta', nil], ['alpha', 'beta']]
|
1045
1085
|
|
1046
|
-
it '
|
1086
|
+
it 'merges options' do
|
1047
1087
|
merger = store.with(:opt1 => :val1, :opt2 => :val2).with(:opt2 => :overwrite, :opt3 => :val3)
|
1048
1088
|
Moneta::OptionMerger::METHODS.each do |method|
|
1049
1089
|
merger.default_options[method].should == {:opt1 => :val1, :opt2 => :overwrite, :opt3 => :val3}
|
1050
1090
|
end
|
1051
1091
|
end
|
1052
1092
|
|
1053
|
-
it '
|
1093
|
+
it 'merges options only for some methods' do
|
1054
1094
|
PREFIX.each do |(alpha,beta)|
|
1055
1095
|
options = {:opt1 => :val1, :opt2 => :val2, :prefix => alpha}
|
1056
1096
|
merger = store.with(options).with(:opt2 => :overwrite, :opt3 => :val3, :prefix => beta, :only => :clear)
|
@@ -1068,7 +1108,7 @@ it 'should merge options only for some methods' do
|
|
1068
1108
|
end
|
1069
1109
|
end
|
1070
1110
|
|
1071
|
-
it '
|
1111
|
+
it 'merges options except for some methods' do
|
1072
1112
|
PREFIX.each do |(alpha,beta)|
|
1073
1113
|
options = {:opt1 => :val1, :opt2 => :val2, :prefix => alpha}
|
1074
1114
|
merger = store.with(options).with(:opt2 => :overwrite, :opt3 => :val3, :except => :clear, :prefix => beta)
|
@@ -1086,12 +1126,12 @@ it 'should merge options except for some methods' do
|
|
1086
1126
|
end
|
1087
1127
|
end
|
1088
1128
|
|
1089
|
-
it '
|
1129
|
+
it 'has method #raw' do
|
1090
1130
|
store.raw.default_options.should == {:store=>{:raw=>true},:load=>{:raw=>true},:delete=>{:raw=>true}}
|
1091
1131
|
store.raw.should equal(store.raw.raw)
|
1092
1132
|
end
|
1093
1133
|
|
1094
|
-
it '
|
1134
|
+
it 'has method #prefix' do
|
1095
1135
|
store.prefix('a').default_options.should == {:store=>{:prefix=>'a'},:load=>{:prefix=>'a'},
|
1096
1136
|
:delete=>{:prefix=>'a'},:key? => {:prefix=>'a'},:increment=>{:prefix=>'a'}}
|
1097
1137
|
|
@@ -1110,122 +1150,100 @@ end}
|
|
1110
1150
|
SPECS = {}
|
1111
1151
|
|
1112
1152
|
KEYS = {
|
1113
|
-
'
|
1114
|
-
'
|
1115
|
-
'
|
1116
|
-
'
|
1117
|
-
'
|
1118
|
-
'
|
1153
|
+
'nil' => [0, 'nil'],
|
1154
|
+
'integer' => [-10, 42],
|
1155
|
+
'boolean' => [true, false],
|
1156
|
+
'string' => ['strkey1', 'strkey2'].map(&:inspect),
|
1157
|
+
'object' => ['Value.new(:objkey1)', 'Value.new(:objkey2)'],
|
1158
|
+
'hash' => [{'hashkey1' => 'hashkey2'}, {'hashkey3' => 'hashkey4'}].map(&:inspect)
|
1119
1159
|
}
|
1120
1160
|
|
1121
1161
|
VALUES = {
|
1122
|
-
'
|
1123
|
-
'
|
1124
|
-
'
|
1125
|
-
'
|
1126
|
-
'
|
1127
|
-
'
|
1162
|
+
'nil' => [0, 'nil'],
|
1163
|
+
'integer' => [41, -12],
|
1164
|
+
'boolean' => [true, false],
|
1165
|
+
'string' => ['strval1', 'strval2'].map(&:inspect),
|
1166
|
+
'hash' => [{'hashval1' => ['array1', 1]}, {'hashval3' => ['array2', {'hashval4' => 42}]}].map(&:inspect),
|
1167
|
+
'object' => ['Value.new(:objval1)', 'Value.new(:objval2)'],
|
1128
1168
|
}
|
1129
1169
|
|
1130
|
-
KEYS.each do |key_type,
|
1131
|
-
VALUES.each do |val_type,
|
1170
|
+
KEYS.each do |key_type, keypair|
|
1171
|
+
VALUES.each do |val_type, valpair|
|
1172
|
+
4.times do |i|
|
1173
|
+
key1, key2 = i % 2 == 0 ? keypair : keypair.reverse
|
1174
|
+
val1, val2 = i < 2 ? valpair : valpair.reverse
|
1132
1175
|
|
1133
|
-
|
1134
|
-
store[#{key1}].should
|
1135
|
-
store.load(#{key1}).should
|
1136
|
-
|
1137
|
-
store[#{key2}].should == nil
|
1138
|
-
store.load(#{key2}).should == nil
|
1176
|
+
code = %{it 'reads from keys like a Hash' do
|
1177
|
+
store[#{key1}].should be_nil
|
1178
|
+
store.load(#{key1}).should be_nil
|
1139
1179
|
end
|
1140
1180
|
|
1141
|
-
it
|
1181
|
+
it 'guarantees that the same value is returned when setting a key' do
|
1142
1182
|
value = #{val1}
|
1143
1183
|
(store[#{key1}] = value).should equal(value)
|
1144
|
-
|
1145
|
-
value = #{val2}
|
1146
|
-
(store[#{key2}] = value).should equal(value)
|
1147
1184
|
end
|
1148
1185
|
|
1149
|
-
it
|
1150
|
-
store.key?(#{key1}).should
|
1151
|
-
store.key?(#{key2}).should == false
|
1186
|
+
it 'returns false from key? if a key is not available' do
|
1187
|
+
store.key?(#{key1}).should be_false
|
1152
1188
|
end
|
1153
1189
|
|
1154
|
-
it
|
1155
|
-
store.delete(#{key1}).should
|
1156
|
-
store.delete(#{key2}).should == nil
|
1190
|
+
it 'returns nil from delete if a value for a key does not exist' do
|
1191
|
+
store.delete(#{key1}).should be_nil
|
1157
1192
|
end
|
1158
1193
|
|
1159
|
-
it
|
1194
|
+
it 'removes all keys from the store with clear' do
|
1160
1195
|
store[#{key1}] = #{val1}
|
1161
1196
|
store[#{key2}] = #{val2}
|
1162
1197
|
store.clear.should equal(store)
|
1163
|
-
store.key?(#{key1}).
|
1164
|
-
store.key?(#{key2}).
|
1198
|
+
store.key?(#{key1}).should be_false
|
1199
|
+
store.key?(#{key2}).should be_false
|
1165
1200
|
end
|
1166
1201
|
|
1167
|
-
it
|
1202
|
+
it 'fetches a key with a default value with fetch, if the key is not available' do
|
1168
1203
|
store.fetch(#{key1}, #{val1}).should == #{val1}
|
1169
|
-
store.fetch(#{key2}, #{val2}).should == #{val2}
|
1170
1204
|
end
|
1171
1205
|
|
1172
|
-
it
|
1206
|
+
it 'fetches a key with a block with fetch, if the key is not available' do
|
1173
1207
|
key = #{key1}
|
1174
1208
|
value = #{val1}
|
1175
1209
|
store.fetch(key) do |k|
|
1176
1210
|
k.should equal(key)
|
1177
1211
|
value
|
1178
1212
|
end.should equal(value)
|
1179
|
-
|
1180
|
-
key = #{key2}
|
1181
|
-
value = #{val2}
|
1182
|
-
store.fetch(key) do |k|
|
1183
|
-
k.should equal(key)
|
1184
|
-
value
|
1185
|
-
end.should equal(value)
|
1186
1213
|
end
|
1187
1214
|
|
1188
|
-
it '
|
1189
|
-
|
1190
|
-
|
1191
|
-
store.
|
1192
|
-
store.
|
1193
|
-
store.
|
1194
|
-
store.
|
1195
|
-
store.
|
1215
|
+
it 'accepts frozen options' do
|
1216
|
+
options = {:option1 => 1, :options2 => 2}
|
1217
|
+
options.freeze
|
1218
|
+
store.key?(#{key1}, options).should be_false
|
1219
|
+
store.load(#{key1}, options).should be_nil
|
1220
|
+
store.fetch(#{key1}, 42, options).should == 42
|
1221
|
+
store.fetch(#{key1}, options) { 42 }.should == 42
|
1222
|
+
store.delete(#{key1}, options).should be_nil
|
1223
|
+
store.clear(options).should equal(store)
|
1224
|
+
store.store(#{key1}, #{val1}, options).should == #{val1}
|
1196
1225
|
end}
|
1197
|
-
SPECS["null_#{key_type
|
1226
|
+
(SPECS["null_#{key_type}key_#{val_type}value"] ||= []) << code
|
1198
1227
|
|
1199
|
-
code = %{it
|
1228
|
+
code = %{it 'writes values to keys that like a Hash' do
|
1200
1229
|
store[#{key1}] = #{val1}
|
1201
1230
|
store[#{key1}].should == #{val1}
|
1202
1231
|
store.load(#{key1}).should == #{val1}
|
1203
|
-
|
1204
|
-
store[#{key2}] = #{val2}
|
1205
|
-
store[#{key2}].should == #{val2}
|
1206
|
-
store.load(#{key2}).should == #{val2}
|
1207
1232
|
end
|
1208
1233
|
|
1209
|
-
it
|
1234
|
+
it 'returns true from key? if a key is available' do
|
1210
1235
|
store[#{key1}] = #{val1}
|
1211
|
-
store.key?(#{key1}).should
|
1212
|
-
store[#{key2}] = #{val2}
|
1213
|
-
store.key?(#{key2}).should == true
|
1236
|
+
store.key?(#{key1}).should be_true
|
1214
1237
|
end
|
1215
1238
|
|
1216
|
-
it
|
1239
|
+
it 'stores values with #store' do
|
1217
1240
|
value = #{val1}
|
1218
1241
|
store.store(#{key1}, value).should equal(value)
|
1219
1242
|
store[#{key1}].should == #{val1}
|
1220
1243
|
store.load(#{key1}).should == #{val1}
|
1221
|
-
|
1222
|
-
value = #{val2}
|
1223
|
-
store.store(#{key2}, value).should equal(value)
|
1224
|
-
store[#{key2}].should == #{val2}
|
1225
|
-
store.load(#{key2}).should == #{val2}
|
1226
1244
|
end
|
1227
1245
|
|
1228
|
-
it
|
1246
|
+
it 'stores values after clear' do
|
1229
1247
|
store[#{key1}] = #{val1}
|
1230
1248
|
store[#{key2}] = #{val2}
|
1231
1249
|
store.clear.should equal(store)
|
@@ -1234,72 +1252,57 @@ it "stores #{key_type} after clear" do
|
|
1234
1252
|
store[#{key2}].should be_nil
|
1235
1253
|
end
|
1236
1254
|
|
1237
|
-
it
|
1255
|
+
it 'removes and returns a value from the backing store via delete if it exists' do
|
1238
1256
|
store[#{key1}] = #{val1}
|
1239
1257
|
store.delete(#{key1}).should == #{val1}
|
1240
|
-
store.key?(#{key1}).should
|
1241
|
-
|
1242
|
-
store[#{key2}] = #{val2}
|
1243
|
-
store.delete(#{key2}).should == #{val2}
|
1244
|
-
store.key?(#{key2}).should == false
|
1258
|
+
store.key?(#{key1}).should be_false
|
1245
1259
|
end
|
1246
1260
|
|
1247
|
-
it
|
1261
|
+
it 'overwrites existing values' do
|
1248
1262
|
store[#{key1}] = #{val1}
|
1249
1263
|
store[#{key1}].should == #{val1}
|
1250
1264
|
store[#{key1}] = #{val2}
|
1251
1265
|
store[#{key1}].should == #{val2}
|
1252
|
-
end
|
1266
|
+
end}
|
1253
1267
|
|
1254
|
-
|
1268
|
+
if val_type != 'nil'
|
1269
|
+
code << %{
|
1270
|
+
it 'fetches a key with a default value with fetch, if the key is available' do
|
1255
1271
|
store[#{key1}] = #{val1}
|
1256
1272
|
store.fetch(#{key1}, #{val2}).should == #{val1}
|
1257
|
-
end
|
1273
|
+
end
|
1258
1274
|
|
1259
|
-
|
1260
|
-
code << %{
|
1261
|
-
it "does not run the block if the #{key_type} key is available" do
|
1275
|
+
it 'does not run the block in fetch if the key is available' do
|
1262
1276
|
store[#{key1}] = #{val1}
|
1263
1277
|
unaltered = 'unaltered'
|
1264
1278
|
store.fetch(#{key1}) { unaltered = 'altered' }
|
1265
1279
|
unaltered.should == 'unaltered'
|
1266
|
-
|
1267
|
-
store[#{key2}] = #{val2}
|
1268
|
-
unaltered = 'unaltered'
|
1269
|
-
store.fetch(#{key2}) { unaltered = 'altered' }
|
1270
|
-
unaltered.should == 'unaltered'
|
1271
1280
|
end}
|
1272
|
-
|
1281
|
+
end
|
1273
1282
|
|
1274
|
-
|
1283
|
+
(SPECS["store_#{key_type}key_#{val_type}value"] ||= []) << code
|
1275
1284
|
|
1276
|
-
|
1285
|
+
code = %{it 'guarantees that a different value is retrieved' do
|
1277
1286
|
value = #{val1}
|
1278
1287
|
store[#{key1}] = #{val1}
|
1279
1288
|
store[#{key1}].should_not be_equal(#{val1})
|
1280
|
-
|
1281
|
-
value = #{val2}
|
1282
|
-
store[#{key2}] = #{val2}
|
1283
|
-
store[#{key2}].should_not be_equal(#{val2})
|
1284
1289
|
end}
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1290
|
+
if val_type != 'boolean' && val_type != 'nil' && val_type != 'integer'
|
1291
|
+
(SPECS["returndifferent_#{key_type}key_#{val_type}value"] ||= []) << code
|
1292
|
+
end
|
1288
1293
|
|
1289
|
-
|
1294
|
+
code = %{it 'persists values' do
|
1290
1295
|
store[#{key1}] = #{val1}
|
1291
|
-
store[#{key2}] = #{val2}
|
1292
1296
|
store.close
|
1293
1297
|
@store = nil
|
1294
|
-
|
1295
1298
|
store[#{key1}].should == #{val1}
|
1296
|
-
store[#{key2}].should == #{val2}
|
1297
1299
|
end}
|
1298
|
-
|
1300
|
+
(SPECS["persist_#{key_type}key_#{val_type}value"] ||= []) << code
|
1301
|
+
end
|
1299
1302
|
end
|
1300
1303
|
end
|
1301
1304
|
|
1302
|
-
SPECS['not_persist'] = %{it
|
1305
|
+
SPECS['not_persist'] = %{it 'does not persist values' do
|
1303
1306
|
store['key'] = 'val'
|
1304
1307
|
store.close
|
1305
1308
|
@store = nil
|
@@ -1307,34 +1310,34 @@ SPECS['not_persist'] = %{it "does not persist values" do
|
|
1307
1310
|
store['key'].should be_nil
|
1308
1311
|
end}
|
1309
1312
|
|
1310
|
-
SPECS['expires'] = %{it '
|
1313
|
+
SPECS['expires'] = %{it 'supports expires on store and #[]' do
|
1311
1314
|
store.store('key1', 'val1', :expires => 2)
|
1312
1315
|
store['key1'].should == 'val1'
|
1313
1316
|
sleep 1
|
1314
1317
|
store['key1'].should == 'val1'
|
1315
1318
|
sleep 2
|
1316
|
-
store['key1'].should
|
1319
|
+
store['key1'].should be_nil
|
1317
1320
|
end
|
1318
1321
|
|
1319
|
-
it '
|
1322
|
+
it 'supports expires on store and load' do
|
1320
1323
|
store.store('key1', 'val1', :expires => 2)
|
1321
1324
|
store.load('key1').should == 'val1'
|
1322
1325
|
sleep 1
|
1323
1326
|
store.load('key1').should == 'val1'
|
1324
1327
|
sleep 2
|
1325
|
-
store.load('key1').should
|
1328
|
+
store.load('key1').should be_nil
|
1326
1329
|
end
|
1327
1330
|
|
1328
|
-
it '
|
1331
|
+
it 'supports expires on store and key?' do
|
1329
1332
|
store.store('key1', 'val1', :expires => 2)
|
1330
|
-
store.key?('key1').should
|
1333
|
+
store.key?('key1').should be_true
|
1331
1334
|
sleep 1
|
1332
|
-
store.key?('key1').should
|
1335
|
+
store.key?('key1').should be_true
|
1333
1336
|
sleep 2
|
1334
|
-
store.key?('key1').should
|
1337
|
+
store.key?('key1').should be_false
|
1335
1338
|
end
|
1336
1339
|
|
1337
|
-
it '
|
1340
|
+
it 'supports updating the expiration time in load' do
|
1338
1341
|
store.store('key2', 'val2', :expires => 2)
|
1339
1342
|
store['key2'].should == 'val2'
|
1340
1343
|
sleep 1
|
@@ -1343,10 +1346,10 @@ it 'should support updating the expiration time in load' do
|
|
1343
1346
|
sleep 1
|
1344
1347
|
store['key2'].should == 'val2'
|
1345
1348
|
sleep 3
|
1346
|
-
store['key2'].should
|
1349
|
+
store['key2'].should be_nil
|
1347
1350
|
end
|
1348
1351
|
|
1349
|
-
it '
|
1352
|
+
it 'supports updating the expiration time in key?' do
|
1350
1353
|
store.store('key2', 'val2', :expires => 2)
|
1351
1354
|
store['key2'].should == 'val2'
|
1352
1355
|
sleep 1
|
@@ -1355,10 +1358,10 @@ it 'should support updating the expiration time in key?' do
|
|
1355
1358
|
sleep 1
|
1356
1359
|
store['key2'].should == 'val2'
|
1357
1360
|
sleep 3
|
1358
|
-
store['key2'].should
|
1361
|
+
store['key2'].should be_nil
|
1359
1362
|
end
|
1360
1363
|
|
1361
|
-
it '
|
1364
|
+
it 'supports updating the expiration time in fetch' do
|
1362
1365
|
store.store('key1', 'val1', :expires => 2)
|
1363
1366
|
store['key1'].should == 'val1'
|
1364
1367
|
sleep 1
|
@@ -1367,42 +1370,42 @@ it 'should support updating the expiration time in fetch' do
|
|
1367
1370
|
sleep 1
|
1368
1371
|
store['key1'].should == 'val1'
|
1369
1372
|
sleep 3
|
1370
|
-
store['key1'].should
|
1373
|
+
store['key1'].should be_nil
|
1371
1374
|
end
|
1372
1375
|
|
1373
|
-
it '
|
1376
|
+
it 'respects expires in delete' do
|
1374
1377
|
store.store('key2', 'val2', :expires => 2)
|
1375
1378
|
store['key2'].should == 'val2'
|
1376
1379
|
sleep 1
|
1377
1380
|
store['key2'].should == 'val2'
|
1378
1381
|
sleep 2
|
1379
|
-
store.delete('key2').should
|
1382
|
+
store.delete('key2').should be_nil
|
1380
1383
|
end
|
1381
1384
|
|
1382
|
-
it '
|
1385
|
+
it 'supports the #expires syntactic sugar' do
|
1383
1386
|
store['longlive_key'] = 'longlive_value'
|
1384
1387
|
store.expires(2).store('key2', 'val2')
|
1385
1388
|
store['key2'].should == 'val2'
|
1386
1389
|
sleep 1
|
1387
1390
|
store['key2'].should == 'val2'
|
1388
1391
|
sleep 2
|
1389
|
-
store.delete('key2').should
|
1392
|
+
store.delete('key2').should be_nil
|
1390
1393
|
store['longlive_key'].should == 'longlive_value'
|
1391
1394
|
end}
|
1392
1395
|
|
1393
|
-
SPECS['not_increment'] = %{it '
|
1396
|
+
SPECS['not_increment'] = %{it 'does not support #increment' do
|
1394
1397
|
expect do
|
1395
1398
|
store.increment('inckey')
|
1396
1399
|
end.to raise_error(NotImplementedError)
|
1397
1400
|
end
|
1398
1401
|
|
1399
|
-
it '
|
1402
|
+
it 'does not support #decrement' do
|
1400
1403
|
expect do
|
1401
1404
|
store.increment('inckey')
|
1402
1405
|
end.to raise_error(NotImplementedError)
|
1403
1406
|
end}
|
1404
1407
|
|
1405
|
-
SPECS['increment'] = %{it '
|
1408
|
+
SPECS['increment'] = %{it 'initializes in #increment with 1' do
|
1406
1409
|
store.key?('inckey').should be_false
|
1407
1410
|
store.increment('inckey').should == 1
|
1408
1411
|
store.key?('inckey').should be_true
|
@@ -1410,65 +1413,41 @@ SPECS['increment'] = %{it 'should initialize in #increment with 1' do
|
|
1410
1413
|
store.raw.load('inckey').should == '1'
|
1411
1414
|
store.load('inckey', :raw => true).should == '1'
|
1412
1415
|
|
1413
|
-
# WARNING: Undefined behaviour!
|
1414
|
-
result = safe_load_value(store.raw['inckey'])
|
1415
|
-
store['inckey'].should == result
|
1416
|
-
|
1417
1416
|
store.delete('inckey', :raw => true).should == '1'
|
1418
1417
|
store.key?('inckey').should be_false
|
1419
1418
|
end
|
1420
1419
|
|
1421
|
-
it '
|
1420
|
+
it 'initializes in #increment with higher value' do
|
1422
1421
|
store.increment('inckey', 42).should == 42
|
1423
1422
|
store.key?('inckey').should be_true
|
1424
1423
|
store.raw['inckey'].should == '42'
|
1425
|
-
|
1426
|
-
# WARNING: Undefined behaviour!
|
1427
|
-
result = safe_load_value(store.raw['inckey'])
|
1428
|
-
store['inckey'].should == result
|
1429
|
-
|
1430
1424
|
store.delete('inckey', :raw => true).should == '42'
|
1431
1425
|
end
|
1432
1426
|
|
1433
|
-
it '
|
1427
|
+
it 'initializes in #increment with 0' do
|
1434
1428
|
store.increment('inckey', 0).should == 0
|
1435
1429
|
store.key?('inckey').should be_true
|
1436
1430
|
store.raw['inckey'].should == '0'
|
1437
|
-
|
1438
|
-
# WARNING: Undefined behaviour!
|
1439
|
-
result = safe_load_value(store.raw['inckey'])
|
1440
|
-
store['inckey'].should == result
|
1441
|
-
|
1442
1431
|
store.delete('inckey', :raw => true).should == '0'
|
1443
1432
|
end
|
1444
1433
|
|
1445
|
-
it '
|
1446
|
-
store.increment('inckey').should == 1
|
1447
|
-
|
1448
|
-
# WARNING: Undefined behaviour!
|
1449
|
-
result = safe_load_value(store.raw['inckey'])
|
1450
|
-
store.delete('inckey').should == result
|
1451
|
-
|
1452
|
-
store.key?('inckey').should be_false
|
1453
|
-
end
|
1454
|
-
|
1455
|
-
it 'should initialize in #decrement with 0' do
|
1434
|
+
it 'initializes in #decrement with 0' do
|
1456
1435
|
store.decrement('inckey', 0).should == 0
|
1457
1436
|
store.raw['inckey'].should == '0'
|
1458
1437
|
end
|
1459
1438
|
|
1460
|
-
it '
|
1439
|
+
it 'initializes in #decrement with negative value' do
|
1461
1440
|
store.decrement('inckey', -42).should == 42
|
1462
1441
|
store.raw['inckey'].should == '42'
|
1463
1442
|
end
|
1464
1443
|
|
1465
|
-
it '
|
1444
|
+
it 'supports incrementing existing value by value' do
|
1466
1445
|
store.increment('inckey').should == 1
|
1467
1446
|
store.increment('inckey', 42).should == 43
|
1468
1447
|
store.raw['inckey'].should == '43'
|
1469
1448
|
end
|
1470
1449
|
|
1471
|
-
it '
|
1450
|
+
it 'supports decrementing existing value by value' do
|
1472
1451
|
store.increment('inckey').should == 1
|
1473
1452
|
store.decrement('inckey').should == 0
|
1474
1453
|
store.increment('inckey', 42).should == 42
|
@@ -1476,13 +1455,13 @@ it 'should support decrementing existing value by value' do
|
|
1476
1455
|
store.raw['inckey'].should == '40'
|
1477
1456
|
end
|
1478
1457
|
|
1479
|
-
it '
|
1458
|
+
it 'supports incrementing existing value by 0' do
|
1480
1459
|
store.increment('inckey').should == 1
|
1481
1460
|
store.increment('inckey', 0).should == 1
|
1482
1461
|
store.raw['inckey'].should == '1'
|
1483
1462
|
end
|
1484
1463
|
|
1485
|
-
it '
|
1464
|
+
it 'supports decrementing existing value' do
|
1486
1465
|
store.increment('inckey', 10).should == 10
|
1487
1466
|
store.increment('inckey', -5).should == 5
|
1488
1467
|
store.raw['inckey'].should == '5'
|
@@ -1490,20 +1469,20 @@ it 'should support decrementing existing value' do
|
|
1490
1469
|
store.raw['inckey'].should == '0'
|
1491
1470
|
end
|
1492
1471
|
|
1493
|
-
it '
|
1472
|
+
it 'interprets raw value as integer' do
|
1494
1473
|
store.store('inckey', '42', :raw => true)
|
1495
1474
|
store.increment('inckey').should == 43
|
1496
1475
|
store.raw['inckey'].should == '43'
|
1497
1476
|
end
|
1498
1477
|
|
1499
|
-
it '
|
1478
|
+
it 'raises error in #increment on non integer value' do
|
1500
1479
|
store['strkey'] = 'value'
|
1501
1480
|
expect do
|
1502
1481
|
store.increment('strkey')
|
1503
1482
|
end.to raise_error
|
1504
1483
|
end
|
1505
1484
|
|
1506
|
-
it '
|
1485
|
+
it 'raises error in #decrement on non integer value' do
|
1507
1486
|
store['strkey'] = 'value'
|
1508
1487
|
expect do
|
1509
1488
|
store.decrement('strkey')
|
@@ -1580,16 +1559,36 @@ it 'allows to bypass transformer with raw syntactic sugar' do
|
|
1580
1559
|
store.raw['key'].should == 'value2'
|
1581
1560
|
end
|
1582
1561
|
|
1583
|
-
it '
|
1562
|
+
it 'returns unmarshalled value' do
|
1584
1563
|
store.store('key', 'unmarshalled value', :raw => true)
|
1585
1564
|
store.load('key', :raw => true).should == 'unmarshalled value'
|
1586
|
-
|
1587
|
-
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
it 'might raise exception on invalid value' do
|
1568
|
+
store.store('key', 'unmarshalled value', :raw => true)
|
1569
|
+
|
1570
|
+
begin
|
1571
|
+
store['key'].should == load_value('unmarshalled value')
|
1572
|
+
store.delete('key').should == load_value('unmarshalled value')
|
1573
|
+
rescue Exception => ex
|
1574
|
+
expect do
|
1575
|
+
store['key']
|
1576
|
+
end.to raise_error
|
1577
|
+
expect do
|
1578
|
+
store.delete('key')
|
1579
|
+
end.to raise_error
|
1580
|
+
end
|
1588
1581
|
end}
|
1589
1582
|
|
1590
1583
|
SPECS['transform_value_with_expires'] = %{it 'allows to bypass transformer with :raw' do
|
1591
1584
|
store['key'] = 'value'
|
1592
|
-
load_value(store.load('key', :raw => true)).should ==
|
1585
|
+
load_value(store.load('key', :raw => true)).should == 'value'
|
1586
|
+
store['key'] = [1,2,3]
|
1587
|
+
load_value(store.load('key', :raw => true)).should == [[1,2,3]]
|
1588
|
+
store['key'] = nil
|
1589
|
+
load_value(store.load('key', :raw => true)).should == [nil]
|
1590
|
+
store['key'] = false
|
1591
|
+
load_value(store.load('key', :raw => true)).should be_false
|
1593
1592
|
|
1594
1593
|
store.store('key', 'value', :expires => 10)
|
1595
1594
|
load_value(store.load('key', :raw => true)).first.should == 'value'
|
@@ -1600,17 +1599,31 @@ SPECS['transform_value_with_expires'] = %{it 'allows to bypass transformer with
|
|
1600
1599
|
store.delete('key', :raw => true).should == 'value'
|
1601
1600
|
end
|
1602
1601
|
|
1603
|
-
it '
|
1602
|
+
it 'returns unmarshalled value' do
|
1604
1603
|
store.store('key', 'unmarshalled value', :raw => true)
|
1605
1604
|
store.load('key', :raw => true).should == 'unmarshalled value'
|
1606
|
-
|
1607
|
-
|
1605
|
+
end
|
1606
|
+
|
1607
|
+
it 'might raise exception on invalid value' do
|
1608
|
+
store.store('key', 'unmarshalled value', :raw => true)
|
1609
|
+
|
1610
|
+
begin
|
1611
|
+
store['key'].should == load_value('unmarshalled value')
|
1612
|
+
store.delete('key').should == load_value('unmarshalled value')
|
1613
|
+
rescue Exception => ex
|
1614
|
+
expect do
|
1615
|
+
store['key']
|
1616
|
+
end.to raise_error
|
1617
|
+
expect do
|
1618
|
+
store.delete('key')
|
1619
|
+
end.to raise_error
|
1620
|
+
end
|
1608
1621
|
end}
|
1609
1622
|
|
1610
1623
|
specs_code = "#{header}\n"
|
1611
1624
|
SPECS.each do |key, code|
|
1612
1625
|
specs_code << "#################### #{key} ####################\n\n" <<
|
1613
|
-
"shared_examples_for '#{key}' do\n " << code.gsub("\n", "\n ") << "\nend\n\n"
|
1626
|
+
"shared_examples_for '#{key}' do\n " << [code].flatten.join("\n\n").gsub("\n", "\n ") << "\nend\n\n"
|
1614
1627
|
end
|
1615
1628
|
specs_code.gsub!(/\n +\n/, "\n\n")
|
1616
1629
|
File.open(File.join(File.dirname(__FILE__), 'monetaspecs.rb'), 'w') {|out| out << specs_code }
|
@@ -1627,7 +1640,7 @@ TESTS.each do |name, options|
|
|
1627
1640
|
specs_code << " it_should_behave_like '#{s}'" if SPECS[s.to_s]
|
1628
1641
|
specs.key.each do |k|
|
1629
1642
|
specs.value.each do |v|
|
1630
|
-
x = "#{s}_#{k
|
1643
|
+
x = "#{s}_#{k}key_#{v}value"
|
1631
1644
|
specs_code << " it_should_behave_like '#{x}'" if SPECS[x]
|
1632
1645
|
end
|
1633
1646
|
end
|