restify 1.15.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +102 -15
  3. data/README.md +23 -31
  4. data/lib/restify/adapter/base.rb +4 -0
  5. data/lib/restify/adapter/telemetry.rb +54 -0
  6. data/lib/restify/adapter/typhoeus.rb +24 -14
  7. data/lib/restify/context.rb +7 -11
  8. data/lib/restify/error.rb +2 -2
  9. data/lib/restify/global.rb +1 -0
  10. data/lib/restify/link.rb +4 -4
  11. data/lib/restify/logging.rb +1 -1
  12. data/lib/restify/processors/base/parsing.rb +5 -24
  13. data/lib/restify/processors/base.rb +1 -1
  14. data/lib/restify/promise.rb +2 -2
  15. data/lib/restify/registry.rb +1 -1
  16. data/lib/restify/relation.rb +45 -17
  17. data/lib/restify/request.rb +6 -6
  18. data/lib/restify/resource.rb +1 -1
  19. data/lib/restify/response.rb +0 -2
  20. data/lib/restify/timeout.rb +2 -2
  21. data/lib/restify/version.rb +4 -4
  22. data/lib/restify.rb +0 -1
  23. data/spec/restify/cache_spec.rb +16 -12
  24. data/spec/restify/context_spec.rb +15 -7
  25. data/spec/restify/error_spec.rb +23 -16
  26. data/spec/restify/features/head_requests_spec.rb +7 -5
  27. data/spec/restify/features/request_bodies_spec.rb +14 -13
  28. data/spec/restify/features/request_errors_spec.rb +2 -2
  29. data/spec/restify/features/request_headers_spec.rb +11 -14
  30. data/spec/restify/features/response_errors_spec.rb +2 -2
  31. data/spec/restify/global_spec.rb +13 -13
  32. data/spec/restify/link_spec.rb +9 -9
  33. data/spec/restify/processors/base_spec.rb +7 -7
  34. data/spec/restify/processors/json_spec.rb +22 -62
  35. data/spec/restify/processors/msgpack_spec.rb +40 -76
  36. data/spec/restify/promise_spec.rb +38 -34
  37. data/spec/restify/registry_spec.rb +6 -8
  38. data/spec/restify/relation_spec.rb +196 -17
  39. data/spec/restify/resource_spec.rb +55 -60
  40. data/spec/restify/timeout_spec.rb +7 -7
  41. data/spec/restify_spec.rb +13 -74
  42. data/spec/spec_helper.rb +13 -17
  43. data/spec/support/stub_server.rb +3 -3
  44. metadata +35 -65
  45. data/lib/restify/adapter/em.rb +0 -139
  46. data/lib/restify/adapter/pooled_em.rb +0 -270
@@ -7,40 +7,42 @@ describe Restify::Promise do
7
7
 
8
8
  describe 'factory methods' do
9
9
  describe '#fulfilled' do
10
- subject { described_class.fulfilled(fulfill_value) }
10
+ subject(:promise) { described_class.fulfilled(fulfill_value) }
11
+
11
12
  let(:fulfill_value) { 42 }
12
13
 
13
14
  it 'returns a fulfilled promise' do
14
- expect(subject.fulfilled?).to be true
15
- expect(subject.rejected?).to be false
15
+ expect(promise.fulfilled?).to be true
16
+ expect(promise.rejected?).to be false
16
17
  end
17
18
 
18
19
  it 'wraps the given value' do
19
- expect(subject.value!).to eq 42
20
+ expect(promise.value!).to eq 42
20
21
  end
21
22
  end
22
23
 
23
24
  describe '#rejected' do
24
- subject { described_class.rejected(rejection_reason) }
25
+ subject(:promise) { described_class.rejected(rejection_reason) }
26
+
25
27
  let(:rejection_reason) { ArgumentError }
26
28
 
27
29
  it 'returns a rejected promise' do
28
- expect(subject.fulfilled?).to be false
29
- expect(subject.rejected?).to be true
30
+ expect(promise.fulfilled?).to be false
31
+ expect(promise.rejected?).to be true
30
32
  end
