rack-cache 1.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack-cache might be problematic. Click here for more details.

data/CHANGES CHANGED
@@ -1,3 +1,22 @@
1
+ ## 1.0.1 / April 2011
2
+
3
+ * Added lib/rack-cache.rb to match package name for auto-requiring machinery.
4
+
5
+ * Fixed a number of issues caused by Rack::Cache not closing the body received
6
+ from the application. Rack::Lock and other middleware use body.close to
7
+ signal the true end of request processing so failure to call this method
8
+ can result in strange issues (e.g.,
9
+ "ThreadError: deadlock; recursive locking")
10
+
11
+ * Fixed a bug where Rack::Cache would blow up writing the rack env to the meta
12
+ store when the env contained an all uppercase key whose value wasn't
13
+ marshalable. Passenger and some other stuff write such keys apparently.
14
+
15
+ * The test suite has moved from test-spec to bacon. This is a short term
16
+ solution to the problem of not being able to run tests under Ruby 1.9.x.
17
+ The test suite will be moved to basic Test::Unit style sometime in the
18
+ future.
19
+
1
20
  ## 1.0 / December 2010
2
21
 
3
22
  * Rack::Cache is 1.0 and will now maintain semantic versioning <http://semver.org/>
data/Rakefile CHANGED
@@ -7,20 +7,21 @@ CLOBBER.include %w[dist]
7
7
 
8
8
  # SPECS =====================================================================
9
9
 
10
- desc 'Run specs with story style output'
11
- task :spec do
12
- sh 'specrb --specdox -Ilib:test test/*_test.rb'
13
- end
14
-
15
10
  desc 'Run specs with unit test style output'
16
11
  task :test => FileList['test/*_test.rb'] do |t|
17
12
  suite = t.prerequisites
18
- sh "specrb -Ilib:test #{suite.join(' ')}", :verbose => false
13
+ sh "bacon -q -I.:lib:test #{suite.join(' ')}", :verbose => false
14
+ end
15
+
16
+ desc 'Run specs with story style output'
17
+ task :spec => FileList['test/*_test.rb'] do |t|
18
+ suite = t.prerequisites
19
+ sh "bacon -I.:lib:test #{suite.join(' ')}", :verbose => false
19
20
  end
20
21
 
21
22
  desc 'Generate test coverage report'
22
23
  task :rcov do
23
- sh "rcov -Ilib:test test/*_test.rb"
24
+ sh "rcov -I.:lib:test test/*_test.rb"
24
25
  end
25
26
 
26
27
  # DOC =======================================================================
