benschwarz-merb-cache 1.0.0
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/LICENSE +20 -0
- data/README +224 -0
- data/Rakefile +17 -0
- data/lib/merb-cache.rb +15 -0
- data/lib/merb-cache/cache.rb +91 -0
- data/lib/merb-cache/cache_request.rb +48 -0
- data/lib/merb-cache/core_ext/enumerable.rb +9 -0
- data/lib/merb-cache/core_ext/hash.rb +21 -0
- data/lib/merb-cache/merb_ext/controller/class_methods.rb +244 -0
- data/lib/merb-cache/merb_ext/controller/instance_methods.rb +163 -0
- data/lib/merb-cache/stores/fundamental/abstract_store.rb +101 -0
- data/lib/merb-cache/stores/fundamental/file_store.rb +113 -0
- data/lib/merb-cache/stores/fundamental/memcached_store.rb +110 -0
- data/lib/merb-cache/stores/strategy/abstract_strategy_store.rb +119 -0
- data/lib/merb-cache/stores/strategy/action_store.rb +61 -0
- data/lib/merb-cache/stores/strategy/adhoc_store.rb +69 -0
- data/lib/merb-cache/stores/strategy/gzip_store.rb +63 -0
- data/lib/merb-cache/stores/strategy/mintcache_store.rb +75 -0
- data/lib/merb-cache/stores/strategy/page_store.rb +68 -0
- data/lib/merb-cache/stores/strategy/sha1_store.rb +62 -0
- data/spec/merb-cache/cache_request_spec.rb +78 -0
- data/spec/merb-cache/cache_spec.rb +88 -0
- data/spec/merb-cache/core_ext/enumerable_spec.rb +26 -0
- data/spec/merb-cache/core_ext/hash_spec.rb +51 -0
- data/spec/merb-cache/merb_ext/controller_spec.rb +5 -0
- data/spec/merb-cache/stores/fundamental/abstract_store_spec.rb +118 -0
- data/spec/merb-cache/stores/fundamental/file_store_spec.rb +205 -0
- data/spec/merb-cache/stores/fundamental/memcached_store_spec.rb +258 -0
- data/spec/merb-cache/stores/strategy/abstract_strategy_store_spec.rb +78 -0
- data/spec/merb-cache/stores/strategy/action_store_spec.rb +208 -0
- data/spec/merb-cache/stores/strategy/adhoc_store_spec.rb +227 -0
- data/spec/merb-cache/stores/strategy/gzip_store_spec.rb +68 -0
- data/spec/merb-cache/stores/strategy/mintcache_store_spec.rb +59 -0
- data/spec/merb-cache/stores/strategy/page_store_spec.rb +146 -0
- data/spec/merb-cache/stores/strategy/sha1_store_spec.rb +84 -0
- data/spec/spec_helper.rb +95 -0
- metadata +112 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
|
5
|
+
describe "to_sha1" do
|
6
|
+
before(:each) do
|
7
|
+
@params = {:id => 1, :string => "string", :symbol => :symbol}
|
8
|
+
end
|
9
|
+
|
10
|
+
it{@params.should respond_to(:to_sha2)}
|
11
|
+
|
12
|
+
# This sec only has meaning in ruby 1.9 that uses an ordered hash
|
13
|
+
it "should encode the hash by alphabetic key" do
|
14
|
+
x = @params.to_sha2
|
15
|
+
y = {:id => 1, :symbol => :symbol, :string => "string"}.to_sha2
|
16
|
+
x.should == y
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not have any collisions between different values (using arrays)" do
|
20
|
+
x = {'test' => ['at','vc'], 'test2' => 'b'}.to_sha2
|
21
|
+
y = {'test' => ['atv', 'c'], 'test2' => 'b'}.to_sha2
|
22
|
+
puts x != y
|
23
|
+
x.should_not == y
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should encode the keys" do
|
27
|
+
x = {'key' => [1,2,3]}.to_sha2
|
28
|
+
y = {'test' => [1,2,3]}.to_sha2
|
29
|
+
x.should_not == y
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not make a distinction between symbol and strings for keys" do
|
33
|
+
x = {:key => 1}.to_sha2
|
34
|
+
y = {'key' => 1}.to_sha2
|
35
|
+
x.should == y
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not have any collisions between keys and values" do
|
39
|
+
x = {'key' => 'ab'}.to_sha2
|
40
|
+
y = {'keya' => 'b'}.to_sha2
|
41
|
+
x.should_not == y
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not have any collisions between the values of two different keys" do
|
45
|
+
x = {'a' => 'abc', 'b' => 'def'}.to_sha2
|
46
|
+
y = {'a' => 'abcd', 'b' => 'ef'}.to_sha2
|
47
|
+
x.should_not == y
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
|
3
|
+
describe 'all stores', :shared => true do
|
4
|
+
describe "#writable?" do
|
5
|
+
it "should not raise a NotImplementedError error" do
|
6
|
+
lambda { @store.writable?(:foo) }.should_not raise_error(NotImplementedError)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should accept a conditions hash" do
|
10
|
+
@store.writable?('key', :conditions => :hash)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#read" do
|
15
|
+
it "should not raise a NotImplementedError error" do
|
16
|
+
lambda { @store.read('foo') }.should_not raise_error(NotImplementedError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should accept a parameters hash" do
|
20
|
+
@store.read('foo', :params => :hash)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#write" do
|
25
|
+
it "should not raise a NotImplementedError error" do
|
26
|
+
lambda { @store.write('foo', 'bar') }.should_not raise_error(NotImplementedError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#fetch" do
|
31
|
+
it "should not raise a NotImplementedError error" do
|
32
|
+
lambda { @store.fetch('foo') {'bar'} }.should_not raise_error(NotImplementedError)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should accept parameters and conditions" do
|
36
|
+
@store.fetch('foo', {:params => :hash}, :conditions => :hash) { 'bar' }
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should accept a value generating block" do
|
40
|
+
@store.fetch('foo') {'bar'}
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return the value of the block if it is called" do
|
44
|
+
@store.fetch(:boo) { "bar" }.should == "bar" if @store.writable?(:boo)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#exists?" do
|
49
|
+
it "should not raise a NotImplementedError error" do
|
50
|
+
lambda { @store.exists?('foo') }.should_not raise_error(NotImplementedError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#delete" do
|
55
|
+
it "should not raise a NotImplementedError error" do
|
56
|
+
lambda { @store.delete('foo') }.should_not raise_error(NotImplementedError)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should accept a parameters hash" do
|
60
|
+
@store.delete('foo', :params => :hash)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#delete_all!" do
|
65
|
+
it "should not raise a NotImplementedError error" do
|
66
|
+
lambda { @store.delete_all! }.should_not raise_error(NotImplementedError)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
describe Merb::Cache::AbstractStore do
|
73
|
+
before(:each) do
|
74
|
+
@store = Merb::Cache::AbstractStore.new
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#writable?" do
|
78
|
+
it "should raise a NotImplementedError error" do
|
79
|
+
lambda { @store.writable?('foo') }.should raise_error(NotImplementedError)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#read" do
|
84
|
+
it "should raise a NotImplementedError" do
|
85
|
+
lambda { @store.read('foo') }.should raise_error(NotImplementedError)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#write" do
|
90
|
+
it "should raise a NotImplementedError" do
|
91
|
+
lambda { @store.write('foo', 'bar') }.should raise_error(NotImplementedError)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#fetch" do
|
96
|
+
it "should raise a NotImplementedError" do
|
97
|
+
lambda { @store.fetch('foo') {'bar'} }.should raise_error(NotImplementedError)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#exists?" do
|
102
|
+
it "should raise a NotImplementedError" do
|
103
|
+
lambda { @store.exists?('foo') }.should raise_error(NotImplementedError)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#delete" do
|
108
|
+
it "should raise a NotImplementedError" do
|
109
|
+
lambda { @store.delete('foo') }.should raise_error(NotImplementedError)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#delete_all!" do
|
114
|
+
it "should raise a NotImplementedError" do
|
115
|
+
lambda { @store.delete_all! }.should raise_error(NotImplementedError)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
# has 'all stores' shared group
|
3
|
+
require File.dirname(__FILE__) + '/abstract_store_spec'
|
4
|
+
|
5
|
+
describe Merb::Cache::FileStore do
|
6
|
+
it_should_behave_like 'all stores'
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
@store = Merb::Cache::FileStore.new(:dir => File.dirname(Tempfile.new("").path))
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# ==== #writable
|
14
|
+
#
|
15
|
+
|
16
|
+
describe "#writable?" do
|
17
|
+
describe "when conditions hash is empty" do
|
18
|
+
it "returns true" do
|
19
|
+
@store.writable?('foo').should be_true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "when given expire_in option" do
|
24
|
+
it "returns false" do
|
25
|
+
@store.writable?('foo', {}, :expire_in => 10).should be_false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return a boolean" do
|
30
|
+
@store.writable?(:foo, {}).should be_true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# ==== #read
|
36
|
+
#
|
37
|
+
|
38
|
+
describe "#read" do
|
39
|
+
describe "when cache file does not exist" do
|
40
|
+
it "should return nil" do
|
41
|
+
key = "body.txt"
|
42
|
+
|
43
|
+
FileUtils.rm(@store.pathify(key)) if File.exists?(@store.pathify(key))
|
44
|
+
@store.read(key).should be_nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "when cache file exists" do
|
49
|
+
it "reads the contents of the file" do
|
50
|
+
key = "tmp.txt"
|
51
|
+
body = "body of the file"
|
52
|
+
|
53
|
+
File.open(@store.pathify(key), "w+") do |file|
|
54
|
+
file << body
|
55
|
+
end
|
56
|
+
|
57
|
+
@store.read(key).should == body
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# ==== #write
|
64
|
+
#
|
65
|
+
|
66
|
+
describe "#write" do
|
67
|
+
it "should write" do
|
68
|
+
@store.write('foo', 'bar', {:params => :hash}, :conditions => :hash).should be_true
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "if it does not exist" do
|
72
|
+
it "create the file" do
|
73
|
+
key = "body.txt"
|
74
|
+
|
75
|
+
FileUtils.rm(@store.pathify(key)) if File.exists?(@store.pathify(key))
|
76
|
+
|
77
|
+
File.should_not be_exist(@store.pathify(key))
|
78
|
+
|
79
|
+
@store.write(key, "")
|
80
|
+
|
81
|
+
File.should be_exist(@store.pathify(key))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "when file already exists" do
|
86
|
+
it "overwrites the file" do
|
87
|
+
key = "tmp.txt"
|
88
|
+
old_body, new_body = "old body", "new body"
|
89
|
+
|
90
|
+
File.open(@store.pathify(key), "w+") do |file|
|
91
|
+
file << old_body
|
92
|
+
end
|
93
|
+
|
94
|
+
File.open(@store.pathify(key), "r") do |file|
|
95
|
+
file.read.should == old_body
|
96
|
+
end
|
97
|
+
|
98
|
+
@store.write(key, new_body)
|
99
|
+
|
100
|
+
File.open(@store.pathify(key), "r") do |file|
|
101
|
+
file.read.should == new_body
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# ==== #fetch
|
109
|
+
#
|
110
|
+
|
111
|
+
describe "#fetch" do
|
112
|
+
describe "when the entry can be read" do
|
113
|
+
it "does not call the block" do
|
114
|
+
key, body = "tmp.txt", "body"
|
115
|
+
called = false
|
116
|
+
proc = lambda { called = true }
|
117
|
+
|
118
|
+
File.open(@store.pathify(key), "w+") do |file|
|
119
|
+
file << body
|
120
|
+
end
|
121
|
+
|
122
|
+
@store.fetch(key, &proc)
|
123
|
+
called.should be_false
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "when entry cannot be read" do
|
128
|
+
it "calls the block" do
|
129
|
+
key = "tmp.txt"
|
130
|
+
called = false
|
131
|
+
proc = lambda { called = true }
|
132
|
+
|
133
|
+
FileUtils.rm(@store.pathify(key)) if File.exists?(@store.pathify(key))
|
134
|
+
|
135
|
+
@store.fetch(key, &proc)
|
136
|
+
called.should be_true
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# ==== # exists?
|
143
|
+
#
|
144
|
+
|
145
|
+
describe "#exists?" do
|
146
|
+
it "should return a boolean" do
|
147
|
+
@store.write('foo', 'bar')
|
148
|
+
@store.exists?('foo').should be_true
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# ==== #delete
|
154
|
+
#
|
155
|
+
|
156
|
+
describe "#delete" do
|
157
|
+
describe "when file exists" do
|
158
|
+
it "deletes the file" do
|
159
|
+
key, body = "tmp.txt", "body of the file"
|
160
|
+
|
161
|
+
File.open(@store.pathify(key), "w+") do |file|
|
162
|
+
file << body
|
163
|
+
end
|
164
|
+
|
165
|
+
File.exists?(@store.pathify(key)).should be_true
|
166
|
+
@store.delete(key)
|
167
|
+
File.exists?(@store.pathify(key)).should be_false
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "when file does not exist" do
|
172
|
+
it "does not raise" do
|
173
|
+
@store.delete("#{rand}-#{rand}-#{Time.now.to_i}.txt")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
#
|
179
|
+
# ==== #delete_all
|
180
|
+
#
|
181
|
+
|
182
|
+
describe "#delete_all" do
|
183
|
+
it "is not supported" do
|
184
|
+
lambda { @store.delete_all }.should raise_error(Merb::Cache::NotSupportedError)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
#
|
189
|
+
# ==== #pathify
|
190
|
+
#
|
191
|
+
|
192
|
+
describe "#pathify" do
|
193
|
+
it "should begin with the cache dir" do
|
194
|
+
@store.pathify("tmp.txt").should include(@store.dir)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should add any parameters to the end of the filename" do
|
198
|
+
@store.pathify("index.html", :page => 3, :lang => :en).should =~ %r[--#{{:page => 3, :lang => :en}.to_sha2}$]
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should separate the parameters from the key by a '?'" do
|
202
|
+
@store.pathify("index.html", :page => 3, :lang => :en).should =~ %r[--#{{:page => 3, :lang => :en}.to_sha2}$]
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/abstract_store_spec'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'memcached'
|
6
|
+
servers = '127.0.0.1:11211'
|
7
|
+
namespace = 'memcached_test_namespace'
|
8
|
+
|
9
|
+
options = {
|
10
|
+
:namespace => @namespace,
|
11
|
+
:hash => :default,
|
12
|
+
:distribution => :modula
|
13
|
+
}
|
14
|
+
cache = Memcached.new(servers, options)
|
15
|
+
key, value = Time.now.to_i.to_s, Time.now.to_s
|
16
|
+
cache.set(key, value)
|
17
|
+
raise Exception unless cache.get(key) == value
|
18
|
+
rescue Exception => e
|
19
|
+
puts e.message
|
20
|
+
puts "Memcached connection failed. Try starting memcached on the default port (11211)"
|
21
|
+
else
|
22
|
+
|
23
|
+
describe Merb::Cache::MemcachedStore do
|
24
|
+
it_should_behave_like 'all stores'
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
@store = Merb::Cache::MemcachedStore.new(:namespace => "specs", :servers => ["127.0.0.1:11211"])
|
28
|
+
@memcached = @store.memcached
|
29
|
+
@memcached.flush
|
30
|
+
end
|
31
|
+
|
32
|
+
after(:each) do
|
33
|
+
@memcached.flush
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
it "has accessor for namespace" do
|
38
|
+
@store.namespace.should == "specs"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has accessor for servers" do
|
42
|
+
@store.servers.should == ["127.0.0.1:11211"]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has accessor for memcached connector" do
|
46
|
+
@store.memcached.should == @memcached
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
#
|
51
|
+
# ==== #writable?
|
52
|
+
#
|
53
|
+
|
54
|
+
describe "#writable?" do
|
55
|
+
describe "when conditions hash is empty" do
|
56
|
+
it "returns true" do
|
57
|
+
@store.writable?('foo').should be_true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# ==== #read
|
64
|
+
#
|
65
|
+
|
66
|
+
describe "#read" do
|
67
|
+
describe "when cache has NO entry matching key" do
|
68
|
+
it "returns nil" do
|
69
|
+
key = "foo"
|
70
|
+
|
71
|
+
@memcached.delete(key) rescue nil
|
72
|
+
@store.read(key).should be_nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "when cache has entry matching key" do
|
77
|
+
it "returns the entry matching the key" do
|
78
|
+
key, data = "foo", "bar"
|
79
|
+
|
80
|
+
@memcached.set(key, data)
|
81
|
+
|
82
|
+
@store.read(key).should == data
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# ==== #write
|
89
|
+
#
|
90
|
+
|
91
|
+
describe "#write" do
|
92
|
+
it "should write" do
|
93
|
+
@store.write('foo', 'bar', {:params => :hash}, :conditions => :hash).should be_true
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "when entry with the same key does not exist" do
|
97
|
+
it "create a new entry" do
|
98
|
+
key, data = "foo", "bar"
|
99
|
+
|
100
|
+
@memcached.delete(key) rescue nil
|
101
|
+
lambda { @memcached.get(key) }.should raise_error(Memcached::NotFound)
|
102
|
+
|
103
|
+
@store.write(key, data)
|
104
|
+
@memcached.get(key).should == data
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "when entry with the same key already exists" do
|
109
|
+
it "overwrites the entry in the cache" do
|
110
|
+
key, data = "foo", "bar"
|
111
|
+
|
112
|
+
@memcached.set(key, "baz")
|
113
|
+
@memcached.get(key).should == "baz"
|
114
|
+
|
115
|
+
@store.write(key, data)
|
116
|
+
@memcached.get(key).should == data
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# ==== #exists?
|
123
|
+
#
|
124
|
+
describe "#exists?" do
|
125
|
+
it "should return a boolean" do
|
126
|
+
@store.write('foo', 'bar')
|
127
|
+
@store.exists?('foo').should be_true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# ==== #fetch
|
133
|
+
#
|
134
|
+
|
135
|
+
describe "#fetch" do
|
136
|
+
describe "when the entry exists in the cache" do
|
137
|
+
it "does NOT call the block" do
|
138
|
+
key, data = "foo", "bar"
|
139
|
+
called = false
|
140
|
+
proc = lambda { called = true }
|
141
|
+
|
142
|
+
@memcached.set(key, data)
|
143
|
+
@store.fetch(key, &proc)
|
144
|
+
|
145
|
+
called.should be_false
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "when the entry does not exist in the cache" do
|
150
|
+
it "calls the block" do
|
151
|
+
key, data = "foo", "bar"
|
152
|
+
called = false
|
153
|
+
proc = lambda { called = true }
|
154
|
+
|
155
|
+
@memcached.delete(key) rescue nil
|
156
|
+
@store.fetch(key, &proc)
|
157
|
+
|
158
|
+
called.should be_true
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# ==== #delete
|
165
|
+
#
|
166
|
+
|
167
|
+
describe "#delete" do
|
168
|
+
describe "when the entry exists in the cache" do
|
169
|
+
it "deletes the entry" do
|
170
|
+
key, data = "foo", "bar"
|
171
|
+
|
172
|
+
@memcached.set(key, data)
|
173
|
+
@memcached.get(key).should == data
|
174
|
+
|
175
|
+
@store.delete(key)
|
176
|
+
lambda { @memcached.get(key) }.should raise_error(Memcached::NotFound)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "when the entry does not exist in the cache" do
|
181
|
+
it "raises Memcached::NotFound" do
|
182
|
+
lambda { @memcached.delete("#{rand}-#{rand}-#{Time.now.to_i}") }.
|
183
|
+
should raise_error(Memcached::NotFound)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
#
|
189
|
+
# ==== #delete_all
|
190
|
+
#
|
191
|
+
|
192
|
+
describe "#delete_all" do
|
193
|
+
it "flushes Memcached object" do
|
194
|
+
@memcached.set("ruby", "rb")
|
195
|
+
@memcached.set("python", "py")
|
196
|
+
@memcached.set("perl", "pl")
|
197
|
+
|
198
|
+
@store.delete_all
|
199
|
+
|
200
|
+
@store.exists?("ruby").should be_false
|
201
|
+
@store.exists?("python").should be_false
|
202
|
+
@store.exists?("perl").should be_false
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
#
|
207
|
+
# ==== #clone
|
208
|
+
#
|
209
|
+
|
210
|
+
describe "#clone" do
|
211
|
+
it "clones Memcached instance" do
|
212
|
+
clone = @store.clone
|
213
|
+
|
214
|
+
clone.memcached.object_id.should_not == @store.memcached.object_id
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
#
|
219
|
+
# ==== #normalize
|
220
|
+
#
|
221
|
+
|
222
|
+
describe "#normalize" do
|
223
|
+
it "should begin with the key" do
|
224
|
+
@store.normalize("this/is/the/key").should =~ /^this\/is\/the\/key/
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should not add the '?' if there are no parameters" do
|
228
|
+
@store.normalize("this/is/the/key").should_not =~ /\?/
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should seperate the parameters from the key by a '?'" do
|
232
|
+
@store.normalize("this/is/the/key", :page => 3, :lang => :en).
|
233
|
+
should =~ %r!this\/is\/the\/key--#{{:page => 3, :lang => :en}.to_sha2}$!
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
#
|
238
|
+
# ==== #expire_time
|
239
|
+
#
|
240
|
+
|
241
|
+
describe "#expire_time" do
|
242
|
+
describe "when there is NO :expire_in parameter" do
|
243
|
+
it "returns 0" do
|
244
|
+
@store.expire_time.should == 0
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
describe "when there is :expire_in parameter" do
|
249
|
+
it "returns Time.now + the :expire_in parameter" do
|
250
|
+
now = Time.now
|
251
|
+
Time.should_receive(:now).and_return now
|
252
|
+
|
253
|
+
@store.expire_time(:expire_in => 100).should == now + 100
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|