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.
Files changed (55) hide show
  1. data/LICENSE +2 -2
  2. data/README +207 -143
  3. data/Rakefile +55 -10
  4. data/TODO +0 -2
  5. data/lib/merb-cache/cache.rb +84 -0
  6. data/lib/merb-cache/core_ext/enumerable.rb +9 -0
  7. data/lib/merb-cache/core_ext/hash.rb +20 -0
  8. data/lib/merb-cache/merb_ext/controller.rb +167 -0
  9. data/lib/merb-cache/stores/fundamental/abstract_store.rb +101 -0
  10. data/lib/merb-cache/stores/fundamental/file_store.rb +112 -0
  11. data/lib/merb-cache/stores/fundamental/memcached_store.rb +112 -0
  12. data/lib/merb-cache/stores/strategy/abstract_strategy_store.rb +123 -0
  13. data/lib/merb-cache/stores/strategy/action_store.rb +56 -0
  14. data/lib/merb-cache/stores/strategy/adhoc_store.rb +69 -0
  15. data/lib/merb-cache/stores/strategy/gzip_store.rb +63 -0
  16. data/lib/merb-cache/stores/strategy/page_store.rb +64 -0
  17. data/lib/merb-cache/stores/strategy/sha1_store.rb +62 -0
  18. data/lib/merb-cache.rb +8 -7
  19. data/spec/merb-cache/cache_spec.rb +88 -0
  20. data/spec/merb-cache/core_ext/enumerable_spec.rb +22 -0
  21. data/spec/merb-cache/core_ext/hash_spec.rb +20 -0
  22. data/spec/merb-cache/merb_ext/controller_spec.rb +284 -0
  23. data/spec/merb-cache/stores/fundamental/abstract_store_spec.rb +166 -0
  24. data/spec/merb-cache/stores/fundamental/file_store_spec.rb +186 -0
  25. data/spec/merb-cache/stores/fundamental/memcached_store_spec.rb +243 -0
  26. data/spec/merb-cache/stores/strategy/abstract_strategy_store_spec.rb +78 -0
  27. data/spec/merb-cache/stores/strategy/action_store_spec.rb +189 -0
  28. data/spec/merb-cache/stores/strategy/adhoc_store_spec.rb +225 -0
  29. data/spec/merb-cache/stores/strategy/gzip_store_spec.rb +51 -0
  30. data/spec/merb-cache/stores/strategy/page_store_spec.rb +111 -0
  31. data/spec/merb-cache/stores/strategy/sha1_store_spec.rb +75 -0
  32. data/spec/spec_helper.rb +69 -72
  33. metadata +42 -31
  34. data/lib/merb-cache/cache-action.rb +0 -144
  35. data/lib/merb-cache/cache-fragment.rb +0 -95
  36. data/lib/merb-cache/cache-page.rb +0 -203
  37. data/lib/merb-cache/cache-store/database-activerecord.rb +0 -88
  38. data/lib/merb-cache/cache-store/database-datamapper.rb +0 -79
  39. data/lib/merb-cache/cache-store/database-sequel.rb +0 -78
  40. data/lib/merb-cache/cache-store/database.rb +0 -144
  41. data/lib/merb-cache/cache-store/dummy.rb +0 -106
  42. data/lib/merb-cache/cache-store/file.rb +0 -194
  43. data/lib/merb-cache/cache-store/memcache.rb +0 -199
  44. data/lib/merb-cache/cache-store/memory.rb +0 -168
  45. data/lib/merb-cache/merb-cache.rb +0 -165
  46. data/lib/merb-cache/merbtasks.rb +0 -6
  47. data/spec/config/database.yml +0 -14
  48. data/spec/controller.rb +0 -101
  49. data/spec/log/merb_test.log +0 -433
  50. data/spec/merb-cache-action_spec.rb +0 -162
  51. data/spec/merb-cache-fragment_spec.rb +0 -100
  52. data/spec/merb-cache-page_spec.rb +0 -150
  53. data/spec/merb-cache_spec.rb +0 -15
  54. data/spec/views/cache_controller/action1.html.erb +0 -4
  55. data/spec/views/cache_controller/action2.html.haml +0 -4
