juno 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +2 -5
  3. data/Gemfile +21 -8
  4. data/README.md +3 -1
  5. data/{unsupported/benchmarks.rb → benchmarks/run.rb} +20 -83
  6. data/lib/juno.rb +4 -4
  7. data/lib/juno/activerecord.rb +2 -5
  8. data/lib/juno/base.rb +4 -0
  9. data/{unsupported → lib/juno}/cassandra.rb +11 -11
  10. data/lib/juno/datamapper.rb +1 -1
  11. data/{unsupported → lib/juno}/fog.rb +7 -19
  12. data/lib/juno/null.rb +23 -0
  13. data/lib/juno/redis.rb +13 -1
  14. data/lib/juno/sequel.rb +3 -6
  15. data/lib/juno/stack.rb +41 -0
  16. data/lib/juno/version.rb +1 -1
  17. data/test/helper.rb +160 -130
  18. data/test/{test_active_record.rb → test_activerecord.rb} +2 -5
  19. data/{unsupported → test}/test_cassandra.rb +1 -1
  20. data/test/test_couch.rb +1 -1
  21. data/test/test_datamapper.rb +2 -2
  22. data/test/test_dbm.rb +1 -1
  23. data/test/test_expires.rb +1 -2
  24. data/test/test_file.rb +1 -1
  25. data/test/test_fog.rb +17 -0
  26. data/test/test_gdbm.rb +1 -1
  27. data/test/test_hashfile.rb +1 -1
  28. data/test/test_localmemcache.rb +1 -1
  29. data/test/test_memcached.rb +1 -2
  30. data/test/test_memcached_dalli.rb +1 -2
  31. data/test/test_memcached_native.rb +1 -2
  32. data/test/test_memory.rb +1 -1
  33. data/test/test_mongodb.rb +1 -1
  34. data/test/test_null.rb +9 -0
  35. data/test/test_proxy.rb +1 -1
  36. data/test/test_pstore.rb +1 -1
  37. data/test/test_redis.rb +1 -1
  38. data/test/test_riak.rb +1 -1
  39. data/test/test_sdbm.rb +1 -1
  40. data/test/test_sequel.rb +4 -4
  41. data/test/test_sqlite.rb +1 -1
  42. data/test/test_stack.rb +10 -0
  43. data/test/test_tokyocabinet.rb +1 -1
  44. data/test/test_yaml.rb +1 -1
  45. metadata +20 -13
  46. data/unsupported/test_rackspace.rb +0 -15
  47. data/unsupported/test_s3.rb +0 -15
data/lib/juno/sequel.rb CHANGED
@@ -6,13 +6,10 @@ module Juno
6
6
  raise 'No option :db specified' unless db = options.delete(:db)
7
7
  @table = options.delete(:table) || :juno
8
8
  @db = ::Sequel.connect(db, options)
9
- end
10
-
11
- def migrate
12
- @db.create_table @table do
9
+ @db.create_table?(@table) do
13
10
  primary_key :k
14
- String :k
15
- String :v
11
+ blob :k
12
+ blob :v
16
13
  end
17
14
  end
18
15
 
data/lib/juno/stack.rb ADDED
@@ -0,0 +1,41 @@
1
+ module Juno
2
+ class Stack < Base
3
+ def initialize(options = {})
4
+ raise 'No option :stores specified' unless @stores = options[:stores]
5
+ end
6
+
7
+ def key?(key, options = {})
8
+ @stores.any? {|s| s.key?(key) }
9
+ end
10
+
11
+ def [](key)
12
+ @stores.each do |s|
13
+ value = s[key]
14
+ return value if value
15
+ end
16
+ nil
17
+ end
18
+
19
+ def store(key, value, options = {})
20
+ @stores.each {|s| s.store(key, value, options) }
21
+ value
22
+ end
23
+
24
+ def delete(key, options = {})
25
+ @stores.inject(nil) do |value, s|
26
+ v = s.delete(key, options)
27
+ value || v
28
+ end
29
+ end
30
+
31
+ def clear(options = {})
32
+ @stores.each {|s| s.clear }
33
+ nil
34
+ end
35
+
36
+ def close
37
+ @stores.each {|s| s.close }
38
+ nil
39
+ end
40
+ end
41
+ end
data/lib/juno/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Juno
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
data/test/helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require 'minitest/autorun'
2
3
  require 'juno'
