rest-core 2.1.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.travis.yml +3 -5
  4. data/CHANGES.md +65 -5
  5. data/Gemfile +10 -5
  6. data/NOTE.md +1 -1
  7. data/README.md +194 -128
  8. data/Rakefile +8 -34
  9. data/TODO.md +3 -2
  10. data/example/simple.rb +6 -4
  11. data/example/use-cases.rb +39 -122
  12. data/lib/rest-core.rb +14 -5
  13. data/lib/rest-core/builder.rb +12 -2
  14. data/lib/rest-core/client.rb +31 -25
  15. data/lib/rest-core/engine.rb +39 -0
  16. data/lib/rest-core/engine/http-client.rb +41 -0
  17. data/lib/rest-core/engine/net-http-persistent.rb +21 -0
  18. data/lib/rest-core/engine/rest-client.rb +13 -42
  19. data/lib/rest-core/event_source.rb +91 -0
  20. data/lib/rest-core/middleware.rb +17 -11
  21. data/lib/rest-core/middleware/error_detector.rb +1 -6
  22. data/lib/rest-core/middleware/oauth1_header.rb +1 -0
  23. data/lib/rest-core/middleware/oauth2_header.rb +20 -8
  24. data/lib/rest-core/middleware/oauth2_query.rb +1 -0
  25. data/lib/rest-core/middleware/timeout.rb +5 -19
  26. data/lib/rest-core/promise.rb +137 -0
  27. data/lib/rest-core/test.rb +2 -43
  28. data/lib/rest-core/thread_pool.rb +122 -0
  29. data/lib/rest-core/timer.rb +30 -0
  30. data/lib/rest-core/util/hmac.rb +0 -8
  31. data/lib/rest-core/version.rb +1 -1
  32. data/lib/rest-core/wrapper.rb +1 -1
  33. data/rest-core.gemspec +36 -25
  34. data/task/README.md +54 -0
  35. data/task/gemgem.rb +150 -156
  36. data/test/test_builder.rb +2 -2
  37. data/test/test_cache.rb +8 -8
  38. data/test/test_client.rb +16 -6
  39. data/test/test_client_oauth1.rb +1 -1
  40. data/test/test_event_source.rb +77 -0
  41. data/test/test_follow_redirect.rb +1 -1
  42. data/test/test_future.rb +16 -0
  43. data/test/test_oauth2_header.rb +28 -0
  44. data/test/test_promise.rb +89 -0
  45. data/test/test_rest-client.rb +21 -0
  46. data/test/test_thread_pool.rb +10 -0
  47. data/test/test_timeout.rb +13 -8
  48. metadata +61 -37
  49. data/example/multi.rb +0 -44
  50. data/lib/rest-core/engine/auto.rb +0 -25
  51. data/lib/rest-core/engine/em-http-request.rb +0 -90
  52. data/lib/rest-core/engine/future/future.rb +0 -107
  53. data/lib/rest-core/engine/future/future_fiber.rb +0 -32
  54. data/lib/rest-core/engine/future/future_thread.rb +0 -29
  55. data/lib/rest-core/middleware/timeout/timer_em.rb +0 -26
  56. data/lib/rest-core/middleware/timeout/timer_thread.rb +0 -36
  57. data/task/.gitignore +0 -1
  58. data/test/test_em-http-request.rb +0 -186
@@ -4,23 +4,27 @@ require 'rest-core/test'
4
4
  describe RC::Simple do
5
5
  after do
6
6
  WebMock.reset!
7
- RR.verify
7
+ Muack.verify
8
8
  end
9
9
 
10
10
  should 'do simple request' do
11
+ c = RC::Simple.new
11
12
  url = 'http://localhost/'
12
- [:get, :post, :delete, :put, :patch, :options].each do |method|
13
+ [:get, :post, :delete, :put, :patch].each do |method|
13
14
  stub_request(method, url).to_return(:body => '[]')
14
- RC::Simple.new.send(method, url).should.eq '[]'
15
+ c.send(method, url).should.eq '[]'
15
16
  end
