merb-cache 0.9.7 → 0.9.8
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 +2 -2
- data/README +207 -143
- data/Rakefile +55 -10
- data/TODO +0 -2
- data/lib/merb-cache/cache.rb +84 -0
- data/lib/merb-cache/core_ext/enumerable.rb +9 -0
- data/lib/merb-cache/core_ext/hash.rb +20 -0
- data/lib/merb-cache/merb_ext/controller.rb +167 -0
- data/lib/merb-cache/stores/fundamental/abstract_store.rb +101 -0
- data/lib/merb-cache/stores/fundamental/file_store.rb +112 -0
- data/lib/merb-cache/stores/fundamental/memcached_store.rb +112 -0
- data/lib/merb-cache/stores/strategy/abstract_strategy_store.rb +123 -0
- data/lib/merb-cache/stores/strategy/action_store.rb +56 -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/page_store.rb +64 -0
- data/lib/merb-cache/stores/strategy/sha1_store.rb +62 -0
- data/lib/merb-cache.rb +8 -7
- data/spec/merb-cache/cache_spec.rb +88 -0
- data/spec/merb-cache/core_ext/enumerable_spec.rb +22 -0
- data/spec/merb-cache/core_ext/hash_spec.rb +20 -0
- data/spec/merb-cache/merb_ext/controller_spec.rb +284 -0
- data/spec/merb-cache/stores/fundamental/abstract_store_spec.rb +166 -0
- data/spec/merb-cache/stores/fundamental/file_store_spec.rb +186 -0
- data/spec/merb-cache/stores/fundamental/memcached_store_spec.rb +243 -0
- data/spec/merb-cache/stores/strategy/abstract_strategy_store_spec.rb +78 -0
- data/spec/merb-cache/stores/strategy/action_store_spec.rb +189 -0
- data/spec/merb-cache/stores/strategy/adhoc_store_spec.rb +225 -0
- data/spec/merb-cache/stores/strategy/gzip_store_spec.rb +51 -0
- data/spec/merb-cache/stores/strategy/page_store_spec.rb +111 -0
- data/spec/merb-cache/stores/strategy/sha1_store_spec.rb +75 -0
- data/spec/spec_helper.rb +69 -72
- metadata +42 -31
- data/lib/merb-cache/cache-action.rb +0 -144
- data/lib/merb-cache/cache-fragment.rb +0 -95
- data/lib/merb-cache/cache-page.rb +0 -203
- data/lib/merb-cache/cache-store/database-activerecord.rb +0 -88
- data/lib/merb-cache/cache-store/database-datamapper.rb +0 -79
- data/lib/merb-cache/cache-store/database-sequel.rb +0 -78
- data/lib/merb-cache/cache-store/database.rb +0 -144
- data/lib/merb-cache/cache-store/dummy.rb +0 -106
- data/lib/merb-cache/cache-store/file.rb +0 -194
- data/lib/merb-cache/cache-store/memcache.rb +0 -199
- data/lib/merb-cache/cache-store/memory.rb +0 -168
- data/lib/merb-cache/merb-cache.rb +0 -165
- data/lib/merb-cache/merbtasks.rb +0 -6
- data/spec/config/database.yml +0 -14
- data/spec/controller.rb +0 -101
- data/spec/log/merb_test.log +0 -433
- data/spec/merb-cache-action_spec.rb +0 -162
- data/spec/merb-cache-fragment_spec.rb +0 -100
- data/spec/merb-cache-page_spec.rb +0 -150
- data/spec/merb-cache_spec.rb +0 -15
- data/spec/views/cache_controller/action1.html.erb +0 -4
- data/spec/views/cache_controller/action2.html.haml +0 -4
@@ -0,0 +1,166 @@
|
|
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 string key" do
|
20
|
+
@store.read('foo')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should accept a symbol key" do
|
24
|
+
@store.read(:foo)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should accept a parameters hash" do
|
28
|
+
@store.read('foo', :params => :hash)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#write" do
|
33
|
+
it "should not raise a NotImplementedError error" do
|
34
|
+
lambda { @store.write('foo', 'bar') }.should_not raise_error(NotImplementedError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should accept a string key" do
|
38
|
+
@store.write('foo', 'bar')
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should accept a symbol as a key" do
|
42
|
+
@store.write(:foo, :bar)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should accept parameters and conditions" do
|
46
|
+
@store.write('foo', 'bar', {:params => :hash}, :conditions => :hash)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#fetch" do
|
51
|
+
it "should not raise a NotImplementedError error" do
|
52
|
+
lambda { @store.fetch('foo') {'bar'} }.should_not raise_error(NotImplementedError)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should accept a string key" do
|
56
|
+
@store.fetch('foo') { 'bar' }
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should accept a symbol as a key" do
|
60
|
+
@store.fetch(:foo) { :bar }
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should accept parameters and conditions" do
|
64
|
+
@store.fetch('foo', {:params => :hash}, :conditions => :hash) { 'bar' }
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should accept a value generating block" do
|
68
|
+
@store.fetch('foo') {'bar'}
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should return the value of the block if it is called" do
|
72
|
+
@store.fetch(:boo) { "bar" }.should == "bar" if @store.writable?(:boo)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#exists?" do
|
77
|
+
it "should not raise a NotImplementedError error" do
|
78
|
+
lambda { @store.exists?('foo') }.should_not raise_error(NotImplementedError)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should accept a string key" do
|
82
|
+
@store.exists?('foo')
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should accept a symbol as a key" do
|
86
|
+
@store.exists?(:foo)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should accept parameters" do
|
90
|
+
@store.exists?('foo', :params => :hash)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#delete" do
|
95
|
+
it "should not raise a NotImplementedError error" do
|
96
|
+
lambda { @store.delete('foo') }.should_not raise_error(NotImplementedError)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should accept a string key" do
|
100
|
+
@store.delete('foo')
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should accept a symbol as a key" do
|
104
|
+
@store.delete(:foo)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should accept a parameters hash" do
|
108
|
+
@store.delete('foo', :params => :hash)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#delete_all!" do
|
113
|
+
it "should not raise a NotImplementedError error" do
|
114
|
+
lambda { @store.delete_all! }.should_not raise_error(NotImplementedError)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
describe Merb::Cache::AbstractStore do
|
121
|
+
before(:each) do
|
122
|
+
@store = Merb::Cache::AbstractStore.new
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#writable?" do
|
126
|
+
it "should raise a NotImplementedError error" do
|
127
|
+
lambda { @store.writable?('foo') }.should raise_error(NotImplementedError)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#read" do
|
132
|
+
it "should raise a NotImplementedError" do
|
133
|
+
lambda { @store.read('foo') }.should raise_error(NotImplementedError)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#write" do
|
138
|
+
it "should raise a NotImplementedError" do
|
139
|
+
lambda { @store.write('foo', 'bar') }.should raise_error(NotImplementedError)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "#fetch" do
|
144
|
+
it "should raise a NotImplementedError" do
|
145
|
+
lambda { @store.fetch('foo') {'bar'} }.should raise_error(NotImplementedError)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "#exists?" do
|
150
|
+
it "should raise a NotImplementedError" do
|
151
|
+
lambda { @store.exists?('foo') }.should raise_error(NotImplementedError)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "#delete" do
|
156
|
+
it "should raise a NotImplementedError" do
|
157
|
+
lambda { @store.delete('foo') }.should raise_error(NotImplementedError)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "#delete_all!" do
|
162
|
+
it "should raise a NotImplementedError" do
|
163
|
+
lambda { @store.delete_all! }.should raise_error(NotImplementedError)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,186 @@
|
|
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
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# ==== #read
|
32
|
+
#
|
33
|
+
|
34
|
+
describe "#read" do
|
35
|
+
describe "when cache file does not exist" do
|
36
|
+
it "should return nil" do
|
37
|
+
key = "body.txt"
|
38
|
+
|
39
|
+
FileUtils.rm(@store.pathify(key)) if File.exists?(@store.pathify(key))
|
40
|
+
@store.read(key).should be_nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "when cache file exists" do
|
45
|
+
it "reads the contents of the file" do
|
46
|
+
key = "tmp.txt"
|
47
|
+
body = "body of the file"
|
48
|
+
|
49
|
+
File.open(@store.pathify(key), "w+") do |file|
|
50
|
+
file << body
|
51
|
+
end
|
52
|
+
|
53
|
+
@store.read(key).should == body
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# ==== #write
|
60
|
+
#
|
61
|
+
|
62
|
+
describe "#write" do
|
63
|
+
describe "if it does not exist" do
|
64
|
+
it "create the file" do
|
65
|
+
key = "body.txt"
|
66
|
+
|
67
|
+
FileUtils.rm(@store.pathify(key)) if File.exists?(@store.pathify(key))
|
68
|
+
|
69
|
+
File.should_not be_exist(@store.pathify(key))
|
70
|
+
|
71
|
+
@store.write(key, "")
|
72
|
+
|
73
|
+
File.should be_exist(@store.pathify(key))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "when file already exists" do
|
78
|
+
it "overwrites the file" do
|
79
|
+
key = "tmp.txt"
|
80
|
+
old_body, new_body = "old body", "new body"
|
81
|
+
|
82
|
+
File.open(@store.pathify(key), "w+") do |file|
|
83
|
+
file << old_body
|
84
|
+
end
|
85
|
+
|
86
|
+
File.open(@store.pathify(key), "r") do |file|
|
87
|
+
file.read.should == old_body
|
88
|
+
end
|
89
|
+
|
90
|
+
@store.write(key, new_body)
|
91
|
+
|
92
|
+
File.open(@store.pathify(key), "r") do |file|
|
93
|
+
file.read.should == new_body
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# ==== #fetch
|
101
|
+
#
|
102
|
+
|
103
|
+
describe "#fetch" do
|
104
|
+
describe "when the entry can be read" do
|
105
|
+
it "does not call the block" do
|
106
|
+
key, body = "tmp.txt", "body"
|
107
|
+
called = false
|
108
|
+
proc = lambda { called = true }
|
109
|
+
|
110
|
+
File.open(@store.pathify(key), "w+") do |file|
|
111
|
+
file << body
|
112
|
+
end
|
113
|
+
|
114
|
+
@store.fetch(key, &proc)
|
115
|
+
called.should be_false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "when entry cannot be read" do
|
120
|
+
it "calls the block" do
|
121
|
+
key = "tmp.txt"
|
122
|
+
called = false
|
123
|
+
proc = lambda { called = true }
|
124
|
+
|
125
|
+
FileUtils.rm(@store.pathify(key)) if File.exists?(@store.pathify(key))
|
126
|
+
|
127
|
+
@store.fetch(key, &proc)
|
128
|
+
called.should be_true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# ==== #delete
|
135
|
+
#
|
136
|
+
|
137
|
+
describe "#delete" do
|
138
|
+
describe "when file exists" do
|
139
|
+
it "deletes the file" do
|
140
|
+
key, body = "tmp.txt", "body of the file"
|
141
|
+
|
142
|
+
File.open(@store.pathify(key), "w+") do |file|
|
143
|
+
file << body
|
144
|
+
end
|
145
|
+
|
146
|
+
File.exists?(@store.pathify(key)).should be_true
|
147
|
+
@store.delete(key)
|
148
|
+
File.exists?(@store.pathify(key)).should be_false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "when file does not exist" do
|
153
|
+
it "does not raise" do
|
154
|
+
@store.delete("#{rand}-#{rand}-#{Time.now.to_i}.txt")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
#
|
160
|
+
# ==== #delete_all
|
161
|
+
#
|
162
|
+
|
163
|
+
describe "#delete_all" do
|
164
|
+
it "is not supported" do
|
165
|
+
lambda { @store.delete_all }.should raise_error(Merb::Cache::NotSupportedError)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
#
|
170
|
+
# ==== #pathify
|
171
|
+
#
|
172
|
+
|
173
|
+
describe "#pathify" do
|
174
|
+
it "should begin with the cache dir" do
|
175
|
+
@store.pathify("tmp.txt").should include(@store.dir)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should add any parameters to the end of the filename" do
|
179
|
+
@store.pathify("index.html", :page => 3, :lang => :en).should =~ %r[--#{{:page => 3, :lang => :en}.to_sha2}$]
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should separate the parameters from the key by a '?'" do
|
183
|
+
@store.pathify("index.html", :page => 3, :lang => :en).should =~ %r[--#{{:page => 3, :lang => :en}.to_sha2}$]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,243 @@
|
|
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:43042', '127.0.0.1:43043']
|
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
|
+
raise "Memcached connection failed. Try starting memcached with the memcached:start rake task or installing memcached gem with sudo gem install memcached."
|
21
|
+
end
|
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:43042", "127.0.0.1:43043"])
|
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:43042", "127.0.0.1:43043"]
|
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
|
+
describe "when entry with the same key does not exist" do
|
93
|
+
it "create a new entry" do
|
94
|
+
key, data = "foo", "bar"
|
95
|
+
|
96
|
+
@memcached.delete(key) rescue nil
|
97
|
+
lambda { @memcached.get(key) }.should raise_error(Memcached::NotFound)
|
98
|
+
|
99
|
+
@store.write(key, data)
|
100
|
+
@memcached.get(key).should == data
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "when entry with the same key already exists" do
|
105
|
+
it "overwrites the entry in the cache" do
|
106
|
+
key, data = "foo", "bar"
|
107
|
+
|
108
|
+
@memcached.set(key, "baz")
|
109
|
+
@memcached.get(key).should == "baz"
|
110
|
+
|
111
|
+
@store.write(key, data)
|
112
|
+
@memcached.get(key).should == data
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# ==== #fetch
|
119
|
+
#
|
120
|
+
|
121
|
+
describe "#fetch" do
|
122
|
+
describe "when the entry exists in the cache" do
|
123
|
+
it "does NOT call the block" do
|
124
|
+
key, data = "foo", "bar"
|
125
|
+
called = false
|
126
|
+
proc = lambda { called = true }
|
127
|
+
|
128
|
+
@memcached.set(key, data)
|
129
|
+
@store.fetch(key, &proc)
|
130
|
+
|
131
|
+
called.should be_false
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "when the entry does not exist in the cache" do
|
136
|
+
it "calls the block" do
|
137
|
+
key, data = "foo", "bar"
|
138
|
+
called = false
|
139
|
+
proc = lambda { called = true }
|
140
|
+
|
141
|
+
@memcached.delete(key) rescue nil
|
142
|
+
@store.fetch(key, &proc)
|
143
|
+
|
144
|
+
called.should be_true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# ==== #delete
|
151
|
+
#
|
152
|
+
|
153
|
+
describe "#delete" do
|
154
|
+
describe "when the entry exists in the cache" do
|
155
|
+
it "deletes the entry" do
|
156
|
+
key, data = "foo", "bar"
|
157
|
+
|
158
|
+
@memcached.set(key, data)
|
159
|
+
@memcached.get(key).should == data
|
160
|
+
|
161
|
+
@store.delete(key)
|
162
|
+
lambda { @memcached.get(key) }.should raise_error(Memcached::NotFound)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "when the entry does not exist in the cache" do
|
167
|
+
it "raises Memcached::NotFound" do
|
168
|
+
lambda { @memcached.delete("#{rand}-#{rand}-#{Time.now.to_i}") }.
|
169
|
+
should raise_error(Memcached::NotFound)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# ==== #delete_all
|
176
|
+
#
|
177
|
+
|
178
|
+
describe "#delete_all" do
|
179
|
+
it "flushes Memcached object" do
|
180
|
+
@memcached.set("ruby", "rb")
|
181
|
+
@memcached.set("python", "py")
|
182
|
+
@memcached.set("perl", "pl")
|
183
|
+
|
184
|
+
@store.delete_all
|
185
|
+
|
186
|
+
@store.exists?("ruby").should be_nil
|
187
|
+
@store.exists?("python").should be_nil
|
188
|
+
@store.exists?("perl").should be_nil
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
#
|
193
|
+
# ==== #clone
|
194
|
+
#
|
195
|
+
|
196
|
+
describe "#clone" do
|
197
|
+
it "clones Memcached instance" do
|
198
|
+
clone = @store.clone
|
199
|
+
|
200
|
+
clone.memcached.object_id.should_not == @store.memcached.object_id
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
#
|
205
|
+
# ==== #normalize
|
206
|
+
#
|
207
|
+
|
208
|
+
describe "#normalize" do
|
209
|
+
it "should begin with the key" do
|
210
|
+
@store.normalize("this/is/the/key").should =~ /^this\/is\/the\/key/
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should not add the '?' if there are no parameters" do
|
214
|
+
@store.normalize("this/is/the/key").should_not =~ /\?/
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should seperate the parameters from the key by a '?'" do
|
218
|
+
@store.normalize("this/is/the/key", :page => 3, :lang => :en).
|
219
|
+
should =~ %r!this\/is\/the\/key--#{{:page => 3, :lang => :en}.to_sha2}$!
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
#
|
224
|
+
# ==== #expire_time
|
225
|
+
#
|
226
|
+
|
227
|
+
describe "#expire_time" do
|
228
|
+
describe "when there is NO :expire_in parameter" do
|
229
|
+
it "returns 0" do
|
230
|
+
@store.expire_time.should == 0
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe "when there is :expire_in parameter" do
|
235
|
+
it "returns Time.now + the :expire_in parameter" do
|
236
|
+
now = Time.now
|
237
|
+
Time.should_receive(:now).and_return now
|
238
|
+
|
239
|
+
@store.expire_time(:expire_in => 100).should == now + 100
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../fundamental/abstract_store_spec'
|
3
|
+
|
4
|
+
|
5
|
+
describe Merb::Cache::AbstractStrategyStore do
|
6
|
+
describe 'all strategy stores', :shared => true do
|
7
|
+
it_should_behave_like 'all stores'
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
Merb::Cache.stores.clear
|
11
|
+
Thread.current[:'merb-cache'] = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "contextualizing method", :shared => true do
|
15
|
+
it "should return a subclass of itself" do
|
16
|
+
subclass = @klass.contextualize(Class.new(Merb::Cache::AbstractStore))
|
17
|
+
subclass.superclass.should == @klass
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should set the contextualized_stores attributes" do
|
21
|
+
subclass = @klass.contextualize(context_class = Class.new(Merb::Cache::AbstractStore))
|
22
|
+
subclass.contextualized_stores.first.should == context_class
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".contextualize" do
|
27
|
+
it_should_behave_like "contextualizing method"
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ".[]" do
|
31
|
+
it_should_behave_like "contextualizing method"
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#initialize" do
|
35
|
+
it "should create an instance of the any context classes" do
|
36
|
+
subclass = @klass.contextualize(context_class = Class.new(Merb::Cache::AbstractStore))
|
37
|
+
instance = subclass.new({})
|
38
|
+
instance.stores.first.class.superclass.should == Merb::Cache::AbstractStore
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should lookup the instance of any context names" do
|
42
|
+
Merb::Cache.register(:foo, Class.new(Merb::Cache::AbstractStore))
|
43
|
+
subclass = @klass.contextualize(:foo)
|
44
|
+
Merb::Cache.should_receive(:[]).with(:foo)
|
45
|
+
subclass.new({})
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#clone" do
|
50
|
+
it "should clone each context instance" do
|
51
|
+
subclass = @klass.contextualize(context_class = Class.new(Merb::Cache::AbstractStore))
|
52
|
+
instance = mock(:instance)
|
53
|
+
context_class.should_receive(:new).and_return(instance)
|
54
|
+
instance.should_receive(:clone)
|
55
|
+
|
56
|
+
subclass.new.clone
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#write_all" do
|
61
|
+
it "should not raise a NotImplementedError error" do
|
62
|
+
lambda { @store.write_all('foo', 'bar') }.should_not raise_error(NotImplementedError)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should accept a string key" do
|
66
|
+
@store.write_all('foo', 'bar')
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should accept a symbol as a key" do
|
70
|
+
@store.write_all(:foo, :bar)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should accept parameters and conditions" do
|
74
|
+
@store.write_all('foo', 'bar', {:params => :hash}, :conditions => :hash)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|