kissifer-hash-persistent 0.0.0 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/hash-persistent.gemspec +12 -21
- data/lib/hash-persistent.rb +2 -5
- data/lib/hash-persistent/basic.rb +36 -0
- data/lib/hash-persistent/counting.rb +40 -0
- data/spec/basic_spec.rb +188 -0
- data/spec/counting_spec.rb +196 -0
- data/spec/spec_helper.rb +0 -2
- metadata +9 -18
- data/lib/hash-persistent/collection.rb +0 -59
- data/lib/hash-persistent/counter.rb +0 -26
- data/lib/hash-persistent/extended_store.rb +0 -49
- data/lib/hash-persistent/resource.rb +0 -20
- data/lib/hash-persistent/store.rb +0 -67
- data/spec/collection_spec.rb +0 -269
- data/spec/counter_spec.rb +0 -61
- data/spec/extended_store_spec.rb +0 -103
- data/spec/resource_spec.rb +0 -48
- data/spec/store_spec.rb +0 -370
data/spec/counter_spec.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe "HashPersistent::Counter" do
|
4
|
-
context "(instantiation)" do
|
5
|
-
it "should expect to persist to a HashPersistent::Store and a string-like key" do
|
6
|
-
HashPersistent::Counter.new(HashPersistent::Store.new({}, ""), "key")
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should reject an incorrect store type" do
|
10
|
-
lambda {HashPersistent::Counter.new(1, "key")}.should raise_error(ArgumentError)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should reject a non-string-like key" do
|
14
|
-
lambda {HashPersistent::Counter.new(HashPersistent::Store.new({}, ""), Dummy_NoStringRep.new)}.should raise_error(ArgumentError)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should reject an empty string key" do
|
18
|
-
lambda {HashPersistent::Counter.new(HashPersistent::Store.new({}, ""), "")}.should raise_error(ArgumentError)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should add an count object to the store" do
|
22
|
-
store = HashPersistent::Store.new({}, "")
|
23
|
-
HashPersistent::Counter.new(store, "counter_name")
|
24
|
-
store.find("counter_name").count.should == 0
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should not change the count object in the store if already present" do
|
28
|
-
store = HashPersistent::Store.new({}, "")
|
29
|
-
counter_1 = HashPersistent::Counter.new(store, "counter_name")
|
30
|
-
counter_1.next.should == 0
|
31
|
-
counter_1.next.should == 1
|
32
|
-
counter_1.next.should == 2
|
33
|
-
|
34
|
-
counter_2 = HashPersistent::Counter.new(store, "counter_name")
|
35
|
-
store.find("counter_name").count.should == 3
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context "(generating unique ids)" do
|
40
|
-
it "should increment the count value in the store when a new id is requested" do
|
41
|
-
store = HashPersistent::Store.new({}, "")
|
42
|
-
counter = HashPersistent::Counter.new(store, "counter_name")
|
43
|
-
counter.next
|
44
|
-
store.find("counter_name").count.should == 1
|
45
|
-
counter.next
|
46
|
-
store.find("counter_name").count.should == 2
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should return the count held in the store when a new id is requested" do
|
50
|
-
store = HashPersistent::Store.new({}, "")
|
51
|
-
counter = HashPersistent::Counter.new(store, "counter_name")
|
52
|
-
counter.next.should == 0
|
53
|
-
counter.next.should == 1
|
54
|
-
counter.next.should == 2
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context "(concurrent access)" do
|
59
|
-
it "should correctly protect against use by mutliple threads/processes"
|
60
|
-
end
|
61
|
-
end
|
data/spec/extended_store_spec.rb
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe "HashPersistent::ExtendedStore" do
|
4
|
-
context "(instantiation)" do
|
5
|
-
it "should initialise its store attribute" do
|
6
|
-
store = HashPersistent::Store.new(Hash.new, "prefix::")
|
7
|
-
extended_store = HashPersistent::ExtendedStore.new(store)
|
8
|
-
extended_store.store.should == store
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
context "(in default configuration)" do
|
13
|
-
it "should delegate the find method to its store" do
|
14
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
15
|
-
extended_store.store.should_receive(:find).with("a_key")
|
16
|
-
extended_store.find("a_key")
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should delegate the save method to its store" do
|
20
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
21
|
-
object = OpenStruct.new
|
22
|
-
object.key = "a_key"
|
23
|
-
extended_store.store.should_receive(:save).with(object)
|
24
|
-
extended_store.save(object)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should delegate the delete method to its store" do
|
28
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
29
|
-
object = OpenStruct.new
|
30
|
-
object.key = "a_key"
|
31
|
-
extended_store.store.should_receive(:delete).with(object)
|
32
|
-
extended_store.delete(object)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should delegate the create method to its store" do
|
36
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
37
|
-
extended_store.store.should_receive(:create).with("key", OpenStruct)
|
38
|
-
extended_store.create("key", OpenStruct)
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should delegate the find_or_create method to its store" do
|
42
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
43
|
-
extended_store.store.should_receive(:find_or_create).with("key", OpenStruct)
|
44
|
-
extended_store.find_or_create("key", OpenStruct)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context "(singleton keys)" do
|
49
|
-
it "should allow a singleton key pattern to be specified" do
|
50
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
51
|
-
extended_store.singleton_key("foo", OpenStruct)
|
52
|
-
|
53
|
-
HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, "")) do |store|
|
54
|
-
store.singleton_key "foo", OpenStruct
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should reject a pattern that cannot be matched against a string" do
|
59
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
60
|
-
lambda{extended_store.singleton_key(1, OpenStruct)}.should raise_error
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should not redirect find for keys that do not match the singleton pattern" do
|
64
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
65
|
-
extended_store.singleton_key("foo", OpenStruct)
|
66
|
-
|
67
|
-
extended_store.store.should_receive(:find).with("bar")
|
68
|
-
extended_store.store.should_not_receive(:find_or_create)
|
69
|
-
|
70
|
-
extended_store.find("bar")
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should redirect find to find_or_create for keys that match the singleton pattern" do
|
74
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
75
|
-
extended_store.singleton_key("foo", OpenStruct, "arg1", "arg2")
|
76
|
-
|
77
|
-
extended_store.store.should_receive(:find_or_create).with("food", OpenStruct, "arg1", "arg2")
|
78
|
-
extended_store.store.should_not_receive(:find)
|
79
|
-
|
80
|
-
extended_store.find("food")
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should allow multiple patterns to be specified" do
|
84
|
-
extended_store = HashPersistent::ExtendedStore.new(HashPersistent::Store.new({}, ""))
|
85
|
-
extended_store.singleton_key("foo", OpenStruct, "arg1", "arg2")
|
86
|
-
extended_store.singleton_key("bar", Object, "arg3", "arg4")
|
87
|
-
|
88
|
-
extended_store.store.should_receive(:find_or_create).with("food", OpenStruct, "arg1", "arg2")
|
89
|
-
extended_store.find("food")
|
90
|
-
|
91
|
-
extended_store.store.should_receive(:find_or_create).with("barney", Object, "arg3", "arg4")
|
92
|
-
extended_store.find("barney")
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
context "(proxy stores)" do
|
97
|
-
it "should be clever"
|
98
|
-
end
|
99
|
-
|
100
|
-
context "(watching objects)" do
|
101
|
-
it "should be clever"
|
102
|
-
end
|
103
|
-
end
|
data/spec/resource_spec.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
class ResourceFoo
|
4
|
-
include HashPersistent::Resource
|
5
|
-
end
|
6
|
-
|
7
|
-
|
8
|
-
describe "A class that includes HashPersistent::Resource" do
|
9
|
-
it "should acquire a store attribute" do
|
10
|
-
resource = ResourceFoo.new
|
11
|
-
resource.store = "foo"
|
12
|
-
resource.store.should == "foo"
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should acquire a key attribute" do
|
16
|
-
resource = ResourceFoo.new
|
17
|
-
resource.key = "foo"
|
18
|
-
resource.key.should == "foo"
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should be savable to its store" do
|
22
|
-
resource = ResourceFoo.new
|
23
|
-
mock_store = "dummy"
|
24
|
-
resource.store = mock_store
|
25
|
-
|
26
|
-
mock_store.should_receive(:save).with(resource)
|
27
|
-
resource.save
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should be deletable from its store" do
|
31
|
-
resource = ResourceFoo.new
|
32
|
-
mock_store = "dummy"
|
33
|
-
resource.store = mock_store
|
34
|
-
|
35
|
-
mock_store.should_receive(:delete).with(resource)
|
36
|
-
resource.delete
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should be movable from one store to another" do
|
40
|
-
resource = ResourceFoo.new
|
41
|
-
mock_store = "dummy" # We use only one so that we can use rspec to check the order of the messages...
|
42
|
-
resource.store = mock_store
|
43
|
-
|
44
|
-
mock_store.should_receive(:delete).with(resource).ordered
|
45
|
-
mock_store.should_receive(:save).with(resource).ordered
|
46
|
-
resource.move(mock_store)
|
47
|
-
end
|
48
|
-
end
|
data/spec/store_spec.rb
DELETED
@@ -1,370 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
class ClassWithKey
|
4
|
-
attr_accessor :key, :var
|
5
|
-
def initialize(key, var)
|
6
|
-
@key = key
|
7
|
-
@var = var
|
8
|
-
end
|
9
|
-
|
10
|
-
def ==(other)
|
11
|
-
(other.class == ClassWithKey) && (key == other.key) && (var == other.var)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class ClassWithKeyAndStore
|
16
|
-
attr_accessor :key, :store, :var
|
17
|
-
|
18
|
-
def initialize(key = nil)
|
19
|
-
@key = key
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "HashPersistent::Store" do
|
24
|
-
context "(instantiation)" do
|
25
|
-
it "should expect to persist to a hash-like key_value_store, with a string-like key_prefix" do
|
26
|
-
HashPersistent::Store.new({}, "_prefix")
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should reject a non-hash-like key_value_store" do
|
30
|
-
lambda {HashPersistent::Store.new(1, "_prefix")}.should raise_error(ArgumentError)
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should reject a non-string-like key_prefix" do
|
34
|
-
lambda {HashPersistent::Store.new({}, Dummy_NoStringRep.new)}.should raise_error(ArgumentError)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should maintain a key_value_store attribute" do
|
38
|
-
a_hash = {}
|
39
|
-
HashPersistent::Store.new(a_hash, "").key_value_store.should == a_hash
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should maintain a key_prefix attribute" do
|
43
|
-
HashPersistent::Store.new({}, "foo_bar").key_prefix.should == "foo_bar"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context "(saving)" do
|
48
|
-
it "should refuse to save an object that does not provide a non-nil key" do
|
49
|
-
lambda{HashPersistent::Store.new({}, "").save(1)}.should raise_error
|
50
|
-
object = ClassWithKey.new(nil, "foo")
|
51
|
-
lambda{HashPersistent::Store.new({}, "").save(object)}.should raise_error
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should add the object, referenced by its prefixed key, to the store" do
|
55
|
-
store = HashPersistent::Store.new({}, "prefix::")
|
56
|
-
object = ClassWithKey.new("foo", "bar")
|
57
|
-
store.save(object).key_value_store["prefix::foo"].should == object
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should overwrite an object with same prefixed key in the store" do
|
61
|
-
store = HashPersistent::Store.new({}, "prefix::")
|
62
|
-
object_1 = ClassWithKey.new("foo", "bar")
|
63
|
-
object_2 = ClassWithKey.new("foo", "baz")
|
64
|
-
store.save(object_1).save(object_2).key_value_store["prefix::foo"].should == object_2
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context "(deleting)" do
|
69
|
-
it "should refuse to delete an object that does not provide a non-nil key" do
|
70
|
-
lambda{HashPersistent::Store.new({}, "").delete(1)}.should raise_error
|
71
|
-
object = ClassWithKey.new(nil, "foo")
|
72
|
-
lambda{HashPersistent::Store.new({}, "").delete(object)}.should raise_error
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should delete a pair from the store based on the object's prefixed key" do
|
76
|
-
store = HashPersistent::Store.new({}, "prefix::")
|
77
|
-
object = ClassWithKey.new("foo", "bar")
|
78
|
-
store.save(object).delete(object).key_value_store["prefix::foo"].should be_nil
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should not complain if the prefixed key does not exist in the store" do
|
82
|
-
store = HashPersistent::Store.new({}, "prefix::")
|
83
|
-
object = ClassWithKey.new("foo", "bar")
|
84
|
-
lambda{store.delete(object)}.should_not raise_error
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
context "(finding)" do
|
89
|
-
it "should retrieve an object that has the correct key" do
|
90
|
-
store = HashPersistent::Store.new({}, "prefix::")
|
91
|
-
object = ClassWithKey.new("foo", "bar")
|
92
|
-
store.save(object).find("foo").should == object
|
93
|
-
end
|
94
|
-
|
95
|
-
it "should return nil if no object is found with the correct key" do
|
96
|
-
store = HashPersistent::Store.new({}, "prefix::")
|
97
|
-
object = ClassWithKey.new("foo", "bar")
|
98
|
-
store.find("foo").should be_nil
|
99
|
-
store.save(object).delete(object).find("foo").should be_nil
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
context "(creating)" do
|
104
|
-
it "should create objects on request" do
|
105
|
-
new_object = ClassWithKeyAndStore.new
|
106
|
-
ClassWithKeyAndStore.should_receive(:new).with("arg1", "arg2").and_return(new_object)
|
107
|
-
object = HashPersistent::Store.new({}, "prefix::").create("a_key", ClassWithKeyAndStore, "arg1", "arg2")
|
108
|
-
object.should == new_object
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should set the key attribute of created objects" do
|
112
|
-
block = lambda{"foo"}
|
113
|
-
object = HashPersistent::Store.new({}, "prefix::").create("a_key", ClassWithKeyAndStore)
|
114
|
-
object.key.should == "a_key"
|
115
|
-
end
|
116
|
-
|
117
|
-
it "should be able to create and save when the requested key is not found" do
|
118
|
-
store = HashPersistent::Store.new({}, "")
|
119
|
-
store.find_or_create("a_key", OpenStruct, {:foo => "bar"})
|
120
|
-
store.find("a_key").should_not be_nil
|
121
|
-
store.find("a_key").foo.should == "bar"
|
122
|
-
end
|
123
|
-
|
124
|
-
it "should not create or modify when the requested key is found" do
|
125
|
-
store = HashPersistent::Store.new({}, "")
|
126
|
-
store.save(store.create("a_key", OpenStruct, {:foo => "bar"}))
|
127
|
-
|
128
|
-
store.find_or_create("a_key", OpenStruct, {:foo => "baz", :fred => "barney"})
|
129
|
-
|
130
|
-
store.find("a_key").should_not be_nil
|
131
|
-
store.find("a_key").fred.should be_nil
|
132
|
-
store.find("a_key").foo.should == "bar"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
context "(isolation of objects in in-memory stores)" do
|
137
|
-
it "should return a copy of the object found in the store" do
|
138
|
-
store = HashPersistent::Store.new({}, "")
|
139
|
-
object = ClassWithKey.new("foo", "bar")
|
140
|
-
store.save(object).find("foo").should_not equal(store.key_value_store["foo"])
|
141
|
-
end
|
142
|
-
|
143
|
-
it "should save a copy of the object being saved" do
|
144
|
-
store = HashPersistent::Store.new({}, "")
|
145
|
-
object = ClassWithKey.new("foo", "bar")
|
146
|
-
store.save(object)
|
147
|
-
store.key_value_store["foo"].should_not equal(object)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
context "(handling objects that expose a store attribute)" do
|
152
|
-
it "should set the store attribute of a created object" do
|
153
|
-
store = HashPersistent::Store.new({}, "prefix::")
|
154
|
-
store.create("key", ClassWithKeyAndStore).store.should == store
|
155
|
-
end
|
156
|
-
|
157
|
-
it "should set the store attribute of a saved object" do
|
158
|
-
object = ClassWithKeyAndStore.new("foo")
|
159
|
-
store = HashPersistent::Store.new({}, "")
|
160
|
-
store.save(object)
|
161
|
-
object.store.should == store
|
162
|
-
end
|
163
|
-
|
164
|
-
it "should not save the store attribute into the store" do
|
165
|
-
object = ClassWithKeyAndStore.new("foo")
|
166
|
-
object.store = "faa"
|
167
|
-
|
168
|
-
store = HashPersistent::Store.new({}, "")
|
169
|
-
store.save(object)
|
170
|
-
|
171
|
-
store.key_value_store["foo"].store.should be_nil
|
172
|
-
end
|
173
|
-
|
174
|
-
it "should set the store attribute of a found object" do
|
175
|
-
object = ClassWithKeyAndStore.new("foo")
|
176
|
-
object.store = "faa"
|
177
|
-
|
178
|
-
store = HashPersistent::Store.new({}, "")
|
179
|
-
store.save(object).find("foo").store.should == store
|
180
|
-
end
|
181
|
-
|
182
|
-
it "leave the in-store object's store attribute nil after finding/returning the object" do
|
183
|
-
object = ClassWithKeyAndStore.new("foo")
|
184
|
-
object.store = "faa"
|
185
|
-
|
186
|
-
store = HashPersistent::Store.new({}, "")
|
187
|
-
store.save(object).find("foo")
|
188
|
-
store.key_value_store["foo"].store.should be_nil
|
189
|
-
end
|
190
|
-
|
191
|
-
it "set the object's store attribute after deleting the object" do
|
192
|
-
store = HashPersistent::Store.new({}, "")
|
193
|
-
object = ClassWithKeyAndStore.new("foo")
|
194
|
-
|
195
|
-
store.save(object)
|
196
|
-
object.store = nil
|
197
|
-
store.delete(object)
|
198
|
-
object.store.should == store
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
context "(use of restricted Hash API)" do
|
203
|
-
it "should not require Hash methods that are not implemented in Moneta"
|
204
|
-
end
|
205
|
-
|
206
|
-
context "(caching)" do
|
207
|
-
it "should accept a HashPersistent::Store cache" do
|
208
|
-
cache = HashPersistent::Store.new({}, "")
|
209
|
-
store = HashPersistent::Store.new({}, "") do |the_store|
|
210
|
-
the_store.cached_to = cache
|
211
|
-
end
|
212
|
-
store.cached_to.should == cache
|
213
|
-
end
|
214
|
-
|
215
|
-
# TODO: can relax this?
|
216
|
-
# We'd like to reproduce some nice behaviours in the cache (like unsetting object.store on saving)
|
217
|
-
it "should reject a cache of the wrong type" do
|
218
|
-
store = HashPersistent::Store.new({}, "")
|
219
|
-
lambda{store.cached_to = {}}.should raise_error(ArgumentError)
|
220
|
-
end
|
221
|
-
|
222
|
-
it "should allow the cache to be unset using nil" do
|
223
|
-
store = HashPersistent::Store.new({}, "")
|
224
|
-
store.cached_to = nil
|
225
|
-
store.cached_to.should == nil
|
226
|
-
end
|
227
|
-
|
228
|
-
context "if supplied a cache" do
|
229
|
-
it "should also save an object to the cache when saving" do
|
230
|
-
cache = HashPersistent::Store.new({}, "")
|
231
|
-
store = HashPersistent::Store.new({}, "")
|
232
|
-
store.cached_to = cache
|
233
|
-
|
234
|
-
object = ClassWithKeyAndStore.new("foo")
|
235
|
-
cache.should_receive(:save) do |the_save_object|
|
236
|
-
the_save_object.key.should == "foo"
|
237
|
-
end
|
238
|
-
store.save(object)
|
239
|
-
end
|
240
|
-
|
241
|
-
it "should also delete an object from the cache when deleting" do
|
242
|
-
cache = HashPersistent::Store.new({}, "")
|
243
|
-
store = HashPersistent::Store.new({}, "")
|
244
|
-
store.cached_to = cache
|
245
|
-
|
246
|
-
object = ClassWithKeyAndStore.new("foo")
|
247
|
-
store.save(object)
|
248
|
-
|
249
|
-
cache.should_receive(:delete) do |the_delete_object|
|
250
|
-
the_delete_object.key.should == "foo"
|
251
|
-
end
|
252
|
-
store.delete(object)
|
253
|
-
end
|
254
|
-
|
255
|
-
it "should save an object to the cache if it is not present on find()" do
|
256
|
-
cache = HashPersistent::Store.new({}, "")
|
257
|
-
store = HashPersistent::Store.new({}, "")
|
258
|
-
|
259
|
-
object = ClassWithKeyAndStore.new("foo")
|
260
|
-
store.save(object)
|
261
|
-
|
262
|
-
# We're making an assumption here that no data is copied to the cache when we do this
|
263
|
-
store.cached_to = cache
|
264
|
-
|
265
|
-
cache.should_receive(:save) do |the_save_object|
|
266
|
-
the_save_object.key.should == "foo"
|
267
|
-
end
|
268
|
-
store.find("foo")
|
269
|
-
end
|
270
|
-
|
271
|
-
it "should return the object from the cache if it is present on find()" do
|
272
|
-
cache = HashPersistent::Store.new({}, "")
|
273
|
-
store = HashPersistent::Store.new({}, "")
|
274
|
-
store.cached_to = cache
|
275
|
-
|
276
|
-
object = ClassWithKeyAndStore.new("foo")
|
277
|
-
object.var = "bar"
|
278
|
-
store.save(object)
|
279
|
-
|
280
|
-
object.var = "baz"
|
281
|
-
cache.save(object)
|
282
|
-
|
283
|
-
store.find("foo").var.should == "baz"
|
284
|
-
end
|
285
|
-
|
286
|
-
it "should not hit the store if the object is present in the cache on find()" do
|
287
|
-
cache = HashPersistent::Store.new({}, "")
|
288
|
-
store = HashPersistent::Store.new({}, "")
|
289
|
-
store.cached_to = cache
|
290
|
-
|
291
|
-
object = ClassWithKeyAndStore.new("foo")
|
292
|
-
store.save(object)
|
293
|
-
|
294
|
-
# We assume that Fixnum is missing methods required in find(), but we verify this assumption below
|
295
|
-
class HashPersistent::Store
|
296
|
-
def hack_key_value_store
|
297
|
-
@key_value_store = 1
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
store.hack_key_value_store
|
302
|
-
|
303
|
-
lambda{store.find("foo")}.should_not raise_error
|
304
|
-
|
305
|
-
store.cached_to = nil
|
306
|
-
lambda{store.find("foo")}.should raise_error
|
307
|
-
|
308
|
-
class HashPersistent::Store
|
309
|
-
undef hack_key_value_store
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
it "should correctly set the object's store attribute when saving" do
|
314
|
-
cache = HashPersistent::Store.new({}, "")
|
315
|
-
store = HashPersistent::Store.new({}, "")
|
316
|
-
store.cached_to = cache
|
317
|
-
|
318
|
-
object = ClassWithKeyAndStore.new("foo")
|
319
|
-
store.save(object)
|
320
|
-
object.store.should == store
|
321
|
-
end
|
322
|
-
|
323
|
-
it "should correctly set the object's store attribute when deleting" do
|
324
|
-
cache = HashPersistent::Store.new({}, "")
|
325
|
-
store = HashPersistent::Store.new({}, "")
|
326
|
-
store.cached_to = cache
|
327
|
-
|
328
|
-
object = ClassWithKeyAndStore.new("foo")
|
329
|
-
|
330
|
-
store.save(object)
|
331
|
-
object.store = nil
|
332
|
-
|
333
|
-
store.delete(object)
|
334
|
-
object.store.should == store
|
335
|
-
end
|
336
|
-
|
337
|
-
it "should correctly set the object's store attribute when finding/caching" do
|
338
|
-
cache = HashPersistent::Store.new({}, "")
|
339
|
-
store = HashPersistent::Store.new({}, "")
|
340
|
-
|
341
|
-
object = ClassWithKeyAndStore.new("foo")
|
342
|
-
store.save(object)
|
343
|
-
|
344
|
-
store.cached_to = cache
|
345
|
-
found = store.find("foo")
|
346
|
-
|
347
|
-
found.store.should == store
|
348
|
-
end
|
349
|
-
|
350
|
-
it "should correctly set the object's store attribute when finding from the cache" do
|
351
|
-
cache = HashPersistent::Store.new({}, "")
|
352
|
-
store = HashPersistent::Store.new({}, "")
|
353
|
-
store.cached_to = cache
|
354
|
-
|
355
|
-
object = ClassWithKeyAndStore.new("foo")
|
356
|
-
store.save(object)
|
357
|
-
|
358
|
-
store.find("foo").store.should == store
|
359
|
-
end
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
context "(consistency of store, watched store and cache after errors occur)" do
|
364
|
-
it "should do something both boring and predictable"
|
365
|
-
end
|
366
|
-
|
367
|
-
context "(concurrent access)" do
|
368
|
-
it "should use locks and such to handle access from multiple threads/processes"
|
369
|
-
end
|
370
|
-
end
|