data/doc/index.markdown CHANGED
@@ -12,8 +12,8 @@ for [Rack][]-based applications that produce freshness (`Expires`,
12
12
  News
13
13
  ----
14
14
 
15
- * Rack::Cache 0.5 was released on May 25, 2009. See the
16
- [`CHANGES`](http://github.com/rtomayko/rack-cache/blob/0.5.0/CHANGES) file
15
+ * Rack::Cache 1.0 was released on December 24, 2010. See the
16
+ [`CHANGES`](http://github.com/rtomayko/rack-cache/blob/1.0/CHANGES) file
17
17
  for details.
18
18
  * [How to use Rack::Cache with Rails 2.3](http://snippets.aktagon.com/snippets/302-How-to-setup-and-use-Rack-Cache-with-Rails-2-3-0-RC-1) - it's really easy.
19
19
  * [RailsLab's Advanced HTTP Caching Screencast](http://railslab.newrelic.com/2009/02/26/episode-11-advanced-http-caching)
data/doc/storage.markdown CHANGED
@@ -141,11 +141,11 @@ The URI must specify the host and port of a remote memcached daemon. The path
141
141
  portion is an optional (but recommended) namespace that is prepended to each
142
142
  cache key.
143
143
 
144
- The memcached storage backend requires either the `memcache-client` or
145
- `memcached` libraries. By default, the `memcache-client` library is used;
146
- require the `memcached` library explicitly to use it instead.
144
+ The memcached storage backend requires either the `dalli` or `memcached`
145
+ libraries. By default, the `dalli` library is used; require the `memcached`
146
+ library explicitly to use it instead.
147
147
 
148
- gem install memcache-client
148
+ gem install dalli
149
149
 
150
150
  Memcached storage is reasonably fast and allows multiple backends to share a
151
151
  single cache. It is also the only storage implementation that allows the cache
data/lib/rack-cache.rb ADDED
@@ -0,0 +1 @@
1
+ require 'rack/cache'
@@ -83,7 +83,10 @@ module Rack::Cache
83
83
 
84
84
  # tidy up response a bit
85
85
  response.not_modified! if not_modified?(response)
86
- response.body = [] if @request.head?
86
+ if @request.head?
87
+ response.body.close if response.body.respond_to?(:close)
88
+ response.body = []
89
+ end
87
90
  response.to_a
88
91
  end
89
92
 
@@ -212,6 +215,11 @@ module Rack::Cache
212
215
  next unless value = response.headers[name]
213
216
  entry.headers[name] = value
214
217
  end
218
+
219
+ # even though it's empty, be sure to close the response body from upstream
220
+ # because middleware use close to signal end of response
221
+ response.body.close if response.body.respond_to?(:close)
222
+
215
223
  response = entry
216
224
  else
217
225
  record :invalid
@@ -222,7 +222,9 @@ module Rack::Cache
222
222
  end
223
223
 
224
224
  def read(key)
225
- cache.get(key)
225
+ data = cache.get(key)
226
+ data.force_encoding('BINARY') if data.respond_to?(:force_encoding)
227
+ data
226
228
  end
227
229
 
228
230
  def write(body)
@@ -1,6 +1,7 @@
1
1
  require 'fileutils'
2
2
  require 'digest/sha1'
3
3
  require 'rack/utils'
4
+ require 'rack/cache/key'
4
5
 
5
6
  module Rack::Cache
6
7
 
@@ -110,7 +111,7 @@ module Rack::Cache
110
111
  # returned must be marshalable.
111
112
  def persist_request(request)
112
113
  env = request.env.dup
113
- env.reject! { |key,val| key =~ /[^0-9A-Z_]/ }
114
+ env.reject! { |key,val| key =~ /[^0-9A-Z_]/ || !val.respond_to?(:to_str) }
114
115
  env
115
116
  end
116
117
 
@@ -227,6 +227,7 @@ module Rack::Cache
227
227
  #
228
228
  # http://tools.ietf.org/html/rfc2616#section-10.3.5
229
229
  def not_modified!
230
+ body.close if body.respond_to?(:close)
230
231
  self.status = 304
231
232
  self.body = []
232
233
  NOT_MODIFIED_OMIT_HEADERS.each { |name| headers.delete(name) }
data/rack-cache.gemspec CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'rack-cache'
6
- s.version = '1.0'
7
- s.date = '2010-12-24'
6
+ s.version = '1.0.1'
7
+ s.date = '2011-04-13'
8
8
 
9
9
  s.description = "HTTP Caching for Rack"
10
10
  s.summary = "HTTP Caching for Rack"
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
29
29
  doc/storage.markdown
30
30
  example/sinatra/app.rb
31
31
  example/sinatra/views/index.erb
32
+ lib/rack-cache.rb
32
33
  lib/rack/cache.rb
33
34
  lib/rack/cache/appengine.rb
34
35
  lib/rack/cache/cachecontrol.rb
@@ -61,7 +62,7 @@ Gem::Specification.new do |s|
61
62
  s.extra_rdoc_files = %w[README COPYING TODO CHANGES]
62
63
  s.add_dependency 'rack', '>= 0.4'
63
64
 
64
- s.add_development_dependency 'test-spec'
65
+ s.add_development_dependency 'bacon'
65
66
  s.add_development_dependency 'memcached'
66
67
  s.add_development_dependency 'dalli'
67
68
 
data/test/cache_test.rb CHANGED
@@ -25,7 +25,7 @@ describe 'Rack::Cache::new' do
25
25
  end
26
26
 
27
27
  it 'takes a block; executes it during initialization' do
28
- state, object = 'not invoked', nil
28
+ state, object = 'not invoked', nil
29
29
  instance =
30
30
  Rack::Cache.new @app do |cache|
31
31
  object = cache
@@ -33,6 +33,6 @@ describe 'Rack::Cache::new' do
33
33
  cache.should.respond_to :set
34
34
  end
35
35
  state.should.equal 'invoked'
36
- object.should.be instance
36
+ object.should.be.same_as instance
37
37
  end
38
38
  end
@@ -11,7 +11,7 @@ describe 'Rack::Cache::CacheControl' do
11
11
  it 'takes a String and parses it into a Hash when created' do
12
12
  cache_control = Rack::Cache::CacheControl.new('max-age=600, foo')
13
13
  cache_control['max-age'].should.equal '600'
14
- cache_control['foo'].should.be true
14
+ cache_control['foo'].should.be.true
15
15
  end
16
16
 
17
17
  it 'takes a String with a single name=value pair' do
@@ -29,17 +29,17 @@ describe 'Rack::Cache::CacheControl' do
29
29
  it 'takes a String with a single flag value' do
30
30
  cache_control = Rack::Cache::CacheControl.new('no-cache')
31
31
  cache_control.should.include 'no-cache'
32
- cache_control['no-cache'].should.be true
32
+ cache_control['no-cache'].should.be.true
33
33
  end
34
34
 
35
35
  it 'takes a String with a bunch of all kinds of stuff' do
36
36
  cache_control =
37
37
  Rack::Cache::CacheControl.new('max-age=600,must-revalidate,min-fresh=3000,foo=bar,baz')
38
38
  cache_control['max-age'].should.equal '600'
39
- cache_control['must-revalidate'].should.be true
39
+ cache_control['must-revalidate'].should.be.true
40
40
  cache_control['min-fresh'].should.equal '3000'
41
41
  cache_control['foo'].should.equal 'bar'
42
- cache_control['baz'].should.be true
42
+ cache_control['baz'].should.be.true
43
43
  end
44
44
 
45
45
  it 'strips leading and trailing spaces from header value' do
@@ -80,7 +80,7 @@ describe 'Rack::Cache::CacheControl' do
80
80
 
81
81
  it 'responds to #max_age with nil when no max-age directive present' do
82
82
  cache_control = Rack::Cache::CacheControl.new('public')
83
- cache_control.max_age.should.be nil
83
+ cache_control.max_age.should.be.nil
84
84
  end
85
85
 
86
86
  it 'responds to #shared_max_age with an integer when s-maxage directive present' do
@@ -90,7 +90,7 @@ describe 'Rack::Cache::CacheControl' do
90
90
 
91
91
  it 'responds to #shared_max_age with nil when no s-maxage directive present' do
92
92
  cache_control = Rack::Cache::CacheControl.new('public')
93
- cache_control.shared_max_age.should.be nil
93
+ cache_control.shared_max_age.should.be.nil
94
94
  end
95
95
 
96
96
  it 'responds to #public? truthfully when public directive present' do
data/test/context_test.rb CHANGED
@@ -2,8 +2,8 @@ require "#{File.dirname(__FILE__)}/spec_setup"
2
2
  require 'rack/cache/context'
3
3
 
4
4
  describe 'Rack::Cache::Context' do
5
- before(:each) { setup_cache_context }
6
- after(:each) { teardown_cache_context }
5
+ before { setup_cache_context }
6
+ after { teardown_cache_context }
7
7
 
8
8
  it 'passes on non-GET/HEAD requests' do
9
9
  respond_with 200
@@ -771,7 +771,7 @@ describe 'Rack::Cache::Context' do
771
771
  end
772
772
 
773
773
  describe 'with responses that include a Vary header' do
774
- before(:each) do
774
+ before do
775
775
  count = 0
776
776
  respond_with 200 do |req,res|
777
777
  res['Vary'] = 'Accept User-Agent Foo'
@@ -8,8 +8,7 @@ class Object
8
8
  end
9
9
  end
10
10
 
11
- describe_shared 'A Rack::Cache::EntityStore Implementation' do
12
-
11
+ shared 'A Rack::Cache::EntityStore Implementation' do
13
12
  it 'responds to all required messages' do
14
13
  %w[read open write exist?].each do |message|
15
14
  @store.should.respond_to message
@@ -86,8 +85,8 @@ end
86
85
  describe 'Rack::Cache::EntityStore' do
87
86
 
88
87
  describe 'Heap' do
89
- it_should_behave_like 'A Rack::Cache::EntityStore Implementation'
90
88
  before { @store = Rack::Cache::EntityStore::Heap.new }
89
+ behaves_like 'A Rack::Cache::EntityStore Implementation'
91
90
  it 'takes a Hash to ::new' do
92
91
  @store = Rack::Cache::EntityStore::Heap.new('foo' => ['bar'])
93
92
  @store.read('foo').should.equal 'bar'
@@ -98,7 +97,6 @@ describe 'Rack::Cache::EntityStore' do
98
97
  end
99
98
 
100
99
  describe 'Disk' do
101
- it_should_behave_like 'A Rack::Cache::EntityStore Implementation'
102
100
  before do
103
101
  @temp_dir = create_temp_directory
104
102
  @store = Rack::Cache::EntityStore::Disk.new(@temp_dir)
@@ -107,6 +105,8 @@ describe 'Rack::Cache::EntityStore' do
107
105
  @store = nil
108
106
  remove_entry_secure @temp_dir
109
107
  end
108
+ behaves_like 'A Rack::Cache::EntityStore Implementation'
109
+
110
110
  it 'takes a path to ::new and creates the directory' do
111
111
  path = @temp_dir + '/foo'
112
112
  @store = Rack::Cache::EntityStore::Disk.new(path)
@@ -177,20 +177,19 @@ describe 'Rack::Cache::EntityStore' do
177
177
 
178
178
  need_memcached 'entity store tests' do
179
179
  describe 'MemCached' do
180
- it_should_behave_like 'A Rack::Cache::EntityStore Implementation'
181
180
  before do
182
181
  @store = Rack::Cache::EntityStore::MemCached.new($memcached)
183
182
  end
184
183
  after do
185
184
  @store = nil
186
185
  end
186
+ behaves_like 'A Rack::Cache::EntityStore Implementation'
187
187
  end
188
188
  end
189
189
 
190
190
 
191
191
  need_dalli 'entity store tests' do
192
192
  describe 'Dalli' do
193
- it_should_behave_like 'A Rack::Cache::EntityStore Implementation'
194
193
  before do
195
194
  $dalli.flush_all
196
195
  @store = Rack::Cache::EntityStore::Dalli.new($dalli)
@@ -198,26 +197,25 @@ describe 'Rack::Cache::EntityStore' do
198
197
  after do
199
198
  @store = nil
200
199
  end
200
+ behaves_like 'A Rack::Cache::EntityStore Implementation'
201
201
  end
202
202
  end
203
-
203
+
204
204
  need_java 'entity store testing' do
205
205
  module Rack::Cache::AppEngine
206
206
  module MC
207
207
  class << (Service = {})
208
-
209
208
  def contains(key); include?(key); end
210
209
  def get(key); self[key]; end;
211
210
  def put(key, value, ttl = nil)
212
211
  self[key] = value
213
- end
212
+ end
214
213
  end
215
-
214
+
216
215
  end
217
216
  end
218
-
217
+
219
218
  describe 'GAEStore' do
220
- it_should_behave_like 'A Rack::Cache::EntityStore Implementation'
221
219
  before do
222
220
  puts Rack::Cache::AppEngine::MC::Service.inspect
223
221
  @store = Rack::Cache::EntityStore::GAEStore.new
@@ -225,6 +223,7 @@ describe 'Rack::Cache::EntityStore' do
225
223
  after do
226
224
  @store = nil
227
225
  end
226
+ behaves_like 'A Rack::Cache::EntityStore Implementation'
228
227
  end
229
228
  end
230
229
  end
data/test/key_test.rb CHANGED
@@ -2,6 +2,18 @@ require "#{File.dirname(__FILE__)}/spec_setup"
2
2
  require 'rack/cache/key'
3
3
 
4
4
  describe 'A Rack::Cache::Key' do
5
+ # Helper Methods =============================================================
6
+
7
+ def mock_request(*args)
8
+ uri, opts = args
9
+ env = Rack::MockRequest.env_for(uri, opts || {})
10
+ Rack::Cache::Request.new(env)
11
+ end
12
+
13
+ def new_key(request)
14
+ Rack::Cache::Key.call(request)
15
+ end
16
+
5
17
  it "sorts params" do
6
18
  request = mock_request('/test?z=last&a=first')
7
19
  new_key(request).should.include('a=first&z=last')
@@ -35,16 +47,4 @@ describe 'A Rack::Cache::Key' do
35
47
  request = mock_request('/test?x=y', "HTTP_HOST" => 'www2.example.org')
36
48
  new_key(request).should.equal "http://www2.example.org/test?x=y"
37
49
  end
38
-
39
- # Helper Methods =============================================================
40
-
41
- define_method :mock_request do |*args|
42
- uri, opts = args
43
- env = Rack::MockRequest.env_for(uri, opts || {})
44
- Rack::Cache::Request.new(env)
45
- end
46
-
47
- define_method :new_key do |request|
48
- Rack::Cache::Key.call(request)
49
- end
50
50
  end
@@ -1,11 +1,44 @@
1
1
  require "#{File.dirname(__FILE__)}/spec_setup"
2
2
  require 'rack/cache/metastore'
3
+ require 'rack/cache/entitystore'
4
+
5
+ shared 'A Rack::Cache::MetaStore Implementation' do
6
+
7
+ ###
8
+ # Helpers
9
+
10
+ def mock_request(uri, opts)
11
+ env = Rack::MockRequest.env_for(uri, opts || {})
12
+ Rack::Cache::Request.new(env)
13
+ end
14
+
15
+ def mock_response(status, headers, body)
16
+ headers ||= {}
17
+ body = Array(body).compact
18
+ Rack::Cache::Response.new(status, headers, body)
19
+ end
20
+
21
+ def slurp(body)
22
+ buf = ''
23
+ body.each { |part| buf << part }
24
+ buf
25
+ end
26
+
27
+ # Stores an entry for the given request args, returns a url encoded cache key
28
+ # for the request.
29
+ def store_simple_entry(*request_args)
30
+ path, headers = request_args
31
+ @request = mock_request(path || '/test', headers || {})
32
+ @response = mock_response(200, {'Cache-Control' => 'max-age=420'}, ['test'])
33
+ body = @response.body
34
+ cache_key = @store.store(@request, @response, @entity_store)
35
+ @response.body.should.not.be.same_as body
36
+ cache_key
37
+ end
3
38
 
4
- describe_shared 'A Rack::Cache::MetaStore Implementation' do
5
39
  before do
6
40
  @request = mock_request('/', {})
7
41
  @response = mock_response(200, {}, ['hello world'])
8
- @entity_store = nil
9
42
  end
10
43
  after do
11
44
  @store = nil
@@ -43,7 +76,7 @@ describe_shared 'A Rack::Cache::MetaStore Implementation' do
43
76
 
44
77
  it 'returns nil from #purge' do
45
78
  @store.write('/test', [[{},{}]])
46
- @store.purge('/test').should.be nil
79
+ @store.purge('/test').should.be.nil
47
80
  @store.read('/test').should.equal []
48
81
  end
49
82
 
@@ -75,20 +108,12 @@ describe_shared 'A Rack::Cache::MetaStore Implementation' do
75
108
  @store.cache_key(request).should == 'tset/'
76
109
  end
77
110
 
78
- # Abstract methods ===========================================================
79
-
80
- # Stores an entry for the given request args, returns a url encoded cache key
81
- # for the request.
82
- define_method :store_simple_entry do |*request_args|
83
- path, headers = request_args
84
- @request = mock_request(path || '/test', headers || {})
85
- @response = mock_response(200, {'Cache-Control' => 'max-age=420'}, ['test'])
86
- body = @response.body
87
- cache_key = @store.store(@request, @response, @entity_store)
88
- @response.body.should.not.be body
89
- cache_key
111
+ it 'does not blow up when given a non-marhsalable object with an ALL_CAPS key' do
112
+ store_simple_entry('/bad', { 'SOME_THING' => Proc.new {} })
90
113
  end
91
114
 
115
+ # Abstract methods ===========================================================
116
+
92
117
  it 'stores a cache entry' do
93
118
  cache_key = store_simple_entry
94
119
  @store.read(cache_key).should.not.be.empty
@@ -206,39 +231,19 @@ describe_shared 'A Rack::Cache::MetaStore Implementation' do
206
231
 
207
232
  @store.read(key).length.should.equal 2
208
233
  end
209
-
210
- # Helper Methods =============================================================
211
-
212
- define_method :mock_request do |uri,opts|
213
- env = Rack::MockRequest.env_for(uri, opts || {})
214
- Rack::Cache::Request.new(env)
215
- end
216
-
217
- define_method :mock_response do |status,headers,body|
218
- headers ||= {}
219
- body = Array(body).compact
220
- Rack::Cache::Response.new(status, headers, body)
221
- end
222
-
223
- define_method :slurp do |body|
224
- buf = ''
225
- body.each {|part| buf << part }
226
- buf
227
- end
228
234
  end
229
235
 
230
236
 
231
237
  describe 'Rack::Cache::MetaStore' do
232
238
  describe 'Heap' do
233
- it_should_behave_like 'A Rack::Cache::MetaStore Implementation'
234
239
  before do
235
240
  @store = Rack::Cache::MetaStore::Heap.new
236
241
  @entity_store = Rack::Cache::EntityStore::Heap.new
237
242
  end
243
+ behaves_like 'A Rack::Cache::MetaStore Implementation'
238
244
  end
239
245
 
240
246
  describe 'Disk' do
241
- it_should_behave_like 'A Rack::Cache::MetaStore Implementation'
242
247
  before do
243
248
  @temp_dir = create_temp_directory
244
249
  @store = Rack::Cache::MetaStore::Disk.new("#{@temp_dir}/meta")
@@ -247,29 +252,30 @@ describe 'Rack::Cache::MetaStore' do
247
252
  after do
248
253
  remove_entry_secure @temp_dir
249
254
  end
255
+ behaves_like 'A Rack::Cache::MetaStore Implementation'
250
256
  end
251
257
 
252
258
  need_memcached 'metastore tests' do
253
259
  describe 'MemCached' do
254
- it_should_behave_like 'A Rack::Cache::MetaStore Implementation'
255
- before :each do
260
+ before do
256
261
  @temp_dir = create_temp_directory
257
262
  $memcached.flush
258
263
  @store = Rack::Cache::MetaStore::MemCached.new($memcached)
259
264
  @entity_store = Rack::Cache::EntityStore::Heap.new
260
265
  end
266
+ behaves_like 'A Rack::Cache::MetaStore Implementation'
261
267
  end
262
268
  end
263
269
 
264
270
  need_dalli 'metastore tests' do
265
271
  describe 'Dalli' do
266
- it_should_behave_like 'A Rack::Cache::MetaStore Implementation'
267
- before :each do
272
+ before do
268
273
  @temp_dir = create_temp_directory
269
274
  $dalli.flush_all
270
275
  @store = Rack::Cache::MetaStore::Dalli.new($dalli)
271
276
  @entity_store = Rack::Cache::EntityStore::Heap.new
272
277
  end
278
+ behaves_like 'A Rack::Cache::MetaStore Implementation'
273
279
  end
274
280
  end
275
281
 
@@ -289,12 +295,12 @@ describe 'Rack::Cache::MetaStore' do
289
295
  end
290
296
 
291
297
  describe 'GAEStore' do
292
- it_should_behave_like 'A Rack::Cache::MetaStore Implementation'
293
298
  before :each do
294
299
  Rack::Cache::AppEngine::MC::Service.clear
295
300
  @store = Rack::Cache::MetaStore::GAEStore.new
296
301
  @entity_store = Rack::Cache::EntityStore::Heap.new
297
302
  end
303
+ behaves_like 'A Rack::Cache::MetaStore Implementation'
298
304
  end
299
305
 
300
306
  end
data/test/options_test.rb CHANGED
@@ -59,13 +59,13 @@ describe 'Rack::Cache::Options' do
59
59
  it 'allows the meta store to be configured' do
60
60
  @options.should.respond_to :metastore
61
61
  @options.should.respond_to :metastore=
62
- @options.metastore.should.not.be nil
62
+ @options.metastore.should.not.be.nil
63
63
  end
64
64
 
65
65
  it 'allows the entity store to be configured' do
66
66
  @options.should.respond_to :entitystore
67
67
  @options.should.respond_to :entitystore=
68
- @options.entitystore.should.not.be nil
68
+ @options.entitystore.should.not.be.nil
69
69
  end
70
70
 
71
71
  it 'allows log verbosity to be configured' do
data/test/request_test.rb CHANGED
@@ -4,16 +4,16 @@ require 'rack/cache/request'
4
4
  describe 'Rack::Cache::Request' do
5
5
  it 'is marked as no_cache when the Cache-Control header includes the no-cache directive' do
6
6
  request = Rack::Cache::Request.new('HTTP_CACHE_CONTROL' => 'public, no-cache')
7
- assert request.no_cache?
7
+ request.should.be.no_cache
8
8
  end
9
9
 
10
10
  it 'is marked as no_cache when request should not be loaded from cache' do
11
11
  request = Rack::Cache::Request.new('HTTP_PRAGMA' => 'no-cache')
12
- assert request.no_cache?
12
+ request.should.be.no_cache
13
13
  end
14
14
 
15
15
  it 'is not marked as no_cache when neither no-cache directive is specified' do
16
16
  request = Rack::Cache::Request.new('HTTP_CACHE_CONTROL' => 'public')
17
- assert !request.no_cache?
17
+ request.should.not.be.no_cache
18
18
  end
19
19
  end
@@ -1,21 +1,21 @@
1
1
  require "#{File.dirname(__FILE__)}/spec_setup"
2
2
 
3
3
  describe 'Rack::Cache::Response' do
4
- before :each do
4
+ before do
5
5
  @now = Time.httpdate(Time.now.httpdate)
6
6
  @one_hour_ago = Time.httpdate((Time.now - (60**2)).httpdate)
7
7
  @one_hour_later = Time.httpdate((Time.now + (60**2)).httpdate)
8
8
  @res = Rack::Cache::Response.new(200, {'Date' => @now.httpdate}, [])
9
9
  end
10
10
 
11
- after :each do
11
+ after do
12
12
  @now, @res, @one_hour_ago = nil
13
13
  end
14
14
 
15
15
  it 'marks Rack tuples with string typed statuses as cacheable' do
16
16
  @res = Rack::Cache::Response.new('200',{'Date' => @now.httpdate},[])
17
17
  @res.headers['Expires'] = @one_hour_later.httpdate
18
- @res.cacheable?.should.equal true
18
+ @res.should.be.cacheable
19
19
  end
20
20
 
21
21
  it 'responds to #to_a with a Rack response tuple' do
@@ -60,7 +60,7 @@ describe 'Rack::Cache::Response' do
60
60
  end
61
61
  it 'uses the current time when no Date header present' do
62
62
  @res = Rack::Cache::Response.new(200, {}, [])
63
- @res.date.should.be.close Time.now, 1
63
+ @res.date.to_i.should.be.close Time.now.to_i, 1
64
64
  end
65
65
  it 'returns the correct date when the header is modified directly' do
66
66
  @res = Rack::Cache::Response.new(200, { 'Date' => @one_hour_ago.httpdate }, [])
data/test/spec_setup.rb CHANGED
@@ -2,13 +2,13 @@ require 'pp'
2
2
  require 'tmpdir'
3
3
  require 'stringio'
4
4
 
5
- [ STDOUT, STDERR ].each { |io| io.sync = true }
5
+ [STDOUT, STDERR].each { |io| io.sync = true }
6
6
 
7
7
  begin
8
- require 'test/spec'
8
+ require 'bacon'
9
9
  rescue LoadError => boom
10
10
  require 'rubygems' rescue nil
11
- require 'test/spec'
11
+ require 'bacon'
12
12
  end
13
13
 
14
14
  # Set the MEMCACHED environment variable as follows to enable testing
@@ -19,17 +19,24 @@ $dalli = nil
19
19
 
20
20
  def have_memcached?(server=ENV['MEMCACHED'])
21
21
  return $memcached unless $memcached.nil?
22
- v, $VERBOSE = $VERBOSE, nil # silence warnings from memcached
23
- require 'memcached'
24
- $VERBOSE = v
22
+
23
+ # silence warnings from memcached
24
+ begin
25
+ v, $VERBOSE = $VERBOSE, nil
26
+ require 'memcached'
27
+ ensure
28
+ $VERBOSE = v
29
+ end
30
+
25
31
  $memcached = Memcached.new(server)
26
32
  $memcached.set('ping', '')
27
33
  true
28
34
  rescue LoadError => boom
35
+ warn "memcached library not available. related tests will be skipped."
29
36
  $memcached = false
30
37
  false
31
38
  rescue => boom
32
- STDERR.puts "memcached not working. related tests will be skipped."
39
+ warn "memcached not working. related tests will be skipped."
33
40
  $memcached = false
34
41
  false
35
42
  end
@@ -43,10 +50,11 @@ def have_dalli?(server=ENV['MEMCACHED'])
43
50
  $dalli.set('ping', '')
44
51
  true
45
52
  rescue LoadError => boom
53
+ warn "dalli library not available. related tests will be skipped."
46
54
  $dalli = false
47
55
  false
48
56
  rescue => boom
49
- STDERR.puts "dalli not working. related tests will be skipped."
57
+ warn "dalli not working. related tests will be skipped."
50
58
  $dalli = false
51
59
  false
52
60
  end
@@ -54,27 +62,15 @@ end
54
62
  have_dalli?
55
63
 
56
64
  def need_dalli(forwhat)
57
- if have_dalli?
58
- yield
59
- else
60
- STDERR.puts "skipping Dalli #{forwhat}"
61
- end
65
+ yield if have_dalli?
62
66
  end
63
67
 
64
68
  def need_memcached(forwhat)
65
- if have_memcached?
66
- yield
67
- else
68
- STDERR.puts "skipping memcached #{forwhat}"
69
- end
69
+ yield if have_memcached?
70
70
  end
71
71
 
72
72
  def need_java(forwhat)
73
- if RUBY_PLATFORM =~ /java/
74
- yield
75
- else
76
- STDERR.puts "skipping app engine #{forwhat}"
77
- end
73
+ yield if RUBY_PLATFORM =~ /java/
78
74
  end
79
75
 
80
76
 
@@ -84,7 +80,6 @@ $LOAD_PATH.unshift File.dirname(__FILE__)
84
80
 
85
81
  require 'rack/cache'
86
82
 
87
-
88
83
  # Methods for constructing downstream applications / response
89
84
  # generators.
90
85
  module CacheContextHelpers
@@ -128,18 +123,18 @@ module CacheContextHelpers
128
123
 
129
124
  def teardown_cache_context
130
125
  @app, @cache_template, @cache, @caches, @called,
131
- @request, @response, @responses, @cache_config = nil
126
+ @request, @response, @responses, @cache_config, @cache_prototype = nil
132
127
  end
133
128
 
134
129
  # A basic response with 200 status code and a tiny body.
135
- def respond_with(status=200, headers={}, body=['Hello World'])
130
+ def respond_with(status=200, headers={}, body=['Hello World'], &bk)
136
131
  called = false
137
132
  @app =
138
133
  lambda do |env|
139
134
  called = true
140
135
  response = Rack::Response.new(body, status, headers)
141
136
  request = Rack::Request.new(env)
142
- yield request, response if block_given?
137
+ bk.call(request, response) if bk
143
138
  response.finish
144
139
  end
145
140
  @app.meta_def(:called?) { called }
@@ -210,7 +205,7 @@ module TestHelpers
210
205
 
211
206
  end
212
207
 
213
- class Test::Unit::TestCase
208
+ class Bacon::Context
214
209
  include TestHelpers
215
210
  include CacheContextHelpers
216
211
  end
data/test/storage_test.rb CHANGED
@@ -15,7 +15,7 @@ describe 'Rack::Cache::Storage' do
15
15
  end
16
16
  it "returns an existing MetaStore instance for URI that exists" do
17
17
  store = @storage.resolve_metastore_uri('heap:/')
18
- @storage.resolve_metastore_uri('heap:/').should.be store
18
+ @storage.resolve_metastore_uri('heap:/').should.be.same_as store
19
19
  end
20
20
  it "creates a new EntityStore for URI if none exists" do
21
21
  @storage.resolve_entitystore_uri('heap:/').
@@ -23,14 +23,14 @@ describe 'Rack::Cache::Storage' do
23
23
  end
24
24
  it "returns an existing EntityStore instance for URI that exists" do
25
25
  store = @storage.resolve_entitystore_uri('heap:/')
26
- @storage.resolve_entitystore_uri('heap:/').should.be store
26
+ @storage.resolve_entitystore_uri('heap:/').should.be.same_as store
27
27
  end
28
28
  it "clears all URI -> store mappings with #clear" do
29
29
  meta = @storage.resolve_metastore_uri('heap:/')
30
30
  entity = @storage.resolve_entitystore_uri('heap:/')
31
31
  @storage.clear
32
- @storage.resolve_metastore_uri('heap:/').should.not.be meta
33
- @storage.resolve_entitystore_uri('heap:/').should.not.be entity
32
+ @storage.resolve_metastore_uri('heap:/').should.not.be.same_as meta
33
+ @storage.resolve_entitystore_uri('heap:/').should.not.be.same_as entity
34
34
  end
35
35
 
36
36
  describe 'Heap Store URIs' do
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-cache
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 0
9
- version: "1.0"
4
+ prerelease:
5
+ version: 1.0.1
10
6
  platform: ruby
11
7
  authors:
12
8
  - Ryan Tomayko
@@ -14,7 +10,7 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2010-12-24 00:00:00 -08:00
13
+ date: 2011-04-13 00:00:00 +01:00
18
14
  default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
@@ -25,24 +21,17 @@ dependencies:
25
21
  requirements:
26
22
  - - ">="
27
23
  - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- - 4
32
24
  version: "0.4"
33
25
  type: :runtime
34
26
  version_requirements: *id001
35
27
  - !ruby/object:Gem::Dependency
36
- name: test-spec
28
+ name: bacon
37
29
  prerelease: false
38
30
  requirement: &id002 !ruby/object:Gem::Requirement
39
31
  none: false
40
32
  requirements:
41
33
  - - ">="
42
34
  - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
35
  version: "0"
47
36
  type: :development
48
37
  version_requirements: *id002
@@ -54,9 +43,6 @@ dependencies:
54
43
  requirements:
55
44
  - - ">="
56
45
  - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
46
  version: "0"
61
47
  type: :development
62
48
  version_requirements: *id003
@@ -68,9 +54,6 @@ dependencies:
68
54
  requirements:
69
55
  - - ">="
70
56
  - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
57
  version: "0"
75
58
  type: :development
76
59
  version_requirements: *id004
@@ -101,6 +84,7 @@ files:
101
84
  - doc/storage.markdown
102
85
  - example/sinatra/app.rb
103
86
  - example/sinatra/views/index.erb
87
+ - lib/rack-cache.rb
104
88
  - lib/rack/cache.rb
105
89
  - lib/rack/cache/appengine.rb
106
90
  - lib/rack/cache/cachecontrol.rb
@@ -144,23 +128,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
128
  requirements:
145
129
  - - ">="
146
130
  - !ruby/object:Gem::Version
147
- hash: 3
148
- segments:
149
- - 0
150
131
  version: "0"
151
132
  required_rubygems_version: !ruby/object:Gem::Requirement
152
133
  none: false
153
134
  requirements:
154
135
  - - ">="
155
136
  - !ruby/object:Gem::Version
156
- hash: 3
157
- segments:
158
- - 0
159
137
  version: "0"
160
138
  requirements: []
161
139
 
162
140
  rubyforge_project:
163
- rubygems_version: 1.3.7
141
+ rubygems_version: 1.6.0
164
142
  signing_key:
165
143
  specification_version: 2
166
144
  summary: HTTP Caching for Rack