summary refs log tree commit
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-01-13 14:59:50 -0800
committerJoshua Peek <josh@joshpeek.com>2011-01-13 18:19:50 -0600
commit812ac75b327c9f3d6ff5074def9721bf6f19e1de (patch)
treefbb774af8458f4685dc7f03b2f35cfdd55a11ea8
parent4d95f605050259d96ad4ccfe9bee0ce7958643b8 (diff)
downloadrack-812ac75b327c9f3d6ff5074def9721bf6f19e1de.tar.gz
refactor Rack::MockResponse to be a subclass of Rack::Response, also make sure the real response object does not set Content-Length if the transfer type is chunked
Signed-off-by: Joshua Peek <josh@joshpeek.com>
-rw-r--r--lib/rack/mock.rb50
-rw-r--r--lib/rack/response.rb11
2 files changed, 30 insertions, 31 deletions
diff --git a/lib/rack/mock.rb b/lib/rack/mock.rb
index 77ef3234..516932a8 100644
--- a/lib/rack/mock.rb
+++ b/lib/rack/mock.rb
@@ -142,43 +142,41 @@ module Rack
   # MockRequest.
 
   class MockResponse < Rack::Response
-    def initialize(status, headers, body, errors=StringIO.new(""))
-      @status = status.to_i
-
-      @original_headers = headers
-      @headers = Rack::Utils::HeaderHash.new("Content-Type" => "text/html").
-        merge(headers)
-
-      @body = ""
-      body.each { |part| @body << part }
-
-      @errors = errors.string if errors.respond_to?(:string)
-    end
-
-    # Status
-    attr_reader :status
-
     # Headers
-    attr_reader :headers, :original_headers
+    attr_reader :original_headers
 
-    def [](field)
-      headers[field]
-    end
+    # Errors
+    attr_accessor :errors
 
+    def initialize(status, headers, body, errors=StringIO.new(""))
+      @original_headers = headers
+      @errors           = errors.string if errors.respond_to?(:string)
+      @body_string      = nil
 
-    # Body
-    attr_reader :body
+      super(body, status, headers)
+    end
 
     def =~(other)
-      @body =~ other
+      body =~ other
     end
 
     def match(other)
-      @body.match other
+      body.match other
     end
 
-    # Errors
-    attr_accessor :errors
+    def body
+      # FIXME: apparently users of MockResponse expect the return value of
+      # MockResponse#body to be a string.  However, the real response object
+      # returns the body as a list.
+      #
+      # See spec_showstatus.rb:
+      #
+      #   should "not replace existing messages" do
+      #     ...
+      #     res.body.should == "foo!"
+      #   end
+      super.join
+    end
 
     def empty?
       [201, 204, 304].include? status
diff --git a/lib/rack/response.rb b/lib/rack/response.rb
index afb44ad7..e2953e75 100644
--- a/lib/rack/response.rb
+++ b/lib/rack/response.rb
@@ -24,9 +24,10 @@ module Rack
       @header = Utils::HeaderHash.new("Content-Type" => "text/html").
                                       merge(header)
 
-      @writer = lambda { |x| @body << x }
-      @block = nil
-      @length = 0
+      @chunked = "chunked" == @header['Transfer-Encoding']
+      @writer  = lambda { |x| @body << x }
+      @block   = nil
+      @length  = 0
 
       @body = []
 
@@ -92,10 +93,10 @@ module Rack
     #
     def write(str)
       s = str.to_s
-      @length += Rack::Utils.bytesize(s)
+      @length += Rack::Utils.bytesize(s) unless @chunked
       @writer.call s
 
-      header["Content-Length"] = @length.to_s
+      header["Content-Length"] = @length.to_s unless @chunked
       str
     end