Skip to content

Commit

Permalink
Added support for status messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Bartosz Blimke committed Mar 14, 2010
1 parent cdb7664 commit 3314aad
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 50 deletions.
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -121,6 +121,13 @@ You can also use WebMock without RSpec or Test::Unit support:

Net::HTTP.get('www.example.com', '/') # ===> "abc\n"

### Response with custom status message

stub_request(:any, "www.example.com").to_return(:status => [500, "Internal Server Error"])

req = Net::HTTP::Get.new("/")
Net::HTTP.start("www.example.com") { |http| http.request(req) }.message # ===> "Internal Server Error"

### Replaying raw responses recorded with `curl -is`

`curl -is www.example.com > /tmp/example_curl_-is_output.txt`
Expand Down
4 changes: 2 additions & 2 deletions lib/webmock/http_lib_adapters/httpclient.rb
Expand Up @@ -55,8 +55,8 @@ def do_request_async_with_webmock(method, uri, query, body, extheader)
def build_httpclient_response(webmock_response, stream = false, &block)
body = stream ? StringIO.new(webmock_response.body) : webmock_response.body
response = HTTP::Message.new_response(body)
response.header.init_response(webmock_response.status)

response.header.init_response(webmock_response.status[0])
response.reason=webmock_response.status[1]
webmock_response.headers.to_a.each { |name, value| response.header.set(name, value) }

webmock_response.raise_error_if_any
Expand Down
2 changes: 1 addition & 1 deletion lib/webmock/http_lib_adapters/net_http.rb
Expand Up @@ -114,7 +114,7 @@ def connect_with_webmock
alias_method :connect, :connect_with_webmock

def build_net_http_response(webmock_response, &block)
response = Net::HTTPResponse.send(:response_class, webmock_response.status.to_s).new("1.0", webmock_response.status.to_s, "")
response = Net::HTTPResponse.send(:response_class, webmock_response.status[0].to_s).new("1.0", webmock_response.status[0].to_s, webmock_response.status[1])
response.instance_variable_set(:@body, webmock_response.body)
webmock_response.headers.to_a.each { |name, value| response[name] = value }

Expand Down
3 changes: 2 additions & 1 deletion lib/webmock/http_lib_adapters/patron.rb
Expand Up @@ -69,7 +69,8 @@ def build_patron_response(webmock_response)
webmock_response.raise_error_if_any
res = Patron::Response.new
res.instance_variable_set(:@body, webmock_response.body)
res.instance_variable_set(:@status, webmock_response.status)
res.instance_variable_set(:@status, webmock_response.status[0])
res.instance_variable_set(:@status_line, webmock_response.status[1])
res.instance_variable_set(:@headers, webmock_response.headers)
res
end
Expand Down
72 changes: 39 additions & 33 deletions lib/webmock/response.rb
Expand Up @@ -14,69 +14,79 @@ def self.response_for(options)
end
end
end

class Response
attr_reader :options

def initialize(options = {})
if options.is_a?(IO) || options.is_a?(String)
self.options = read_raw_response(options)
else
self.options = options
end
if @options.has_key?(:headers) && !@options[:headers].is_a?(Proc)
@options[:headers] = Util::Headers.normalize_headers(@options[:headers])
end
end

def headers
@options[:headers]
@headers
end

def headers=(headers)
@headers = headers
if @headers && !@headers.is_a?(Proc)
@headers = Util::Headers.normalize_headers(@headers)
end
end

def body
return '' unless @options.has_key?(:body)
@body || ''
end

def body=(body)
@body = body
stringify_body!
@options[:body]
end

def status
@options.has_key?(:status) ? @options[:status] : 200
@status || [200, ""]
end

def raise_error_if_any
raise @options[:exception].new('Exception from WebMock') if @options.has_key?(:exception)
def status=(status)
@status = status.is_a?(Integer) ? [status, ""] : status
end

def options=(options)
@options = options
stringify_body!
def exception
@exception
end

def dup
dup_response = super
dup_response.options = options.dup
dup_response
def raise_error_if_any
raise @exception.new('Exception from WebMock') if @exception
end

def options=(options)
self.headers = options[:headers]
self.status = options[:status]
self.body = options[:body]
@exception = options[:exception]
end

def evaluate!(request_signature)
[:body, :headers, :status].each do |attribute|
if options[attribute].is_a?(Proc)
options[attribute] = options[attribute].call(request_signature)
end
end
self.body = @body.call(request_signature) if @body.is_a?(Proc)
self.headers = @headers.call(request_signature) if @headers.is_a?(Proc)
self.status = @status.call(request_signature) if @status.is_a?(Proc)
self
end

def ==(other)
options == other.options
self.body == other.body &&
self.headers === other.headers &&
self.status == other.status &&
self.exception == other.exception
end

private

def stringify_body!
if @options[:body].is_a?(IO)
io = @options[:body]
@options[:body] = io.read
if @body.is_a?(IO)
io = @body
@body = io.read
io.close
end
end
Expand All @@ -97,7 +107,7 @@ def read_raw_response(raw_response)
response.each_header {|name, value| options[:headers][name] = value}
options[:headers]['transfer-encoding'] = transfer_encoding if transfer_encoding
options[:body] = response.read_body
options[:status] = response.code.to_i
options[:status] = [response.code.to_i, response.message]
options
end