@@ -0,0 +1,189 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.dirname(__FILE__) + '/abstract_strategy_store_spec'
3
+
4
+ describe Merb::Cache::ActionStore do
5
+ it_should_behave_like 'all strategy stores'
6
+
7
+ # this could be cleaned up a bit
8
+ before(:each) do
9
+ Merb::Cache.stores.clear
10
+ Thread.current[:'merb-cache'] = nil
11
+
12
+ @klass = Merb::Cache::ActionStore[:dummy]
13
+ Merb::Cache.register(:dummy, DummyStore)
14
+ Merb::Cache.register(:default, @klass)
15
+
16
+ @store = Merb::Cache[:default]
17
+ @dummy = @store.stores.first
18
+
19
+ class TestController < Merb::Controller; def action; end; end
20
+ @controller = TestController.new(fake_request)
21
+ @controller.stub!(:action_name).and_return :action
22
+ @controller.stub!(:body).and_return 'body'
23
+ end
24
+
25
+ describe "#writable?" do
26
+ it "should be false if the key argument is not an instance of a controller" do
27
+ @store.writable?(:foo).should be_false
28
+ end
29
+
30
+ it "should be false if the fundamental store cannot write the normalized key" do
31
+ @store.stores.first.should_receive(:writable?).and_return false
32
+
33
+ @store.writable?(@controller).should be_false
34
+ end
35
+
36
+ it "should be true if the key is a controller instance and the fundamental store is writable" do
37
+ @store.writable?(@controller).should be_true
38
+ end
39
+ end
40
+
41
+ describe "#read" do
42
+ it "should pass the normalized dispatch as the key to the context cache" do
43
+ @dummy.should_receive(:read).with("TestController#action", {})
44
+
45
+ @store.read(@controller)
46
+ end
47
+ end
48
+
49
+ describe "#write" do
50
+ it "should pass the normalized dispatch as the key to the fundamental store" do
51
+ @dummy.should_receive(:write).with("TestController#action", @controller.body, {}, {})
52
+
53
+ @store.write(@controller)
54
+ end
55
+
56
+ it "should not store to the context cache if the dispatch is not storable" do
57
+ @dummy.should_not_receive(:write)
58
+
59
+ @store.write(:foo).should be_nil
60
+ end
61
+
62
+ it "should use the controller instance's body as the data" do
63
+ @controller.should_receive(:body)
64
+
65
+ @store.write(@controller)
66
+ end
67
+ end
68
+
69
+ describe "#write_all" do
70
+ it "should pass the normalized dispatch as the key to the fundamental store" do
71
+ @dummy.should_receive(:write_all).with("TestController#action", @controller.body, {}, {})
72
+
73
+ @store.write_all(@controller)
74
+ end
75
+
76
+ it "should not store to the context cache if the dispatch is not storable" do
77
+ @dummy.should_not_receive(:write_all)
78
+
79
+ @store.write_all(:foo).should be_nil
80
+ end
81
+
82
+ it "should use the controller instance's body as the data" do
83
+ @controller.should_receive(:body)
84
+
85
+ @store.write_all(@controller)
86
+ end
87
+ end
88
+
89
+ describe "examples" do
90
+ class MLBSchedule < Merb::Controller
91
+ cache :index
92
+
93
+ def index
94
+ "MLBSchedule index"
95
+ end
96
+ end
97
+
98
+ class MLBScores < Merb::Controller
99
+ cache :index, :show
100
+ cache :overview
101
+ cache :short, :params => :page
102
+ cache :stats, :params => [:start_date, :end_date]
103
+ cache :ticker, :expire_in => 10
104
+
105
+ eager_cache :index, [MLBSchedule, :index]
106
+ eager_cache :overview, :index
107
+ eager_cache(:short, :params => :page) {|c| c.params[:page] = (c.params[:page].to_i + 1).to_s}
108
+
109
+ def index
110
+ "MLBScores index"
111
+ end
112
+
113
+ def show(team)
114
+ "MLBScores show(#{team})"
115
+ end
116
+
117
+ def overview(team = :all)
118
+ "MLBScores overview(#{team})"
119
+ end
120
+
121
+ def short(team = :all)
122
+ "MLBScores short(#{team})[#{params[:page]}]"
123
+ end
124
+
125
+ def stats(start_date, end_date, team = :all)
126
+ "MLBScores stats(#{team}, #{start_date}, #{end_date})"
127
+ end
128
+
129
+ def ticker
130
+ "MLBScores ticker"
131
+ end
132
+ end
133
+
134
+ it "should cache the index action on the first request" do
135
+ dispatch_to(MLBScores, :index)
136
+
137
+ @dummy.data("MLBScores#index").should == "MLBScores index"
138
+ end
139
+
140
+ it "should cache the show action by the team parameter using the action arguments" do
141
+ dispatch_to(MLBScores, :show, :team => :redsox)
142
+
143
+ @dummy.data("MLBScores#show", :team => 'redsox').should == "MLBScores show(redsox)"
144
+ end
145
+
146
+ it "should cache the overview action by the default parameter if none is given" do
147
+ dispatch_to(MLBScores, :overview)
148
+
149
+ @dummy.data("MLBScores#overview", :team => :all).should == "MLBScores overview(all)"
150
+ end
151
+
152
+ it "should cache the short action by the team & page parameters" do
153
+ dispatch_to(MLBScores, :short, :team => :bosux, :page => 4)
154
+
155
+ @dummy.data("MLBScores#short", :team => 'bosux', :page => '4').should == "MLBScores short(bosux)[4]"
156
+ end
157
+
158
+ it "should cache the stats action by team, start_date & end_date parameters" do
159
+ start_date, end_date = Time.today.to_s, Time.now.to_s
160
+ dispatch_to(MLBScores, :stats, :start_date => start_date, :end_date => end_date)
161
+
162
+ @dummy.data("MLBScores#stats", :team => :all, :start_date => start_date, :end_date => end_date).should == "MLBScores stats(all, #{start_date}, #{end_date})"
163
+ end
164
+
165
+ it "should cache the ticker action with an expire_in condition" do
166
+ dispatch_to(MLBScores, :ticker)
167
+
168
+ @dummy.conditions("MLBScores#ticker")[:expire_in].should == 10
169
+ end
170
+
171
+ it "should eager cache MLBSchedule#index after a request to MLBScores#index" do
172
+ dispatch_to(MLBScores, :index)
173
+
174
+ @dummy.data("MLBSchedule#index").should == "MLBSchedule index"
175
+ end
176
+
177
+ it "should eager cache :index after a request to :overview" do
178
+ dispatch_to(MLBScores, :overview)
179
+
180
+ @dummy.data("MLBScores#index").should == "MLBScores index"
181
+ end
182
+
183
+ it "should eager cache the next :short page" do
184
+ dispatch_to(MLBScores, :short, :team => :bosux, :page => 4)
185
+
186
+ @dummy.data("MLBScores#short", :team => 'bosux', :page => '5').should == "MLBScores short(bosux)[5]"
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,225 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.dirname(__FILE__) + '/abstract_strategy_store_spec'
3
+
4
+ describe Merb::Cache::AdhocStore do
5
+ it_should_behave_like 'all stores'
6
+
7
+ before(:each) do
8
+ Merb::Cache.stores.clear
9
+ Thread.current[:'merb-cache'] = nil
10
+ Merb::Cache.register(:dummy, DummyStore)
11
+ @store = Merb::Cache::AdhocStore[:dummy]
12
+ end
13
+
14
+ describe "#initialize" do
15
+ it "should lookup all store names" do
16
+ names = [:first, :second, :third]
17
+ names.each {|n| Merb::Cache.should_receive(:[]).with(n)}
18
+
19
+ Merb::Cache::AdhocStore[*names]
20
+ end
21
+ end
22
+
23
+ describe "#writable?" do
24
+ it "should return the first non-nil result of a writeable store" do
25
+ unwritable, writable = mock(:unwritable_store), mock(:writable_store)
26
+ unwritable.should_receive(:writable?).and_return nil
27
+ writable.should_receive(:writable?).and_return true
28
+
29
+ adhoc = Merb::Cache::AdhocStore.new
30
+ adhoc.stores = [unwritable, writable]
31
+ adhoc.writable?(:foo).should be_true
32
+ end
33
+
34
+ it "should stop calling writable after the first non-nil result" do
35
+ unwritable, writable, unused = mock(:unwritable_store), mock(:writable_store), mock(:unused_store)
36
+ unwritable.stub!(:writable?).and_return nil
37
+ writable.should_receive(:writable?).and_return true
38
+ unused.should_not_receive(:writable?)
39
+
40
+ adhoc = Merb::Cache::AdhocStore.new
41
+ adhoc.stores = [unwritable, writable, unused]
42
+ adhoc.writable?(:foo).should be_true
43
+ end
44
+
45
+ it "should return nil if none of the stores are writable" do
46
+ unwritable = mock(:unwritable_store)
47
+ unwritable.should_receive(:writable?).exactly(3).times.and_return(nil)
48
+
49
+ adhoc = Merb::Cache::AdhocStore.new
50
+ adhoc.stores = [unwritable, unwritable, unwritable]
51
+ adhoc.writable?(:foo).should be_nil
52
+ end
53
+ end
54
+
55
+ describe "#write" do
56
+ it "should return the first non-nil result of a writeable store" do
57
+ unwritable, writable = mock(:unwritable_store), mock(:writable_store)
58
+ unwritable.should_receive(:write).and_return nil
59
+ writable.should_receive(:write).and_return true
60
+
61
+ adhoc = Merb::Cache::AdhocStore.new
62
+ adhoc.stores = [unwritable, writable]
63
+ adhoc.write(:foo).should be_true
64
+ end
65
+
66
+ it "should stop calling writable after the first non-nil result" do
67
+ unwritable, writable, unused = mock(:unwritable_store), mock(:writable_store), mock(:unused_store)
68
+ unwritable.stub!(:write).and_return nil
69
+ writable.should_receive(:write).and_return true
70
+ unused.should_not_receive(:write)
71
+
72
+ adhoc = Merb::Cache::AdhocStore.new
73
+ adhoc.stores = [unwritable, writable, unused]
74
+ adhoc.write(:foo).should be_true
75
+ end
76
+
77
+ it "should return nil if none of the stores are writable" do
78
+ unwritable = mock(:unwritable_store)
79
+ unwritable.should_receive(:write).exactly(3).times.and_return(nil)
80
+
81
+ adhoc = Merb::Cache::AdhocStore.new
82
+ adhoc.stores = [unwritable, unwritable, unwritable]
83
+ adhoc.write(:foo).should be_nil
84
+ end
85
+ end
86
+
87
+ describe "#write_all" do
88
+ it "should return false if a store returns nil for write_all" do
89
+ unwritable, writable = mock(:unwritable_store), mock(:writable_store)
90
+ unwritable.should_receive(:write_all).and_return nil
91
+ writable.should_receive(:write_all).and_return "bar"
92
+
93
+ adhoc = Merb::Cache::AdhocStore.new
94
+ adhoc.stores = [unwritable, writable]
95
+ adhoc.write_all(:foo).should be_false
96
+ end
97
+
98
+ it "should always call write_all on every store" do
99
+ unwritable, writable, used = mock(:unwritable_store), mock(:writable_store), mock(:used_store)
100
+ unwritable.stub!(:write_all).and_return nil
101
+ writable.should_receive(:write_all).and_return true
102
+ used.should_receive(:write_all).and_return true
103
+
104
+ adhoc = Merb::Cache::AdhocStore.new
105
+ adhoc.stores = [unwritable, writable, used]
106
+ adhoc.write_all(:foo).should be_false
107
+ end
108
+ end
109
+
110
+ describe "#fetch" do
111
+ it "should return a call to read if it is non-nil" do
112
+ adhoc = Merb::Cache::AdhocStore.new
113
+ adhoc.should_receive(:read).and_return "bar"
114
+ adhoc.fetch(:foo).should == "bar"
115
+ end
116
+
117
+ it "should return the first non-nil result of a fetchable store" do
118
+ unfetchable, fetchable = mock(:unfetchable_store), mock(:fetchable_store)
119
+ unfetchable.should_receive(:fetch).and_return nil
120
+ fetchable.should_receive(:fetch).and_return true
121
+
122
+ adhoc = Merb::Cache::AdhocStore.new
123
+ adhoc.stores = [unfetchable, fetchable]
124
+ adhoc.should_receive(:read).and_return nil
125
+ adhoc.fetch(:foo).should be_true
126
+ end
127
+
128
+ it "should return the value of the block if none of the stores are fetchable" do
129
+ adhoc = Merb::Cache::AdhocStore.new
130
+ adhoc.fetch(:foo) {
131
+ 'foo'
132
+
133
+ }.should == 'foo'
134
+ end
135
+
136
+ it "should stop calling fetch after the first non-nil result" do
137
+ unfetchable, fetchable, unused = mock(:unwritable_store), mock(:writable_store), mock(:unused_store)
138
+ unfetchable.stub!(:fetch).and_return nil
139
+ fetchable.should_receive(:fetch).and_return true
140
+ unused.should_not_receive(:fetch)
141
+
142
+ adhoc = Merb::Cache::AdhocStore.new
143
+ adhoc.stores = [unfetchable, fetchable, unused]
144
+ adhoc.should_receive(:read).and_return nil
145
+ adhoc.fetch(:foo).should be_true
146
+ end
147
+ end
148
+
149
+ describe "#exists?" do
150
+ it "should return the first non-nil result of a readable store" do
151
+ unreadable, readable = mock(:unreadable_store), mock(:readable_store)
152
+ unreadable.should_receive(:exists?).and_return nil
153
+ readable.should_receive(:exists?).and_return true
154
+
155
+ adhoc = Merb::Cache::AdhocStore.new
156
+ adhoc.stores = [unreadable, readable]
157
+ adhoc.exists?(:foo).should be_true
158
+ end
159
+
160
+ it "should stop calling readable after the first non-nil result" do
161
+ unreadable, readable, unused = mock(:unreadable_store), mock(:readable_store), mock(:unused_store)
162
+ unreadable.stub!(:exists?).and_return nil
163
+ readable.should_receive(:exists?).and_return true
164
+ unused.should_not_receive(:exists?)
165
+
166
+ adhoc = Merb::Cache::AdhocStore.new
167
+ adhoc.stores = [unreadable, readable, unused]
168
+ adhoc.exists?(:foo).should be_true
169
+ end
170
+
171
+ it "should return nil if none of the stores are readable" do
172
+ unreadable = mock(:unreadable_store)
173
+ unreadable.should_receive(:exists?).exactly(3).times.and_return(nil)
174
+
175
+ adhoc = Merb::Cache::AdhocStore.new
176
+ adhoc.stores = [unreadable, unreadable, unreadable]
177
+ adhoc.exists?(:foo).should be_nil
178
+ end
179
+ end
180
+
181
+ describe "#delete" do
182
+ it "should return false if all stores returns nil for delete" do
183
+ undeletable = mock(:undeletable_store)
184
+ undeletable.should_receive(:delete).and_return nil
185
+
186
+ adhoc = Merb::Cache::AdhocStore.new
187
+ adhoc.stores = [undeletable]
188
+ adhoc.delete(:foo).should be_false
189
+ end
190
+
191
+ it "should always call delete on every store" do
192
+ undeletable, deletable, used = mock(:undeletable_store), mock(:deletable_store), mock(:used_store)
193
+ undeletable.stub!(:delete).and_return nil
194
+ deletable.should_receive(:delete).and_return true
195
+ used.should_receive(:delete).and_return true
196
+
197
+ adhoc = Merb::Cache::AdhocStore.new
198
+ adhoc.stores = [undeletable, deletable, used]
199
+ adhoc.delete(:foo).should be_true
200
+ end
201
+ end
202
+
203
+ describe "#delete_all!" do
204
+ it "should return false if a store returns nil for write_all" do
205
+ undeletable, deletable = mock(:undeletable_store), mock(:deletable_store)
206
+ undeletable.should_receive(:delete_all!).and_return nil
207
+ deletable.should_receive(:delete_all!).and_return true
208
+
209
+ adhoc = Merb::Cache::AdhocStore.new
210
+ adhoc.stores = [undeletable, deletable]
211
+ adhoc.delete_all!.should be_false
212
+ end
213
+
214
+ it "should always call write_all on every store" do
215
+ undeletable, deletable, used = mock(:undeletable_store), mock(:deletable_store), mock(:used_store)
216
+ undeletable.stub!(:delete_all!).and_return nil
217
+ deletable.should_receive(:delete_all!).and_return true
218
+ used.should_receive(:delete_all!).and_return true
219
+
220
+ adhoc = Merb::Cache::AdhocStore.new
221
+ adhoc.stores = [undeletable, deletable, used]
222
+ adhoc.delete_all!.should be_false
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.dirname(__FILE__) + '/abstract_strategy_store_spec'
3
+
4
+ describe Merb::Cache::GzipStore do
5
+ it_should_behave_like 'all strategy stores'
6
+
7
+ before(:each) do
8
+ @klass = Merb::Cache::GzipStore
9
+ @store = Merb::Cache::GzipStore[DummyStore].new
10
+ end
11
+
12
+ describe "#writable?" do
13
+ it "should always be true" do
14
+ @store.writable?(:foo).should be_true
15
+ @store.writable?('foo').should be_true
16
+ @store.writable?(123).should be_true
17
+ end
18
+ end
19
+
20
+ describe "#read" do
21
+ it "should return nil if hash does not exist as a key in any context store" do
22
+ @store.stores.each {|s| s.should_receive(:read).with(:foo, :bar => :baz).and_return nil}
23
+
24
+ @store.read(:foo, :bar => :baz).should be_nil
25
+ end
26
+
27
+ it "should return the data from the context store when there is a hash key match" do
28
+ @store.stores.first.should_receive(:read).with(:foo, {}).and_return @store.compress("bar")
29
+
30
+ @store.read(:foo).should == "bar"
31
+ end
32
+ end
33
+
34
+ describe "#write" do
35
+ it "should pass the hashed key to the context store" do
36
+ @store.stores.first.should_receive(:write).with(:foo, @store.compress('body'), {}, {}).and_return true
37
+
38
+ @store.write(:foo, 'body').should be_true
39
+ end
40
+
41
+ it "should use the parameters to create the hashed key" do
42
+ @store.stores.first.should_receive(:write).with(:foo, @store.compress('body'), {:bar => :baz}, {}).and_return true
43
+
44
+ @store.write(:foo, 'body', :bar => :baz).should be_true
45
+ end
46
+ end
47
+
48
+ describe "#fetch" do
49
+ # not sure how to spec this yet
50
+ end
51
+ end
@@ -0,0 +1,111 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.dirname(__FILE__) + '/abstract_strategy_store_spec'
3
+
4
+ describe Merb::Cache::PageStore do
5
+ it_should_behave_like 'all strategy stores'
6
+
7
+ before(:each) do
8
+ Merb::Cache.stores.clear
9
+ Thread.current[:'merb-cache'] = nil
10
+
11
+ @klass = Merb::Cache::PageStore[:dummy]
12
+ Merb::Cache.register(:dummy, DummyStore)
13
+ Merb::Cache.register(:default, @klass)
14
+
15
+ @store = Merb::Cache[:default]
16
+ @dummy = @store.stores.first
17
+ end
18
+
19
+ def dispatch(url, attrs = {})
20
+ Merb::Dispatcher.handle(request_for(url, attrs))
21
+ end
22
+
23
+ def request_for(url, attrs = {})
24
+ Merb::Request.new(Rack::MockRequest.env_for(url, attrs))
25
+ end
26
+
27
+ describe "examples" do
28
+
29
+ class NhlScores < Merb::Controller
30
+ provides :xml, :json, :yaml
31
+
32
+ cache :index, :show
33
+ cache :overview
34
+
35
+ eager_cache(:index, :overview) {|c| c.request.env['REQUEST_PATH'] = c.url(:overview)}
36
+ eager_cache :overview, :index
37
+
38
+ def index
39
+ "NHLScores index"
40
+ end
41
+
42
+ def show(team)
43
+ "NHLScores show(#{team})"
44
+ end
45
+
46
+ def overview
47
+ "NHLScores overview"
48
+ end
49
+ end
50
+
51
+ before(:each) do
52
+ Merb::Router.prepare do |r|
53
+ r.match("/").to(:controller => "nhl_scores", :action => "index").name(:index)
54
+ r.match("/show/:team").to(:controller => "nhl_scores", :action => "show").name(:show)
55
+ r.match("/overview").to(:controller => "nhl_scores", :action => "overview").name(:overview)
56
+ end
57
+ end
58
+
59
+
60
+ # NOTE: the "REQUEST_URI" => ... stuff will be removed after has_query_params? is in core.
61
+ it "should cache the index action on the first request" do
62
+ dispatch(url(:index), "REQUEST_URI" => url(:index))
63
+
64
+ @dummy.data("/index.html").should == "NHLScores index"
65
+ end
66
+
67
+ it "should cache the yaml version of the index action request" do
68
+ dispatch(url(:index), "HTTP_ACCEPT" => "application/x-yaml", "REQUEST_URI" => url(:index))
69
+
70
+ @dummy.data("/index.yaml").should == "NHLScores index"
71
+ end
72
+
73
+ it "should cache the show action when the team parameter is a route parameter" do
74
+ dispatch(url(:show, :team => 'redwings'), "REQUEST_URI" => url(:show, :team => 'redwings'))
75
+
76
+ @dummy.data("/show/redwings.html").should == "NHLScores show(redwings)"
77
+ end
78
+
79
+ it "should cache the xml version of a request" do
80
+ dispatch(url(:show, :team => 'redwings'), "HTTP_ACCEPT" => "application/xml", "REQUEST_URI" => url(:show, :team => 'redwings'))
81
+
82
+ @dummy.data("/show/redwings.xml").should == "NHLScores show(redwings)"
83
+ end
84
+
85
+
86
+ it "should not cache the show action when the team parameter is not a route parameter" do
87
+ pending "the has_query_params? is implemented in merb-core"
88
+ dispatch_to(NhlScores, :show, :team => 'readwings', "REQUEST_URI" => url(:show, :team => 'redwings'))
89
+
90
+ @dummy.vault.should be_empty
91
+ end
92
+
93
+ it "should not cache the action when a there is a query string parameter" do
94
+ dispatch(url(:index, :page => 2))
95
+
96
+ @dummy.data(url(:index)).should be_nil
97
+ end
98
+
99
+ it "should not cache a POST request" do
100
+ dispatch(url(:index), "REQUEST_METHOD" => "POST")
101
+
102
+ @dummy.vault.should be_empty
103
+ end
104
+
105
+ it "should not eager cache during an eager cache, causing an infinit loop of eagerness" do
106
+ dispatch(url(:overview), "REQUEST_URI" => url(:overview))
107
+
108
+ @dummy.data("/overview.html").should == "NHLScores overview"
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,75 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+ require File.dirname(__FILE__) + '/abstract_strategy_store_spec'
3
+
4
+ describe Merb::Cache::SHA1Store do
5
+ it_should_behave_like 'all strategy stores'
6
+
7
+ before(:each) do
8
+ @klass = Merb::Cache::SHA1Store
9
+ @store = Merb::Cache::SHA1Store[DummyStore].new
10
+ end
11
+
12
+ describe "#writable?" do
13
+ it "should be true if the key is a string, symbol, or number" do
14
+ @store.writable?(:foo).should be_true
15
+ @store.writable?('foo').should be_true
16
+ @store.writable?(123).should be_true
17
+ end
18
+
19
+ it "should be false if none of the context caches are writable" do
20
+ @store.stores.each {|s| s.should_receive(:writable?).and_return false}
21
+
22
+ @store.writable?(:foo).should be_false
23
+ end
24
+ end
25
+
26
+ describe "#read" do
27
+ it "should return nil if hash does not exist as a key in any context store" do
28
+ @store.stores.each {|s| s.should_receive(:read).with(@store.digest(:foo, :bar => :baz)).and_return nil}
29
+
30
+ @store.read(:foo, :bar => :baz).should be_nil
31
+ end
32
+
33
+ it "should return the data from the context store when there is a hash key match" do
34
+ @store.stores.first.should_receive(:read).with(@store.digest(:foo)).and_return :bar
35
+
36
+ @store.read(:foo).should == :bar
37
+ end
38
+ end
39
+
40
+ describe "#write" do
41
+ it "should pass the hashed key to the context store" do
42
+ @store.stores.first.should_receive(:write).with(@store.digest(:foo), 'body', {}, {}).and_return true
43
+
44
+ @store.write(:foo, 'body').should be_true
45
+ end
46
+
47
+ it "should use the parameters to create the hashed key" do
48
+ @store.stores.first.should_receive(:write).with(@store.digest(:foo, :bar => :baz), 'body', {}, {}).and_return true
49
+
50
+ @store.write(:foo, 'body', :bar => :baz).should be_true
51
+ end
52
+ end
53
+
54
+ describe "#fetch" do
55
+ it "should return nil if the arguments are not storable" do
56
+ @store.fetch(mock(:request)) {'body'}.should be_nil
57
+ end
58
+
59
+
60
+ end
61
+
62
+ describe "#digest" do
63
+ it "should produce the same digest for the exact same key and parameters" do
64
+ @store.digest(:foo, :bar => :baz).should == @store.digest(:foo, :bar => :baz)
65
+ end
66
+
67
+ it "should use the string result of the parameter arguments to_param in the hash" do
68
+ @store.digest(:foo, :bar => :baz).should_not == @store.digest(:foo)
69
+ end
70
+
71
+ it "should use the key argument in the hash" do
72
+ @store.digest('', :bar => :baz).should_not == @store.digest('')
73
+ end
74
+ end
75
+ end