16
17
 
17
- stub_request(:head, url).to_return(:headers => {'A' => 'B'})
18
- RC::Simple.new.head(url).should.eq({'A' => 'B'})
18
+ stub_request(:head , url).to_return(:headers => {'A' => 'B'})
19
+ c. head(url).should.eq('A' => 'B')
20
+
21
+ stub_request(:options, url).to_return(:headers => {'A' => 'B'})
22
+ c.options(url).should.eq('A' => 'B')
19
23
  end
20
24
 
21
25
  should 'call the callback' do
22
26
  url = 'http://localhost/'
23
- [:get, :post, :delete, :put, :patch, :options].each do |method|
27
+ [:get, :post, :delete, :put, :patch].each do |method|
24
28
  stub_request(method, url).to_return(:body => '123')
25
29
  (client = RC::Simple.new).send(method, url){ |res|
26
30
  res.should.eq '123' }.should.eq client
@@ -32,6 +36,12 @@ describe RC::Simple do
32
36
  res.should.eq({'A' => 'B'})
33
37
  }.should.eq client
34
38
  client.wait
39
+
40
+ stub_request(:options, url).to_return(:headers => {'A' => 'B'})
41
+ (client = RC::Simple.new).options(url){ |res|
42
+ res.should.eq('A' => 'B')
43
+ }.should.eq client
44
+ client.wait
35
45
  end
36
46
 
37
47
  should 'have correct to_i' do
@@ -4,7 +4,7 @@ require 'rest-core/test'
4
4
  describe RC::ClientOauth1 do
5
5
  after do
6
6
  WebMock.reset!
7
- RR.verify
7
+ Muack.verify
8
8
  end
9
9
 
10
10
  client = RC::Builder.client do
@@ -0,0 +1,77 @@
1
+
2
+ require 'socket'
3
+ require 'rest-core/test'
4
+
5
+ describe RC::EventSource do
6
+ client = RC::Builder.client.new
7
+ server = lambda do |close=true|
8
+ serv = TCPServer.new(0)
9
+ port = serv.addr[1]
10
+ path = "http://localhost:#{port}/"
11
+ payload = <<-SSE
12
+ event: put
13
+ data: {}
14
+
15
+ event: keep-alive
16
+ data: null
17
+ SSE
18
+ m = [{'event' => 'put' , 'data' => '{}'},
19
+ {'event' => 'keep-alive', 'data' => 'null'}]
20
+
21
+ t = Thread.new do
22
+ sock = serv.accept
23
+ sock.readline("\r\n\r\n")
24
+ sock.puts("HTTP/1.1 200 OK\r")
25
+ sock.puts("Content-Type: text/event-stream\r")
26
+ sock.puts
27
+ sock.puts(payload)
28
+ sock.close if close
29
+ end
30
+
31
+ [client.event_source(path, :a => 'b'), m, t]
32
+ end
33
+
34
+ should 'work regularly' do
35
+ es, m, t = server.call
36
+ flag = 0
37
+
38
+ es.onopen do |sock|
39
+ sock.should.kind_of IO
40
+ flag.should.eq 0
41
+ flag += 1
42
+ end
43
+
44
+ es.onmessage do |event, sock|
45
+ event.should.eq(m.shift)
46
+ sock.should.kind_of IO
47
+ sock.should.not.closed?
48
+ flag += 1
49
+ end
50
+
51
+ es.onerror do |error, sock|
52
+ error.should.kind_of EOFError
53
+ m.should.eq []
54
+ sock.should.closed?
55
+ flag.should.eq 3
56
+ flag += 1
57
+ end
58
+
59
+ es.start
60
+ es.wait
61
+ flag.should.eq 4
62
+ t.join
63
+ end
64
+
65
+ should 'close' do
66
+ es, _, t = server.call(false)
67
+ flag = 0
68
+ es.onmessage do
69
+ es.close
70
+ flag += 1
71
+ end
72
+ es.start
73
+ es.wait
74
+ flag.should.eq 1
75
+ t.join
76
+ end
77
+ end
@@ -12,7 +12,7 @@ describe RC::FollowRedirect do
12
12
  app = RC::FollowRedirect.new(dry, 1)