31
33
 
32
34
  it 'bubbles up the caught exception on #value!' do
33
- expect { subject.value! }.to raise_error(ArgumentError)
35
+ expect { promise.value! }.to raise_error(ArgumentError)
34
36
  end
35
37
 
36
38
  it 'swallows the exception on #value' do
37
- expect(subject.value).to be nil
39
+ expect(promise.value).to be_nil
38
40
  end
39
41
  end
40
42
 
41
43
  describe '#create' do
42
44
  context 'when fulfilling the promise in the writer block' do
43
- subject do
45
+ subject(:promise) do
44
46
  described_class.create do |writer|
45
47
  # Calculate a value and fulfill the promise with it
46
48
  writer.fulfill 42
@@ -48,17 +50,17 @@ describe Restify::Promise do
48
50
  end
49
51
 
50
52
  it 'returns a fulfilled promise' do
51
- expect(subject.fulfilled?).to be true
52
- expect(subject.rejected?).to be false
53
+ expect(promise.fulfilled?).to be true
54
+ expect(promise.rejected?).to be false
53
55
  end
54
56
 
55
57
  it 'wraps the given value' do
56
- expect(subject.value!).to eq 42
58
+ expect(promise.value!).to eq 42
57
59
  end
58
60
  end
59
61
 
60
62
  context 'when rejecting the promise in the writer block' do
61
- subject do
63
+ subject(:promise) do
62
64
  described_class.create do |writer|
63
65
  # Calculate a value and fulfill the promise with it
64
66
  writer.reject ArgumentError
@@ -66,21 +68,21 @@ describe Restify::Promise do
66
68
  end
67
69
 
68
70
  it 'returns a rejected promise' do
69
- expect(subject.fulfilled?).to be false
70
- expect(subject.rejected?).to be true
71
+ expect(promise.fulfilled?).to be false
72
+ expect(promise.rejected?).to be true
71
73
  end
72
74
 
73
75
  it 'bubbles up the caught exception on #value!' do
74
- expect { subject.value! }.to raise_error(ArgumentError)
76
+ expect { promise.value! }.to raise_error(ArgumentError)
75
77
  end
76
78
 
77
79
  it 'swallows the exception on #value' do
78
- expect(subject.value).to be nil
80
+ expect(promise.value).to be_nil
79
81
  end
80
82
  end
81
83
 
82
84
  context 'when fulfilling the promise asynchronously' do
83
- subject do
85
+ subject(:promise) do
84
86
  described_class.create do |writer|
85
87
  Thread.new do
86
88
  sleep 0.1
@@ -90,20 +92,21 @@ describe Restify::Promise do
90
92
  end
91
93
 
92
94
  it 'returns a pending promise' do
93
- expect(subject.fulfilled?).to be false
94
- expect(subject.rejected?).to be false
95
- expect(subject.pending?).to be true
95
+ expect(promise.fulfilled?).to be false
96
+ expect(promise.rejected?).to be false
97
+ expect(promise.pending?).to be true
96
98
  end
97
99
 
98
100
  it 'waits for the fulfillment value' do
99
- expect(subject.value!).to eq 42
101
+ expect(promise.value!).to eq 42
100
102
  end
101
103
  end
102
104
  end
103
105
  end
104
106
 
105
107
  describe 'result' do
106
- subject { described_class.new(*dependencies, &task).value! }
108
+ subject(:result) { described_class.new(*dependencies, &task).value! }
109
+
107
110
  let(:dependencies) { [] }
108
111
  let(:task) { nil }
109
112
 
@@ -116,7 +119,7 @@ describe Restify::Promise do
116
119
  end
117
120
 
118
121
  it 'is calculated using the task block' do
119
- expect(subject).to eq 42
122
+ expect(result).to eq 42
120
123
  end
121
124
  end
122
125
 
@@ -125,12 +128,12 @@ describe Restify::Promise do
125
128
  [
126
129
  Restify::Promise.fulfilled(1),
127
130
  Restify::Promise.fulfilled(2),
128
- Restify::Promise.fulfilled(3)
131
+ Restify::Promise.fulfilled(3),
129
132
  ]
