restify 1.15.2 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -2
  3. data/README.md +23 -31
  4. data/doc/file.README.html +192 -0
  5. data/lib/restify/adapter/base.rb +4 -0
  6. data/lib/restify/adapter/telemetry.rb +54 -0
  7. data/lib/restify/adapter/typhoeus.rb +37 -4
  8. data/lib/restify/context.rb +3 -3
  9. data/lib/restify/error.rb +2 -2
  10. data/lib/restify/link.rb +4 -4
  11. data/lib/restify/processors/base/parsing.rb +2 -21
  12. data/lib/restify/processors/base.rb +1 -1
  13. data/lib/restify/promise.rb +2 -2
  14. data/lib/restify/registry.rb +1 -1
  15. data/lib/restify/relation.rb +45 -17
  16. data/lib/restify/request.rb +6 -6
  17. data/lib/restify/timeout.rb +2 -2
  18. data/lib/restify/version.rb +3 -3
  19. data/lib/restify.rb +0 -1
  20. data/spec/restify/cache_spec.rb +16 -12
  21. data/spec/restify/context_spec.rb +8 -3
  22. data/spec/restify/error_spec.rb +13 -16
  23. data/spec/restify/features/head_requests_spec.rb +5 -4
  24. data/spec/restify/features/opentelemetry_spec.rb +46 -0
  25. data/spec/restify/features/request_bodies_spec.rb +8 -8
  26. data/spec/restify/features/request_errors_spec.rb +2 -2
  27. data/spec/restify/features/request_headers_spec.rb +3 -6
  28. data/spec/restify/features/response_errors_spec.rb +1 -1
  29. data/spec/restify/features/webmock_spec.rb +27 -0
  30. data/spec/restify/global_spec.rb +10 -10
  31. data/spec/restify/processors/base_spec.rb +6 -7
  32. data/spec/restify/processors/json_spec.rb +21 -62
  33. data/spec/restify/processors/msgpack_spec.rb +33 -70
  34. data/spec/restify/promise_spec.rb +31 -31
  35. data/spec/restify/registry_spec.rb +5 -7
  36. data/spec/restify/relation_spec.rb +185 -7
  37. data/spec/restify/resource_spec.rb +47 -53
  38. data/spec/restify/timeout_spec.rb +3 -3
  39. data/spec/restify_spec.rb +12 -73
  40. data/spec/spec_helper.rb +12 -15
  41. data/spec/support/opentelemetry.rb +29 -0
  42. data/spec/support/stub_server.rb +4 -0
  43. metadata +37 -64
  44. data/lib/restify/adapter/em.rb +0 -134
  45. data/lib/restify/adapter/pooled_em.rb +0 -269
@@ -1,21 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
+ require 'active_support'
4
5
 
5
6
  describe Restify::Relation do
6
7
  subject(:relation) { described_class.new context, pattern }
7
8
 
8
9
  let(:context) { Restify::Context.new('http://test.host/') }
9
- let(:pattern) { '/resource/{id}' }
10
+ let(:pattern) { '/resource/{id}{?q*}' }
10
11
 
11
12
  describe '#==' do
12
13
  it 'equals pattern' do
13
- expect(subject).to eq pattern
14
+ expect(relation).to eq pattern
14
15
  end
15
16
  end
16
17
 
17
18
  describe '#expand' do
18
- subject(:expaned) { relation.expand params }
19
+ subject(:expanded) { relation.expand params }
19
20
 
20
21
  let(:params) { {id: 1337} }
21
22
  let(:cls_to_param) do
@@ -28,29 +29,206 @@ describe Restify::Relation do
28
29
 
29
30
  it { is_expected.to be_a Addressable::URI }
30
31
 
32
+ context 'with nil' do
33
+ let(:params) { {id: nil} }
34
+
35
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/' }
36
+ end
37
+
38
+ context 'with false' do
39
+ let(:params) { {id: false} }
40
+
41
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/' }
42
+ end
43
+
44
+ context 'with true' do
45
+ let(:params) { {id: true} }
46
+
47
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/true' }
48
+ end
49
+
31
50
  context 'with #to_param object' do
32
51
  let(:params) { {id: cls_to_param.new} }