13
13
 
14
14
  after do
15
- RR.verify
15
+ Muack.verify
16
16
  end
17
17
 
18
18
  [301, 302, 303, 307].each do |status|
@@ -0,0 +1,16 @@
1
+
2
+ require 'stringio'
3
+ require 'rest-core/test'
4
+
5
+ describe RC::Promise::Future do
6
+ should '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
@@ -0,0 +1,28 @@
1
+
2
+ require 'rest-core/test'
3
+
4
+ describe RC::Oauth2Header do
5
+ env = {RC::REQUEST_HEADERS => {}}
6
+ auth = RC::Oauth2Header.new(RC::Dry.new)
7
+
8
+ should 'do nothing if no access token' do
9
+ auth.call(env){ |res| res.should.eq(env) }
10
+ end
11
+
12
+ should 'Bearer token' do
13
+ auth.call(env.merge('access_token_type' => 'Bearer',
14
+ 'access_token' => 'token')){ |res|
15
+ res[RC::REQUEST_HEADERS].should.eq 'Authorization' => 'Bearer token'
16
+ }
17
+ end
18
+
19
+ should 'MAC token' do # http://tools.ietf.org/html/rfc6749#section-7.1
20
+ auth.call(env.merge('access_token_type' => 'MAC',
21
+ 'access_token' =>
22
+ {'id' => 'h480djs93hd8',
23
+ 'mac' => 'kDZvddkndxv='})){ |res|
24
+ res[RC::REQUEST_HEADERS].should.eq \
25
+ 'Authorization' => 'MAC id="h480djs93hd8", mac="kDZvddkndxv="'
26
+ }
27
+ end
28
+ end
@@ -0,0 +1,89 @@
1
+
2
+ require 'rest-core/test'
3
+
4
+ describe RC::Promise do
5
+ def new_promise
6
+ RC::Promise.new(RC::CLIENT => @client.new)
7
+ end
8
+
9
+ before do
10
+ @client = RC::Builder.client
11
+ @promise = new_promise
12
+ end
13
+
14
+ after do
15
+ @client.thread_pool.shutdown
16
+ Muack.verify
17
+ end
18
+
19
+ should 'work, reject, yield' do
20
+ @client.pool_size = 1
21
+ flag = 0
22
+ @promise.defer do
23
+ flag.should.eq 0
24
+ flag += 1
25
+ @promise.reject(nil)
26
+ end
27
+ @promise.yield
28
+ flag.should.eq 1
29
+ @promise.send(:error).should.kind_of RC::Error
30
+ end
31
+
32
+ should 'work, fulfill, yield' do
33
+ @client.pool_size = 2
34
+ flag = 0
35
+ @promise.defer do
36
+ flag.should.eq 0
37
+ flag += 1
38
+ @promise.fulfill('body', 1, {'K' => 'V'})
39
+ end
40
+ @promise.yield
41
+ flag.should.eq 1
42
+ @promise.send(:body) .should.eq 'body'
43
+ @promise.send(:status) .should.eq 1
44
+ @promise.send(:headers).should.eq('K' => 'V')
45
+ end
46
+
47
+ should 'call inline if pool_size < 0' do
48
+ @client.pool_size = -1
49
+ current_thread = Thread.current
50
+ @promise.defer do
51
+ Thread.current.should.eq current_thread
52
+ end
53
+ end
54
+
55
+ should 'call in a new thread if pool_size == 0' do
56
+ @client.pool_size = 0
57
+ thread = nil
58
+ mock(Thread).new.with_any_args.peek_return do |t|
59
+ thread = t
60
+ end
61
+ @promise.defer do
62
+ Thread.current.should.eq thread
63
+ @promise.reject(nil)
64
+ end
65
+ @promise.yield
66
+ end
67
+
68
+ should 'call in thread pool if pool_size > 0' do
69
+ @client.pool_size = 1
70
+ flag = 0
71
+ rd, wr = IO.pipe
72
+ @promise.defer do
73
+ rd.gets
74
+ flag.should.eq 0
75
+ flag += 1
76
+ @promise.reject(nil)
77
+ end
78
+ p1 = new_promise
79
+ p1.defer do # block until promise #0 is done because pool_size == 1
80
+ flag.should.eq 1
81
+ flag += 1
82
+ p1.reject(nil)
83
+ end
84
+ wr.puts # start promise #0
85
+ @promise.yield
86
+ p1.yield # block until promise #1 is done
87
+ flag.should.eq 2
88
+ end
89
+ end
@@ -36,5 +36,26 @@ describe RC::RestClient do
36
36
  wr.close
