Skip to content

Commit

Permalink
Rewrote deflater tests to be more concise.
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubpawlowicz committed Nov 21, 2012
1 parent dc5927f commit 649629c
Showing 1 changed file with 97 additions and 112 deletions.
209 changes: 97 additions & 112 deletions test/spec_deflater.rb
Expand Up @@ -31,29 +31,49 @@ def inflate(buf)
inflater.inflate(buf) << inflater.finish inflater.inflate(buf) << inflater.finish
end end


def verify(response, body_text, options = {}, &block)
response[0].should.equal(options['status'] || 200)

text_body = ''
response[2].each { |part| text_body << part }

deflated_body = case options['deflate']
when 'deflate'
inflate(text_body)
when 'gzip'
io = StringIO.new(text_body)
gz = Zlib::GzipReader.new(io)
temp_body = gz.read
gz.close
temp_body
else
text_body
end

deflated_body.should.equal(body_text)

block.yield(response[1]) if block_given?
end

should "be able to deflate bodies that respond to each" do should "be able to deflate bodies that respond to each" do
body = Object.new body = Object.new
class << body; def each; yield("foo"); yield("bar"); end; end class << body; def each; yield("foo"); yield("bar"); end; end


response = build_response(200, body, "deflate") response = build_response(200, body, "deflate")

verify(response, 'foobar', { 'deflate' => 'deflate' }) do |headers|
response[0].should.equal(200) headers.should.equal({
response[1].should.equal({ "Content-Encoding" => "deflate",
"Content-Encoding" => "deflate", "Vary" => "Accept-Encoding",
"Vary" => "Accept-Encoding", "Content-Type" => "text/plain"
"Content-Type" => "text/plain" })
}) end
buf = ''
response[2].each { |part| buf << part }
inflate(buf).should.equal("foobar")
end end


should "flush deflated chunks to the client as they become ready" do should "flush deflated chunks to the client as they become ready" do
body = Object.new body = Object.new
class << body; def each; yield("foo"); yield("bar"); end; end class << body; def each; yield("foo"); yield("bar"); end; end


response = build_response(200, body, "deflate") response = build_response(200, body, "deflate")

