alexvollmer-httparty 0.2.6 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History +34 -0
- data/Manifest +25 -2
- data/README +2 -2
- data/Rakefile +6 -2
- data/bin/httparty +39 -44
- data/cucumber.yml +1 -0
- data/examples/basic.rb +6 -1
- data/examples/delicious.rb +1 -0
- data/examples/rubyurl.rb +1 -1
- data/features/basic_authentication.feature +20 -0
- data/features/command_line.feature +7 -0
- data/features/deals_with_http_error_codes.feature +26 -0
- data/features/handles_multiple_formats.feature +34 -0
- data/features/steps/env.rb +15 -0
- data/features/steps/httparty_response_steps.rb +26 -0
- data/features/steps/httparty_steps.rb +15 -0
- data/features/steps/mongrel_helper.rb +55 -0
- data/features/steps/remote_service_steps.rb +47 -0
- data/features/supports_redirection.feature +22 -0
- data/httparty.gemspec +4 -7
- data/lib/core_extensions.rb +48 -222
- data/lib/httparty/cookie_hash.rb +9 -0
- data/lib/httparty/exceptions.rb +3 -0
- data/lib/httparty/module_inheritable_attributes.rb +25 -0
- data/lib/httparty/parsers/json.rb +74 -0
- data/lib/httparty/parsers/xml.rb +209 -0
- data/lib/httparty/parsers.rb +4 -0
- data/lib/httparty/request.rb +63 -76
- data/lib/httparty/response.rb +17 -0
- data/lib/httparty/version.rb +2 -2
- data/lib/httparty.rb +108 -19
- data/spec/fixtures/empty.xml +0 -0
- data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
- data/spec/hash_spec.rb +49 -0
- data/spec/httparty/cookie_hash_spec.rb +38 -0
- data/spec/httparty/parsers/json_spec.rb +42 -0
- data/spec/httparty/parsers/xml_spec.rb +445 -0
- data/spec/httparty/request_spec.rb +219 -80
- data/spec/httparty/response_spec.rb +53 -0
- data/spec/httparty_spec.rb +125 -64
- data/spec/spec_helper.rb +5 -8
- data/spec/string_spec.rb +27 -0
- metadata +34 -14
- data/lib/module_level_inheritable_attributes.rb +0 -25
- data/spec/as_buggery_spec.rb +0 -16
data/lib/httparty/request.rb
CHANGED
@@ -11,8 +11,7 @@ module HTTParty
|
|
11
11
|
self.path = path
|
12
12
|
self.options = {
|
13
13
|
:limit => o.delete(:no_follow) ? 0 : 5,
|
14
|
-
:default_params => {}
|
15
|
-
:keep_body => false
|
14
|
+
:default_params => {}
|
16
15
|
}.merge(o)
|
17
16
|
end
|
18
17
|
|
@@ -21,9 +20,13 @@ module HTTParty
|
|
21
20
|
end
|
22
21
|
|
23
22
|
def uri
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
new_uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
|
24
|
+
|
25
|
+
if Net::HTTP::Get === http_method and !@redirect
|
26
|
+
new_uri.query = query_string(new_uri)
|
27
|
+
end
|
28
|
+
|
29
|
+
new_uri
|
27
30
|
end
|
28
31
|
|
29
32
|
def format
|
@@ -31,38 +34,47 @@ module HTTParty
|
|
31
34
|
end
|
32
35
|
|
33
36
|
def perform
|
34
|
-
validate
|
35
|
-
|
37
|
+
validate
|
38
|
+
setup_raw_request
|
39
|
+
handle_response(get_response)
|
36
40
|
end
|
37
41
|
|
38
42
|
private
|
39
|
-
def http
|
43
|
+
def http
|
40
44
|
http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport])
|
41
45
|
http.use_ssl = (uri.port == 443)
|
42
46
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
43
47
|
http
|
44
48
|
end
|
45
49
|
|
46
|
-
def
|
47
|
-
|
50
|
+
def configure_basic_auth
|
51
|
+
@raw_request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password])
|
52
|
+
end
|
53
|
+
|
54
|
+
def setup_raw_request
|
55
|
+
@raw_request = http_method.new(uri.request_uri)
|
48
56
|
|
49
57
|
if post? && options[:query]
|
50
|
-
|
58
|
+
@raw_request.set_form_data(options[:query])
|
51
59
|
end
|
60
|
+
|
61
|
+
@raw_request.body = options[:body].is_a?(Hash) ? options[:body].to_params : options[:body] unless options[:body].blank?
|
62
|
+
@raw_request.initialize_http_header options[:headers]
|
63
|
+
|
64
|
+
configure_basic_auth if options[:basic_auth]
|
65
|
+
end
|
52
66
|
|
53
|
-
|
54
|
-
request
|
55
|
-
|
56
|
-
if options[:basic_auth]
|
57
|
-
request.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password])
|
58
|
-
end
|
67
|
+
def perform_actual_request
|
68
|
+
http.request(@raw_request)
|
69
|
+
end
|
59
70
|
|
60
|
-
|
71
|
+
def get_response
|
72
|
+
response = perform_actual_request
|
61
73
|
options[:format] ||= format_from_mimetype(response['content-type'])
|
62
74
|
response
|
63
75
|
end
|
64
|
-
|
65
|
-
def query_string(uri)
|
76
|
+
|
77
|
+
def query_string(uri)
|
66
78
|
query_string_parts = []
|
67
79
|
query_string_parts << uri.query unless uri.query.blank?
|
68
80
|
|
@@ -75,48 +87,47 @@ module HTTParty
|
|
75
87
|
|
76
88
|
query_string_parts.size > 0 ? query_string_parts.join('&') : nil
|
77
89
|
end
|
78
|
-
|
90
|
+
|
79
91
|
# Raises exception Net::XXX (http error code) if an http error occured
|
80
|
-
def handle_response
|
92
|
+
def handle_response(response)
|
81
93
|
case response
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
94
|
+
when Net::HTTPRedirection
|
95
|
+
options[:limit] -= 1
|
96
|
+
if options[:limit].to_i <= 0
|
97
|
+
raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep'
|
98
|
+
end
|
99
|
+
self.http_method = Net::HTTP::Get
|
100
|
+
self.path = response['location']
|
101
|
+
@redirect = true
|
102
|
+
perform
|
103
|
+
else
|
104
|
+
parsed_response = parse_response(response.body)
|
105
|
+
Response.new(parsed_response, response.body, response.code, response.to_hash)
|
106
|
+
end
|
96
107
|
end
|
97
|
-
|
98
|
-
def parse_response(body)
|
108
|
+
|
109
|
+
def parse_response(body)
|
99
110
|
return nil if body.nil? or body.empty?
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
111
|
+
case format
|
112
|
+
when :xml
|
113
|
+
HTTParty::Parsers::XML.parse(body)
|
114
|
+
when :json
|
115
|
+
HTTParty::Parsers::JSON.decode(body)
|
116
|
+
when :yaml
|
117
|
+
YAML::load(body)
|
118
|
+
else
|
119
|
+
body
|
120
|
+
end
|
109
121
|
end
|
110
122
|
|
111
123
|
# Uses the HTTP Content-Type header to determine the format of the response
|
112
124
|
# It compares the MIME type returned to the types stored in the AllowedFormats hash
|
113
|
-
def format_from_mimetype(mimetype)
|
125
|
+
def format_from_mimetype(mimetype)
|
114
126
|
return nil if mimetype.nil?
|
115
|
-
AllowedFormats.each { |k, v| return
|
127
|
+
AllowedFormats.each { |k, v| return v if mimetype.include?(k) }
|
116
128
|
end
|
117
|
-
|
118
|
-
def validate
|
119
|
-
raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0
|
129
|
+
|
130
|
+
def validate
|
120
131
|
raise ArgumentError, 'only get, post, put and delete methods are supported' unless SupportedHTTPMethods.include?(http_method)
|
121
132
|
raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
|
122
133
|
raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
|
@@ -127,28 +138,4 @@ module HTTParty
|
|
127
138
|
Net::HTTP::Post == http_method
|
128
139
|
end
|
129
140
|
end
|
130
|
-
|
131
|
-
class Response
|
132
|
-
attr_accessor :original_body, :format, :headers
|
133
|
-
|
134
|
-
def initialize(original_body, format, delegate)
|
135
|
-
self.original_body = original_body
|
136
|
-
self.format = format
|
137
|
-
self.headers = { }
|
138
|
-
@delegate = delegate
|
139
|
-
end
|
140
|
-
|
141
|
-
def add_header(name, value)
|
142
|
-
@headers[name] = value
|
143
|
-
end
|
144
|
-
|
145
|
-
def method_missing(sym, *args)
|
146
|
-
@delegate.send(sym, *args)
|
147
|
-
end
|
148
|
-
|
149
|
-
def pretty_print(pp)
|
150
|
-
@delegate.pretty_print(pp)
|
151
|
-
end
|
152
|
-
|
153
|
-
end
|
154
141
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module HTTParty
|
2
|
+
class Response < BlankSlate #:nodoc:
|
3
|
+
attr_accessor :body, :code, :headers
|
4
|
+
attr_reader :delegate
|
5
|
+
|
6
|
+
def initialize(delegate, body, code, headers={})
|
7
|
+
@delegate = delegate
|
8
|
+
@body = body
|
9
|
+
@code = code
|
10
|
+
@headers = headers
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(name, *args, &block)
|
14
|
+
@delegate.send(name, *args, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/httparty/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module HTTParty
|
2
|
-
Version = '0.
|
1
|
+
module HTTParty #:nodoc:
|
2
|
+
Version = '0.3.1'
|
3
3
|
end
|
data/lib/httparty.rb
CHANGED
@@ -2,63 +2,135 @@ $:.unshift(File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
require 'net/http'
|
4
4
|
require 'net/https'
|
5
|
-
require 'rubygems'
|
6
|
-
gem 'json', '>= 1.1.3'
|
7
|
-
require 'json'
|
8
|
-
|
9
|
-
require 'module_level_inheritable_attributes'
|
10
5
|
require 'core_extensions'
|
6
|
+
require 'httparty/module_inheritable_attributes'
|
11
7
|
|
12
|
-
module HTTParty
|
13
|
-
|
8
|
+
module HTTParty
|
9
|
+
|
10
|
+
AllowedFormats = {
|
11
|
+
'text/xml' => :xml,
|
12
|
+
'application/xml' => :xml,
|
13
|
+
'application/json' => :json,
|
14
|
+
'text/json' => :json,
|
15
|
+
'application/javascript' => :json,
|
16
|
+
'text/javascript' => :json,
|
17
|
+
'text/html' => :html,
|
18
|
+
'application/x-yaml' => :yaml,
|
19
|
+
'text/yaml' => :yaml
|
20
|
+
} unless defined?(AllowedFormats)
|
14
21
|
|
15
22
|
def self.included(base)
|
16
23
|
base.extend ClassMethods
|
17
|
-
base.send :include,
|
24
|
+
base.send :include, HTTParty::ModuleInheritableAttributes
|
18
25
|
base.send(:mattr_inheritable, :default_options)
|
19
26
|
base.instance_variable_set("@default_options", {})
|
20
27
|
end
|
21
28
|
|
22
29
|
module ClassMethods
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
# Allows setting http proxy information to be used
|
31
|
+
#
|
32
|
+
# class Foo
|
33
|
+
# include HTTParty
|
34
|
+
# http_proxy 'http://foo.com', 80
|
35
|
+
# end
|
27
36
|
def http_proxy(addr=nil, port = nil)
|
28
37
|
default_options[:http_proxyaddr] = addr
|
29
38
|
default_options[:http_proxyport] = port
|
30
39
|
end
|
31
|
-
|
40
|
+
|
41
|
+
# Allows setting a base uri to be used for each request.
|
42
|
+
# Will normalize uri to include http, etc.
|
43
|
+
#
|
44
|
+
# class Foo
|
45
|
+
# include HTTParty
|
46
|
+
# base_uri 'twitter.com'
|
47
|
+
# end
|
32
48
|
def base_uri(uri=nil)
|
33
49
|
return default_options[:base_uri] unless uri
|
34
50
|
default_options[:base_uri] = HTTParty.normalize_base_uri(uri)
|
35
51
|
end
|
36
|
-
|
52
|
+
|
53
|
+
# Allows setting basic authentication username and password.
|
54
|
+
#
|
55
|
+
# class Foo
|
56
|
+
# include HTTParty
|
57
|
+
# basic_auth 'username', 'password'
|
58
|
+
# end
|
37
59
|
def basic_auth(u, p)
|
38
60
|
default_options[:basic_auth] = {:username => u, :password => p}
|
39
61
|
end
|
40
62
|
|
63
|
+
# Allows setting default parameters to be appended to each request.
|
64
|
+
# Great for api keys and such.
|
65
|
+
#
|
66
|
+
# class Foo
|
67
|
+
# include HTTParty
|
68
|
+
# default_params :api_key => 'secret', :another => 'foo'
|
69
|
+
# end
|
41
70
|
def default_params(h={})
|
42
71
|
raise ArgumentError, 'Default params must be a hash' unless h.is_a?(Hash)
|
43
72
|
default_options[:default_params] ||= {}
|
44
73
|
default_options[:default_params].merge!(h)
|
45
74
|
end
|
46
|
-
|
75
|
+
|
76
|
+
# Allows setting a base uri to be used for each request.
|
77
|
+
#
|
78
|
+
# class Foo
|
79
|
+
# include HTTParty
|
80
|
+
# headers 'Accept' => 'text/html'
|
81
|
+
# end
|
47
82
|
def headers(h={})
|
48
83
|
raise ArgumentError, 'Headers must be a hash' unless h.is_a?(Hash)
|
49
84
|
default_options[:headers] ||= {}
|
50
85
|
default_options[:headers].merge!(h)
|
51
86
|
end
|
87
|
+
|
88
|
+
def cookies(h={})
|
89
|
+
raise ArgumentError, 'Cookies must be a hash' unless h.is_a?(Hash)
|
90
|
+
default_options[:cookies] ||= CookieHash.new
|
91
|
+
default_options[:cookies].add_cookies(h)
|
92
|
+
end
|
52
93
|
|
94
|
+
# Allows setting the format with which to parse.
|
95
|
+
# Must be one of the allowed formats ie: json, xml
|
96
|
+
#
|
97
|
+
# class Foo
|
98
|
+
# include HTTParty
|
99
|
+
# format :json
|
100
|
+
# end
|
53
101
|
def format(f)
|
54
|
-
raise UnsupportedFormat, "Must be one of: #{AllowedFormats.
|
102
|
+
raise UnsupportedFormat, "Must be one of: #{AllowedFormats.values.join(', ')}" unless AllowedFormats.value?(f)
|
55
103
|
default_options[:format] = f
|
56
104
|
end
|
57
105
|
|
106
|
+
# Allows making a get request to a url.
|
107
|
+
#
|
108
|
+
# class Foo
|
109
|
+
# include HTTParty
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# # Simple get with full url
|
113
|
+
# Foo.get('http://foo.com/resource.json')
|
114
|
+
#
|
115
|
+
# # Simple get with full url and query parameters
|
116
|
+
# # ie: http://foo.com/resource.json?limit=10
|
117
|
+
# Foo.get('http://foo.com/resource.json', :query => {:limit => 10})
|
58
118
|
def get(path, options={})
|
59
119
|
perform_request Net::HTTP::Get, path, options
|
60
120
|
end
|
61
|
-
|
121
|
+
|
122
|
+
# Allows making a post request to a url.
|
123
|
+
#
|
124
|
+
# class Foo
|
125
|
+
# include HTTParty
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
# # Simple post with full url and setting the body
|
129
|
+
# Foo.post('http://foo.com/resources', :body => {:bar => 'baz'})
|
130
|
+
#
|
131
|
+
# # Simple post with full url using :query option,
|
132
|
+
# # which gets set as form data on the request.
|
133
|
+
# Foo.post('http://foo.com/resources', :query => {:bar => 'baz'})
|
62
134
|
def post(path, options={})
|
63
135
|
perform_request Net::HTTP::Post, path, options
|
64
136
|
end
|
@@ -70,11 +142,25 @@ module HTTParty
|
|
70
142
|
def delete(path, options={})
|
71
143
|
perform_request Net::HTTP::Delete, path, options
|
72
144
|
end
|
145
|
+
|
146
|
+
def default_options #:nodoc:
|
147
|
+
@default_options
|
148
|
+
end
|
73
149
|
|
74
150
|
private
|
75
151
|
def perform_request(http_method, path, options) #:nodoc:
|
152
|
+
process_cookies(options)
|
76
153
|
Request.new(http_method, path, default_options.dup.merge(options)).perform
|
77
154
|
end
|
155
|
+
|
156
|
+
def process_cookies(options) #:nodoc:
|
157
|
+
return unless options[:cookies] || default_options[:cookies]
|
158
|
+
options[:headers] ||= {}
|
159
|
+
options[:headers]["cookie"] = cookies(options[:cookies] || {}).to_cookie_string
|
160
|
+
|
161
|
+
default_options.delete(:cookies)
|
162
|
+
options.delete(:cookies)
|
163
|
+
end
|
78
164
|
end
|
79
165
|
|
80
166
|
def self.normalize_base_uri(url) #:nodoc:
|
@@ -87,7 +173,7 @@ module HTTParty
|
|
87
173
|
"http#{'s' if use_ssl}://#{url}"
|
88
174
|
end
|
89
175
|
|
90
|
-
class Basement
|
176
|
+
class Basement #:nodoc:
|
91
177
|
include HTTParty
|
92
178
|
end
|
93
179
|
|
@@ -108,5 +194,8 @@ module HTTParty
|
|
108
194
|
end
|
109
195
|
end
|
110
196
|
|
197
|
+
require 'httparty/cookie_hash'
|
111
198
|
require 'httparty/exceptions'
|
112
|
-
require 'httparty/request'
|
199
|
+
require 'httparty/request'
|
200
|
+
require 'httparty/response'
|
201
|
+
require 'httparty/parsers'
|
File without changes
|
data/spec/hash_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Hash, "to_xml_attributes" do
|
4
|
+
before do
|
5
|
+
@hash = { :one => "ONE", "two" => "TWO" }
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should turn the hash into xml attributes" do
|
9
|
+
attrs = @hash.to_xml_attributes
|
10
|
+
attrs.should match(/one="ONE"/m)
|
11
|
+
attrs.should match(/two="TWO"/m)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should preserve _ in hash keys' do
|
15
|
+
attrs = {
|
16
|
+
:some_long_attribute => "with short value",
|
17
|
+
:crash => :burn,
|
18
|
+
:merb => "uses extlib"
|
19
|
+
}.to_xml_attributes
|
20
|
+
|
21
|
+
attrs.should =~ /some_long_attribute="with short value"/
|
22
|
+
attrs.should =~ /merb="uses extlib"/
|
23
|
+
attrs.should =~ /crash="burn"/
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
describe Hash, 'to_params' do
|
29
|
+
{
|
30
|
+
{ "foo" => "bar", "baz" => "bat" } => "foo=bar&baz=bat",
|
31
|
+
{ "foo" => [ "bar", "baz" ] } => "foo[]=bar&foo[]=baz",
|
32
|
+
{ "foo" => [ {"bar" => "1"}, {"bar" => 2} ] } => "foo[][bar]=1&foo[][bar]=2",
|
33
|
+
{ "foo" => { "bar" => [ {"baz" => 1}, {"baz" => "2"} ] } } => "foo[bar][][baz]=1&foo[bar][][baz]=2",
|
34
|
+
{ "foo" => {"1" => "bar", "2" => "baz"} } => "foo[1]=bar&foo[2]=baz"
|
35
|
+
}.each do |hash, params|
|
36
|
+
it "should covert hash: #{hash.inspect} to params: #{params.inspect}" do
|
37
|
+
hash.to_params.split('&').sort.should == params.split('&').sort
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should not leave a trailing &' do
|
42
|
+
{ :name => 'Bob', :address => { :street => '111 Ruby Ave.', :city => 'Ruby Central', :phones => ['111-111-1111', '222-222-2222'] } }.to_params.should_not match(/&$/)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should URL encode unsafe characters' do
|
46
|
+
{:q => "?&\" +"}.to_params.should == "q=%3F%26%22%20%2B"
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../spec_helper')
|
2
|
+
|
3
|
+
describe HTTParty::CookieHash do
|
4
|
+
before(:each) do
|
5
|
+
@cookie_hash = HTTParty::CookieHash.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#add_cookies" do
|
9
|
+
it "should add new key/value pairs to the hash" do
|
10
|
+
@cookie_hash.add_cookies(:foo => "bar")
|
11
|
+
@cookie_hash.add_cookies(:rofl => "copter")
|
12
|
+
@cookie_hash.length.should eql(2)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should overwrite any existing key" do
|
16
|
+
@cookie_hash.add_cookies(:foo => "bar")
|
17
|
+
@cookie_hash.add_cookies(:foo => "copter")
|
18
|
+
@cookie_hash.length.should eql(1)
|
19
|
+
@cookie_hash[:foo].should eql("copter")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# The regexen are required because Hashes aren't ordered, so a test against
|
24
|
+
# a hardcoded string was randomly failing.
|
25
|
+
describe "#to_cookie_string" do
|
26
|
+
before(:each) do
|
27
|
+
@cookie_hash.add_cookies(:foo => "bar")
|
28
|
+
@cookie_hash.add_cookies(:rofl => "copter")
|
29
|
+
@s = @cookie_hash.to_cookie_string
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should format the key/value pairs, delimited by semi-colons" do
|
33
|
+
@s.should match(/foo=bar/)
|
34
|
+
@s.should match(/rofl=copter/)
|
35
|
+
@s.should match(/^\w+=\w+; \w+=\w+$/)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe HTTParty::Parsers::JSON do
|
4
|
+
TESTS = {
|
5
|
+
%q({"data": "G\u00fcnter"}) => {"data" => "Günter"},
|
6
|
+
%q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
|
7
|
+
%q({returnTo:{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
|
8
|
+
%q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
|
9
|
+
%q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
|
10
|
+
%({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
|
11
|
+
%({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
|
12
|
+
%({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
|
13
|
+
%({a: "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
|
14
|
+
%({a: "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
|
15
|
+
%({a: "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
|
16
|
+
# no time zone
|
17
|
+
%({a: "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
|
18
|
+
%([]) => [],
|
19
|
+
%({}) => {},
|
20
|
+
%(1) => 1,
|
21
|
+
%("") => "",
|
22
|
+
%("\\"") => "\"",
|
23
|
+
%(null) => nil,
|
24
|
+
%(true) => true,
|
25
|
+
%(false) => false,
|
26
|
+
%q("http:\/\/test.host\/posts\/1") => "http://test.host/posts/1"
|
27
|
+
}
|
28
|
+
|
29
|
+
TESTS.each do |json, expected|
|
30
|
+
it "should decode json (#{json})" do
|
31
|
+
lambda {
|
32
|
+
HTTParty::Parsers::JSON.decode(json).should == expected
|
33
|
+
}.should_not raise_error
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should raise error for failed decoding" do
|
38
|
+
lambda {
|
39
|
+
HTTParty::Parsers::JSON.decode(%({: 1}))
|
40
|
+
}.should raise_error(HTTParty::Parsers::JSON::ParseError)
|
41
|
+
end
|
42
|
+
end
|