37
37
  post[rd, 'socket']
38
38
  end
39
+
40
+ should 'not kill the thread if error was coming from the task' do
41
+ mock(RestClient::Request).execute{ raise 'boom' }.with_any_args
42
+ c.request({}, RC::FAIL).first.message.should.eq 'boom'
43
+ Muack.verify
44
+ end
45
+
46
+ should 'cancel the task if timing out' do
47
+ timer = Object.new.instance_eval do
48
+ def on_timeout; yield ; end
49
+ def error ; 'boom'; end
50
+ def cancel ; ; end
51
+ self
52
+ end
53
+ stub(c.class).pool_size{ 1 }
54
+ stub(c.class.thread_pool).queue{ [] } # don't queue the task
55
+ mock(RC::ThreadPool::Task).new.with_any_args.
56
+ peek_return{ |t| mock(t).cancel; t } # the task should be cancelled
57
+ c.request({RC::TIMER => timer}, RC::FAIL).first.message.should.eq 'boom'
58
+ Muack.verify
59
+ end
39
60
  end
40
61
  end
@@ -0,0 +1,10 @@
1
+
2
+ require 'rest-core/test'
3
+
4
+ describe RC::ThreadPool do
5
+ should 'have the same pool for the same client' do
6
+ client = RC::Builder.client
7
+ pool = RC::ThreadPool[client]
8
+ RC::ThreadPool[client].object_id.should.eq pool.object_id
9
+ end
10
+ end
@@ -2,23 +2,28 @@
2
2
  require 'rest-core/test'
3
3
 
4
4
  describe RC::Timeout do
5
- before do
6
- @app = RC::Timeout.new(RC::Dry.new, 0)
7
- end
5
+ app = RC::Timeout.new(RC::Dry.new, 0)
8
6
 
9
7
  after do
10
8
  WebMock.reset!
11
- RR.verify
9
+ Muack.verify
12
10
  end
13
11
 
14
12
  should 'bypass timeout if timeout is 0' do
15
- mock(@app).monitor.times(0)
16
- @app.call({}){ |e| e.should.eq({}) }
13
+ mock(app).monitor.times(0)
14
+ app.call({}){ |e| e.should.eq({}) }
17
15
  end
18
16
 
19
17
  should 'run the monitor to setup timeout' do
20
18
  env = {'timeout' => 2}
21
- mock.proxy(@app).monitor(env).times(1)
22
- @app.call(env){|e| e[RC::TIMER].should.kind_of?(RC::Timeout::TimerThread)}
19
+ mock(app).monitor(env)
20
+ app.call(env){|e| e[RC::TIMER].should.kind_of?(RC::Timer)}
21
+ end
22
+
23
+ should "not raise timeout error if there's already an error" do
24
+ env = {'timeout' => 0.01}
25
+ mock(app.app).call(hash_including(env)){ raise "error" }
26
+ lambda{ app.call(env){} }.should .raise(RuntimeError)
27
+ lambda{ sleep 0.01 }.should.not.raise(Timeout::Error)
23
28
  end
24
29
  end
