moneta 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/.yardopts +1 -0
  2. data/CHANGES +21 -10
  3. data/README.md +1 -1
  4. data/SPEC.md +4 -12
  5. data/lib/moneta.rb +7 -5
  6. data/lib/moneta/adapters/activerecord.rb +9 -3
  7. data/lib/moneta/adapters/cassandra.rb +9 -4
  8. data/lib/moneta/adapters/client.rb +9 -3
  9. data/lib/moneta/adapters/cookie.rb +3 -0
  10. data/lib/moneta/adapters/couch.rb +8 -3
  11. data/lib/moneta/adapters/datamapper.rb +8 -3
  12. data/lib/moneta/adapters/dbm.rb +1 -2
  13. data/lib/moneta/adapters/file.rb +9 -4
  14. data/lib/moneta/adapters/fog.rb +8 -3
  15. data/lib/moneta/adapters/gdbm.rb +1 -2
  16. data/lib/moneta/adapters/hbase.rb +10 -3
  17. data/lib/moneta/adapters/leveldb.rb +3 -2
  18. data/lib/moneta/adapters/localmemcache.rb +4 -4
  19. data/lib/moneta/adapters/lruhash.rb +8 -4
  20. data/lib/moneta/adapters/memcached/dalli.rb +10 -4
  21. data/lib/moneta/adapters/memcached/native.rb +9 -4
  22. data/lib/moneta/adapters/memory.rb +8 -3
  23. data/lib/moneta/adapters/mongo.rb +7 -3
  24. data/lib/moneta/adapters/null.rb +8 -1
  25. data/lib/moneta/adapters/pstore.rb +9 -3
  26. data/lib/moneta/adapters/redis.rb +10 -4
  27. data/lib/moneta/adapters/riak.rb +12 -7
  28. data/lib/moneta/adapters/sdbm.rb +1 -2
  29. data/lib/moneta/adapters/sequel.rb +9 -3
  30. data/lib/moneta/adapters/sqlite.rb +10 -4
  31. data/lib/moneta/adapters/tokyocabinet.rb +2 -2
  32. data/lib/moneta/builder.rb +11 -7
  33. data/lib/moneta/cache.rb +16 -6
  34. data/lib/moneta/expires.rb +12 -6
  35. data/lib/moneta/lock.rb +0 -2
  36. data/lib/moneta/logger.rb +0 -2
  37. data/lib/moneta/mixins.rb +175 -47
  38. data/lib/moneta/optionmerger.rb +2 -0
  39. data/lib/moneta/proxy.rb +14 -30
  40. data/lib/moneta/server.rb +0 -2
  41. data/lib/moneta/shared.rb +1 -3
  42. data/lib/moneta/stack.rb +20 -10
  43. data/lib/moneta/transformer.rb +84 -61
  44. data/lib/moneta/version.rb +1 -1
  45. data/lib/rack/moneta_rest.rb +56 -0
  46. data/moneta.gemspec +1 -1
  47. data/spec/active_support/cache_moneta_store_spec.rb +4 -4
  48. data/spec/generate.rb +216 -203
  49. data/spec/helper.rb +0 -6
  50. data/spec/moneta/adapter_cassandra_spec.rb +2 -2
  51. data/spec/moneta/adapter_datamapper_spec.rb +1 -1
  52. data/spec/moneta/adapter_lruhash_spec.rb +1 -1
  53. data/spec/moneta/adapter_memcached_dalli_spec.rb +2 -2
  54. data/spec/moneta/adapter_memcached_native_spec.rb +2 -2
  55. data/spec/moneta/adapter_memcached_spec.rb +2 -2
  56. data/spec/moneta/adapter_redis_spec.rb +2 -2
  57. data/spec/moneta/cache_file_memory_spec.rb +3 -3
  58. data/spec/moneta/expires_file_spec.rb +4 -4
  59. data/spec/moneta/expires_memory_spec.rb +2 -2
  60. data/spec/moneta/optionmerger_spec.rb +6 -6
  61. data/spec/moneta/shared_spec.rb +1 -1
  62. data/spec/moneta/simple_client_tcp_spec.rb +1 -1
  63. data/spec/moneta/transformer_key_marshal_spec.rb +109 -0
  64. data/spec/moneta/transformer_key_yaml_spec.rb +109 -0
  65. data/spec/moneta/transformer_marshal_spec.rb +109 -0
  66. data/spec/moneta/transformer_value_marshal_spec.rb +109 -0
  67. data/spec/moneta/transformer_value_yaml_spec.rb +109 -0
  68. data/spec/monetaspecs.rb +14460 -3956
  69. metadata +16 -6
  70. data/lib/moneta/base.rb +0 -98
  71. data/lib/moneta/net.rb +0 -22
