restify 2.0.2 → 3.0.0.rc2
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/CHANGELOG.md +56 -0
- data/README.md +31 -5
- data/lib/restify/adapter/base.rb +11 -2
- data/lib/restify/adapter/ethon.rb +462 -0
- data/lib/restify/adapter/loop_lock.rb +124 -0
- data/lib/restify/adapter/telemetry.rb +6 -4
- data/lib/restify/adapter/typhoeus.rb +48 -23
- data/lib/restify/cache.rb +1 -1
- data/lib/restify/context.rb +5 -5
- data/lib/restify/error.rb +13 -0
- data/lib/restify/global.rb +9 -30
- data/lib/restify/logging.rb +10 -4
- data/lib/restify/processors/base/parsing.rb +13 -1
- data/lib/restify/promise.rb +20 -2
- data/lib/restify/registry.rb +2 -2
- data/lib/restify/relation.rb +9 -17
- data/lib/restify/request.rb +2 -2
- data/lib/restify/resource.rb +20 -2
- data/lib/restify/response.rb +41 -5
- data/lib/restify/timeout.rb +11 -5
- data/lib/restify/version.rb +3 -3
- data/lib/restify/webmock.rb +126 -0
- data/lib/restify.rb +5 -1
- data/spec/restify/adapter/base_spec.rb +33 -0
- data/spec/restify/adapter/ethon_spec.rb +263 -0
- data/spec/restify/adapter/loop_lock_spec.rb +144 -0
- data/spec/restify/adapter/telemetry_spec.rb +61 -0
- data/spec/restify/adapter/typhoeus_spec.rb +26 -0
- data/spec/restify/cache_spec.rb +1 -3
- data/spec/restify/context_spec.rb +57 -2
- data/spec/restify/features/opentelemetry_spec.rb +1 -1
- data/spec/restify/features/protocols_spec.rb +28 -0
- data/spec/restify/features/redirects_spec.rb +45 -0
- data/spec/restify/features/request_errors_spec.rb +1 -1
- data/spec/restify/features/response_bodies_spec.rb +45 -0
- data/spec/restify/features/response_encoding_spec.rb +82 -0
- data/spec/restify/features/response_errors_spec.rb +22 -1
- data/spec/restify/features/webmock_spec.rb +92 -1
- data/spec/restify/global_spec.rb +118 -1
- data/spec/restify/link_spec.rb +13 -3
- data/spec/restify/processors/json_spec.rb +36 -0
- data/spec/restify/processors/msgpack_spec.rb +36 -0
- data/spec/restify/promise_spec.rb +82 -0
- data/spec/restify/relation_spec.rb +22 -7
- data/spec/restify/request_spec.rb +26 -0
- data/spec/restify/resource_spec.rb +6 -0
- data/spec/restify/timeout_spec.rb +11 -0
- data/spec/restify_spec.rb +1 -1
- data/spec/spec_helper.rb +10 -7
- data/spec/support/stub_server.rb +4 -4
- metadata +27 -105
- data/vendor/bundle/ruby/3.4.0/bundler/gems/my-rubocop-3bcd2110ca87/LICENSE +0 -21
- data/vendor/bundle/ruby/3.4.0/bundler/gems/my-rubocop-3bcd2110ca87/README.md +0 -23
- data/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/CHANGELOG.md +0 -255
- data/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/MIT-LICENSE +0 -20
- data/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/README.rdoc +0 -40
- data/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/CHANGELOG.md +0 -301
- data/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/LICENSE.txt +0 -202
- data/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/README.md +0 -121
- data/vendor/bundle/ruby/3.4.0/gems/base64-0.2.0/LICENSE.txt +0 -22
- data/vendor/bundle/ruby/3.4.0/gems/base64-0.2.0/README.md +0 -48
- data/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.0/README.md +0 -138
- data/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.1.9/LICENSE +0 -56
- data/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/CHANGELOG.md +0 -603
- data/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/LICENSE.txt +0 -21
- data/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/README.md +0 -407
- data/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/LICENSE +0 -20
- data/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/README.md +0 -167
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.1/LICENSE.txt +0 -22
- data/vendor/bundle/ruby/3.4.0/gems/ethon-0.16.0/CHANGELOG.md +0 -375
- data/vendor/bundle/ruby/3.4.0/gems/ethon-0.16.0/LICENSE +0 -20
- data/vendor/bundle/ruby/3.4.0/gems/ethon-0.16.0/README.md +0 -118
- data/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.2-x86_64-linux-gnu/CHANGELOG.md +0 -473
- data/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.2-x86_64-linux-gnu/LICENSE +0 -24
- data/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.2-x86_64-linux-gnu/LICENSE.SPECS +0 -22
- data/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.2-x86_64-linux-gnu/README.md +0 -137
- data/vendor/bundle/ruby/3.4.0/gems/hitimes-3.1.0/LICENSE.txt +0 -16
- data/vendor/bundle/ruby/3.4.0/gems/hitimes-3.1.0/README.md +0 -187
- data/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/MIT-LICENSE +0 -20
- data/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/README.md +0 -127
- data/vendor/bundle/ruby/3.4.0/gems/little-plugger-1.1.4/README.rdoc +0 -53
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md +0 -104
- data/vendor/bundle/ruby/3.4.0/gems/logging-2.4.0/LICENSE +0 -22
- data/vendor/bundle/ruby/3.4.0/gems/logging-2.4.0/README.md +0 -140
- data/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/README.rdoc +0 -842
- data/vendor/bundle/ruby/3.4.0/gems/msgpack-1.8.0/ChangeLog +0 -368
- data/vendor/bundle/ruby/3.4.0/gems/msgpack-1.8.0/LICENSE +0 -177
- data/vendor/bundle/ruby/3.4.0/gems/msgpack-1.8.0/README.md +0 -302
- data/vendor/bundle/ruby/3.4.0/gems/multi_json-1.15.0/CHANGELOG.md +0 -275
- data/vendor/bundle/ruby/3.4.0/gems/multi_json-1.15.0/LICENSE.md +0 -20
- data/vendor/bundle/ruby/3.4.0/gems/multi_json-1.15.0/README.md +0 -121
- data/vendor/bundle/ruby/3.4.0/gems/opentelemetry-api-1.5.0/CHANGELOG.md +0 -193
- data/vendor/bundle/ruby/3.4.0/gems/opentelemetry-api-1.5.0/LICENSE +0 -201
- data/vendor/bundle/ruby/3.4.0/gems/opentelemetry-api-1.5.0/README.md +0 -68
- data/vendor/bundle/ruby/3.4.0/gems/opentelemetry-common-0.22.0/CHANGELOG.md +0 -98
- data/vendor/bundle/ruby/3.4.0/gems/opentelemetry-common-0.22.0/LICENSE +0 -201
- data/vendor/bundle/ruby/3.4.0/gems/opentelemetry-common-0.22.0/README.md +0 -62
- data/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/CHANGELOG.md +0 -498
- data/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/LICENSE.txt +0 -22
- data/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/README.md +0 -222
- data/vendor/bundle/ruby/3.4.0/gems/rack-3.1.15/CHANGELOG.md +0 -1146
- data/vendor/bundle/ruby/3.4.0/gems/rack-3.1.15/MIT-LICENSE +0 -20
- data/vendor/bundle/ruby/3.4.0/gems/rack-3.1.15/README.md +0 -355
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.2.1/MIT-LICENSE +0 -21
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.2.1/README.rdoc +0 -155
- data/vendor/bundle/ruby/3.4.0/gems/rake-release-1.3.0/LICENSE +0 -21
- data/vendor/bundle/ruby/3.4.0/gems/rake-release-1.3.0/README.md +0 -107
- data/vendor/bundle/ruby/3.4.0/gems/securerandom-0.4.1/README.md +0 -72
- data/vendor/bundle/ruby/3.4.0/gems/typhoeus-1.4.1/CHANGELOG.md +0 -410
- data/vendor/bundle/ruby/3.4.0/gems/typhoeus-1.4.1/LICENSE +0 -22
- data/vendor/bundle/ruby/3.4.0/gems/typhoeus-1.4.1/README.md +0 -588
- data/vendor/bundle/ruby/3.4.0/gems/tzinfo-2.0.6/LICENSE +0 -19
- data/vendor/bundle/ruby/3.4.0/gems/tzinfo-2.0.6/README.md +0 -406
- data/vendor/bundle/ruby/3.4.0/gems/uri-1.0.3/README.md +0 -55
data/spec/restify/global_spec.rb
CHANGED
|
@@ -21,7 +21,7 @@ describe Restify::Global do
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
context 'with registry symbol' do
|
|
24
|
-
subject(:restify) { global.new(
|
|
24
|
+
subject(:restify) { global.new(name, **options) }
|
|
25
25
|
|
|
26
26
|
let(:name) { :registry_item_name }
|
|
27
27
|
let(:uri) { 'http://api.github.com/' }
|
|
@@ -38,4 +38,121 @@ describe Restify::Global do
|
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
|
+
|
|
42
|
+
describe '#adapter' do
|
|
43
|
+
subject(:adapter) { global.adapter }
|
|
44
|
+
|
|
45
|
+
around do |example|
|
|
46
|
+
Restify.adapter.tap do |configured|
|
|
47
|
+
Restify.adapter = nil
|
|
48
|
+
example.run
|
|
49
|
+
ensure
|
|
50
|
+
Restify.adapter = configured
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'defaults to Ethon adapter' do
|
|
55
|
+
expect(adapter).to be_a Restify::Adapter::Ethon
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe '#adapter=' do
|
|
60
|
+
let(:stub) { Object.new }
|
|
61
|
+
|
|
62
|
+
# Ensure to restore the configured adapter after these specs!
|
|
63
|
+
around do |example|
|
|
64
|
+
Restify.adapter.tap do |configured|
|
|
65
|
+
Restify.adapter = nil
|
|
66
|
+
example.run
|
|
67
|
+
ensure
|
|
68
|
+
Restify.adapter = configured
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'sets a new adapter' do
|
|
73
|
+
global.adapter = stub
|
|
74
|
+
expect(global.adapter).to be stub
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe '#cache' do
|
|
79
|
+
subject(:cache) { global.cache }
|
|
80
|
+
|
|
81
|
+
it 'is not set by default' do
|
|
82
|
+
expect(cache).to be_nil
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe '#cache=' do
|
|
87
|
+
let(:stub) { Object.new }
|
|
88
|
+
|
|
89
|
+
# Ensure to reset cache after these specs!
|
|
90
|
+
after { Restify.cache = nil }
|
|
91
|
+
|
|
92
|
+
it 'sets a new cache' do
|
|
93
|
+
global.cache = stub
|
|
94
|
+
expect(global.cache).to be stub
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe '#logger' do
|
|
99
|
+
subject(:logger) { global.logger }
|
|
100
|
+
|
|
101
|
+
around do |example|
|
|
102
|
+
global.logger.tap do |configured|
|
|
103
|
+
global.logger = nil
|
|
104
|
+
example.run
|
|
105
|
+
ensure
|
|
106
|
+
global.logger = configured
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'is not set by default' do
|
|
111
|
+
expect(logger).to be_nil
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'does not log anything without a logger' do
|
|
115
|
+
loggable = Class.new { include Restify::Logging }.new
|
|
116
|
+
|
|
117
|
+
expect { loggable.debug('message') }.not_to output.to_stdout_from_any_process
|
|
118
|
+
expect { loggable.error(RuntimeError.new('kaboom')) }.not_to output.to_stderr_from_any_process
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
describe '#logger=' do
|
|
123
|
+
let(:configured) { Logger.new(nil) }
|
|
124
|
+
|
|
125
|
+
around do |example|
|
|
126
|
+
global.logger.tap do |previous|
|
|
127
|
+
example.run
|
|
128
|
+
ensure
|
|
129
|
+
global.logger = previous
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'sets the logger' do
|
|
134
|
+
global.logger = configured
|
|
135
|
+
|
|
136
|
+
expect(global.logger).to be configured
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'is used for messages from Restify' do
|
|
140
|
+
output = StringIO.new
|
|
141
|
+
global.logger = Logger.new(output, level: :debug)
|
|
142
|
+
|
|
143
|
+
Class.new { include Restify::Logging }.new.debug('message', key: 'value')
|
|
144
|
+
|
|
145
|
+
expect(output.string).to include 'message key=value'
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'is used for errors from Restify' do
|
|
149
|
+
output = StringIO.new
|
|
150
|
+
global.logger = Logger.new(output)
|
|
151
|
+
|
|
152
|
+
stub_const('Loggable', Class.new { include Restify::Logging })
|
|
153
|
+
Loggable.new.error(RuntimeError.new('kaboom'))
|
|
154
|
+
|
|
155
|
+
expect(output.string).to include 'ERROR -- Loggable: kaboom (RuntimeError)'
|
|
156
|
+
end
|
|
157
|
+
end
|
|
41
158
|
end
|
data/spec/restify/link_spec.rb
CHANGED
|
@@ -9,7 +9,7 @@ describe Restify::Link do
|
|
|
9
9
|
links = described_class
|
|
10
10
|
.parse('<http://example.org/search{?query}>; rel="search"')
|
|
11
11
|
|
|
12
|
-
expect(links).to
|
|
12
|
+
expect(links.size).to eq(1)
|
|
13
13
|
expect(links[0].uri).to eq 'http://example.org/search{?query}'
|
|
14
14
|
expect(links[0].metadata).to eq 'rel' => 'search'
|
|
15
15
|
end
|
|
@@ -18,7 +18,7 @@ describe Restify::Link do
|
|
|
18
18
|
links = described_class
|
|
19
19
|
.parse('<http://example.org/search{?query}>; rel=search')
|
|
20
20
|
|
|
21
|
-
expect(links).to
|
|
21
|
+
expect(links.size).to eq(1)
|
|
22
22
|
expect(links[0].uri).to eq 'http://example.org/search{?query}'
|
|
23
23
|
expect(links[0].metadata).to eq 'rel' => 'search'
|
|
24
24
|
end
|
|
@@ -27,7 +27,7 @@ describe Restify::Link do
|
|
|
27
27
|
links = described_class
|
|
28
28
|
.parse('<p://h.tld/p>; rel=abc, <p://h.tld/b>; a=b; c="d"')
|
|
29
29
|
|
|
30
|
-
expect(links).to
|
|
30
|
+
expect(links.size).to eq(2)
|
|
31
31
|
expect(links[0].uri).to eq 'p://h.tld/p'
|
|
32
32
|
expect(links[0].metadata).to eq 'rel' => 'abc'
|
|
33
33
|
expect(links[1].uri).to eq 'p://h.tld/b'
|
|
@@ -50,6 +50,16 @@ describe Restify::Link do
|
|
|
50
50
|
expect { described_class.parse('</>; rel="s", abc-invalid') }
|
|
51
51
|
.to raise_error ArgumentError, /Invalid token at \d+:/i
|
|
52
52
|
end
|
|
53
|
+
|
|
54
|
+
it 'errors on invalid param' do
|
|
55
|
+
expect { described_class.parse('<https://example.org>; rel') }
|
|
56
|
+
.to raise_error ArgumentError, /Invalid token at \d+:/i
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'errors on invalid param value' do
|
|
60
|
+
expect { described_class.parse('<https://example.org>; rel=') }
|
|
61
|
+
.to raise_error ArgumentError, /Invalid token at \d+:/i
|
|
62
|
+
end
|
|
53
63
|
end
|
|
54
64
|
end
|
|
55
65
|
end
|
|
@@ -31,6 +31,42 @@ describe Restify::Processors::Json do
|
|
|
31
31
|
|
|
32
32
|
before { allow(response).to receive(:body).and_return(body) }
|
|
33
33
|
|
|
34
|
+
describe 'empty body' do
|
|
35
|
+
let(:body) { '' }
|
|
36
|
+
|
|
37
|
+
it { is_expected.to be_a Restify::Resource }
|
|
38
|
+
it { expect(resource.data).to be_nil }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe 'invalid body' do
|
|
42
|
+
let(:body) { '{"json": ' }
|
|
43
|
+
|
|
44
|
+
before do
|
|
45
|
+
allow(response).to receive_messages(
|
|
46
|
+
uri: Addressable::URI.parse('http://test.host/'),
|
|
47
|
+
links: Restify::Link.parse('<http://test.host/other>; rel="other"'),
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it { is_expected.to be_a Restify::Resource }
|
|
52
|
+
it { is_expected.to have_relation :other }
|
|
53
|
+
it { expect(resource.response).to be response }
|
|
54
|
+
|
|
55
|
+
it 'raises on accessing data' do
|
|
56
|
+
expect { resource.data }.to raise_error(Restify::ParseError) do |error|
|
|
57
|
+
expect(error.response).to be response
|
|
58
|
+
expect(error.cause).to be_a JSON::ParserError
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'raises on accessing delegated data' do
|
|
63
|
+
expect { resource['json'] }.to raise_error Restify::ParseError
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it { is_expected.not_to respond_to :each }
|
|
67
|
+
it { expect(resource.inspect).to include '@error=' }
|
|
68
|
+
end
|
|
69
|
+
|
|
34
70
|
describe 'parsing' do
|
|
35
71
|
context 'single object' do
|
|
36
72
|
let(:body) do
|
|
@@ -41,6 +41,42 @@ describe Restify::Processors::Msgpack do
|
|
|
41
41
|
|
|
42
42
|
before { allow(response).to receive(:body).and_return(body) }
|
|
43
43
|
|
|
44
|
+
describe 'empty body' do
|
|
45
|
+
let(:body) { '' }
|
|
46
|
+
|
|
47
|
+
it { is_expected.to be_a Restify::Resource }
|
|
48
|
+
it { expect(resource.data).to be_nil }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe 'invalid body' do
|
|
52
|
+
let(:body) { "\xC1".b }
|
|
53
|
+
|
|
54
|
+
before do
|
|
55
|
+
allow(response).to receive_messages(
|
|
56
|
+
uri: Addressable::URI.parse('http://test.host/'),
|
|
57
|
+
links: Restify::Link.parse('<http://test.host/other>; rel="other"'),
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it { is_expected.to be_a Restify::Resource }
|
|
62
|
+
it { is_expected.to have_relation :other }
|
|
63
|
+
it { expect(resource.response).to be response }
|
|
64
|
+
|
|
65
|
+
it 'raises on accessing data' do
|
|
66
|
+
expect { resource.data }.to raise_error(Restify::ParseError) do |error|
|
|
67
|
+
expect(error.response).to be response
|
|
68
|
+
expect(error.cause).to be_a MessagePack::MalformedFormatError
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'raises on accessing delegated data' do
|
|
73
|
+
expect { resource['json'] }.to raise_error Restify::ParseError
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it { is_expected.not_to respond_to :each }
|
|
77
|
+
it { expect(resource.inspect).to include '@error=' }
|
|
78
|
+
end
|
|
79
|
+
|
|
44
80
|
describe 'parsing' do
|
|
45
81
|
context 'single object' do
|
|
46
82
|
let(:body) do
|
|
@@ -81,6 +81,43 @@ describe Restify::Promise do
|
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
+
context 'when resolving the promise from a block' do
|
|
85
|
+
subject(:promise) do
|
|
86
|
+
described_class.create do |writer|
|
|
87
|
+
writer.set { block.call }
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'with a returned value' do
|
|
92
|
+
let(:block) { -> { 42 } }
|
|
93
|
+
|
|
94
|
+
it 'fulfills the promise with it' do
|
|
95
|
+
expect(promise.fulfilled?).to be true
|
|
96
|
+
expect(promise.value!).to eq 42
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context 'with a raised exception' do
|
|
101
|
+
let(:block) { -> { raise ArgumentError.new('nope') } }
|
|
102
|
+
|
|
103
|
+
it 'rejects the promise with it' do
|
|
104
|
+
expect(promise.rejected?).to be true
|
|
105
|
+
expect { promise.value! }.to raise_error ArgumentError, 'nope'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Handlers can run from e.g. a libcurl callback, from where no
|
|
110
|
+
# exception must ever escape, not even a non-StandardError.
|
|
111
|
+
context 'with a raised non-StandardError' do
|
|
112
|
+
let(:block) { -> { raise NotImplementedError.new('nope') } }
|
|
113
|
+
|
|
114
|
+
it 'rejects the promise with it' do
|
|
115
|
+
expect(promise.rejected?).to be true
|
|
116
|
+
expect { promise.value! }.to raise_error NotImplementedError, 'nope'
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
84
121
|
context 'when fulfilling the promise asynchronously' do
|
|
85
122
|
subject(:promise) do
|
|
86
123
|
described_class.create do |writer|
|
|
@@ -180,6 +217,51 @@ describe Restify::Promise do
|
|
|
180
217
|
it 'can time out' do
|
|
181
218
|
expect { promise.wait(0.1) }.to raise_error Timeout::Error
|
|
182
219
|
end
|
|
220
|
+
|
|
221
|
+
context 'with a driver' do
|
|
222
|
+
subject(:promise) { described_class.create(driver:) {|w| writers << w } }
|
|
223
|
+
|
|
224
|
+
let(:driver) { instance_double(Restify::Adapter::Ethon) }
|
|
225
|
+
let(:writers) { [] }
|
|
226
|
+
let(:writer) { writers.first }
|
|
227
|
+
|
|
228
|
+
before { promise }
|
|
229
|
+
|
|
230
|
+
it 'lets the driver complete the promise in the waiting thread' do
|
|
231
|
+
expect(driver).to receive(:drive).once do |p, timeout|
|
|
232
|
+
expect(p).to be promise
|
|
233
|
+
expect(timeout).to be_a Restify::Timeout
|
|
234
|
+
writer.fulfill 42
|
|
235
|
+
true
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
expect(promise.value!).to eq 42
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it 'waits as usual when the driver declines' do
|
|
242
|
+
allow(driver).to receive(:drive).and_return(false)
|
|
243
|
+
|
|
244
|
+
Thread.new do
|
|
245
|
+
sleep 0.05
|
|
246
|
+
writer.fulfill 42
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
expect(promise.value!).to eq 42
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it 'times out when the driver returns without completing it' do
|
|
253
|
+
allow(driver).to receive(:drive).and_return(true)
|
|
254
|
+
|
|
255
|
+
expect { promise.wait(0.1) }.to raise_error Timeout::Error
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it 'does not call the driver for a complete promise' do
|
|
259
|
+
expect(driver).not_to receive(:drive)
|
|
260
|
+
writer.fulfill 42
|
|
261
|
+
|
|
262
|
+
expect(promise.value!).to eq 42
|
|
263
|
+
end
|
|
264
|
+
end
|
|
183
265
|
end
|
|
184
266
|
|
|
185
267
|
describe '#value' do
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'spec_helper'
|
|
4
|
-
require 'active_support'
|
|
5
4
|
|
|
6
5
|
describe Restify::Relation do
|
|
7
6
|
subject(:relation) { described_class.new context, pattern }
|
|
@@ -47,6 +46,16 @@ describe Restify::Relation do
|
|
|
47
46
|
it { expect(expanded.to_s).to eq 'http://test.host/resource/true' }
|
|
48
47
|
end
|
|
49
48
|
|
|
49
|
+
context 'with Object' do
|
|
50
|
+
# Without #to_param, e.g. from ActiveSupport
|
|
51
|
+
let(:object) { Class.new.new }
|
|
52
|
+
let(:params) { {id: object} }
|
|
53
|
+
|
|
54
|
+
it 'raise a TypeError from adressable' do
|
|
55
|
+
expect { expanded }.to raise_error(TypeError, /Can't convert #<Class:0x.*> into String or Array/)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
50
59
|
context 'with #to_param object' do
|
|
51
60
|
let(:params) { {id: cls_to_param.new} }
|
|
52
61
|
|
|
@@ -213,15 +222,15 @@ describe Restify::Relation do
|
|
|
213
222
|
end
|
|
214
223
|
|
|
215
224
|
describe '#get' do
|
|
216
|
-
|
|
225
|
+
it_behaves_like 'non-data-request', :get
|
|
217
226
|
end
|
|
218
227
|
|
|
219
228
|
describe '#head' do
|
|
220
|
-
|
|
229
|
+
it_behaves_like 'non-data-request', :head
|
|
221
230
|
end
|
|
222
231
|
|
|
223
232
|
describe '#delete' do
|
|
224
|
-
|
|
233
|
+
it_behaves_like 'non-data-request', :delete
|
|
225
234
|
end
|
|
226
235
|
|
|
227
236
|
shared_examples 'data-request' do |method|
|
|
@@ -274,14 +283,20 @@ describe Restify::Relation do
|
|
|
274
283
|
end
|
|
275
284
|
|
|
276
285
|
describe '#post' do
|
|
277
|
-
|
|
286
|
+
it_behaves_like 'data-request', :post
|
|
278
287
|
end
|
|
279
288
|
|
|
280
289
|
describe '#put' do
|
|
281
|
-
|
|
290
|
+
it_behaves_like 'data-request', :put
|
|
282
291
|
end
|
|
283
292
|
|
|
284
293
|
describe '#patch' do
|
|
285
|
-
|
|
294
|
+
it_behaves_like 'data-request', :patch
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
describe '#to_s' do
|
|
298
|
+
subject(:string) { relation.to_s }
|
|
299
|
+
|
|
300
|
+
it { is_expected.to eq '/resource/{id}{?q*}' }
|
|
286
301
|
end
|
|
287
302
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Restify::Request do
|
|
6
|
+
subject(:request) { described_class.new(uri:) }
|
|
7
|
+
|
|
8
|
+
describe '#uri' do
|
|
9
|
+
context 'with a string' do
|
|
10
|
+
let(:uri) { 'https://example.org:8443/resources?page=2' }
|
|
11
|
+
|
|
12
|
+
it 'parses it' do
|
|
13
|
+
expect(request.uri).to be_a Addressable::URI
|
|
14
|
+
expect(request.uri.to_s).to eq uri
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'with an Addressable::URI' do
|
|
19
|
+
let(:uri) { Addressable::URI.parse('https://example.org/resources') }
|
|
20
|
+
|
|
21
|
+
it 'keeps it as is' do
|
|
22
|
+
expect(request.uri).to be uri
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -21,6 +21,17 @@ describe Restify::Timeout do
|
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
describe '#remaining' do
|
|
25
|
+
it 'returns the seconds left' do
|
|
26
|
+
expect(timer.remaining).to be_within(0.05).of(0.2)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'is not positive after having timed out' do
|
|
30
|
+
sleep timer.remaining
|
|
31
|
+
expect(timer.remaining).not_to be_positive
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
24
35
|
describe '#wait_on!' do
|
|
25
36
|
it 'calls block on IVar timeout' do
|
|
26
37
|
expect do
|
data/spec/restify_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'logger'
|
|
3
4
|
require 'rspec'
|
|
4
|
-
require 'rspec/collection_matchers'
|
|
5
5
|
|
|
6
6
|
require 'simplecov'
|
|
7
7
|
require 'simplecov-cobertura'
|
|
8
8
|
|
|
9
9
|
SimpleCov.start do
|
|
10
|
-
|
|
10
|
+
skip %r{\Aspec/}i
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
SimpleCov.formatters = [
|
|
@@ -19,6 +19,9 @@ require 'restify'
|
|
|
19
19
|
|
|
20
20
|
if ENV['ADAPTER']
|
|
21
21
|
case ENV['ADAPTER'].to_s.downcase
|
|
22
|
+
when 'ethon'
|
|
23
|
+
require 'restify/adapter/ethon'
|
|
24
|
+
Restify.adapter = Restify::Adapter::Ethon.new
|
|
22
25
|
when 'typhoeus'
|
|
23
26
|
require 'restify/adapter/typhoeus'
|
|
24
27
|
Restify.adapter = Restify::Adapter::Typhoeus.new
|
|
@@ -33,6 +36,8 @@ end
|
|
|
33
36
|
require_relative 'support/opentelemetry'
|
|
34
37
|
require_relative 'support/stub_server'
|
|
35
38
|
|
|
39
|
+
require 'restify/webmock'
|
|
40
|
+
|
|
36
41
|
RSpec.configure do |config|
|
|
37
42
|
config.order = 'random'
|
|
38
43
|
|
|
@@ -47,11 +52,9 @@ RSpec.configure do |config|
|
|
|
47
52
|
skip 'Spec not enabled for current adapter'
|
|
48
53
|
end
|
|
49
54
|
|
|
50
|
-
config.before do
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Logging.logger.root.level = :debug
|
|
54
|
-
Logging.logger.root.add_appenders Logging.appenders.stdout
|
|
55
|
+
config.before(:suite) do
|
|
56
|
+
Restify.logger = Logger.new($stdout, level: ENV.fetch('LOG_LEVEL', 'debug'))
|
|
57
|
+
Ethon.logger = Restify.logger
|
|
55
58
|
end
|
|
56
59
|
|
|
57
60
|
config.warnings = true
|
data/spec/support/stub_server.rb
CHANGED
|
@@ -65,8 +65,8 @@ module Stub
|
|
|
65
65
|
|
|
66
66
|
class Exception < ::StandardError; end
|
|
67
67
|
|
|
68
|
-
# Inject into base adapter to have HTTP 599 (missing stub) error
|
|
69
|
-
# extra exception, not just a server error.
|
|
68
|
+
# Inject into base adapter to have HTTP 599 (missing stub) error
|
|
69
|
+
# raised as an extra exception, not just a server error.
|
|
70
70
|
module Patch
|
|
71
71
|
def call(request)
|
|
72
72
|
super.then do |response|
|
|
@@ -98,8 +98,8 @@ RSpec.configure do |config|
|
|
|
98
98
|
config.before(:suite) do
|
|
99
99
|
Stub.start_server!
|
|
100
100
|
|
|
101
|
-
# Net::HTTP adapter must be enabled, otherwise webmock fails to
|
|
102
|
-
# responses from raw strings.
|
|
101
|
+
# Net::HTTP adapter must be enabled, otherwise webmock fails to
|
|
102
|
+
# create mock responses from raw strings.
|
|
103
103
|
WebMock.disable!(except: %i[net_http])
|
|
104
104
|
end
|
|
105
105
|
|