metadata CHANGED
@@ -1,28 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Cardinal Blue
8
7
  - Lin Jen-Shin (godfat)
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-31 00:00:00.000000000 Z
11
+ date: 2014-05-04 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: rest-client
14
+ name: httpclient
16
15
  requirement: !ruby/object:Gem::Requirement
17
16
  requirements:
18
- - - '>='
17
+ - - ">="
19
18
  - !ruby/object:Gem::Version
20
19
  version: '0'
21
20
  type: :runtime
22
21
  prerelease: false
23
22
  version_requirements: !ruby/object:Gem::Requirement
24
23
  requirements:
25
- - - '>='
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mime-types
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: timers
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
26
53
  - !ruby/object:Gem::Version
27
54
  version: '0'
28
55
  description: |-
@@ -35,16 +62,16 @@ description: |-
35
62
  common APIs such as Facebook, Github, and Twitter, you can simply use the
36
63
  dedicated clients provided by [rest-more][].
37
64
 
38
- [rest-more]: https://github.com/cardinalblue/rest-more
65
+ [rest-more]: https://github.com/godfat/rest-more
39
66
  email:
40
- - dev (XD) cardinalblue.com
67
+ - godfat (XD) godfat.org
41
68
  executables: []
42
69
  extensions: []
43
70
  extra_rdoc_files: []
44
71
  files:
45
- - .gitignore
46
- - .gitmodules
47
- - .travis.yml
72
+ - ".gitignore"
73
+ - ".gitmodules"
74
+ - ".travis.yml"
48
75
  - CHANGES.md
49
76
  - Gemfile
50
77
  - LICENSE
@@ -52,7 +79,6 @@ files:
52
79
  - README.md
53
80
  - Rakefile
54
81
  - TODO.md
55
- - example/multi.rb
56
82
  - example/simple.rb
57
83
  - example/use-cases.rb
58
84
  - lib/rest-core.rb
@@ -61,15 +87,14 @@ files:
61
87
  - lib/rest-core/client/simple.rb
62
88
  - lib/rest-core/client/universal.rb
63
89
  - lib/rest-core/client_oauth1.rb
64
- - lib/rest-core/engine/auto.rb
90
+ - lib/rest-core/engine.rb
65
91
  - lib/rest-core/engine/dry.rb
66
- - lib/rest-core/engine/em-http-request.rb
67
- - lib/rest-core/engine/future/future.rb
68
- - lib/rest-core/engine/future/future_fiber.rb
69
- - lib/rest-core/engine/future/future_thread.rb
92
+ - lib/rest-core/engine/http-client.rb
93
+ - lib/rest-core/engine/net-http-persistent.rb
70
94
  - lib/rest-core/engine/rest-client.rb
71
95
  - lib/rest-core/error.rb
72
96
  - lib/rest-core/event.rb
97
+ - lib/rest-core/event_source.rb
73
98
  - lib/rest-core/middleware.rb
74
99
  - lib/rest-core/middleware/auth_basic.rb
75
100
  - lib/rest-core/middleware/bypass.rb
@@ -90,11 +115,12 @@ files:
90
115
  - lib/rest-core/middleware/oauth2_header.rb
91
116
  - lib/rest-core/middleware/oauth2_query.rb
92
117
  - lib/rest-core/middleware/timeout.rb
93
- - lib/rest-core/middleware/timeout/timer_em.rb
94
- - lib/rest-core/middleware/timeout/timer_thread.rb
95
118
  - lib/rest-core/patch/multi_json.rb
96
119
  - lib/rest-core/patch/rest-client.rb
120
+ - lib/rest-core/promise.rb
97
121
  - lib/rest-core/test.rb
122
+ - lib/rest-core/thread_pool.rb
123
+ - lib/rest-core/timer.rb
98
124
  - lib/rest-core/util/hmac.rb
99
125
  - lib/rest-core/util/json.rb
100
126
  - lib/rest-core/util/parse_query.rb
@@ -102,7 +128,7 @@ files:
102
128
  - lib/rest-core/version.rb
103
129
  - lib/rest-core/wrapper.rb