Expand All @@ -118,9 +128,5 @@ def evaluate!(request_signature)
self.options = @responder.call(request_signature)
self
end

def ==(other)
options == other.options
end
end
end
4 changes: 3 additions & 1 deletion spec/httpclient_spec_helper.rb
Expand Up @@ -20,7 +20,9 @@ def http_request(method, uri, options = {}, &block)
OpenStruct.new({
:body => HTTPClientSpecHelper.async_mode ? response.content.read : response.content,
:headers => Hash[*response.header.all.flatten],
:status => response.code.to_s })
:status => response.code.to_s,
:message => response.reason
})
end

def default_client_request_headers(request_method = nil, has_body = false)
Expand Down
1 change: 0 additions & 1 deletion spec/net_http_spec.rb
Expand Up @@ -46,5 +46,4 @@
}.should raise_error("both of body argument and HTTPRequest#body set")
end


end
4 changes: 3 additions & 1 deletion spec/net_http_spec_helper.rb
Expand Up @@ -21,7 +21,9 @@ def http_request(method, uri, options = {}, &block)
OpenStruct.new({
:body => response.body,
:headers => WebMock::Util::Headers.normalize_headers(headers),
:status => response.code })
:status => response.code,
:message => response.message
})
end

def default_client_request_headers(request_method = nil, has_body = false)
Expand Down
4 changes: 3 additions & 1 deletion spec/patron_spec_helper.rb
Expand Up @@ -16,7 +16,9 @@ def http_request(method, uri, options = {}, &block)
OpenStruct.new({
:body => response.body,
:headers => WebMock::Util::Headers.normalize_headers(response.headers),
:status => response.status.to_s })
:status => response.status.to_s,
:message => response.status_line
})
end

def default_client_request_headers(request_method = nil, has_body = false)
Expand Down
2 changes: 1 addition & 1 deletion spec/request_stub_spec.rb
Expand Up @@ -40,7 +40,7 @@
it "should assign response with provided options" do
@request_stub.to_return(:body => "abc", :status => 500)
@request_stub.response.body.should == "abc"
@request_stub.response.status.should == 500
@request_stub.response.status.should == [500, ""]
end

it "should assign responses with provided options" do
Expand Down
19 changes: 12 additions & 7 deletions spec/response_spec.rb
Expand Up @@ -34,13 +34,18 @@

describe "status" do

it "should be 200 by default" do
@response.status.should == 200
it "should have 200 code and empty message by default" do
@response.status.should == [200, ""]
end

it "should return assigned status" do
@response = Response.new(:status => 500)
@response.status.should == 500
@response.status.should == [500, ""]
end

it "should return assigned message" do
@response = Response.new(:status => [500, "Internal Server Error"])
@response.status.should == [500, "Internal Server Error"]
end

end
Expand Down Expand Up @@ -99,7 +104,7 @@


it "should read status" do
@response.status.should == 202
@response.status.should == [202, "OK"]
end

it "should read headers" do
Expand Down Expand Up @@ -128,7 +133,7 @@
end

it "should read status" do
@response.status.should == 202
@response.status.should == [202, "OK"]
end

it "should read headers" do
Expand Down Expand Up @@ -170,7 +175,7 @@

it "should have evaluated status" do
@response = Response.new(:status => lambda {|request| 302})
@response.evaluate!(@request_signature).status.should == 302
@response.evaluate!(@request_signature).status.should == [302, ""]
end

end
Expand All @@ -193,7 +198,7 @@
response.evaluate!(request_signature)
response.body.should == "abc"
response.headers.should == {'A' => 'a'}
response.status.should == 302
response.status.should == [302, ""]
end

it "should be equal to static response after evaluation" do
Expand Down
25 changes: 24 additions & 1 deletion spec/webmock_spec.rb
Expand Up @@ -304,10 +304,25 @@ class MyException < StandardError; end;
response.headers["Content-Length"].should == "8888"
end

it "should return declared status" do
it "should return declared status code" do
stub_http_request(:get, "www.example.com").to_return(:status => 500)
http_request(:get, "http://www.example.com/").status.should == "500"
end

it "should return declared status message" do
stub_http_request(:get, "www.example.com").to_return(:status => [500, "Internal Server Error"])
http_request(:get, "http://www.example.com/").message.should == "Internal Server Error"
end

it "should return default status code" do
stub_http_request(:get, "www.example.com")
http_request(:get, "http://www.example.com/").status.should == "200"
end

it "should return default empty message" do
stub_http_request(:get, "www.example.com")
http_request(:get, "http://www.example.com/").message.should == ""
end

it "should return body declared as IO" do
stub_http_request(:get, "www.example.com").to_return(:body => File.new(__FILE__))
Expand Down Expand Up @@ -401,6 +416,10 @@ def call(request)
it "should return recorded status" do
@response.status.should == "202"
end

it "should return recorded status message" do
@response.message.should == "OK"
end

it "should ensure file is closed" do
@file.should be_closed
Expand Down Expand Up @@ -432,6 +451,10 @@ def call(request)
it "should return recorded status" do
@response.status.should == "202"
end

it "should return recorded status message" do
@response.message.should == "OK"
end
end

describe "sequences of responses" do
Expand Down

0 comments on commit 3314aad

Please sign in to comment.