33
52
 
34
- it { expect(expaned.to_s).to eq 'http://test.host/resource/42' }
53
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/42' }
54
+ end
55
+
56
+ context 'with array parameter' do
57
+ let(:params) { {id: [1, 2]} }
58
+
59
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/1,2' }
35
60
  end
36
61
 
37
62
  context 'with unknown additional query parameter' do
38
63
  let(:pattern) { '/resource{?a,b}' }
39
64
  let(:params) { {a: 1, b: 2, c: 3} }
40
65
 
41
- it { expect(expaned.to_s).to eq 'http://test.host/resource?a=1&b=2&c=3' }
66
+ it { expect(expanded.to_s).to eq 'http://test.host/resource?a=1&b=2&c=3' }
42
67
  end
43
68
 
44
69
  context 'with additional parameters' do
45
70
  let(:params) { {id: '5', abc: 'cde'} }
46
71
 
47
- it { expect(expaned.to_s).to eq 'http://test.host/resource/5?abc=cde' }
72
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/5?abc=cde' }
73
+ end
74
+
75
+ context 'with additional nil parameters' do
76
+ let(:params) { {id: '5', abc: nil} }
77
+
78
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/5?abc' }
79
+ end
80
+
81
+ context 'with additional false parameters' do
82
+ let(:params) { {id: '5', abc: false} }
83
+
84
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/5?abc=false' }
85
+ end
86
+
87
+ context 'with additional true parameters' do
88
+ let(:params) { {id: '5', abc: true} }
89
+
90
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/5?abc=true' }
48
91
  end
49
92
 
50
93
  context 'with additional #to_param parameter' do
51
94
  let(:params) { {id: '5', abc: cls_to_param.new} }
52
95
 
53
- it { expect(expaned.to_s).to eq 'http://test.host/resource/5?abc=42' }
96
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/5?abc=42' }
97
+ end
98
+
99
+ context 'with additional array parameter' do
100
+ let(:params) { {id: 5, abc: [1, 2]} }
101
+
102
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/5?abc=1&abc=2' }
54
103
  end