130
133
  end
131
134
 
132
135
  it 'is an array of the dependencies\' results' do
133
- expect(subject).to eq [1, 2, 3]
136
+ expect(result).to eq [1, 2, 3]
134
137
  end
135
138
  end
136
139
 
@@ -139,12 +142,12 @@ describe Restify::Promise do
139
142
  [[
140
143
  Restify::Promise.fulfilled(1),
141
144
  Restify::Promise.fulfilled(2),
142
- Restify::Promise.fulfilled(3)
145
+ Restify::Promise.fulfilled(3),
143
146
  ]]
144
147
  end
145
148
 
146
149
  it 'is an array of the dependencies\' results' do
147
- expect(subject).to eq [1, 2, 3]
150
+ expect(result).to eq [1, 2, 3]
148
151
  end
149
152
  end
150
153
 
@@ -152,7 +155,7 @@ describe Restify::Promise do
152
155
  let(:dependencies) do
153
156
  [
154
157
  Restify::Promise.fulfilled(5),
155
- Restify::Promise.fulfilled(12)
158
+ Restify::Promise.fulfilled(12),
156
159
  ]
157
160
  end
158
161
  let(:task) do
@@ -160,7 +163,7 @@ describe Restify::Promise do
160
163
  end
161
164
 
162
165
  it 'can use the dependencies to calculate the value' do
163
- expect(subject).to eq 17
166
+ expect(result).to eq 17
164
167
  end
165
168
  end
166
169
 
@@ -168,25 +171,26 @@ describe Restify::Promise do
168
171
  # dependencies is built dynamically.
169
172
  context 'with an empty array of dependencies and without task' do
170
173
  subject { described_class.new([]).value! }
174
+
171
175
  it { is_expected.to eq [] }
172
176
  end
173
177
  end
174
178
 
175
179
  describe '#wait' do
176
180
  it 'can time out' do
177
- expect { promise.wait(0.1) }.to raise_error ::Timeout::Error
181
+ expect { promise.wait(0.1) }.to raise_error Timeout::Error
178
182
  end
179
183
  end
180
184
 
181
185
  describe '#value' do
182
186
  it 'can time out' do
183
- expect { promise.value!(0.1) }.to raise_error ::Timeout::Error
187
+ expect { promise.value(0.1) }.to raise_error Timeout::Error
184
188
  end
185
189
  end
186
190
 
187
191
  describe '#value!' do
188
192
  it 'can time out' do
189
- expect { promise.value!(0.1) }.to raise_error ::Timeout::Error
193
+ expect { promise.value!(0.1) }.to raise_error Timeout::Error
190
194
  end
191
195
  end
192
196
  end
@@ -3,15 +3,13 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Restify::Registry do
6
- let(:registry) { described_class.instance }
6
+ subject(:registry) { described_class.instance }
7
7
 
8
8
  describe 'class' do
9
9
  describe '#instance' do
10
- subject { described_class.instance }
11
-
12
10
  it 'returns singleton instance' do
13
- expect(subject).to be_a described_class
14
- expect(subject).to be described_class.instance
11
+ expect(registry).to be_a described_class
12
+ expect(registry).to be described_class.instance
15
13
  end
16
14
  end
17
15
 
@@ -36,14 +34,14 @@ describe Restify::Registry do
36
34
  end
37
35
 
38
36
  describe '#store / #fetch' do
37
+ subject(:store) { registry.store(name, uri, **opts) }
38
+
39
39
  let(:name) { 'remote' }
40
40
  let(:uri) { 'http://remote/entry/point' }
41
41
  let(:opts) { {accept: 'application/vnd.remote+json'} }
42
42
 
43
- subject { registry.store name, uri, **opts }
44
-
45
43
  it 'stores registry item' do
46
- subject
44
+ store
47
45
 
48
46
  item = registry.fetch name
49
47
 
@@ -1,55 +1,234 @@
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
7
+ subject(:relation) { described_class.new context, pattern }
8
+
6
9
  let(:context) { Restify::Context.new('http://test.host/') }
