diff --git a/bin/httparty b/bin/httparty
index dbbfd0a..75fc18a 100755
--- a/bin/httparty
+++ b/bin/httparty
@@ -18,7 +18,7 @@ OptionParser.new do |o|
o.on("-f",
"--format [FORMAT]",
"Output format to use instead of pretty-print ruby: " +
- "plain, json or xml") do |f|
+ "plain, csv, json or xml") do |f|
opts[:output_format] = f.downcase.to_sym
end
@@ -107,6 +107,9 @@ else
require 'rexml/document'
REXML::Document.new(response.body).write(STDOUT, 2)
puts
+ when :csv
+ require 'csv'
+ puts CSV.parse(response.body).map{|row| row.to_s }
else
puts response
end
diff --git a/features/handles_multiple_formats.feature b/features/handles_multiple_formats.feature
index 2f53844..05c5553 100644
--- a/features/handles_multiple_formats.feature
+++ b/features/handles_multiple_formats.feature
@@ -14,6 +14,21 @@ Feature: Handles Multiple Formats
Then it should return a String
And the return value should match '
Some HTML
'
+ Scenario: A CSV service
+ Given a remote service that returns
+ '"Last Name","Name"
+ "jennings","waylon"
+ "cash","johnny"'
+ And that service is accessed at the path '/service.csv'
+ And the response from the service has a Content-Type of 'application/csv'
+ When I call HTTParty#get with '/service.csv'
+ Then it should return a multidimensional array equaling:
+ [
+ ["Last Name","Name"],
+ ["jennings","waylon"],
+ ["cash","johnny"]
+ ]
+
Scenario: A JSON service
Given a remote service that returns '{ "jennings": "waylon", "cash": "johnny" }'
And that service is accessed at the path '/service.json'
diff --git a/lib/httparty.rb b/lib/httparty.rb
index 932290c..4123048 100644
--- a/lib/httparty.rb
+++ b/lib/httparty.rb
@@ -5,6 +5,7 @@ require 'uri'
require 'zlib'
require 'multi_xml'
require 'json'
+require 'csv'
require 'httparty/module_inheritable_attributes'
require 'httparty/cookie_hash'
diff --git a/lib/httparty/parser.rb b/lib/httparty/parser.rb
index b91ff46..8e611cb 100644
--- a/lib/httparty/parser.rb
+++ b/lib/httparty/parser.rb
@@ -1,5 +1,5 @@
module HTTParty
- # The default parser used by HTTParty, supports xml, json, html, and
+ # The default parser used by HTTParty, supports xml, json, html, csv and
# plain text.
#
# == Custom Parsers
@@ -45,7 +45,10 @@ module HTTParty
'application/javascript' => :plain,
'text/javascript' => :plain,
'text/html' => :html,
- 'text/plain' => :plain
+ 'text/plain' => :plain,
+ 'text/csv' => :csv,
+ 'application/csv' => :csv,
+ 'text/comma-separated-values' => :csv
}
# The response body of the request
@@ -113,6 +116,10 @@ module HTTParty
JSON.load(body, nil)
end
+ def csv
+ CSV.parse(body)
+ end
+
def html
body
end
diff --git a/spec/httparty/parser_spec.rb b/spec/httparty/parser_spec.rb
index 23f5770..fae4c23 100644
--- a/spec/httparty/parser_spec.rb
+++ b/spec/httparty/parser_spec.rb
@@ -156,5 +156,10 @@ describe HTTParty::Parser do
it "parses plain text by simply returning the body" do
subject.send(:plain).should == 'body'
end
+
+ it "parses csv with CSV" do
+ CSV.should_receive(:parse).with('body')
+ subject.send(:csv)
+ end
end
end
diff --git a/spec/httparty/request_spec.rb b/spec/httparty/request_spec.rb
index aaab6fe..e86d7e9 100644
--- a/spec/httparty/request_spec.rb
+++ b/spec/httparty/request_spec.rb
@@ -202,6 +202,24 @@ describe HTTParty::Request do
end
end
+ it 'should handle text/csv' do
+ ["text/csv", "text/csv; charset=iso8859-1"].each do |ct|
+ @request.send(:format_from_mimetype, ct).should == :csv
+ end
+ end
+
+ it 'should handle application/csv' do
+ ["application/csv", "application/csv; charset=iso8859-1"].each do |ct|
+ @request.send(:format_from_mimetype, ct).should == :csv
+ end
+ end
+
+ it 'should handle text/comma-separated-values' do
+ ["text/comma-separated-values", "text/comma-separated-values; charset=iso8859-1"].each do |ct|
+ @request.send(:format_from_mimetype, ct).should == :csv
+ end
+ end
+
it 'should handle text/javascript' do
["text/javascript", "text/javascript; charset=iso8859-1"].each do |ct|
@request.send(:format_from_mimetype, ct).should == :plain
@@ -231,6 +249,12 @@ describe HTTParty::Request do
@request.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
end
+ it 'should handle csv automatically' do
+ csv=[%q["id","Name"],%q["1234","Foo Bar!"]].join("\n")
+ @request.options[:format] = :csv
+ @request.send(:parse_response, csv).should == [["id","Name"],["1234","Foo Bar!"]]
+ end
+
it 'should handle json automatically' do
json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}]
@request.options[:format] = :json
diff --git a/spec/httparty_spec.rb b/spec/httparty_spec.rb
index 6d5d4ed..efb41ae 100644
--- a/spec/httparty_spec.rb
+++ b/spec/httparty_spec.rb
@@ -391,6 +391,11 @@ describe HTTParty do
@klass.default_options[:format].should == :xml
end
+ it "should allow csv" do
+ @klass.format :csv
+ @klass.default_options[:format].should == :csv
+ end
+
it "should allow json" do
@klass.format :json
@klass.default_options[:format].should == :json
@@ -410,7 +415,7 @@ describe HTTParty do
it 'should only print each format once with an exception' do
lambda do
@klass.format :foobar
- end.should raise_error(HTTParty::UnsupportedFormat, "':foobar' Must be one of: html, json, plain, xml")
+ end.should raise_error(HTTParty::UnsupportedFormat, "':foobar' Must be one of: csv, html, json, plain, xml")
end
it 'sets the default parser' do
@@ -703,6 +708,14 @@ describe HTTParty do
}
end
+ it "should be able parse response type csv automatically" do
+ stub_http_response_with('twitter.csv')
+ profile = HTTParty.get('http://twitter.com/statuses/profile.csv')
+ profile.size.should == 2
+ profile[0].should == ["name","url","id","description","protected","screen_name","followers_count","profile_image_url","location"]
+ profile[1].should == ["Magic 8 Bot",nil,"17656026","ask me a question","false","magic8bot","90","http://s3.amazonaws.com/twitter_production/profile_images/65565851/8ball_large_normal.jpg",nil]
+ end
+
it "should not get undefined method add_node for nil class for the following xml" do
stub_http_response_with('undefined_method_add_node_for_nil.xml')
result = HTTParty.get('http://foobar.com')