104
+
105
+ context 'with additional array parameter with objects' do
106
+ let(:params) { {id: 5, abc: [1, 2, cls_to_param.new]} }
107
+
108
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/5?abc=1&abc=2&abc=42' }
109
+ end
110
+
111
+ context 'with additional nested array parameter' do
112
+ let(:params) { {id: 5, abc: [1, 2, [1]]} }
113
+
114
+ it { expect { expanded }.to raise_exception TypeError, /Can't convert Array into String./ }
115
+ end
116
+
117
+ context 'with additional hash parameter' do
118
+ let(:params) { {id: 5, abc: {a: 1, b: 2}} }
119
+
120
+ it { expect { expanded }.to raise_exception TypeError, /Can't convert Hash into String./ }
121
+ end
122
+ end
123
+
124
+ shared_examples 'non-data-request' do |method|
125
+ it "issues a #{method.upcase} request" do
126
+ expect(context).to receive(:request) do |meth, uri, opts|
127
+ expect(meth).to eq method
128
+ expect(uri.to_s).to eq 'http://test.host/resource/'
129
+ expect(opts).to be_nil
130
+ end
131
+ relation.send(method)
132
+ end
133
+
134
+ it 'accepts params as keyword argument' do
135
+ expect(context).to receive(:request) do |meth, uri, opts|
136
+ expect(meth).to eq method
137
+ expect(uri.to_s).to eq 'http://test.host/resource/1'
138
+ expect(opts).to be_nil
139
+ end
140
+ relation.send(method, params: {id: 1})
141
+ end
142
+
143
+ it 'accepts params as positional argument' do
144
+ expect(context).to receive(:request) do |meth, uri, opts|
145
+ expect(meth).to eq method
146
+ expect(uri.to_s).to eq 'http://test.host/resource/1'
147
+ expect(opts).to be_nil
148
+ end
149
+ relation.send(method, {id: 1})
150
+ end
151
+
152
+ it 'merges keyword params into positional params' do
153
+ expect(context).to receive(:request) do |meth, uri, opts|
154
+ expect(meth).to eq method
155
+ expect(uri.to_s).to eq 'http://test.host/resource/1?a=2&b=3'
156
+ expect(opts).to be_nil
157
+ end
158
+ relation.send(method, {id: 1, q: {a: 1, c: 1}}, params: {q: {a: 2, b: 3}})
159
+ end
160
+ end
161
+
162
+ describe '#get' do
163
+ include_examples 'non-data-request', :get
164
+ end
165
+
166
+ describe '#head' do
167
+ include_examples 'non-data-request', :head
168
+ end
169
+
170
+ describe '#delete' do
171
+ include_examples 'non-data-request', :delete
172
+ end
173
+
174
+ shared_examples 'data-request' do |method|
175
+ let(:data) { Object.new }
176
+
177
+ it "issues a #{method.upcase} request" do
178
+ expect(context).to receive(:request) do |meth, uri, opts|
179
+ expect(meth).to eq method
180
+ expect(uri.to_s).to eq 'http://test.host/resource/'
181
+ expect(opts).to eq({data: nil})
182
+ end
183
+ relation.send(method)
184
+ end
185
+
186
+ it 'accepts params as keyword argument' do
187
+ expect(context).to receive(:request) do |meth, uri, opts|
188
+ expect(meth).to eq method
189
+ expect(uri.to_s).to eq 'http://test.host/resource/1'
190
+ expect(opts).to eq({data: nil})
191
+ end
192
+ relation.send(method, params: {id: 1})
193
+ end
194
+
195
+ it 'accepts data as keyword argument' do
196
+ expect(context).to receive(:request) do |meth, uri, opts|
197
+ expect(meth).to eq method
198
+ expect(uri.to_s).to eq 'http://test.host/resource/1'
199
+ expect(opts).to eq({data:})
200
+ end
201
+ relation.send(method, data:, params: {id: 1})
202
+ end
203
+
204
+ it 'accepts data as position argument' do
205
+ expect(context).to receive(:request) do |meth, uri, opts|
206
+ expect(meth).to eq method
207
+ expect(uri.to_s).to eq 'http://test.host/resource/1'
208
+ expect(opts).to eq({data:})
209
+ end
210
+ relation.send(method, data, params: {id: 1})
211
+ end
212
+
213
+ it 'prefers data from keyword argument' do
214
+ expect(context).to receive(:request) do |meth, uri, opts|
215
+ expect(meth).to eq method
216
+ expect(uri.to_s).to eq 'http://test.host/resource/1'
217
+ expect(opts).to eq({data:})
218
+ end
219
+ relation.send(method, 'DATA', data:, params: {id: 1})
220
+ end
221
+ end
222
+
223
+ describe '#post' do
224
+ include_examples 'data-request', :post
225
+ end
226
+
227
+ describe '#put' do
228
+ include_examples 'data-request', :put
229
+ end
230
+
231
+ describe '#patch' do
232
+ include_examples 'data-request', :patch
55
233
  end
56
234
  end
@@ -3,18 +3,12 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Restify::Resource do
6
- subject { resource }
6
+ subject(:resource) { described_class.new(context, response:, data:, relations:) }
7
7
 
8
8
  let(:data) { {} }
9
9
  let(:relations) { {} }
10
- let(:context) { double 'context' }
11
- let(:response) { double 'response' }
12
- let(:resource) { described_class.new(context, response: response, data: data, relations: relations) }
13
-
14
- before do
15
- allow(context).to receive(:relation?).and_return(false)
16
- allow(context).to receive(:relation).and_raise(KeyError)
17
- end
10
+ let(:context) { instance_double(Restify::Context) }
11
+ let(:response) { instance_double(Restify::Response) }
18
12
 
19
13
  context 'relations' do
20
14
  let(:relations) do
@@ -26,41 +20,41 @@ describe Restify::Resource do
26
20
 
27
21
  describe '#relation?' do
28
22
  it 'matches relations' do
29
- expect(subject.relation?(:users)).to eq true
30
- expect(subject.relation?('users')).to eq true
31
- expect(subject.relation?(:projects)).to eq true
32
- expect(subject.relation?('projects')).to eq true
33
- expect(subject.relation?('fuu')).to eq false
34
-
35
- expect(subject).to have_relation :users
36
- expect(subject).to have_relation :projects
37
-
38
- expect(subject.rel?(:users)).to eq true
39
- expect(subject.rel?('users')).to eq true
40
- expect(subject.rel?(:projects)).to eq true
41
- expect(subject.rel?('projects')).to eq true
42
- expect(subject.rel?('fuu')).to eq false
43
-
44
- expect(subject).to have_rel :users
45
- expect(subject).to have_rel :projects
23
+ expect(resource.relation?(:users)).to be true
24
+ expect(resource.relation?('users')).to be true
25
+ expect(resource.relation?(:projects)).to be true
26
+ expect(resource.relation?('projects')).to be true
27
+ expect(resource.relation?('fuu')).to be false
28
+
29
+ expect(resource).to have_relation :users
30
+ expect(resource).to have_relation :projects
31
+
32
+ expect(resource.rel?(:users)).to be true
33
+ expect(resource.rel?('users')).to be true
34
+ expect(resource.rel?(:projects)).to be true
35
+ expect(resource.rel?('projects')).to be true
36
+ expect(resource.rel?('fuu')).to be false
37
+
38
+ expect(resource).to have_rel :users
39
+ expect(resource).to have_rel :projects
46
40
  end
47
41
  end
48
42
 
49
43
  describe '#relation' do
50
44
  it 'returns relation' do
51
- expect(subject.rel(:users)).to be_a Restify::Relation
52
-
53
- expect(subject.rel(:users)).to eq 'http://example.org/users'
54
- expect(subject.rel('users')).to eq 'http://example.org/users'
55
- expect(subject.rel(:projects)).to eq 'http://example.org/projects'
56
- expect(subject.rel('projects')).to eq 'http://example.org/projects'
57
- expect { subject.rel(:fuu) }.to raise_error KeyError
58
-
59
- expect(subject.relation(:users)).to eq 'http://example.org/users'
60
- expect(subject.relation('users')).to eq 'http://example.org/users'
61
- expect(subject.relation(:projects)).to eq 'http://example.org/projects'
62
- expect(subject.relation('projects')).to eq 'http://example.org/projects'
63
- expect { subject.relation(:fuu) }.to raise_error KeyError
45
+ expect(resource.rel(:users)).to be_a Restify::Relation
46
+
47
+ expect(resource.rel(:users)).to eq 'http://example.org/users'
48
+ expect(resource.rel('users')).to eq 'http://example.org/users'
49
+ expect(resource.rel(:projects)).to eq 'http://example.org/projects'
50
+ expect(resource.rel('projects')).to eq 'http://example.org/projects'
51
+ expect { resource.rel(:fuu) }.to raise_error KeyError
52
+
53
+ expect(resource.relation(:users)).to eq 'http://example.org/users'
54
+ expect(resource.relation('users')).to eq 'http://example.org/users'
55
+ expect(resource.relation(:projects)).to eq 'http://example.org/projects'
56
+ expect(resource.relation('projects')).to eq 'http://example.org/projects'
57
+ expect { resource.relation(:fuu) }.to raise_error KeyError
64
58
  end
65
59
  end
66
60
 
@@ -68,15 +62,15 @@ describe Restify::Resource do
68
62
  let(:relations) { {_restify_follow: 'http://localhost/10'} }
69
63
 
70
64
  it 'returns follow relation' do
71
- expect(subject.follow).to be_a Restify::Relation
72
- expect(subject.follow).to eq 'http://localhost/10'
65
+ expect(resource.follow).to be_a Restify::Relation
66
+ expect(resource.follow).to eq 'http://localhost/10'
73
67
  end
74
68
 
75
69
  context 'when nil' do
76
70
  let(:relations) { {} }
77
71
 
78
72
  it 'returns nil' do
79
- expect(subject.follow).to be nil
73
+ expect(resource.follow).to be_nil
80
74
  end
81
75
  end
82
76
  end
@@ -85,15 +79,15 @@ describe Restify::Resource do
85
79
  let(:relations) { {_restify_follow: 'http://localhost/10'} }
86
80
 
87
81
  it 'returns follow relation' do
88
- expect(subject.follow!).to be_a Restify::Relation
89
- expect(subject.follow!).to eq 'http://localhost/10'
82
+ expect(resource.follow!).to be_a Restify::Relation
83
+ expect(resource.follow!).to eq 'http://localhost/10'
90
84
  end
91
85
 
92
86
  context 'when nil' do
93
87
  let(:relations) { {} }
94
88
 
95
89
  it 'raise runtime error' do
96
- expect { subject.follow! }.to raise_error RuntimeError do |err|
90
+ expect { resource.follow! }.to raise_error RuntimeError do |err|
97
91
  expect(err.message).to eq 'Nothing to follow'
98
92
  end
99
93
  end
@@ -102,25 +96,25 @@ describe Restify::Resource do
102
96
  end
103
97
 
104
98
  context 'data' do
105
- let(:data) { double 'data' }
99
+ let(:data) { double 'data' } # rubocop:disable RSpec/VerifiedDoubles
106
100
 
107
101
  it 'delegates methods (I)' do
108
- expect(data).to receive(:some_method).and_return(42)
102
+ allow(data).to receive(:some_method).and_return(42)
109
103
 
110
- expect(subject).to respond_to :some_method
111
- expect(subject.some_method).to eq 42
104
+ expect(resource).to respond_to :some_method
105
+ expect(resource.some_method).to eq 42
112
106
  end
113
107
 
114
108
  it 'delegates methods (II)' do
115
- expect(data).to receive(:[]).with(1).and_return(2)
109
+ allow(data).to receive(:[]).with(1).and_return(2)
116
110
 
117
- expect(subject).to respond_to :[]
118
- expect(subject[1]).to eq 2
111
+ expect(resource).to respond_to :[]
112
+ expect(resource[1]).to eq 2
119
113
  end
120
114
 
121
115
  describe '#data' do
122
116
  it 'returns data' do
123
- expect(subject.data).to equal data
117
+ expect(resource.data).to equal data
124
118
  end
125
119
  end
126
120
  end
@@ -16,7 +16,7 @@ describe Restify::Timeout do
16
16
  it 'calls given block' do
17
17
  expect { timer.timeout! }.not_to raise_error
18
18
  sleep timer.send(:wait_interval)
19
- expect { timer.timeout! }.to raise_error ::Restify::Timeout::Error
19
+ expect { timer.timeout! }.to raise_error Restify::Timeout::Error
20
20
  end
21
21
  end
22
22
  end
@@ -25,13 +25,13 @@ describe Restify::Timeout do
25
25
  it 'calls block on IVar timeout' do
26
26
  expect do
27
27
  timer.wait_on!(Concurrent::IVar.new)
28
- end.to raise_error ::Restify::Timeout::Error
28
+ end.to raise_error Restify::Timeout::Error
29
29
  end
30
30
 
31
31
  it 'calls block on Promise timeout' do
32
32
  expect do
33
33
  timer.wait_on!(Restify::Promise.new)
34
- end.to raise_error ::Restify::Timeout::Error
34
+ end.to raise_error Restify::Timeout::Error
35
35
  end
36
36
 
37
37
  it 'does nothing on successful IVar' do
data/spec/restify_spec.rb CHANGED
@@ -132,21 +132,21 @@ describe Restify do
132
132
  # Because we forgot to send a "name" the server complains
133
133
  # with an error code that will lead to a raised error.
134
134
 
135
- expect(e.status).to eq :unprocessable_entity
135
+ expect(e.status).to eq :unprocessable_content
136
136
  expect(e.code).to eq 422
137
137
  expect(e.errors).to eq 'name' => ["can't be blank"]
138
138
  end
139
139
 
140
140
  # Let's try again.
141
- created_user = users_relation.post(name: 'John Smith').value!
141
+ created_user = users_relation.post({name: 'John Smith'}).value!
142
142
 
143
143
  # The server returns a 201 Created response with the created
144
144
  # resource.
145
145
  expect(created_user.response.status).to eq :created
146
146
  expect(created_user.response.code).to eq 201
147
147
 
148
- expect(created_user).to have_key :name
149
- expect(created_user.name).to eq 'John Smith'
148
+ expect(created_user).to have_key 'name'
149
+ expect(created_user['name']).to eq 'John Smith'
150
150
 
151
151
  # Let's follow the "Location" header.
152
152
  followed_resource = created_user.follow.get.value!
@@ -154,8 +154,8 @@ describe Restify do
154
154
  expect(followed_resource.response.status).to eq :ok
155
155
  expect(followed_resource.response.code).to eq 200
156
156
 
157
- expect(followed_resource).to have_key :name
158
- expect(followed_resource.name).to eq 'John Smith'
157
+ expect(followed_resource).to have_key 'name'
158
+ expect(followed_resource['name']).to eq 'John Smith'
159
159
 
160
160
  # Now we will fetch a list of all users.
161
161
  users = users_relation.get.value!
@@ -168,80 +168,19 @@ describe Restify do
168
168
 
169
169
  # We have all our attributes and relations here as defined in the
170
170
  # responses from the server.
171
- expect(user).to have_key :name
172
- expect(user[:name]).to eq 'John Smith'
171
+ expect(user).to have_key 'name'
172
+ expect(user['name']).to eq 'John Smith'
173
173
  expect(user).to have_relation :self
174
174
  expect(user).to have_relation :blurb
175
175
 
176
176
  # Let's get the blurb.
177
177
  blurb = user.rel(:blurb).get.value!
178
178
 
179
- expect(blurb).to have_key :title
180
- expect(blurb).to have_key :image
179
+ expect(blurb).to have_key 'title'
180
+ expect(blurb).to have_key 'image'
181
181
 
182
- expect(blurb[:title]).to eq 'Prof. Dr. John Smith'
183
- expect(blurb[:image]).to eq 'http://example.org/avatar.png'
184
- end
185
- end
186
-
187
- context 'within EM-synchrony' do
188
- it 'consumes the API' do
189
- skip 'Seems to be impossible to detect EM scheduled fibers from within'
190
-
191
- EM.synchrony do
192
- root = Restify.new('http://localhost:9292/base').get.value!
193
-
194
- users_relation = root.rel(:users)
195
-
196
- expect(users_relation).to be_a Restify::Relation
197
-
198
- create_user_promise = users_relation.post
199
- expect(create_user_promise).to be_a Restify::Promise
200
-
201
- expect { create_user_promise.value! }.to \
202
- raise_error(Restify::ClientError) do |e|
203
- expect(e.status).to eq :unprocessable_entity
204
- expect(e.code).to eq 422
205
- expect(e.errors).to eq 'name' => ["can't be blank"]
206
- end
207
-
208
- created_user = users_relation.post(name: 'John Smith').value!
209
-
210
- expect(created_user.response.status).to eq :created
211
- expect(created_user.response.code).to eq 201
212
-
213
- expect(created_user).to have_key :name
214
- expect(created_user.name).to eq 'John Smith'
215
-
216
- followed_resource = created_user.follow.get.value!
217
-
218
- expect(followed_resource.response.status).to eq :ok
219
- expect(followed_resource.response.code).to eq 200
220
-
221
- expect(followed_resource).to have_key :name
222
- expect(followed_resource.name).to eq 'John Smith'
223
-
224
- users = users_relation.get.value!
225
-
226
- expect(users).to have(2).items
227
-
228
- user = users.first
229
-
230
- expect(user).to have_key :name
231
- expect(user[:name]).to eq 'John Smith'
232
- expect(user).to have_relation :self
233
- expect(user).to have_relation :blurb
234
-
235
- blurb = user.rel(:blurb).get.value!
236
-
237
- expect(blurb).to have_key :title
238
- expect(blurb).to have_key :image
239
-
240
- expect(blurb[:title]).to eq 'Prof. Dr. John Smith'
241
- expect(blurb[:image]).to eq 'http://example.org/avatar.png'
242
-
243
- EventMachine.stop
244
- end
182
+ expect(blurb['title']).to eq 'Prof. Dr. John Smith'
183
+ expect(blurb['image']).to eq 'http://example.org/avatar.png'
245
184
  end
246
185
  end
247
186
  end
data/spec/spec_helper.rb CHANGED
@@ -4,25 +4,21 @@ require 'rspec'
4
4
  require 'rspec/collection_matchers'
5
5
 
6
6
  require 'simplecov'
7
+ require 'simplecov-cobertura'
8
+
7
9
  SimpleCov.start do
8
10
  add_filter 'spec'
9
11
  end
10
12
 
11
- if ENV['CI']
12
- require 'codecov'
13
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
14
- end
13
+ SimpleCov.formatters = [
14
+ SimpleCov::Formatter::HTMLFormatter,
15
+ SimpleCov::Formatter::CoberturaFormatter,
16
+ ]
15
17
 
16
18
  require 'restify'
17
19
 
18
20
  if ENV['ADAPTER']
19
21
  case ENV['ADAPTER'].to_s.downcase
20
- when 'em'
21
- require 'restify/adapter/em'
22
- Restify.adapter = Restify::Adapter::EM.new
23
- when 'em-pooled'
24
- require 'restify/adapter/pooled_em'
25
- Restify.adapter = Restify::Adapter::PooledEM.new
26
22
  when 'typhoeus'
27
23
  require 'restify/adapter/typhoeus'
28
24
  Restify.adapter = Restify::Adapter::Typhoeus.new
@@ -34,27 +30,28 @@ if ENV['ADAPTER']
34
30
  end
35
31
  end
36
32
 
33
+ require_relative 'support/opentelemetry'
37
34
  require_relative 'support/stub_server'
38
35
 
39
36
  RSpec.configure do |config|
40
37
  config.order = 'random'
41
38
 
42
39
  config.before(:suite) do
43
- ::Restify::Timeout.default_timeout = 1.0
40
+ Restify::Timeout.default_timeout = 1.0
44
41
  end
45
42
 
46
43
  config.before do |example|
47
44
  next unless (adapter = example.metadata[:adapter])
48
- next if Restify.adapter.is_a?(adapter)
45
+ next if Restify.adapter.class.ancestors.map(&:to_s).include?(adapter)
49
46
 
50
47
  skip 'Spec not enabled for current adapter'
51
48
  end
52
49
 
53
50
  config.before do
54
- Ethon.logger = ::Logging.logger[Ethon] if defined?(Ethon)
51
+ Ethon.logger = Logging.logger[Ethon] if defined?(Ethon)
55
52
 
56
- ::Logging.logger.root.level = :debug
57
- ::Logging.logger.root.add_appenders ::Logging.appenders.stdout
53
+ Logging.logger.root.level = :debug
54
+ Logging.logger.root.add_appenders Logging.appenders.stdout
58
55
  end
59
56
 
60
57
  config.warnings = true
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'opentelemetry/sdk'
4
+ require 'opentelemetry/instrumentation/ethon'
5
+
6
+ OTLE_EXPORTER = OpenTelemetry::SDK::Trace::Export::InMemorySpanExporter.new
7
+ span_processor = OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(OTLE_EXPORTER)
8
+
9
+ OpenTelemetry::SDK.configure do |c|
10
+ c.error_handler = ->(exception:, message:) { raise(exception || message) }
11
+ c.logger = Logger.new($stderr, level: ENV.fetch('OTEL_LOG_LEVEL', 'fatal').to_sym)
12
+ c.add_span_processor span_processor
13
+
14
+ c.use 'OpenTelemetry::Instrumentation::Ethon'
15
+ end
16
+
17
+ RSpec.configure do |config|
18
+ config.around do |example|
19
+ OTLE_EXPORTER.reset
20
+
21
+ original_propagation = OpenTelemetry.propagation
22
+ propagator = OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator
23
+ OpenTelemetry.propagation = propagator
24
+
25
+ example.run
26
+ ensure
27
+ OpenTelemetry.propagation = original_propagation
28
+ end
29
+ end
@@ -18,6 +18,10 @@ module Stub
18
18
  # If no stub is found a special HTTP 599 error code will be returned.
19
19
  class Handler
20
20
  def call(env)
21
+ if env['REQUEST_URI'] == '/echo'
22
+ return [200, {'content-type': 'application/json'}, [env.to_json]]
23
+ end
24
+
21
25
  signature = WebMock::RequestSignature.new(
22
26
  env['REQUEST_METHOD'].downcase,
23
27
  "http://stubserver#{env['REQUEST_URI']}",