response[0].should.equal(200) response[0].should.equal(200)
response[1].should.equal({ response[1].should.equal({
"Content-Encoding" => "deflate", "Content-Encoding" => "deflate",
Expand All @@ -70,38 +90,29 @@ class << body; def each; yield("foo"); yield("bar"); end; end


# TODO: This is really just a special case of the above... # TODO: This is really just a special case of the above...
should "be able to deflate String bodies" do should "be able to deflate String bodies" do
response = build_response(200, "Hello world!", "deflate") body = "Hello world!"

response = build_response(200, body, "deflate")
response[0].should.equal(200) verify(response, body, { 'deflate' => 'deflate' }) do |headers|
response[1].should.equal({ headers.should.equal({
"Content-Encoding" => "deflate", "Content-Encoding" => "deflate",
"Vary" => "Accept-Encoding", "Vary" => "Accept-Encoding",
"Content-Type" => "text/plain" "Content-Type" => "text/plain"
}) })
buf = '' end
response[2].each { |part| buf << part }
inflate(buf).should.equal("Hello world!")
end end


should "be able to gzip bodies that respond to each" do should "be able to gzip bodies that respond to each" do
body = Object.new body = Object.new
class << body; def each; yield("foo"); yield("bar"); end; end class << body; def each; yield("foo"); yield("bar"); end; end


response = build_response(200, body, "gzip") response = build_response(200, 'foobar', "gzip")

verify(response, 'foobar', { 'deflate' => 'gzip' }) do |headers|
response[0].should.equal(200) headers.should.equal({
response[1].should.equal({ "Content-Encoding" => "gzip",
"Content-Encoding" => "gzip", "Vary" => "Accept-Encoding",
"Vary" => "Accept-Encoding", "Content-Type" => "text/plain"
"Content-Type" => "text/plain" })
}) end

buf = ''
response[2].each { |part| buf << part }
io = StringIO.new(buf)
gz = Zlib::GzipReader.new(io)
gz.read.should.equal("foobar")
gz.close
end end


should "flush gzipped chunks to the client as they become ready" do should "flush gzipped chunks to the client as they become ready" do
Expand All @@ -125,84 +136,82 @@ class << body; def each; yield("foo"); yield("bar"); end; end
end end


should "be able to fallback to no deflation" do should "be able to fallback to no deflation" do
response = build_response(200, "Hello world!", "superzip") body = "Hello world!"

response = build_response(200, body, "superzip")
response[0].should.equal(200) verify(response, body) do |headers|
response[1].should.equal({ "Vary" => "Accept-Encoding", "Content-Type" => "text/plain" }) headers.should.equal({ "Vary" => "Accept-Encoding", "Content-Type" => "text/plain" })
Enumerator.new(response[2]).to_a.should.equal(["Hello world!"]) end
end end


should "be able to skip when there is no response entity body" do should "be able to skip when there is no response entity body" do
response = build_response(304, [], "gzip") response = build_response(304, [], "gzip")


response[0].should.equal(304) verify(response, '', { 'status' => 304 }) do |headers|
response[1].should.equal({}) headers.should.equal({})
Enumerator.new(response[2]).to_a.should.equal([]) end
end end


should "handle the lack of an acceptable encoding" do should "handle the lack of an acceptable encoding" do
response1 = build_response(200, "Hello world!", "identity;q=0", "PATH_INFO" => "/") body = "Hello world!"
response1[0].should.equal(406) not_found_body1 = "An acceptable encoding for the requested resource / could not be found."
response1[1].should.equal({"Content-Type" => "text/plain", "Content-Length" => "71"}) not_found_body2 = "An acceptable encoding for the requested resource /foo/bar could not be found."
Enumerator.new(response1[2]).to_a.should.equal(["An acceptable encoding for the requested resource / could not be found."])
response1 = build_response(200, body, "identity;q=0", "PATH_INFO" => "/")
verify(response1, not_found_body1, { 'status' => 406 }) do |headers|
headers.should.equal({"Content-Type" => "text/plain", "Content-Length" => not_found_body1.length.to_s})
end


response2 = build_response(200, "Hello world!", "identity;q=0", "SCRIPT_NAME" => "/foo", "PATH_INFO" => "/bar") response2 = build_response(200, "Hello world!", "identity;q=0", "SCRIPT_NAME" => "/foo", "PATH_INFO" => "/bar")
response2[0].should.equal(406) verify(response2, not_found_body2, { 'status' => 406 }) do |headers|
response2[1].should.equal({"Content-Type" => "text/plain", "Content-Length" => "78"}) headers.should.equal({"Content-Type" => "text/plain", "Content-Length" => not_found_body2.length.to_s})
Enumerator.new(response2[2]).to_a.should.equal(["An acceptable encoding for the requested resource /foo/bar could not be found."]) end
end end


should "handle gzip response with Last-Modified header" do should "handle gzip response with Last-Modified header" do
body = 'Hello World!'
last_modified = Time.now.httpdate last_modified = Time.now.httpdate


app = lambda { |env| [200, { "Content-Type" => "text/plain", "Last-Modified" => last_modified }, ["Hello World!"]] } app = lambda { |env| [200, { "Content-Type" => "text/plain", "Last-Modified" => last_modified }, [body]] }
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app).call(request) response = deflater(app).call(request)


response[0].should.equal(200) verify(response, body, { 'deflate' => 'gzip' }) do |headers|
response[1].should.equal({ headers.should.equal({
"Content-Encoding" => "gzip", "Content-Encoding" => "gzip",
"Vary" => "Accept-Encoding", "Vary" => "Accept-Encoding",
"Last-Modified" => last_modified, "Last-Modified" => last_modified,
"Content-Type" => "text/plain" "Content-Type" => "text/plain"
}) })

end
buf = ''
response[2].each { |part| buf << part }
io = StringIO.new(buf)
gz = Zlib::GzipReader.new(io)
gz.read.should.equal("Hello World!")
gz.close
end end


should "do nothing when no-transform Cache-Control directive present" do should "do nothing when no-transform Cache-Control directive present" do
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Cache-Control' => 'no-transform'}, ['Hello World!']] } body = 'Hello World!'
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Cache-Control' => 'no-transform'}, [body]] }
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app).call(request) response = deflater(app).call(request)


response[0].should.equal(200) verify(response, body) do |headers|
response[1].should.not.include "Content-Encoding" headers.should.not.include "Content-Encoding"
Enumerator.new(response[2]).to_a.join.should.equal("Hello World!") end
end end


should "do nothing when Content-Encoding already present" do should "do nothing when Content-Encoding already present" do
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Content-Encoding' => 'gzip'}, ['Hello World!']] } body = 'Hello World!'
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Content-Encoding' => 'gzip'}, [body]] }
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app).call(request) response = deflater(app).call(request)


response[0].should.equal(200) verify(response, body)
Enumerator.new(response[2]).to_a.join.should.equal("Hello World!")
end end


should "deflate when Content-Encoding is identity" do should "deflate when Content-Encoding is identity" do
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Content-Encoding' => 'identity'}, ['Hello World!']] } body = 'Hello World!'
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Content-Encoding' => 'identity'}, [body]] }
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "deflate") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "deflate")
response = deflater(app).call(request) response = deflater(app).call(request)


