Skip to content

Commit 9fd5259

Browse files
committed
Lazy parsing of responses to allow for response code checking prior to parsing.
Fixes #79
1 parent c2d4615 commit 9fd5259

File tree

4 files changed

+32
-29
lines changed

4 files changed

+32
-29
lines changed

lib/httparty/request.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def handle_response(body)
208208
perform
209209
else
210210
body = body || last_response.body
211-
Response.new(self, last_response, parse_response(body), :body => body)
211+
Response.new(self, last_response, lambda { parse_response(body) }, :body => body)
212212
end
213213
end
214214

lib/httparty/response.rb

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ def self.underscore(string)
44
string.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
55
end
66

7-
attr_reader :request, :response, :parsed_response, :body, :headers
7+
attr_reader :request, :response, :body, :headers
88

9-
def initialize(request, response, parsed_response, options={})
10-
@request = request
11-
@response = response
12-
@body = response.body || options[:body]
13-
@parsed_response = parsed_response
14-
@headers = Headers.new(response.to_hash)
9+
def initialize(request, response, parsed_block, options={})
10+
@request = request
11+
@response = response
12+
@body = response.body || options[:body]
13+
@parsed_block = parsed_block
14+
@headers = Headers.new(response.to_hash)
15+
end
16+
17+
def parsed_response
18+
@parsed_response ||= @parsed_block.call
1519
end
1620

1721
def class
@@ -24,7 +28,7 @@ def code
2428

2529
def inspect
2630
inspect_id = "%x" % (object_id * 2)
27-
%(#<#{self.class}:0x#{inspect_id} @parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>)
31+
%(#<#{self.class}:0x#{inspect_id} parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>)
2832
end
2933

3034
CODES_TO_OBJ = ::Net::HTTPResponse::CODE_CLASS_TO_OBJ.merge ::Net::HTTPResponse::CODE_TO_OBJ

spec/httparty/request_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,16 @@
411411
resp.body.should == "<foo><bar>error</bar></foo>"
412412
resp['foo']['bar'].should == "error"
413413
end
414+
415+
it "parses response lazily so codes can be checked prior" do
416+
stub_response 'not xml', 500
417+
@request.options[:format] = :xml
418+
lambda {
419+
response = @request.perform
420+
response.code.should == 500
421+
response.body.should == 'not xml'
422+
}.should_not raise_error
423+
end
414424
end
415425
end
416426

spec/httparty/response_spec.rb

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
@response_object.stub(:body => "{foo:'bar'}")
1010
@response_object['last-modified'] = @last_modified
1111
@response_object['content-length'] = @content_length
12-
@parsed_response = {"foo" => "bar"}
12+
@parsed_response = lambda { {"foo" => "bar"} }
1313
@response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
1414
end
1515

@@ -51,42 +51,42 @@
5151
end
5252

5353
it "should send missing methods to delegate" do
54-
response = HTTParty::Response.new(@request_object, @response_object, {'foo' => 'bar'})
54+
response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
5555
response['foo'].should == 'bar'
5656
end
5757

5858
it "response to request" do
59-
response = HTTParty::Response.new(@request_object, @response_object, {'foo' => 'bar'})
59+
response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
6060
response.respond_to?(:request).should be_true
6161
end
6262

6363
it "responds to response" do
64-
response = HTTParty::Response.new(@request_object, @response_object, {'foo' => 'bar'})
64+
response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
6565
response.respond_to?(:response).should be_true
6666
end
6767

6868
it "responds to body" do
69-
response = HTTParty::Response.new(@request_object, @response_object, {'foo' => 'bar'})
69+
response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
7070
response.respond_to?(:body).should be_true
7171
end
7272

7373
it "responds to headers" do
74-
response = HTTParty::Response.new(@request_object, @response_object, {'foo' => 'bar'})
74+
response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
7575
response.respond_to?(:headers).should be_true
7676
end
7777

7878
it "responds to parsed_response" do
79-
response = HTTParty::Response.new(@request_object, @response_object, {'foo' => 'bar'})
79+
response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
8080
response.respond_to?(:parsed_response).should be_true
8181
end
8282

8383
it "responds to anything parsed_response responds to" do
84-
response = HTTParty::Response.new(@request_object, @response_object, {'foo' => 'bar'})
84+
response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
8585
response.respond_to?(:[]).should be_true
8686
end
8787

8888
it "should be able to iterate if it is array" do
89-
response = HTTParty::Response.new(@request_object, @response_object, [{'foo' => 'bar'}, {'foo' => 'baz'}])
89+
response = HTTParty::Response.new(@request_object, @response_object, lambda { [{'foo' => 'bar'}, {'foo' => 'baz'}] })
9090
response.size.should == 2
9191
expect {
9292
response.each { |item| }
@@ -114,17 +114,6 @@
114114
end
115115
end
116116

117-
xit "should allow hashes to be accessed with dot notation" do
118-
response = HTTParty::Response.new(@request_object, {'foo' => 'bar'}, "{foo:'bar'}", 200, 'OK')
119-
response.foo.should == 'bar'
120-
end
121-
122-
xit "should allow nested hashes to be accessed with dot notation" do
123-
response = HTTParty::Response.new(@request_object, {'foo' => {'bar' => 'baz'}}, "{foo: {bar:'baz'}}", 200, 'OK')
124-
response.foo.should == {'bar' => 'baz'}
125-
response.foo.bar.should == 'baz'
126-
end
127-
128117
describe "semantic methods for response codes" do
129118
def response_mock(klass)
130119
response = klass.new('', '', '')

0 commit comments

Comments
 (0)