3
4
  require 'fileutils'
@@ -10,173 +11,202 @@ module Helper
10
11
  end
11
12
  end
12
13
 
13
- JunoSpecification = proc do
14
- include Helper
15
-
16
- before do
17
- @store = new_store
18
- @store.clear
19
- end
20
-
21
- after do
22
- @store.close.must_equal nil if @store
23
- end
24
-
25
- types = {
14
+ module Juno
15
+ TYPES = {
26
16
  'String' => ['key', 'key2'],
27
17
  'Object' => [{:foo => :bar}, {:bar => :baz}]
28
18
  }
29
19
 
30
- types.each do |type, (key, key2)|
31
- it "reads from keys that are #{type}s like a Hash" do
32
- @store[key].must_equal nil
33
- end
20
+ NullSpecification = proc do
21
+ include Helper
34
22
 
35
- it "writes String values to keys that are #{type}s like a Hash" do
36
- @store[key] = 'value'
37
- @store[key].must_equal 'value'
23
+ before do
24
+ @store = new_store
25
+ @store.clear
38
26
  end
39
27
 
40
- it "guarantees that a different String value is retrieved from the #{type} key" do
41
- value = 'value'
42
- (@store[key] = value).must_be_same_as value
43
- @store[key].wont_be_same_as(value)
28
+ after do
29
+ @store.close.must_equal nil if @store
44
30
  end
45
31
 
46
- it "writes Object values to keys that are #{type}s like a Hash" do
47
- value = {:foo => :bar}
48
- (@store[key] = value).must_be_same_as value
49
- @store[key].must_equal(:foo => :bar)
50
- end
32
+ TYPES.each do |type, (key, key2)|
33
+ it "reads from keys that are #{type}s like a Hash" do
34
+ @store[key].must_equal nil
35
+ end
51
36
 
52
- it "guarantees that a different Object value is retrieved from the #{type} key" do
53
- value = {:foo => :bar}
54
- @store[key] = value
55
- @store[key].wont_be_same_as(:foo => :bar)
56
- end
37
+ it "guarantees that the same String value is returned when setting a #{type} key" do
38
+ value = 'value'
39
+ (@store[key] = value).must_be_same_as value
40
+ end
57
41
 
58
- it "returns false from key? if a #{type} key is not available" do
59
- @store.key?(key).must_equal false
60
- end
42
+ it "guarantees that the same Object value is returned when setting a #{type} key" do
43
+ value = {:foo => :bar}
44
+ (@store[key] = value).must_be_same_as value
45
+ end
61
46
 
62
- it "returns true from key? if a #{type} key is available" do
63
- @store[key] = 'value'
64
- @store.key?(key).must_equal true
65
- end
47
+ it "returns false from key? if a #{type} key is not available" do
48
+ @store.key?(key).must_equal false
49
+ end
66
50
 
67
- it "removes and returns an element with a #{type} key from the backing store via delete if it exists" do
68
- @store[key] = 'value'
69
- @store.delete(key).must_equal 'value'
70
- @store.key?(key).must_equal false
71
- end
51
+ it "returns nil from delete if an element for a #{type} key does not exist" do
52
+ @store.delete(key).must_equal nil
53
+ end
72
54
 
73
- it "returns nil from delete if an element for a #{type} key does not exist" do
74
- @store.delete(key).must_equal nil
75
- end
55
+ it "removes all #{type} keys from the store with clear" do
56
+ @store[key] = 'value'
57
+ @store[key2] = 'value2'
58
+ @store.clear.must_equal nil
59
+ @store.key?(key).wont_equal true
60
+ @store.key?(key2).wont_equal true
61
+ end
76
62
 
77
- it "removes all #{type} keys from the store with clear" do
78
- @store[key] = 'value'
79
- @store[key2] = 'value2'
80
- @store.clear.must_equal nil
81
- @store.key?(key).wont_equal true
82
- @store.key?(key2).wont_equal true
83
- end
63
+ it "fetches a #{type} key with a default value with fetch, if the key is not available" do
64
+ @store.fetch(key, 'value').must_equal 'value'
65
+ end
84
66
 
85
- it "fetches a #{type} key with a default value with fetch, if the key is not available" do
86
- @store.fetch(key, 'value').must_equal 'value'
87
- end
67
+ it "fetches a #{type} key with a block with fetch, if the key is not available" do
68
+ @store.fetch(key) { |k| 'value' }.must_equal 'value'
69
+ end
88
70
 
89
- it "fetches a #{type} key with a block with fetch, if the key is not available" do
90
- @store.fetch(key) { |k| 'value' }.must_equal 'value'
71
+ it 'must accept options' do
72
+ @store.key?(key, :foo => 42).must_equal false
73
+ @store.fetch(key, nil, :foo => 42).must_equal nil
74
+ @store.delete(key, :foo => 42).must_equal nil
75
+ @store.clear(:foo => 42).must_equal nil
76
+ @store.store(key, 'value', :foo => 42).must_equal 'value'
77
+ end
91
78
  end
79
+ end
92
80
 
93
- it "does not run the block if the #{type} key is available" do
94
- @store[key] = 'value'
95
- unaltered = "unaltered"
96
- @store.fetch(key) { unaltered = "altered" }
97
- unaltered.must_equal "unaltered"
98
- end
81
+ Specification = proc do
82
+ class_eval(&NullSpecification)
83
+
84
+ TYPES.each do |type, (key, key2)|
85
+ it "writes String values to keys that are #{type}s like a Hash" do
86
+ @store[key] = 'value'
87
+ @store[key].must_equal 'value'
88
+ end
89
+
90
+ it "writes Object values to keys that are #{type}s like a Hash" do
91
+ value = {:foo => :bar}
92
+ @store[key] = value
93
+ @store[key].must_equal(:foo => :bar)
94
+ end
95
+
96
+ it "guarantees that a different String value is retrieved from the #{type} key" do
97
+ value = 'value'
98
+ @store[key] = value
99
+ @store[key].wont_be_same_as(value)
100
+ end
101
+
102
+ it "guarantees that a different Object value is retrieved from the #{type} key" do
103
+ value = {:foo => :bar}
104
+ @store[key] = value
105
+ @store[key].wont_be_same_as(:foo => :bar)
106
+ end
107
+
108
+ it "returns true from key? if a #{type} key is available" do
109
+ @store[key] = 'value'
110
+ @store.key?(key).must_equal true
111
+ end
112
+
113
+ it "removes and returns an element with a #{type} key from the backing store via delete if it exists" do
114
+ @store[key] = 'value'
115
+ @store.delete(key).must_equal 'value'
116
+ @store.key?(key).must_equal false
117
+ end
99
118
 
100
- it "fetches a #{type} key with a default value with fetch, if the key is available" do
101
- @store[key] = 'value2'
102
- @store.fetch(key, 'value').must_equal 'value2'
119
+ it "does not run the block if the #{type} key is available" do
120
+ @store[key] = 'value'
121
+ unaltered = "unaltered"
122
+ @store.fetch(key) { unaltered = "altered" }
123
+ unaltered.must_equal "unaltered"
124
+ end
125
+
126
+ it "fetches a #{type} key with a default value with fetch, if the key is available" do
127
+ @store[key] = 'value2'
128
+ @store.fetch(key, 'value').must_equal 'value2'
129
+ end
130
+
131
+ it "stores #{key} values with #store" do
132
+ @store.store(key, 'value').must_equal 'value'
133
+ @store[key].must_equal 'value'
134
+ end
103
135
  end
104
136
 
105
- it "stores #{key} values with #store" do
106
- @store.store(key, 'value').must_equal 'value'
107
- @store[key].must_equal 'value'
137
+ def marshal_error
138
+ # HACK: Marshalling structs in rubinius without class name throws
139
+ # NoMethodError (to_sym). TODO: Create an issue for rubinius!
140
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
141
+ RUBY_VERSION < '1.9' ? ArgumentError : NoMethodError
142
+ else
143
+ TypeError
144
+ end
108
145
  end
109
146
 
110
- it 'must accept options' do
111
- @store.store(key, 'value', :foo => 42).must_equal 'value'
112
- @store.key?(key, :foo => 42).must_equal true
113
- @store.fetch(key, nil, :foo => 42).must_equal 'value'
114
- @store.delete(key, :foo => 42).must_equal 'value'
115
- @store.key?(key, :foo => 42).must_equal false
116
- @store.clear(:foo => 42).must_equal nil
147
+ it "refuses to #[] from keys that cannot be marshalled" do
148
+ lambda do
149
+ @store[Struct.new(:foo).new(:bar)]
150
+ end.must_raise(marshal_error)
117
151
  end
118
- end
119
152
 
120
- it "refuses to #[] from keys that cannot be marshalled" do
121
- lambda do
122
- @store[Struct.new(:foo).new(:bar)]
123
- end.must_raise(TypeError)
124
- end
153
+ it "refuses to fetch from keys that cannot be marshalled" do
154
+ lambda do
155
+ @store.fetch(Struct.new(:foo).new(:bar), true)
156
+ end.must_raise(marshal_error)
157
+ end
125
158
 
126
- it "refuses to fetch from keys that cannot be marshalled" do
127
- lambda do
128
- @store.fetch(Struct.new(:foo).new(:bar), true)
129
- end.must_raise(TypeError)
130
- end
159
+ it "refuses to #[]= to keys that cannot be marshalled" do
160
+ lambda do
161
+ @store[Struct.new(:foo).new(:bar)] = 'value'
162
+ end.must_raise(marshal_error)
163
+ end
131
164
 
132
- it "refuses to #[]= to keys that cannot be marshalled" do
133
- lambda do
134
- @store[Struct.new(:foo).new(:bar)] = 'value'
135
- end.must_raise(TypeError)
136
- end
165
+ it "refuses to store to keys that cannot be marshalled" do
166
+ lambda do
167
+ @store.store Struct.new(:foo).new(:bar), 'value'
168
+ end.must_raise(marshal_error)
169
+ end
137
170
 
138
- it "refuses to store to keys that cannot be marshalled" do
139
- lambda do
140
- @store.store Struct.new(:foo).new(:bar), 'value'
141
- end.must_raise(TypeError)
142
- end
171
+ it "refuses to check for key? if the key cannot be marshalled" do
172
+ lambda do
173
+ @store.key? Struct.new(:foo).new(:bar)
174
+ end.must_raise(marshal_error)
175
+ end
143
176
 
144
- it "refuses to check for key? if the key cannot be marshalled" do
145
- lambda do
146
- @store.key? Struct.new(:foo).new(:bar)
147
- end.must_raise(TypeError)
177
+ it "refuses to delete a key if the key cannot be marshalled" do
178
+ lambda do
179
+ @store.delete Struct.new(:foo).new(:bar)
180
+ end.must_raise(marshal_error)
181
+ end
148
182
  end
149
183
 
150
- it "refuses to delete a key if the key cannot be marshalled" do
151
- lambda do
152
- @store.delete Struct.new(:foo).new(:bar)
153
- end.must_raise(TypeError)
154
- end
155
- end
184
+ ExpiresSpecification = proc do
185
+ class_eval(&Specification)
156
186
 
157
- JunoExpiresSpecification = proc do
158
- it 'should support expires on store' do
159
- @store.store('key', 'value', :expires => 2)
160
- @store['key'].must_equal 'value'
161
- sleep 3
162
- @store['key'].must_equal nil
163
- end
187
+ it 'should support expires on store' do
188
+ @store.store('key', 'value', :expires => 2)
189
+ @store['key'].must_equal 'value'
190
+ sleep 3
191
+ @store['key'].must_equal nil
192
+ end
164
193
 
165
- it 'should support updating the expiration time in fetch' do
166
- @store.store('key2', 'value2', :expires => 2)
167
- @store['key2'].must_equal 'value2'
168
- sleep 1
169
- @store.fetch('key2', nil, :expires => 3).must_equal 'value2'
170
- sleep 1
171
- @store['key2'].must_equal 'value2'
172
- sleep 3
173
- @store['key2'].must_equal nil
174
- end
194
+ it 'should support updating the expiration time in fetch' do
195
+ @store.store('key2', 'value2', :expires => 2)
196
+ @store['key2'].must_equal 'value2'
197
+ sleep 1
198
+ @store.fetch('key2', nil, :expires => 3).must_equal 'value2'
199
+ sleep 1
200
+ @store['key2'].must_equal 'value2'
201
+ sleep 3
202
+ @store['key2'].must_equal nil
203
+ end
175
204
 
176
- it 'should respect expires in delete' do
177
- @store.store('key', 'value', :expires => 2)
205
+ it 'should respect expires in delete' do
206
+ @store.store('key', 'value', :expires => 2)
178
207
  @store['key'].must_equal 'value'
179
208
  sleep 3
180
209
  @store.delete('key').must_equal nil
181
210
  end
182
211
  end
212
+ end
@@ -4,12 +4,10 @@ begin
4
4
  describe Juno::ActiveRecord do
5
5
  describe 'with connection option set' do
6
6
  def new_store
7
- store = Juno::ActiveRecord.new(:connection => { :adapter => 'sqlite3', :database => File.join(make_tempdir, 'db.sqlite3')})
8
- store.migrate
9
- store
7
+ Juno::ActiveRecord.new(:connection => { :adapter => 'sqlite3', :database => File.join(make_tempdir, 'db.sqlite3')})
10
8
  end
11
9
 
12
- class_eval(&JunoSpecification)
10
+ class_eval(&Juno::Specification)
13
11
 
14
12
  it 'updates an existing key/value' do
15
13
  @store['foo/bar'] = 4
@@ -26,7 +24,6 @@ begin
26
24
  ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => File.join(make_tempdir, 'db.sqlite3')
27
25
 
28
26
  store = Juno::ActiveRecord.new
29
- store.migrate
30
27
  store.table.table_exists?.must_equal true
31
28
  end
32
29
  end
@@ -6,7 +6,7 @@ begin
6
6
  Juno::Cassandra.new
7
7
  end
8
8
 
9
- class_eval(&JunoSpecification)
9
+ class_eval(&Juno::ExpiresSpecification)
10
10
  end
11
11
  rescue LoadError => ex
12
12
  puts "Juno::Cassandra not tested: #{ex.message}"
data/test/test_couch.rb CHANGED
@@ -6,7 +6,7 @@ begin
6
6
  Juno::Couch.new :db => 'juno'
7
7
  end
8
8
 
9
- class_eval(&JunoSpecification)
9
+ class_eval(&Juno::Specification)
10
10
  end
11
11
  rescue LoadError => ex
12
12
  puts "Juno::Couch not tested: #{ex.message}"
@@ -15,7 +15,7 @@ begin
15
15
  Juno::DataMapper::Store.auto_migrate!(:juno)
16
16
  end
17
17
 
18
- class_eval(&JunoSpecification)
18
+ class_eval(&Juno::Specification)
19
19
  end
20
20
 
21
21
  describe 'when :repository specified' do
@@ -27,7 +27,7 @@ begin
27
27
  Juno::DataMapper::Store.auto_migrate!(:sample)
28
28
  end
29
29
 
30
- class_eval(&JunoSpecification)
30
+ class_eval(&Juno::Specification)
31
31
  end
32
32
 
33
33
  describe 'with multiple stores' do