response[0].should.equal(200) verify(response, body, { 'deflate' => 'deflate' })
buf = ''
response[2].each { |part| buf << part }
inflate(buf).should.equal("Hello World!")
end end


should "do nothing if body length is less than a given threshold" do should "do nothing if body length is less than a given threshold" do
Expand All @@ -213,8 +222,7 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app, { "min_content_length" => body.length + 1 }).call(request) response = deflater(app, { "min_content_length" => body.length + 1 }).call(request)


response[0].should.equal(200) verify(response, body)
Enumerator.new(response[2]).to_a.join.should.equal("Hello World!")
end end


should "do nothing if Content-Length is not given" do should "do nothing if Content-Length is not given" do
Expand All @@ -225,8 +233,7 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app, { "min_content_length" => body.length + 1 }).call(request) response = deflater(app, { "min_content_length" => body.length + 1 }).call(request)


response[0].should.equal(200) verify(response, body)
Enumerator.new(response[2]).to_a.join.should.equal("Hello World!")
end end


should "gzip response if body length is equal or longer than a given threshold" do should "gzip response if body length is equal or longer than a given threshold" do
Expand All @@ -237,13 +244,7 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app, { "min_content_length" => body.length }).call(request) response = deflater(app, { "min_content_length" => body.length }).call(request)


response[0].should.equal(200) verify(response, body, { 'deflate' => 'gzip' })
buf = ''
response[2].each { |part| buf << part }
io = StringIO.new(buf)
gz = Zlib::GzipReader.new(io)
gz.read.should.equal(body)
gz.close
end end


should "process if path matches :include" do should "process if path matches :include" do
Expand All @@ -254,13 +255,7 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app, { "include" => /^\/$/ }).call(request) response = deflater(app, { "include" => /^\/$/ }).call(request)


response[0].should.equal(200) verify(response, body, { 'deflate' => 'gzip' })
buf = ''
response[2].each { |part| buf << part }
io = StringIO.new(buf)
gz = Zlib::GzipReader.new(io)
gz.read.should.equal(body)
gz.close
end end


should "skip processing if path do not match :include" do should "skip processing if path do not match :include" do
Expand All @@ -271,8 +266,7 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app, { "include" => /^\/something$/ }).call(request) response = deflater(app, { "include" => /^\/something$/ }).call(request)


response[0].should.equal(200) verify(response, body)
Enumerator.new(response[2]).to_a.join.should.equal("Hello World!")
end end


should "skip processing if path matches :exclude" do should "skip processing if path matches :exclude" do
Expand All @@ -283,8 +277,7 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app, { "exclude" => /^\/$/ }).call(request) response = deflater(app, { "exclude" => /^\/$/ }).call(request)


response[0].should.equal(200) verify(response, body)
Enumerator.new(response[2]).to_a.join.should.equal("Hello World!")
end end


should "gzip response if path do not match :exclude" do should "gzip response if path do not match :exclude" do
Expand All @@ -295,13 +288,7 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app, { "exclude" => /^sth$/ }).call(request) response = deflater(app, { "exclude" => /^sth$/ }).call(request)


response[0].should.equal(200) verify(response, body, { 'deflate' => 'gzip' })
buf = ''
response[2].each { |part| buf << part }
io = StringIO.new(buf)
gz = Zlib::GzipReader.new(io)
gz.read.should.equal(body)
gz.close
end end


should "do nothing if :skip_if lambda evaluates to true" do should "do nothing if :skip_if lambda evaluates to true" do
Expand All @@ -315,8 +302,7 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
response = deflater(app, { "skip_if" => skip_if }).call(request) response = deflater(app, { "skip_if" => skip_if }).call(request)


response[0].should.equal(200) verify(response, body_text)
Enumerator.new(response[2]).to_a.join.should.equal(body_text)
end end


should "deflate response if :skip_if lambda evaluates to false" do should "deflate response if :skip_if lambda evaluates to false" do
Expand All @@ -330,7 +316,6 @@ class << body; def each; yield("foo"); yield("bar"); end; end
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "deflate") request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "deflate")
response = deflater(app, { "skip_if" => skip_if }).call(request) response = deflater(app, { "skip_if" => skip_if }).call(request)


response[0].should.equal(200) verify(response, body_text, { 'deflate' => 'deflate' })
inflate(Enumerator.new(response[2]).to_a.join).should.equal(body_text)
end end
end end

0 comments on commit 649629c

Please sign in to comment.