7
- let(:pattern) { '/resource/{id}' }
8
- let(:relation) { described_class.new context, pattern }
9
- subject { relation }
10
+ let(:pattern) { '/resource/{id}{?q*}' }
10
11
 
11
12
  describe '#==' do
12
- it 'should equal pattern' do
13
- expect(subject).to eq pattern
13
+ it 'equals pattern' do
14
+ expect(relation).to eq pattern
14
15
  end
15
16
  end
16
17
 
17
18
  describe '#expand' do
18
- let(:params) { {id: 1337} }
19
+ subject(:expanded) { relation.expand params }
19
20
 
20
- subject { relation.expand params }
21
+ let(:params) { {id: 1337} }
22
+ let(:cls_to_param) do
23
+ Class.new do
24
+ def to_param
25
+ 42
26
+ end
27
+ end
28
+ end
21
29
 
22
30
  it { is_expected.to be_a Addressable::URI }
23
31
 
24
- class ParamObject
25
- def to_param
26
- 42
27
- end
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' }
28
48
  end
29
49
 
30
50
  context 'with #to_param object' do
31
- let(:params) { {id: ParamObject.new} }
51
+ let(:params) { {id: cls_to_param.new} }
52
+
53
+ it { expect(expanded.to_s).to eq 'http://test.host/resource/42' }
54
+ end
32
55
 
33
- it { expect(subject.to_s).to eq 'http://test.host/resource/42' }
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' }
34
60
  end
35
61
 
36
62
  context 'with unknown additional query parameter' do
37
63
  let(:pattern) { '/resource{?a,b}' }
38
64
  let(:params) { {a: 1, b: 2, c: 3} }
39
65
 