@@ -10,19 +10,17 @@ module Moneta
10
10
  #
11
11
  # @example Bypass serialization
12
12
  # store.store('key', 'value', :raw => true)
13
- # store['key'] => Error
14
- # store.load('key', :raw => true) => 'value'
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) => "\x04\bI\"\nvalue\x06:\x06ET"
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(options[:quiet] ? 'Quiet' : '', keys, values)
41
- const_set(name, compile(options, keys, values)) unless const_defined?(name)
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(options, keys, values)
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
- if values.empty?
72
- klass.class_eval <<-end_eval, __FILE__, __LINE__
73
- def load(key, options = {})
74
- options.delete(:raw)
75
- @adapter.load(#{key}, options)
76
- end
77
- def store(key, value, options = {})
78
- options.delete(:raw)
79
- @adapter.store(#{key}, value, options)
80
- end
81
- def delete(key, options = {})
82
- options.delete(:raw)
83
- @adapter.delete(#{key}, options)
84
- end
85
- end_eval
86
- else
87
- dump = compile_transformer(values, 'value')
88
- load = compile_transformer(values.reverse, 'value', 1)
89
-
90
- klass.class_eval <<-end_eval, __FILE__, __LINE__
91
- def load(key, options = {})
92
- raw = options.delete(:raw)
93
- value = @adapter.load(#{key}, options)
94
- begin
95
- return #{load} if value && !raw
96
- rescue Exception => ex
97
- #{options[:quiet] ? '' : 'puts "Tried to load invalid value: #{ex.message}"'}
98
- end
99
- value
100
- end
101
- def store(key, value, options = {})
102
- raw = options.delete(:raw)
103
- @adapter.store(#{key}, raw ? value : #{dump}, options)
104
- value
105
- end
106
- def delete(key, options = {})
107
- raw = options.delete(:raw)
108
- value = @adapter.delete(#{key}, options)
109
- begin
110
- return #{load} if value && !raw
111
- rescue Exception => ex
112
- #{options[:quiet] ? '' : 'puts "Tried to delete invalid value: #{ex.message}"'}
113
- end
114
- value
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(prefix, keys, values)
153
- prefix << (keys.empty? ? '' : keys.map(&:to_s).map(&:capitalize).join << 'Key') <<
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
@@ -1,5 +1,5 @@
1
1
  module Moneta
2
2
  # Moneta version number
3
3
  # @api public
4
- VERSION = '0.7.1'
4
+ VERSION = '0.7.2'
5
5
  end
@@ -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 MongoDB, Redis, Tokyo, and ActiveRecord}
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(Object String Hash Boolean Nil Integer)
7
- @value = value || %w(Object String Hash Boolean Nil Integer)
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(String), value)
11
+ Specs.new(specs, %w(string), value)
12
12
  end
13
13
 
14
14
  def stringvalues_only
15
- Specs.new(specs, key, %w(String))
15
+ Specs.new(specs, key, %w(string))
16
16
  end
17
17
 
18
18
  def simplekeys_only
19
- Specs.new(specs, %w(String Hash Integer), value)
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(String Hash Integer))
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(String), %w(String))
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 'should support multiple clients' do
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 'should support default expiration time' do
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 == nil
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 'should delete expired value in underlying file storage' do
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 == nil
479
- store.adapter['foo'].should == nil
480
- store.adapter.adapter['foo'].should == nil
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 'should store loaded values in cache' do
510
+ it 'stores loaded values in cache' do
511
511
  store.backend['foo'] = 'bar'
512
- store.cache['foo'].should == nil
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 == nil
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 'should share values' do
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 'should support default expiration time' do
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 == nil
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 == false
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 'should support default expiration time' do
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 == nil
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 'should support default expiration time' do
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 == nil
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 'should support default expiration time' do
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 == nil
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 'should delete oldest' do
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 'should support default expiration time' do
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 == nil
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 'should save default options' do
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 'should merge options' do
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 'should merge options only for some methods' do
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 'should merge options except for some methods' do
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 'should have method #raw' do
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 'should have method #prefix' do
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
- 'Nil' => [0, 'nil'],
1114
- 'Integer' => [-10, 42],
1115
- 'Boolean' => [true, false],
1116
- 'String' => ['strkey1', 'strkey2'].map(&:inspect),
1117
- 'Object' => ['Value.new(:objkey1)', 'Value.new(:objkey2)'],
1118
- 'Hash' => [{'hashkey1' => 'hashkey2'}, {'hashkey3' => 'hashkey4'}].map(&:inspect)
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
- 'Nil' => [0, 'nil'],
1123
- 'Integer' => [41, -12],
1124
- 'Boolean' => [false, true],
1125
- 'String' => ['strval1', 'strval2'].map(&:inspect),
1126
- 'Hash' => [{'hashval1' => ['array1', 1]}, {'hashval3' => ['array2', {'hashval4' => 42}]}].map(&:inspect),
1127
- 'Object' => ['Value.new(:objval1)', 'Value.new(:objval2)'],
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, (key1,key2)|
1131
- VALUES.each do |val_type, (val1,val2)|
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
- code = %{it "reads from keys that are #{key_type}s like a Hash" do
1134
- store[#{key1}].should == nil
1135
- store.load(#{key1}).should == nil
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 "guarantees that the same #{val_type} value is returned when setting a #{key_type} key" do
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 "returns false from key? if a #{key_type} key is not available" do
1150
- store.key?(#{key1}).should == false
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 "returns nil from delete if an element for a #{key_type} key does not exist" do
1155
- store.delete(#{key1}).should == nil
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 "removes all #{key_type} keys from the store with clear" do
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}).should_not == true
1164
- store.key?(#{key2}).should_not == true
1198
+ store.key?(#{key1}).should be_false
1199
+ store.key?(#{key2}).should be_false
1165
1200
  end
1166
1201
 
1167
- it "fetches a #{key_type} key with a default value with fetch, if the key is not available" do
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 "fetches a #{key_type} key with a block with fetch, if the key is not available" do
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 'should accept options' do
1189
- store.key?(#{key1}, :option1 => 1).should == false
1190
- store.load(#{key1}, :option2 => 2).should == nil
1191
- store.fetch(#{key1}, 42, :option3 => 3).should == 42
1192
- store.fetch(#{key1}, :option3 => 3) { 42 }.should == 42
1193
- store.delete(#{key1}, :option4 => 4).should == nil
1194
- store.clear(:option5 => 5).should equal(store)
1195
- store.store(#{key1}, #{val1}, :option6 => 6).should == #{val1}
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.downcase}key_#{val_type.downcase}value"] = code
1226
+ (SPECS["null_#{key_type}key_#{val_type}value"] ||= []) << code
1198
1227
 
1199
- code = %{it "writes #{val_type} values to keys that are #{key_type}s like a Hash" do
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 "returns true from key? if a #{key_type} key is available" do
1234
+ it 'returns true from key? if a key is available' do
1210
1235
  store[#{key1}] = #{val1}
1211
- store.key?(#{key1}).should == true
1212
- store[#{key2}] = #{val2}
1213
- store.key?(#{key2}).should == true
1236
+ store.key?(#{key1}).should be_true
1214
1237
  end
1215
1238
 
1216
- it "stores #{val_type} values with #{key_type} keys with #store" do
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 "stores #{key_type} after clear" do
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 "removes and returns a #{val_type} element with a #{key_type} key from the backing store via delete if it exists" do
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 == false
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 "overwrites existing #{val_type} values with #{key_type}" do
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
- it "fetches a #{key_type} key with a default value with fetch, if the key is available" do
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
- if val_type != 'Nil'
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
- end
1281
+ end
1273
1282
 
1274
- SPECS["store_#{key_type.downcase}key_#{val_type.downcase}value"] = code
1283
+ (SPECS["store_#{key_type}key_#{val_type}value"] ||= []) << code
1275
1284
 
1276
- code = %{it "guarantees that a different #{val_type} value is retrieved from the #{key_type} key" do
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
- if val_type != 'Boolean' && val_type != 'Nil' && val_type != 'Integer'
1286
- SPECS["returndifferent_#{key_type.downcase}key_#{val_type.downcase}value"] = code
1287
- end
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
- code = %{it "persists #{val_type} values with #{key_type} keys" do
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
- SPECS["persist_#{key_type.downcase}key_#{val_type.downcase}value"] = code
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 "does not persist values" do
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 'should support expires on store and #[]' do
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 == nil
1319
+ store['key1'].should be_nil
1317
1320
  end
1318
1321
 
1319
- it 'should support expires on store and load' do
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 == nil
1328
+ store.load('key1').should be_nil
1326
1329
  end
1327
1330
 
1328
- it 'should support expires on store and key?' do
1331
+ it 'supports expires on store and key?' do
1329
1332
  store.store('key1', 'val1', :expires => 2)
1330
- store.key?('key1').should == true
1333
+ store.key?('key1').should be_true
1331
1334
  sleep 1
1332
- store.key?('key1').should == true
1335
+ store.key?('key1').should be_true
1333
1336
  sleep 2
1334
- store.key?('key1').should == false
1337
+ store.key?('key1').should be_false
1335
1338
  end
1336
1339
 
1337
- it 'should support updating the expiration time in load' do
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 == nil
1349
+ store['key2'].should be_nil
1347
1350
  end
1348
1351
 
1349
- it 'should support updating the expiration time in key?' do
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 == nil
1361
+ store['key2'].should be_nil
1359
1362
  end
1360
1363
 
1361
- it 'should support updating the expiration time in fetch' do
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 == nil
1373
+ store['key1'].should be_nil
1371
1374
  end
1372
1375
 
1373
- it 'should respect expires in delete' do
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 == nil
1382
+ store.delete('key2').should be_nil
1380
1383
  end
1381
1384
 
1382
- it 'should support the #expires syntactic sugar' do
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 == nil
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 'should not support #increment' do
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 'should not support #decrement' do
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 'should initialize in #increment with 1' do
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 'should initialize in #increment with higher value' do
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 'should initialize in #increment with 0' do
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 'should support deleting integer value' do
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 'should initialize in #decrement with negative value' do
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 'should support incrementing existing value by value' do
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 'should support decrementing existing value by value' do
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 'should support incrementing existing value by 0' do
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 'should support decrementing existing value' do
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 'interpret raw value as integer' do
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 'should raise error in #increment on non integer value' do
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 'should raise error in #decrement on non integer value' do
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 'should return unmarshalled value' do
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
- store['key'].should == 'unmarshalled value'
1587
- store.delete('key').should == 'unmarshalled value'
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 == ['value']
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 'should return unmarshalled value' do
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
- store['key'].should == 'unmarshalled value'
1607
- store.delete('key').should == 'unmarshalled value'
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.downcase}key_#{v.downcase}value"
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