em-http-request 0.2.13 → 0.2.14
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.
Potentially problematic release.
This version of em-http-request might be problematic. Click here for more details.
- data/Changelog.md +4 -0
- data/README.md +1 -0
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/em-http-request.gemspec +4 -5
- data/lib/em-http-request.rb +1 -1
- data/lib/em-http.rb +0 -1
- data/lib/em-http/client.rb +28 -6
- data/lib/em-http/decoders.rb +122 -122
- data/spec/encoding_spec.rb +34 -0
- data/spec/request_spec.rb +13 -0
- metadata +5 -6
- data/lib/em-http/core_ext/hash.rb +0 -53
- data/spec/hash_spec.rb +0 -24
data/Changelog.md
CHANGED
data/README.md
CHANGED
@@ -29,6 +29,7 @@ Libraries & Applications using em-http
|
|
29
29
|
- [RDaneel](http://github.com/hasmanydevelopers/RDaneel) - Ruby crawler which respects robots.txt
|
30
30
|
- [rsolr-async](http://github.com/mwmitchell/rsolr-async) - An asynchronus connection adapter for RSolr
|
31
31
|
- [PubSubHubbub](http://github.com/igrigorik/PubSubHubbub) - Asynchronous PubSubHubbub ruby client
|
32
|
+
- [Firering](http://github.com/EmmanuelOga/firering) - Eventmachine powered Campfire API
|
32
33
|
- and many others.. drop me a link if you want yours included!
|
33
34
|
|
34
35
|
Simple client example
|
data/Rakefile
CHANGED
@@ -19,9 +19,9 @@ task :default => :compile
|
|
19
19
|
Rake::RDocTask.new(:rdoc) do |task|
|
20
20
|
task.rdoc_dir = 'doc'
|
21
21
|
task.title = 'EventMachine::HttpRequest'
|
22
|
-
task.options = %w(--title HttpRequest --main README --line-numbers)
|
22
|
+
task.options = %w(--title HttpRequest --main README.md --line-numbers)
|
23
23
|
task.rdoc_files.include(['lib/**/*.rb'])
|
24
|
-
task.rdoc_files.include(['README', 'LICENSE'])
|
24
|
+
task.rdoc_files.include(['README.md', 'LICENSE'])
|
25
25
|
end
|
26
26
|
|
27
27
|
# Rebuild parser Ragel
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.14
|
data/em-http-request.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{em-http-request}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.14"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ilya Grigorik"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-10-06}
|
13
13
|
s.description = %q{EventMachine based, async HTTP Request interface}
|
14
14
|
s.email = %q{ilya@igvita.com}
|
15
15
|
s.extensions = ["ext/buffer/extconf.rb", "ext/http11_client/extconf.rb"]
|
@@ -43,14 +43,13 @@ Gem::Specification.new do |s|
|
|
43
43
|
"lib/em-http.rb",
|
44
44
|
"lib/em-http/client.rb",
|
45
45
|
"lib/em-http/core_ext/bytesize.rb",
|
46
|
-
"lib/em-http/core_ext/hash.rb",
|
47
46
|
"lib/em-http/decoders.rb",
|
48
47
|
"lib/em-http/http_options.rb",
|
49
48
|
"lib/em-http/mock.rb",
|
50
49
|
"lib/em-http/multi.rb",
|
51
50
|
"lib/em-http/request.rb",
|
51
|
+
"spec/encoding_spec.rb",
|
52
52
|
"spec/fixtures/google.ca",
|
53
|
-
"spec/hash_spec.rb",
|
54
53
|
"spec/helper.rb",
|
55
54
|
"spec/mock_spec.rb",
|
56
55
|
"spec/multi_spec.rb",
|
@@ -67,7 +66,7 @@ Gem::Specification.new do |s|
|
|
67
66
|
s.rubygems_version = %q{1.3.7}
|
68
67
|
s.summary = %q{EventMachine based, async HTTP Request interface}
|
69
68
|
s.test_files = [
|
70
|
-
"spec/
|
69
|
+
"spec/encoding_spec.rb",
|
71
70
|
"spec/helper.rb",
|
72
71
|
"spec/mock_spec.rb",
|
73
72
|
"spec/multi_spec.rb",
|
data/lib/em-http-request.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'em-http'
|
1
|
+
require 'em-http'
|
data/lib/em-http.rb
CHANGED
@@ -10,7 +10,6 @@ require 'socket'
|
|
10
10
|
require File.dirname(__FILE__) + '/http11_client'
|
11
11
|
require File.dirname(__FILE__) + '/em_buffer'
|
12
12
|
|
13
|
-
require File.dirname(__FILE__) + '/em-http/core_ext/hash'
|
14
13
|
require File.dirname(__FILE__) + '/em-http/core_ext/bytesize'
|
15
14
|
|
16
15
|
require File.dirname(__FILE__) + '/em-http/client'
|
data/lib/em-http/client.rb
CHANGED
@@ -82,9 +82,9 @@ module EventMachine
|
|
82
82
|
|
83
83
|
# Escapes a URI.
|
84
84
|
def escape(s)
|
85
|
-
s.to_s.gsub(/([^
|
85
|
+
s.to_s.gsub(/([^a-zA-Z0-9_.-]+)/n) {
|
86
86
|
'%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
|
87
|
-
}
|
87
|
+
}
|
88
88
|
end
|
89
89
|
|
90
90
|
# Unescapes a URI escaped string.
|
@@ -153,6 +153,29 @@ module EventMachine
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
+
def form_encode_body(obj)
|
157
|
+
pairs = []
|
158
|
+
recursive = Proc.new do |h, prefix|
|
159
|
+
h.each do |k,v|
|
160
|
+
key = prefix == '' ? escape(k) : "#{prefix}[#{escape(k)}]"
|
161
|
+
|
162
|
+
if v.is_a? Array
|
163
|
+
nh = Hash.new
|
164
|
+
v.size.times { |t| nh[t] = v[t] }
|
165
|
+
recursive.call(nh, key)
|
166
|
+
|
167
|
+
elsif v.is_a? Hash
|
168
|
+
recursive.call(v, key)
|
169
|
+
else
|
170
|
+
pairs << "#{key}=#{escape(v)}"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
recursive.call(obj, '')
|
176
|
+
return pairs.join('&')
|
177
|
+
end
|
178
|
+
|
156
179
|
# Encode a field in an HTTP header
|
157
180
|
def encode_field(k, v)
|
158
181
|
FIELD_ENCODING % [k, v]
|
@@ -236,8 +259,8 @@ module EventMachine
|
|
236
259
|
@state = :connect_socks_proxy
|
237
260
|
send_socks_handshake
|
238
261
|
|
239
|
-
|
240
|
-
|
262
|
+
# if we need to negotiate the proxy connection first, then
|
263
|
+
# issue a CONNECT query and wait for 200 response
|
241
264
|
elsif connect_proxy? and @state == :response_header
|
242
265
|
@state = :connect_http_proxy
|
243
266
|
send_request_header
|
@@ -308,7 +331,7 @@ module EventMachine
|
|
308
331
|
def normalize_body
|
309
332
|
@normalized_body ||= begin
|
310
333
|
if @options[:body].is_a? Hash
|
311
|
-
@options[:body]
|
334
|
+
form_encode_body(@options[:body])
|
312
335
|
else
|
313
336
|
@options[:body]
|
314
337
|
end
|
@@ -845,4 +868,3 @@ module EventMachine
|
|
845
868
|
end
|
846
869
|
|
847
870
|
end
|
848
|
-
|
data/lib/em-http/decoders.rb
CHANGED
@@ -1,122 +1,122 @@
|
|
1
|
-
require 'zlib'
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
##
|
5
|
-
# Provides a unified callback interface to decompression libraries.
|
6
|
-
module EventMachine::HttpDecoders
|
7
|
-
|
8
|
-
class DecoderError < StandardError
|
9
|
-
end
|
10
|
-
|
11
|
-
class << self
|
12
|
-
def accepted_encodings
|
13
|
-
DECODERS.inject([]) { |r,d| r + d.encoding_names }
|
14
|
-
end
|
15
|
-
|
16
|
-
def decoder_for_encoding(encoding)
|
17
|
-
DECODERS.each { |d|
|
18
|
-
return d if d.encoding_names.include? encoding
|
19
|
-
}
|
20
|
-
nil
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class Base
|
25
|
-
def self.encoding_names
|
26
|
-
name = to_s.split('::').last.downcase
|
27
|
-
[name]
|
28
|
-
end
|
29
|
-
|
30
|
-
##
|
31
|
-
# chunk_callback:: [Block] To handle a decompressed chunk
|
32
|
-
def initialize(&chunk_callback)
|
33
|
-
@chunk_callback = chunk_callback
|
34
|
-
end
|
35
|
-
|
36
|
-
def <<(compressed)
|
37
|
-
return unless compressed && compressed.size > 0
|
38
|
-
|
39
|
-
decompressed = decompress(compressed)
|
40
|
-
receive_decompressed decompressed
|
41
|
-
end
|
42
|
-
|
43
|
-
def finalize!
|
44
|
-
decompressed = finalize
|
45
|
-
receive_decompressed decompressed
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def receive_decompressed(decompressed)
|
51
|
-
if decompressed && decompressed.size > 0
|
52
|
-
@chunk_callback.call(decompressed)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
protected
|
57
|
-
|
58
|
-
##
|
59
|
-
# Must return a part of decompressed
|
60
|
-
def decompress(compressed)
|
61
|
-
nil
|
62
|
-
end
|
63
|
-
|
64
|
-
##
|
65
|
-
# May return last part
|
66
|
-
def finalize
|
67
|
-
nil
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class Deflate < Base
|
72
|
-
def decompress(compressed)
|
73
|
-
begin
|
74
|
-
@zstream ||= Zlib::Inflate.new(nil)
|
75
|
-
@zstream.inflate(compressed)
|
76
|
-
rescue Zlib::Error
|
77
|
-
raise DecoderError
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def finalize
|
82
|
-
return nil unless @zstream
|
83
|
-
|
84
|
-
begin
|
85
|
-
r = @zstream.inflate(nil)
|
86
|
-
@zstream.close
|
87
|
-
r
|
88
|
-
rescue Zlib::Error
|
89
|
-
raise DecoderError
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
##
|
95
|
-
# Oneshot decompressor, due to lack of a streaming Gzip reader
|
96
|
-
# implementation. We may steal code from Zliby to improve this.
|
97
|
-
#
|
98
|
-
# For now, do not put `gzip' or `compressed' in your accept-encoding
|
99
|
-
# header if you expect much data through the :on_response interface.
|
100
|
-
class GZip < Base
|
101
|
-
def self.encoding_names
|
102
|
-
%w(gzip compressed)
|
103
|
-
end
|
104
|
-
|
105
|
-
def decompress(compressed)
|
106
|
-
@buf ||= ''
|
107
|
-
@buf += compressed
|
108
|
-
nil
|
109
|
-
end
|
110
|
-
|
111
|
-
def finalize
|
112
|
-
begin
|
113
|
-
Zlib::GzipReader.new(StringIO.new(@buf.to_s)).read
|
114
|
-
rescue Zlib::Error
|
115
|
-
raise DecoderError
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
DECODERS = [Deflate, GZip]
|
121
|
-
|
122
|
-
end
|
1
|
+
require 'zlib'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
##
|
5
|
+
# Provides a unified callback interface to decompression libraries.
|
6
|
+
module EventMachine::HttpDecoders
|
7
|
+
|
8
|
+
class DecoderError < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def accepted_encodings
|
13
|
+
DECODERS.inject([]) { |r,d| r + d.encoding_names }
|
14
|
+
end
|
15
|
+
|
16
|
+
def decoder_for_encoding(encoding)
|
17
|
+
DECODERS.each { |d|
|
18
|
+
return d if d.encoding_names.include? encoding
|
19
|
+
}
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Base
|
25
|
+
def self.encoding_names
|
26
|
+
name = to_s.split('::').last.downcase
|
27
|
+
[name]
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# chunk_callback:: [Block] To handle a decompressed chunk
|
32
|
+
def initialize(&chunk_callback)
|
33
|
+
@chunk_callback = chunk_callback
|
34
|
+
end
|
35
|
+
|
36
|
+
def <<(compressed)
|
37
|
+
return unless compressed && compressed.size > 0
|
38
|
+
|
39
|
+
decompressed = decompress(compressed)
|
40
|
+
receive_decompressed decompressed
|
41
|
+
end
|
42
|
+
|
43
|
+
def finalize!
|
44
|
+
decompressed = finalize
|
45
|
+
receive_decompressed decompressed
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def receive_decompressed(decompressed)
|
51
|
+
if decompressed && decompressed.size > 0
|
52
|
+
@chunk_callback.call(decompressed)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
|
58
|
+
##
|
59
|
+
# Must return a part of decompressed
|
60
|
+
def decompress(compressed)
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# May return last part
|
66
|
+
def finalize
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Deflate < Base
|
72
|
+
def decompress(compressed)
|
73
|
+
begin
|
74
|
+
@zstream ||= Zlib::Inflate.new(nil)
|
75
|
+
@zstream.inflate(compressed)
|
76
|
+
rescue Zlib::Error
|
77
|
+
raise DecoderError
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def finalize
|
82
|
+
return nil unless @zstream
|
83
|
+
|
84
|
+
begin
|
85
|
+
r = @zstream.inflate(nil)
|
86
|
+
@zstream.close
|
87
|
+
r
|
88
|
+
rescue Zlib::Error
|
89
|
+
raise DecoderError
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Oneshot decompressor, due to lack of a streaming Gzip reader
|
96
|
+
# implementation. We may steal code from Zliby to improve this.
|
97
|
+
#
|
98
|
+
# For now, do not put `gzip' or `compressed' in your accept-encoding
|
99
|
+
# header if you expect much data through the :on_response interface.
|
100
|
+
class GZip < Base
|
101
|
+
def self.encoding_names
|
102
|
+
%w(gzip compressed)
|
103
|
+
end
|
104
|
+
|
105
|
+
def decompress(compressed)
|
106
|
+
@buf ||= ''
|
107
|
+
@buf += compressed
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def finalize
|
112
|
+
begin
|
113
|
+
Zlib::GzipReader.new(StringIO.new(@buf.to_s)).read
|
114
|
+
rescue Zlib::Error
|
115
|
+
raise DecoderError
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
DECODERS = [Deflate, GZip]
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
|
3
|
+
describe EventMachine::HttpEncoding do
|
4
|
+
include EventMachine::HttpEncoding
|
5
|
+
|
6
|
+
it "should transform a basic hash into HTTP POST Params" do
|
7
|
+
form_encode_body({:a => "alpha", :b => "beta"}).should == "a=alpha&b=beta"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should transform a more complex hash into HTTP POST Params" do
|
11
|
+
form_encode_body({:a => "a", :b => ["c", "d", "e"]}).should == "a=a&b[0]=c&b[1]=d&b[2]=e"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should transform a very complex hash into HTTP POST Params" do
|
15
|
+
params = form_encode_body({:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]})
|
16
|
+
params.should == "a=a&b[0][c]=c&b[0][d]=d&b[1][e]=e&b[1][f]=f"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should escape values" do
|
20
|
+
params = form_encode_body({:stuff => 'string&string'})
|
21
|
+
params.should == "stuff=string%26string"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should escape keys" do
|
25
|
+
params = form_encode_body({'bad&str'=> {'key&key' => [:a, :b]}})
|
26
|
+
params.should == 'bad%26str[key%26key][0]=a&bad%26str[key%26key][1]=b'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should escape keys and values" do
|
30
|
+
params = form_encode_body({'bad&str'=> {'key&key' => ['bad+&stuff', '[test]']}})
|
31
|
+
params.should == "bad%26str[key%26key][0]=bad%2B%26stuff&bad%26str[key%26key][1]=%5Btest%5D"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/spec/request_spec.rb
CHANGED
@@ -247,6 +247,19 @@ describe EventMachine::HttpRequest do
|
|
247
247
|
}
|
248
248
|
end
|
249
249
|
|
250
|
+
it "should escape body on POST" do
|
251
|
+
EventMachine.run {
|
252
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').post :body => {:stuff => 'string&string'}
|
253
|
+
|
254
|
+
http.errback { failed }
|
255
|
+
http.callback {
|
256
|
+
http.response_header.status.should == 200
|
257
|
+
http.response.should == "stuff=string%26string"
|
258
|
+
EventMachine.stop
|
259
|
+
}
|
260
|
+
}
|
261
|
+
end
|
262
|
+
|
250
263
|
it "should perform successfull POST with Ruby Hash/Array as params" do
|
251
264
|
EventMachine.run {
|
252
265
|
http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').post :body => {"key1" => 1, "key2" => [2,3]}
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 14
|
9
|
+
version: 0.2.14
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ilya Grigorik
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-10-06 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -83,14 +83,13 @@ files:
|
|
83
83
|
- lib/em-http.rb
|
84
84
|
- lib/em-http/client.rb
|
85
85
|
- lib/em-http/core_ext/bytesize.rb
|
86
|
-
- lib/em-http/core_ext/hash.rb
|
87
86
|
- lib/em-http/decoders.rb
|
88
87
|
- lib/em-http/http_options.rb
|
89
88
|
- lib/em-http/mock.rb
|
90
89
|
- lib/em-http/multi.rb
|
91
90
|
- lib/em-http/request.rb
|
91
|
+
- spec/encoding_spec.rb
|
92
92
|
- spec/fixtures/google.ca
|
93
|
-
- spec/hash_spec.rb
|
94
93
|
- spec/helper.rb
|
95
94
|
- spec/mock_spec.rb
|
96
95
|
- spec/multi_spec.rb
|
@@ -133,7 +132,7 @@ signing_key:
|
|
133
132
|
specification_version: 3
|
134
133
|
summary: EventMachine based, async HTTP Request interface
|
135
134
|
test_files:
|
136
|
-
- spec/
|
135
|
+
- spec/encoding_spec.rb
|
137
136
|
- spec/helper.rb
|
138
137
|
- spec/mock_spec.rb
|
139
138
|
- spec/multi_spec.rb
|
@@ -1,53 +0,0 @@
|
|
1
|
-
class Hash
|
2
|
-
# Stolen partially from Merb : http://noobkit.com/show/ruby/gems/development/merb/hash/to_params.html
|
3
|
-
# Convert this hash to a query string:
|
4
|
-
#
|
5
|
-
# { :name => "Bob",
|
6
|
-
# :address => {
|
7
|
-
# :street => '111 Ruby Ave.',
|
8
|
-
# :city => 'Ruby Central',
|
9
|
-
# :phones => ['111-111-1111', '222-222-2222']
|
10
|
-
# }
|
11
|
-
# }.to_params
|
12
|
-
# #=> "name=Bob&address[city]=Ruby Central&address[phones]=111-111-1111222-222-2222&address[street]=111 Ruby Ave."
|
13
|
-
#
|
14
|
-
def to_params
|
15
|
-
params = ''
|
16
|
-
stack = []
|
17
|
-
|
18
|
-
each do |k, v|
|
19
|
-
if v.is_a?(Hash)
|
20
|
-
stack << [k,v]
|
21
|
-
elsif v.is_a?(Array)
|
22
|
-
stack << [k,Hash.from_array(v)]
|
23
|
-
else
|
24
|
-
params << "#{k}=#{v}&"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
stack.each do |parent, hash|
|
29
|
-
hash.each do |k, v|
|
30
|
-
if v.is_a?(Hash)
|
31
|
-
stack << ["#{parent}[#{k}]", v]
|
32
|
-
else
|
33
|
-
params << "#{parent}[#{k}]=#{v}&"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
params.chop! # trailing &
|
39
|
-
params
|
40
|
-
end
|
41
|
-
|
42
|
-
##
|
43
|
-
# Builds a hash from an array with keys as array indices.
|
44
|
-
def self.from_array(array = [])
|
45
|
-
h = Hash.new
|
46
|
-
array.size.times do |t|
|
47
|
-
h[t] = array[t]
|
48
|
-
end
|
49
|
-
h
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
data/spec/hash_spec.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'spec/helper'
|
2
|
-
|
3
|
-
describe Hash do
|
4
|
-
|
5
|
-
describe ".to_params" do
|
6
|
-
it "should transform a basic hash into HTTP POST Params" do
|
7
|
-
{:a => "alpha", :b => "beta"}.to_params.split("&").should include "a=alpha"
|
8
|
-
{:a => "alpha", :b => "beta"}.to_params.split("&").should include "b=beta"
|
9
|
-
end
|
10
|
-
|
11
|
-
it "should transform a more complex hash into HTTP POST Params" do
|
12
|
-
{:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "a=a"
|
13
|
-
{:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[0]=c"
|
14
|
-
{:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[1]=d"
|
15
|
-
{:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[2]=e"
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should transform a very complex hash into HTTP POST Params" do
|
19
|
-
params = {:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]}.to_params.split("&")
|
20
|
-
params.should include "a=a"
|
21
|
-
params.should include "b[0][d]=d"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|