40
- it { expect(subject.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' }
41
67
  end
42
68
 
43
69
  context 'with additional parameters' do
44
70
  let(:params) { {id: '5', abc: 'cde'} }
45
71
 
46
- it { expect(subject.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' }
47
91
  end
48
92
 
49
93
  context 'with additional #to_param parameter' do
50
- let(:params) { {id: '5', abc: ParamObject.new} }
94
+ let(:params) { {id: '5', abc: cls_to_param.new} }
95
+
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' }
103
+ end
51
104
 
52
- it { expect(subject.to_s).to eq 'http://test.host/resource/5?abc=42' }
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./ }
53
121
  end
54
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
233
+ end
55
234
  end
@@ -3,63 +3,58 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Restify::Resource do
6
+ subject(:resource) { described_class.new(context, response:, data:, relations:) }
7
+
6
8
  let(:data) { {} }
7
9
  let(:relations) { {} }
8
- let(:context) { double 'context' }
9
- let(:response) { double 'response' }
10
- let(:resource) { described_class.new(context, response: response, data: data, relations: relations) }
11
- subject { resource }
12
-
13
- before do
14
- allow(context).to receive(:relation?).and_return(false)
15
- allow(context).to receive(:relation).and_raise(KeyError)
16
- end
10
+ let(:context) { instance_double(Restify::Context) }
11
+ let(:response) { instance_double(Restify::Response) }
17
12
 
18
13
  context 'relations' do
19
14
  let(:relations) do
20
15
  {
21
16
  'users' => 'http://example.org/users',
22
- 'projects' => 'http://example.org/projects'
17
+ 'projects' => 'http://example.org/projects',
23
18
  }
24
19
  end
25
20
 
26
21
  describe '#relation?' do
27
- it 'should match relations' do
28
- expect(subject.relation?(:users)).to eq true
29
- expect(subject.relation?('users')).to eq true
30
- expect(subject.relation?(:projects)).to eq true
31
- expect(subject.relation?('projects')).to eq true
32
- expect(subject.relation?('fuu')).to eq false
33
-
34
- expect(subject).to have_relation :users
35
- expect(subject).to have_relation :projects
36
-
37
- expect(subject.rel?(:users)).to eq true
38
- expect(subject.rel?('users')).to eq true
39
- expect(subject.rel?(:projects)).to eq true
40
- expect(subject.rel?('projects')).to eq true
41
- expect(subject.rel?('fuu')).to eq false
42
-
43
- expect(subject).to have_rel :users
44
- expect(subject).to have_rel :projects
22
+ it 'matches relations' do
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
45
40
  end
46
41
  end
47
42
 
48
43
  describe '#relation' do
49
- it 'should return relation' do
50
- expect(subject.rel(:users)).to be_a Restify::Relation
51
-
52
- expect(subject.rel(:users)).to eq 'http://example.org/users'
53
- expect(subject.rel('users')).to eq 'http://example.org/users'
54
- expect(subject.rel(:projects)).to eq 'http://example.org/projects'
55
- expect(subject.rel('projects')).to eq 'http://example.org/projects'
56
- expect { subject.rel(:fuu) }.to raise_error KeyError
57
-
58
- expect(subject.relation(:users)).to eq 'http://example.org/users'
59
- expect(subject.relation('users')).to eq 'http://example.org/users'
60
- expect(subject.relation(:projects)).to eq 'http://example.org/projects'
61
- expect(subject.relation('projects')).to eq 'http://example.org/projects'
62
- expect { subject.relation(:fuu) }.to raise_error KeyError
44
+ it 'returns relation' do
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
63
58
  end
64
59
  end
65
60
 
@@ -67,32 +62,32 @@ describe Restify::Resource do
67
62
  let(:relations) { {_restify_follow: 'http://localhost/10'} }
68
63
 
69
64
  it 'returns follow relation' do
70
- expect(subject.follow).to be_a Restify::Relation
71
- 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'
72
67
  end
73
68
 
74
69
  context 'when nil' do
75
70
  let(:relations) { {} }
76
71
 
77
72
  it 'returns nil' do
78
- expect(subject.follow).to be nil
73
+ expect(resource.follow).to be_nil
79
74
  end
80
75
  end
81
76
  end
82
77
 
83
- context '#follow!' do
78
+ describe '#follow!' do
84
79
  let(:relations) { {_restify_follow: 'http://localhost/10'} }
85
80
 
86
81
  it 'returns follow relation' do
87
- expect(subject.follow!).to be_a Restify::Relation
88
- 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'
89
84
  end
90
85
 
91
86
  context 'when nil' do
92
87
  let(:relations) { {} }
93
88
 
94
89
  it 'raise runtime error' do
95
- expect { subject.follow! }.to raise_error RuntimeError do |err|
90
+ expect { resource.follow! }.to raise_error RuntimeError do |err|
96
91
  expect(err.message).to eq 'Nothing to follow'
97
92
  end
98
93
  end
@@ -101,25 +96,25 @@ describe Restify::Resource do
101
96
  end
102
97
 
103
98
  context 'data' do
104
- let(:data) { double 'data' }
99
+ let(:data) { double 'data' } # rubocop:disable RSpec/VerifiedDoubles
105
100
 
106
- it 'should delegate methods (I)' do
107
- expect(data).to receive(:some_method).and_return(42)
101
+ it 'delegates methods (I)' do
102
+ allow(data).to receive(:some_method).and_return(42)
108
103
 
109
- expect(subject).to respond_to :some_method
110
- expect(subject.some_method).to eq 42
104
+ expect(resource).to respond_to :some_method
105
+ expect(resource.some_method).to eq 42
111
106
  end
112
107
 
113
- it 'should delegate methods (II)' do
114
- expect(data).to receive(:[]).with(1).and_return(2)
108
+ it 'delegates methods (II)' do
109
+ allow(data).to receive(:[]).with(1).and_return(2)
115
110
 
116
- expect(subject).to respond_to :[]
117
- expect(subject[1]).to eq 2
111
+ expect(resource).to respond_to :[]
112
+ expect(resource[1]).to eq 2
118
113
  end
119
114
 
120
115
  describe '#data' do
121
- it 'should return data' do
122
- expect(subject.data).to equal data
116
+ it 'returns data' do
117
+ expect(resource.data).to equal data
123
118
  end
124
119
  end
125
120
  end