add Response.apply_request method

Useful, for example, to re-apply the current request environment after
a response object was restored from cache.
This commit is contained in:
Mislav Marohnić 2011-03-27 23:27:15 +02:00
parent f739002d0b
commit b9e54dbe0f
3 changed files with 82 additions and 16 deletions

View File

@ -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

View File

@ -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

View File

@ -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