104
130
  - rest-core.gemspec
105
- - task/.gitignore
131
+ - task/README.md
106
132
  - task/gemgem.rb
107
133
  - test/test_auth_basic.rb
108
134
  - test/test_builder.rb
@@ -111,51 +137,45 @@ files:
111
137
  - test/test_client_oauth1.rb
112
138
  - test/test_default_payload.rb
113
139
  - test/test_default_query.rb
114
- - test/test_em-http-request.rb
115
140
  - test/test_error_detector.rb
116
141
  - test/test_error_detector_http.rb
117
142
  - test/test_error_handler.rb
143
+ - test/test_event_source.rb
118
144
  - test/test_follow_redirect.rb
145
+ - test/test_future.rb
119
146
  - test/test_json_request.rb
120
147
  - test/test_json_response.rb
121
148
  - test/test_oauth1_header.rb
149
+ - test/test_oauth2_header.rb
122
150
  - test/test_payload.rb
151
+ - test/test_promise.rb
123
152
  - test/test_rest-client.rb
124
153
  - test/test_simple.rb
154
+ - test/test_thread_pool.rb
125
155
  - test/test_timeout.rb
126
156
  - test/test_universal.rb
127
157
  - test/test_wrapper.rb
128
- homepage: https://github.com/cardinalblue/rest-core
158
+ homepage: https://github.com/godfat/rest-core
129
159
  licenses:
130
160
  - Apache License 2.0
131
161
  metadata: {}
132
- post_install_message: |
133
- # [rest-core] Since 2.1.0, Incompatible changes for POST requests:
134
-
135
- * We no longer support Rails-like POST payload, like translating
136
- `{:foo => [1, 2]}` to `'foo[]=1&foo[]=2'`. It would now be translated to
137
- `'foo=1&foo=2'`. If you like `'foo[]'` as the key, simply pass it as
138
- `{'foo[]' => [1, 2]}`.
139
-
140
- * This also applies to nested hashes like `{:foo => {:bar => 1}`. If you
141
- want that behaviour, just pass `{'foo[bar]' => 1}` which would then be
142
- translated to `'foo[bar]=1'`.
162
+ post_install_message:
143
163
  rdoc_options: []
144
164
  require_paths:
145
165
  - lib
146
166
  required_ruby_version: !ruby/object:Gem::Requirement
147
167
  requirements:
148
- - - '>='
168
+ - - ">="
149
169
  - !ruby/object:Gem::Version
150
170
  version: '0'
151
171
  required_rubygems_version: !ruby/object:Gem::Requirement
152
172
  requirements:
153
- - - '>='
173
+ - - ">="
154
174
  - !ruby/object:Gem::Version
155
175
  version: '0'
156
176
  requirements: []
157
177
  rubyforge_project:
158
- rubygems_version: 2.0.3
178
+ rubygems_version: 2.2.2
159
179
  signing_key:
160
180
  specification_version: 4
161
181
  summary: Modular Ruby clients interface for REST APIs.
@@ -167,17 +187,21 @@ test_files:
167
187
  - test/test_client_oauth1.rb
168
188
  - test/test_default_payload.rb
169
189
  - test/test_default_query.rb
170
- - test/test_em-http-request.rb
171
190
  - test/test_error_detector.rb
172
191
  - test/test_error_detector_http.rb
173
192
  - test/test_error_handler.rb
193
+ - test/test_event_source.rb
174
194
  - test/test_follow_redirect.rb
195
+ - test/test_future.rb
175
196
  - test/test_json_request.rb
176
197
  - test/test_json_response.rb
177
198
  - test/test_oauth1_header.rb
199
+ - test/test_oauth2_header.rb
178
200
  - test/test_payload.rb
201
+ - test/test_promise.rb
179
202
  - test/test_rest-client.rb
180
203
  - test/test_simple.rb
204
+ - test/test_thread_pool.rb
181
205
  - test/test_timeout.rb
182
206
  - test/test_universal.rb
183
207
  - test/test_wrapper.rb