rest-core 3.6.0 → 4.0.0
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.
- checksums.yaml +4 -4
- data/.gitmodules +3 -0
- data/.travis.yml +0 -1
- data/CHANGES.md +28 -0
- data/Gemfile +0 -2
- data/README.md +14 -95
- data/Rakefile +16 -3
- data/example/simple.rb +1 -0
- data/example/use-cases.rb +15 -3
- data/lib/rest-core.rb +38 -75
- data/lib/rest-core/client/universal.rb +3 -1
- data/lib/rest-core/client_oauth1.rb +64 -59
- data/lib/rest-core/event.rb +9 -11
- data/lib/rest-core/middleware/auth_basic.rb +21 -21
- data/lib/rest-core/middleware/bypass.rb +8 -8
- data/lib/rest-core/middleware/cache.rb +94 -90
- data/lib/rest-core/middleware/clash_response.rb +15 -14
- data/lib/rest-core/middleware/common_logger.rb +27 -26
- data/lib/rest-core/middleware/default_headers.rb +8 -8
- data/lib/rest-core/middleware/default_payload.rb +8 -8
- data/lib/rest-core/middleware/default_query.rb +8 -8
- data/lib/rest-core/middleware/default_site.rb +12 -12
- data/lib/rest-core/middleware/defaults.rb +38 -38
- data/lib/rest-core/middleware/error_detector.rb +10 -10
- data/lib/rest-core/middleware/error_detector_http.rb +6 -4
- data/lib/rest-core/middleware/error_handler.rb +14 -14
- data/lib/rest-core/middleware/follow_redirect.rb +28 -27
- data/lib/rest-core/middleware/json_request.rb +13 -11
- data/lib/rest-core/middleware/json_response.rb +29 -28
- data/lib/rest-core/middleware/oauth1_header.rb +84 -83
- data/lib/rest-core/middleware/oauth2_header.rb +27 -25
- data/lib/rest-core/middleware/oauth2_query.rb +15 -15
- data/lib/rest-core/middleware/query_response.rb +14 -14
- data/lib/rest-core/middleware/retry.rb +25 -23
- data/lib/rest-core/middleware/smash_response.rb +15 -14
- data/lib/rest-core/middleware/timeout.rb +18 -19
- data/lib/rest-core/test.rb +1 -18
- data/lib/rest-core/util/clash.rb +38 -37
- data/lib/rest-core/util/config.rb +40 -39
- data/lib/rest-core/util/dalli_extension.rb +11 -10
- data/lib/rest-core/util/hmac.rb +9 -8
- data/lib/rest-core/util/json.rb +55 -54
- data/lib/rest-core/util/parse_link.rb +13 -12
- data/lib/rest-core/util/parse_query.rb +24 -22
- data/lib/rest-core/version.rb +1 -1
- data/rest-core.gemspec +121 -158
- data/test/test_cache.rb +2 -0
- data/test/test_default_payload.rb +1 -1
- data/test/test_error_handler.rb +5 -4
- data/test/test_timeout.rb +9 -8
- data/test/test_universal.rb +8 -0
- metadata +9 -73
- data/lib/rest-core/builder.rb +0 -162
- data/lib/rest-core/client.rb +0 -277
- data/lib/rest-core/client/simple.rb +0 -2
- data/lib/rest-core/engine.rb +0 -36
- data/lib/rest-core/engine/dry.rb +0 -9
- data/lib/rest-core/engine/http-client.rb +0 -41
- data/lib/rest-core/error.rb +0 -5
- data/lib/rest-core/event_source.rb +0 -137
- data/lib/rest-core/middleware.rb +0 -151
- data/lib/rest-core/promise.rb +0 -249
- data/lib/rest-core/thread_pool.rb +0 -131
- data/lib/rest-core/timer.rb +0 -58
- data/lib/rest-core/util/payload.rb +0 -173
- data/test/test_builder.rb +0 -40
- data/test/test_client.rb +0 -177
- data/test/test_event_source.rb +0 -159
- data/test/test_future.rb +0 -16
- data/test/test_httpclient.rb +0 -118
- data/test/test_payload.rb +0 -204
- data/test/test_promise.rb +0 -146
- data/test/test_simple.rb +0 -38
- data/test/test_thread_pool.rb +0 -10
data/test/test_event_source.rb
DELETED
@@ -1,159 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'socket'
|
3
|
-
require 'rest-core/test'
|
4
|
-
|
5
|
-
describe RC::EventSource do
|
6
|
-
after do
|
7
|
-
Muack.verify
|
8
|
-
WebMock.reset!
|
9
|
-
end
|
10
|
-
|
11
|
-
client = RC::Builder.client{use RC::Cache, {}, nil}.new
|
12
|
-
server = lambda do |close=true|
|
13
|
-
serv = TCPServer.new(0)
|
14
|
-
port = serv.addr[1]
|
15
|
-
path = "http://localhost:#{port}/"
|
16
|
-
payload = <<-SSE
|
17
|
-
event: put
|
18
|
-
data: {}
|
19
|
-
|
20
|
-
event: keep-alive
|
21
|
-
data: null
|
22
|
-
SSE
|
23
|
-
m = [{'event' => 'put' , 'data' => '{}'},
|
24
|
-
{'event' => 'keep-alive', 'data' => 'null'}]
|
25
|
-
|
26
|
-
t = Thread.new do
|
27
|
-
sock = serv.accept
|
28
|
-
sock.readline("\r\n\r\n")
|
29
|
-
sock.puts("HTTP/1.1 200 OK\r")
|
30
|
-
sock.puts("Content-Type: text/event-stream\r")
|
31
|
-
sock.puts
|
32
|
-
sock.puts(payload)
|
33
|
-
sock.close if close
|
34
|
-
end
|
35
|
-
|
36
|
-
[client.event_source(path, :a => 'b'), m, t]
|
37
|
-
end
|
38
|
-
|
39
|
-
would 'work regularly' do
|
40
|
-
es, m, t = server.call
|
41
|
-
flag = 0
|
42
|
-
|
43
|
-
es.onopen do |sock|
|
44
|
-
sock.should.kind_of? IO
|
45
|
-
flag.should.eq 0
|
46
|
-
flag += 1
|
47
|
-
end.
|
48
|
-
onmessage do |event, data, sock|
|
49
|
-
{'event' => event, 'data' => data}.should.eq m.shift
|
50
|
-
sock.should.kind_of? IO
|
51
|
-
sock.should.not.closed?
|
52
|
-
flag += 1
|
53
|
-
end.
|
54
|
-
onerror do |error, sock|
|
55
|
-
error.should.kind_of? EOFError
|
56
|
-
m.should.empty?
|
57
|
-
sock.should.closed?
|
58
|
-
flag.should.eq 3
|
59
|
-
flag += 1
|
60
|
-
end.start.wait
|
61
|
-
|
62
|
-
flag.should.eq 4
|
63
|
-
t.join
|
64
|
-
end
|
65
|
-
|
66
|
-
would 'close' do
|
67
|
-
es, _, t = server.call(false)
|
68
|
-
flag = 0
|
69
|
-
es.onmessage do
|
70
|
-
es.close
|
71
|
-
flag += 1
|
72
|
-
end.start.wait
|
73
|
-
|
74
|
-
flag.should.eq 1
|
75
|
-
t.join
|
76
|
-
end
|
77
|
-
|
78
|
-
would 'reconnect' do
|
79
|
-
stub_select_for_stringio
|
80
|
-
stub_request(:get, 'https://a?b=c').to_return(:body => <<-SSE)
|
81
|
-
event: put
|
82
|
-
data: 0
|
83
|
-
|
84
|
-
event: put
|
85
|
-
data: 1
|
86
|
-
SSE
|
87
|
-
stub_request(:get, 'https://a?c=d').to_return(:body => <<-SSE)
|
88
|
-
event: put
|
89
|
-
data: 2
|
90
|
-
|
91
|
-
event: put
|
92
|
-
data: 3
|
93
|
-
SSE
|
94
|
-
es = client.event_source('https://a', :b => 'c')
|
95
|
-
m = ('0'..'3').to_a
|
96
|
-
es.onmessage do |event, data|
|
97
|
-
data.should.eq m.shift
|
98
|
-
|
99
|
-
end.onerror do |error|
|
100
|
-
error.should.kind_of? EOFError
|
101
|
-
es.query = {:c => 'd'}
|
102
|
-
|
103
|
-
end.onreconnect do |error, sock|
|
104
|
-
error.should.kind_of? EOFError
|
105
|
-
sock.should.respond_to? :read
|
106
|
-
!m.empty? # not empty to reconnect
|
107
|
-
|
108
|
-
end.start.wait
|
109
|
-
m.should.empty?
|
110
|
-
end
|
111
|
-
|
112
|
-
would 'not cache' do
|
113
|
-
stub_select_for_stringio
|
114
|
-
stub_request(:get, 'https://a?b=c').to_return(:body => <<-SSE)
|
115
|
-
event: put
|
116
|
-
data: 0
|
117
|
-
|
118
|
-
event: put
|
119
|
-
data: 1
|
120
|
-
SSE
|
121
|
-
es = client.event_source('https://a', :b => 'c')
|
122
|
-
m = %w[0 1 0 1]
|
123
|
-
es.onmessage do |event, data|
|
124
|
-
data.should.eq m.shift
|
125
|
-
|
126
|
-
end.onerror do |error|
|
127
|
-
error.should.kind_of? EOFError
|
128
|
-
|
129
|
-
end.onreconnect do |error, sock|
|
130
|
-
error.should.kind_of? EOFError
|
131
|
-
sock.should.respond_to? :read
|
132
|
-
!m.empty? # not empty to reconnect
|
133
|
-
|
134
|
-
end.start.wait
|
135
|
-
m.should.empty?
|
136
|
-
end
|
137
|
-
|
138
|
-
would 'not deadlock without ErrorHandler' do
|
139
|
-
c = RC::Simple.new.event_source('http://localhost:1')
|
140
|
-
c.onerror{ |e| e.should.kind_of?(Errno::ECONNREFUSED) }
|
141
|
-
c.start.wait
|
142
|
-
end
|
143
|
-
|
144
|
-
would 'not deadlock with ErrorHandler' do
|
145
|
-
c = RC::Universal.new(:log_method => false).
|
146
|
-
event_source('http://localhost:1')
|
147
|
-
c.onerror{ |e| e.should.kind_of?(Errno::ECONNREFUSED) }
|
148
|
-
c.start.wait
|
149
|
-
end
|
150
|
-
|
151
|
-
would 'not deadlock if errors in onmessage' do
|
152
|
-
err = nil
|
153
|
-
es, _, _ = server.call
|
154
|
-
es.onmessage do |event, data|
|
155
|
-
raise err = "error"
|
156
|
-
end.start.wait
|
157
|
-
err.should.eq "error"
|
158
|
-
end
|
159
|
-
end
|
data/test/test_future.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'stringio'
|
3
|
-
require 'rest-core/test'
|
4
|
-
|
5
|
-
describe RC::Promise::Future do
|
6
|
-
would 'fulfill the future' do
|
7
|
-
promise = RC::Promise.new(RC::FAIL => [])
|
8
|
-
promise.fulfill('body', 200, {'A' => 'B'}, StringIO.new)
|
9
|
-
|
10
|
-
promise.future_body .should.eq 'body'
|
11
|
-
promise.future_status .should.eq 200
|
12
|
-
promise.future_headers .should.eq('A' => 'B')
|
13
|
-
promise.future_socket .should.kind_of?(StringIO)
|
14
|
-
promise.future_failures.should.eq []
|
15
|
-
end
|
16
|
-
end
|
data/test/test_httpclient.rb
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/test'
|
3
|
-
|
4
|
-
require 'openssl'
|
5
|
-
require 'socket'
|
6
|
-
require 'zlib'
|
7
|
-
|
8
|
-
describe RC::HttpClient do
|
9
|
-
describe 'POST Payload' do
|
10
|
-
after do
|
11
|
-
WebMock.reset!
|
12
|
-
end
|
13
|
-
|
14
|
-
client = RC::Builder.client
|
15
|
-
path = 'http://example.com'
|
16
|
-
ok = 'OK'
|
17
|
-
c = client.new
|
18
|
-
|
19
|
-
post = lambda do |payload, body|
|
20
|
-
WebMock::API.stub_request(:post, path).
|
21
|
-
with(:body => body).to_return(:body => ok)
|
22
|
-
c.post(path, payload).should.eq ok
|
23
|
-
end
|
24
|
-
|
25
|
-
would 'post with string' do
|
26
|
-
post['string', 'string']
|
27
|
-
end
|
28
|
-
|
29
|
-
would 'post with file' do
|
30
|
-
File.open(__FILE__) do |f|
|
31
|
-
b = f.read
|
32
|
-
f.rewind
|
33
|
-
post[f, b]
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
would 'post with socket' do
|
38
|
-
rd, wr = IO.pipe
|
39
|
-
wr.write('socket')
|
40
|
-
wr.close
|
41
|
-
post[rd, 'socket']
|
42
|
-
end
|
43
|
-
|
44
|
-
would 'not kill the thread if error was coming from the task' do
|
45
|
-
mock(HTTPClient).new{ raise 'boom' }.with_any_args
|
46
|
-
c.request(RC::ASYNC => true).message.should.eq 'boom'
|
47
|
-
Muack.verify
|
48
|
-
end
|
49
|
-
|
50
|
-
def accept body
|
51
|
-
server = TCPServer.new(0)
|
52
|
-
t = Thread.new do
|
53
|
-
client = server.accept
|
54
|
-
client.write(<<-HTTP)
|
55
|
-
HTTP/1.0 200 OK\r
|
56
|
-
Connection: close\r
|
57
|
-
Content-Encoding: deflate\r
|
58
|
-
\r
|
59
|
-
#{body}\r
|
60
|
-
HTTP
|
61
|
-
client.close_write
|
62
|
-
end
|
63
|
-
|
64
|
-
yield("http://localhost:#{server.local_address.ip_port}")
|
65
|
-
|
66
|
-
t.join
|
67
|
-
end
|
68
|
-
|
69
|
-
would 'accept deflate' do
|
70
|
-
accept(Zlib::Deflate.deflate(ok)) do |site|
|
71
|
-
c.post(site, 'body').should.eq ok
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
config_engine = lambda do |engine|
|
76
|
-
engine.transparent_gzip_decompression = false
|
77
|
-
engine.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
78
|
-
end
|
79
|
-
|
80
|
-
define_method(:define_default_config_engine) do |d|
|
81
|
-
d.singleton_class.module_eval do
|
82
|
-
define_method(:default_config_engine) do
|
83
|
-
config_engine
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
would 'disable auto-deflate' do
|
89
|
-
accept(ok) do |site|
|
90
|
-
c.post(site, 'body', {}, :config_engine => config_engine).
|
91
|
-
chomp.should.eq ok
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
would 'disable auto-deflate with class default_config_engine' do
|
96
|
-
accept(ok) do |site|
|
97
|
-
d = RC::Builder.client
|
98
|
-
define_default_config_engine(d)
|
99
|
-
d.new.post(site, 'body').chomp.should.eq ok
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
would 'disable auto-deflate with instance default_config_engine' do
|
104
|
-
accept(ok) do |site|
|
105
|
-
d = RC::Builder.client.new
|
106
|
-
define_default_config_engine(d)
|
107
|
-
d.post(site, 'body').chomp.should.eq ok
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
would 'disable auto-deflate with setting config_engine' do
|
112
|
-
accept(ok) do |site|
|
113
|
-
d = RC::Builder.client.new(:config_engine => config_engine)
|
114
|
-
d.post(site, 'body').chomp.should.eq ok
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
data/test/test_payload.rb
DELETED
@@ -1,204 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/test'
|
3
|
-
|
4
|
-
describe RC::Payload do
|
5
|
-
describe 'A regular Payload' do
|
6
|
-
would 'use standard enctype as default content-type' do
|
7
|
-
RC::Payload::UrlEncoded.new({}).headers['Content-Type'].
|
8
|
-
should.eq 'application/x-www-form-urlencoded'
|
9
|
-
end
|
10
|
-
|
11
|
-
would 'form properly encoded params' do
|
12
|
-
RC::Payload::UrlEncoded.new(:foo => 'bar').read.
|
13
|
-
should.eq 'foo=bar'
|
14
|
-
RC::Payload::UrlEncoded.new(:foo => 'bar', :baz => 'qux').read.
|
15
|
-
should.eq 'baz=qux&foo=bar'
|
16
|
-
end
|
17
|
-
|
18
|
-
would 'escape parameters' do
|
19
|
-
RC::Payload::UrlEncoded.new('foo ' => 'bar').read.
|
20
|
-
should.eq 'foo%20=bar'
|
21
|
-
end
|
22
|
-
|
23
|
-
would 'properly handle arrays as repeated parameters' do
|
24
|
-
RC::Payload::UrlEncoded.new(:foo => ['bar']).read.
|
25
|
-
should.eq 'foo=bar'
|
26
|
-
RC::Payload::UrlEncoded.new(:foo => ['bar', 'baz']).read.
|
27
|
-
should.eq 'foo=bar&foo=baz'
|
28
|
-
end
|
29
|
-
|
30
|
-
would 'not close if stream already closed' do
|
31
|
-
p = RC::Payload::UrlEncoded.new('foo ' => 'bar')
|
32
|
-
p.close
|
33
|
-
2.times{ p.close.should.eq nil }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe 'A multipart Payload' do
|
38
|
-
would 'use standard enctype as default content-type' do
|
39
|
-
p = RC::Payload::Multipart.new({})
|
40
|
-
stub(p).boundary{123}
|
41
|
-
p.headers['Content-Type'].should.eq 'multipart/form-data; boundary=123'
|
42
|
-
end
|
43
|
-
|
44
|
-
would 'not error on close if stream already closed' do
|
45
|
-
p = RC::Payload::Multipart.new(:file => File.open(__FILE__))
|
46
|
-
p.close
|
47
|
-
2.times{ p.close.should.eq nil }
|
48
|
-
end
|
49
|
-
|
50
|
-
would 'form properly separated multipart data' do
|
51
|
-
p = RC::Payload::Multipart.new(:bar => 'baz', :foo => 'bar')
|
52
|
-
p.read.should.eq <<-EOS
|
53
|
-
--#{p.boundary}\r
|
54
|
-
Content-Disposition: form-data; name="bar"\r
|
55
|
-
\r
|
56
|
-
baz\r
|
57
|
-
--#{p.boundary}\r
|
58
|
-
Content-Disposition: form-data; name="foo"\r
|
59
|
-
\r
|
60
|
-
bar\r
|
61
|
-
--#{p.boundary}--\r
|
62
|
-
EOS
|
63
|
-
end
|
64
|
-
|
65
|
-
would 'form multiple files with the same name' do
|
66
|
-
with_img do |f, n|
|
67
|
-
with_img do |ff, nn|
|
68
|
-
p = RC::Payload::Multipart.new(:foo => [f, ff])
|
69
|
-
p.read.should.eq <<-EOS
|
70
|
-
--#{p.boundary}\r
|
71
|
-
Content-Disposition: form-data; name="foo"; filename="#{n}"\r
|
72
|
-
Content-Type: image/jpeg\r
|
73
|
-
\r
|
74
|
-
#{'a'*10}\r
|
75
|
-
--#{p.boundary}\r
|
76
|
-
Content-Disposition: form-data; name="foo"; filename="#{nn}"\r
|
77
|
-
Content-Type: image/jpeg\r
|
78
|
-
\r
|
79
|
-
#{'a'*10}\r
|
80
|
-
--#{p.boundary}--\r
|
81
|
-
EOS
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
would 'not escape parameters names' do
|
87
|
-
p = RC::Payload::Multipart.new('bar ' => 'baz')
|
88
|
-
p.read.should.eq <<-EOS
|
89
|
-
--#{p.boundary}\r
|
90
|
-
Content-Disposition: form-data; name="bar "\r
|
91
|
-
\r
|
92
|
-
baz\r
|
93
|
-
--#{p.boundary}--\r
|
94
|
-
EOS
|
95
|
-
end
|
96
|
-
|
97
|
-
would 'form properly separated multipart data' do
|
98
|
-
with_img do |f, n|
|
99
|
-
p = RC::Payload::Multipart.new(:foo => f)
|
100
|
-
p.read.should.eq <<-EOS
|
101
|
-
--#{p.boundary}\r
|
102
|
-
Content-Disposition: form-data; name="foo"; filename="#{n}"\r
|
103
|
-
Content-Type: image/jpeg\r
|
104
|
-
\r
|
105
|
-
#{File.read(f.path)}\r
|
106
|
-
--#{p.boundary}--\r
|
107
|
-
EOS
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
would "ignore the name attribute when it's not set" do
|
112
|
-
with_img do |f, n|
|
113
|
-
p = RC::Payload::Multipart.new(nil => f)
|
114
|
-
p.read.should.eq <<-EOS
|
115
|
-
--#{p.boundary}\r
|
116
|
-
Content-Disposition: form-data; filename="#{n}"\r
|
117
|
-
Content-Type: image/jpeg\r
|
118
|
-
\r
|
119
|
-
#{File.read(f.path)}\r
|
120
|
-
--#{p.boundary}--\r
|
121
|
-
EOS
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
would 'detect optional (original) content type and filename' do
|
126
|
-
File.open(__FILE__) do |f|
|
127
|
-
def f.content_type ; 'image/jpeg'; end
|
128
|
-
def f.original_filename; 'foo.txt' ; end
|
129
|
-
p = RC::Payload::Multipart.new(:foo => f)
|
130
|
-
p.read.should.eq <<-EOS
|
131
|
-
--#{p.boundary}\r
|
132
|
-
Content-Disposition: form-data; name="foo"; filename="foo.txt"\r
|
133
|
-
Content-Type: image/jpeg\r
|
134
|
-
\r
|
135
|
-
#{File.read(f.path)}\r
|
136
|
-
--#{p.boundary}--\r
|
137
|
-
EOS
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
describe 'streamed payloads' do
|
143
|
-
would 'properly determine the size of file payloads' do
|
144
|
-
File.open(__FILE__) do |f|
|
145
|
-
p = RC::Payload.generate(f)
|
146
|
-
p.size.should.eq f.stat.size
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
would 'properly determine the size of other kinds of payloads' do
|
151
|
-
s = StringIO.new('foo')
|
152
|
-
p = RC::Payload.generate(s)
|
153
|
-
p.size.should.eq 3
|
154
|
-
|
155
|
-
begin
|
156
|
-
f = Tempfile.new('rest-core')
|
157
|
-
f.write('foo bar')
|
158
|
-
f.rewind
|
159
|
-
|
160
|
-
p = RC::Payload.generate(f)
|
161
|
-
p.size.should.eq 7
|
162
|
-
ensure
|
163
|
-
f.close!
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
describe 'Payload generation' do
|
169
|
-
would 'recognize standard urlencoded params' do
|
170
|
-
RC::Payload.generate('foo' => 'bar').should.
|
171
|
-
kind_of?(RC::Payload::UrlEncoded)
|
172
|
-
end
|
173
|
-
|
174
|
-
would 'recognize multipart params' do
|
175
|
-
File.open(__FILE__) do |f|
|
176
|
-
RC::Payload.generate('foo' => f).should.
|
177
|
-
kind_of?(RC::Payload::Multipart)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
would 'return data if none of the above' do
|
182
|
-
RC::Payload.generate('data').should.
|
183
|
-
kind_of?(RC::Payload::StreamedString)
|
184
|
-
end
|
185
|
-
|
186
|
-
would 'recognize nested multipart payloads in arrays' do
|
187
|
-
File.open(__FILE__) do |f|
|
188
|
-
RC::Payload.generate('foo' => [f]).should.
|
189
|
-
kind_of?(RC::Payload::Multipart)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
would 'recognize file payloads that can be streamed' do
|
194
|
-
File.open(__FILE__) do |f|
|
195
|
-
RC::Payload.generate(f).should.kind_of?(RC::Payload::Streamed)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
would 'recognize other payloads that can be streamed' do
|
200
|
-
RC::Payload.generate(StringIO.new('foo')).should.
|
201
|
-
kind_of?(RC::Payload::Streamed)
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|