test/spec_deflater.rb in rack-1.6.13 vs test/spec_deflater.rb in rack-2.0.0.alpha

- old
+ new

@@ -1,5 +1,6 @@ +require 'minitest/autorun' require 'stringio' require 'time' # for Time#httpdate require 'rack/deflater' require 'rack/lint' require 'rack/mock' @@ -30,11 +31,11 @@ # 'deflate' - accepts and expects deflate encoding in response # { 'gzip' => nil } - accepts gzip but expects no encoding in response # [options] hash of request options, i.e. # 'app_status' - what status dummy app should return (may be changed by deflater at some point) # 'app_body' - what body dummy app should return (may be changed by deflater at some point) - # 'request_headers' - extra reqest headers to be sent + # 'request_headers' - extra request headers to be sent # 'response_headers' - extra response headers to be returned # 'deflater_options' - options passed to deflater middleware # [block] useful for doing some extra verification def verify(expected_status, expected_body, accept_encoding, options = {}, &block) accept_encoding, expected_encoding = if accept_encoding.kind_of?(Hash) @@ -50,11 +51,11 @@ accept_encoding, options ) # verify status - status.should.equal(expected_status) + status.must_equal expected_status # verify body unless options['skip_body_verify'] body_text = '' body.each { |part| body_text << part } @@ -71,110 +72,135 @@ tmp else body_text end - deflated_body.should.equal(expected_body) + deflated_body.must_equal expected_body end # yield full response verification yield(status, headers, body) if block_given? end - should 'be able to deflate bodies that respond to each' do + it 'be able to deflate bodies that respond to each' do app_body = Object.new class << app_body; def each; yield('foo'); yield('bar'); end; end verify(200, 'foobar', 'deflate', { 'app_body' => app_body }) do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Content-Encoding' => 'deflate', 'Vary' => 'Accept-Encoding', 'Content-Type' => 'text/plain' }) end end - should 'flush deflated chunks to the client as they become ready' do + it 'flush deflated chunks to the client as they become ready' do app_body = Object.new class << app_body; def each; yield('foo'); yield('bar'); end; end verify(200, app_body, 'deflate', { 'skip_body_verify' => true }) do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Content-Encoding' => 'deflate', 'Vary' => 'Accept-Encoding', 'Content-Type' => 'text/plain' }) buf = [] inflater = Zlib::Inflate.new(-Zlib::MAX_WBITS) body.each { |part| buf << inflater.inflate(part) } buf << inflater.finish - buf.delete_if { |part| part.empty? }.join.should.equal('foobar') + buf.delete_if { |part| part.empty? }.join.must_equal 'foobar' end end + it 'does not raise when a client aborts reading' do + app_body = Object.new + class << app_body; def each; yield('foo'); yield('bar'); end; end + opts = { 'skip_body_verify' => true } + verify(200, app_body, 'deflate', opts) do |status, headers, body| + headers.must_equal({ + 'Content-Encoding' => 'deflate', + 'Vary' => 'Accept-Encoding', + 'Content-Type' => 'text/plain' + }) + + buf = [] + inflater = Zlib::Inflate.new(-Zlib::MAX_WBITS) + FakeDisconnect = Class.new(RuntimeError) + assert_raises(FakeDisconnect, "not Zlib::DataError not raised") do + body.each do |part| + buf << inflater.inflate(part) + raise FakeDisconnect + end + end + assert_raises(Zlib::BufError) { inflater.finish } + buf.must_equal(%w(foo)) + end + end + # TODO: This is really just a special case of the above... - should 'be able to deflate String bodies' do + it 'be able to deflate String bodies' do verify(200, 'Hello world!', 'deflate') do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Content-Encoding' => 'deflate', 'Vary' => 'Accept-Encoding', 'Content-Type' => 'text/plain' }) end end - should 'be able to gzip bodies that respond to each' do + it 'be able to gzip bodies that respond to each' do app_body = Object.new class << app_body; def each; yield('foo'); yield('bar'); end; end verify(200, 'foobar', 'gzip', { 'app_body' => app_body }) do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Content-Encoding' => 'gzip', 'Vary' => 'Accept-Encoding', 'Content-Type' => 'text/plain' }) end end - should 'flush gzipped chunks to the client as they become ready' do + it 'flush gzipped chunks to the client as they become ready' do app_body = Object.new class << app_body; def each; yield('foo'); yield('bar'); end; end verify(200, app_body, 'gzip', { 'skip_body_verify' => true }) do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Content-Encoding' => 'gzip', 'Vary' => 'Accept-Encoding', 'Content-Type' => 'text/plain' }) buf = [] inflater = Zlib::Inflate.new(Zlib::MAX_WBITS + 32) body.each { |part| buf << inflater.inflate(part) } buf << inflater.finish - buf.delete_if { |part| part.empty? }.join.should.equal('foobar') + buf.delete_if { |part| part.empty? }.join.must_equal 'foobar' end end - should 'be able to fallback to no deflation' do + it 'be able to fallback to no deflation' do verify(200, 'Hello world!', 'superzip') do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Vary' => 'Accept-Encoding', 'Content-Type' => 'text/plain' }) end end - should 'be able to skip when there is no response entity body' do + it 'be able to skip when there is no response entity body' do verify(304, '', { 'gzip' => nil }, { 'app_body' => [] }) do |status, headers, body| - headers.should.equal({}) + headers.must_equal({}) end end - should 'handle the lack of an acceptable encoding' do + it 'handle the lack of an acceptable encoding' do app_body = 'Hello world!' not_found_body1 = 'An acceptable encoding for the requested resource / could not be found.' not_found_body2 = 'An acceptable encoding for the requested resource /foo/bar could not be found.' options1 = { 'app_status' => 200, @@ -190,76 +216,76 @@ 'PATH_INFO' => '/foo/bar' } } verify(406, not_found_body1, 'identity;q=0', options1) do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Content-Type' => 'text/plain', 'Content-Length' => not_found_body1.length.to_s }) end verify(406, not_found_body2, 'identity;q=0', options2) do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Content-Type' => 'text/plain', 'Content-Length' => not_found_body2.length.to_s }) end end - should 'handle gzip response with Last-Modified header' do + it 'handle gzip response with Last-Modified header' do last_modified = Time.now.httpdate options = { 'response_headers' => { 'Content-Type' => 'text/plain', 'Last-Modified' => last_modified } } verify(200, 'Hello World!', 'gzip', options) do |status, headers, body| - headers.should.equal({ + headers.must_equal({ 'Content-Encoding' => 'gzip', 'Vary' => 'Accept-Encoding', 'Last-Modified' => last_modified, 'Content-Type' => 'text/plain' }) end end - should 'do nothing when no-transform Cache-Control directive present' do + it 'do nothing when no-transform Cache-Control directive present' do options = { 'response_headers' => { 'Content-Type' => 'text/plain', 'Cache-Control' => 'no-transform' } } verify(200, 'Hello World!', { 'gzip' => nil }, options) do |status, headers, body| - headers.should.not.include 'Content-Encoding' + headers.wont_include 'Content-Encoding' end end - should 'do nothing when Content-Encoding already present' do + it 'do nothing when Content-Encoding already present' do options = { 'response_headers' => { 'Content-Type' => 'text/plain', 'Content-Encoding' => 'gzip' } } verify(200, 'Hello World!', { 'gzip' => nil }, options) end - should 'deflate when Content-Encoding is identity' do + it 'deflate when Content-Encoding is identity' do options = { 'response_headers' => { 'Content-Type' => 'text/plain', 'Content-Encoding' => 'identity' } } verify(200, 'Hello World!', 'deflate', options) end - should "deflate if content-type matches :include" do + it "deflate if content-type matches :include" do options = { 'response_headers' => { 'Content-Type' => 'text/plain' }, 'deflater_options' => { @@ -267,11 +293,11 @@ } } verify(200, 'Hello World!', 'gzip', options) end - should "deflate if content-type is included it :include" do + it "deflate if content-type is included it :include" do options = { 'response_headers' => { 'Content-Type' => 'text/plain; charset=us-ascii' }, 'deflater_options' => { @@ -279,20 +305,20 @@ } } verify(200, 'Hello World!', 'gzip', options) end - should "not deflate if content-type is not set but given in :include" do + it "not deflate if content-type is not set but given in :include" do options = { 'deflater_options' => { :include => %w(text/plain) } } verify(304, 'Hello World!', { 'gzip' => nil }, options) end - should "not deflate if content-type do not match :include" do + it "not deflate if content-type do not match :include" do options = { 'response_headers' => { 'Content-Type' => 'text/plain' }, 'deflater_options' => { @@ -300,40 +326,40 @@ } } verify(200, 'Hello World!', { 'gzip' => nil }, options) end - should "deflate response if :if lambda evaluates to true" do + it "deflate response if :if lambda evaluates to true" do options = { 'deflater_options' => { :if => lambda { |env, status, headers, body| true } } } verify(200, 'Hello World!', 'deflate', options) end - should "not deflate if :if lambda evaluates to false" do + it "not deflate if :if lambda evaluates to false" do options = { 'deflater_options' => { :if => lambda { |env, status, headers, body| false } } } verify(200, 'Hello World!', { 'gzip' => nil }, options) end - should "check for Content-Length via :if" do - body = 'Hello World!' - body_len = body.length + it "check for Content-Length via :if" do + response = 'Hello World!' + response_len = response.length options = { 'response_headers' => { - 'Content-Length' => body_len.to_s + 'Content-Length' => response_len.to_s }, 'deflater_options' => { :if => lambda { |env, status, headers, body| - headers['Content-Length'].to_i >= body_len + headers['Content-Length'].to_i >= response_len } } } - verify(200, body, 'gzip', options) + verify(200, response, 'gzip', options) end end