merb-cache 0.9.7 → 0.9.8

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