benschwarz-merb-cache 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|