diff --git a/lib/faraday/response.rb b/lib/faraday/response.rb index 645e098b..80038084 100644 --- a/lib/faraday/response.rb +++ b/lib/faraday/response.rb @@ -1,3 +1,5 @@ +require 'forwardable' + module Faraday class Response # Used for simple response middleware. @@ -17,6 +19,7 @@ module Faraday end end + extend Forwardable extend AutoloadHelper autoload_all 'faraday/response', @@ -28,40 +31,42 @@ module Faraday :logger => :Logger def initialize(env = nil) - @finished_env = env + @env = env @on_complete_callbacks = [] end + attr_reader :env + alias_method :to_hash, :env + def status - @finished_env ? @finished_env[:status] : nil + finished? ? env[:status] : nil end def headers - @finished_env ? @finished_env[:response_headers] : nil + finished? ? env[:response_headers] : {} end + def_delegator :headers, :[] def body - @finished_env ? @finished_env[:body] : nil + finished? ? env[:body] : nil end def finished? - !!@finished_env + !!env end def on_complete if not finished? @on_complete_callbacks << Proc.new else - yield @finished_env + yield env end return self end def finish(env) raise "response already finished" if finished? - @finished_env = env - env[:body] ||= '' - env[:response_headers] ||= {} + @env = env @on_complete_callbacks.each { |callback| callback.call(env) } return self end @@ -72,15 +77,22 @@ module Faraday # because @on_complete_callbacks cannot be marshalled def marshal_dump - @finished_env.nil? ? nil : { - :status => @finished_env[:status], - :response_headers => @finished_env[:response_headers], - :body => @finished_env[:body] + !finished? ? nil : { + :status => @env[:status], :body => @env[:body], + :response_headers => @env[:response_headers] } end def marshal_load(env) - @finished_env = env + @env = env + end + + # Expand the env with more properties, without overriding existing ones. + # Useful for applying request params after restoring a marshalled Response. + def apply_request(request_env) + raise "response didn't finish yet" unless finished? + @env = request_env.merge @env + return self end end end diff --git a/test/env_test.rb b/test/env_test.rb index 5bd8ecd2..332c3e90 100644 --- a/test/env_test.rb +++ b/test/env_test.rb @@ -79,3 +79,56 @@ class HeadersTest < Faraday::TestCase assert_equal 'text/html', @headers['content-type'] end end + +class ResponseTest < Faraday::TestCase + def setup + @env = { + :status => 404, :body => 'yikes', + :response_headers => Faraday::Utils::Headers.new('Content-Type' => 'text/plain') + } + @response = Faraday::Response.new @env + end + + def test_finished + assert @response.finished? + end + + def test_error_on_finish + assert_raises RuntimeError do + @response.finish({}) + end + end + + def test_not_success + assert !@response.success? + end + + def test_status + assert_equal 404, @response.status + end + + def test_body + assert_equal 'yikes', @response.body + end + + def test_headers + assert_equal 'text/plain', @response.headers['Content-Type'] + assert_equal 'text/plain', @response['content-type'] + end + + def test_apply_request + @response.apply_request :body => 'a=b', :method => :post + assert_equal 'yikes', @response.body + assert_equal :post, @response.env[:method] + end + + def test_marshal + @response = Faraday::Response.new + @response.on_complete { } + @response.finish @env.merge(:custom => 'moo') + + loaded = Marshal.load Marshal.dump(@response) + assert_nil loaded.env[:custom] + assert_equal %w[body response_headers status], loaded.env.keys.map { |k| k.to_s }.sort + end +end diff --git a/test/response_middleware_test.rb b/test/response_middleware_test.rb index 45a5c033..c811ef99 100644 --- a/test/response_middleware_test.rb +++ b/test/response_middleware_test.rb @@ -19,8 +19,9 @@ class ResponseMiddlewareTest < Faraday::TestCase end def test_success - response = @conn.get('ok') - assert response.success? + assert_nothing_raised do + @conn.get('ok') + end end def test_raises_not_found