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