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
@@ -19,32 +19,35 @@ module Restify
19
19
  @template = Addressable::Template.new template
20
20
  end
21
21
 
22
- def request(method, data, params, opts = {})
23
- context.request method, expand(params), **opts, data: data
22
+ def request(method:, params: {}, **opts)
23
+ context.request(method, expand(params), **opts)
24
24
  end
25
25
 
26
- def get(params = {}, opts = {})
27
- request :get, nil, params, opts
26
+ def get(data = {}, params: {}, **opts)
27
+ request(**opts, method: :get, params: data.merge(params))
28
28
  end
29
29
 
30
- def head(params = {}, opts = {})
31
- request :head, nil, params, opts
30
+ def head(data = {}, params: {}, **opts)
31
+ request(**opts, method: :head, params: data.merge(params))
32
32
  end
33
33
 
34
- def delete(params = {}, opts = {})
35
- request :delete, nil, params, opts
34
+ def delete(data = {}, params: {}, **opts)
35
+ request(**opts, method: :delete, params: data.merge(params))
36
36
  end
37
37
 
38
- def post(data = {}, params = {}, opts = {})
39
- request :post, data, params, opts
38
+ def post(data = nil, **opts)
39
+ opts[:data] = data unless opts.key?(:data)
40
+ request(**opts, method: :post)
40
41
  end
41
42
 
42
- def put(data = {}, params = {}, opts = {})
43
- request :put, data, params, opts
43
+ def put(data = nil, **opts)
44
+ opts[:data] = data unless opts.key?(:data)
45
+ request(**opts, method: :put)
44
46
  end
45
47
 
46
- def patch(data = {}, params = {}, opts = {})
47
- request :patch, data, params, opts
48
+ def patch(data = nil, **opts)
49
+ opts[:data] = data unless opts.key?(:data)
50
+ request(**opts, method: :patch)
48
51
  end
49
52
 
50
53
  def ==(other)
@@ -72,14 +75,39 @@ module Restify
72
75
  private
73
76
 
74
77
  def convert(params)
75
- params.each_pair.each_with_object({}) do |param, hash|
78
+ params.each_pair.with_object({}) do |param, hash|
76
79
  hash[param[0]] = convert_param param[1]
77
80
  end
78
81
  end
79
82
 
80
- def convert_param(value)
81
- return value.to_param.to_s if value.respond_to?(:to_param)
83
+ def convert_param(value, nesting: true)
84
+ # Convert parameters into values acceptable in a
85
+ # Addressable::Template, with some support for #to_param, but not
86
+ # for basic types.
87
+ if value == nil || # rubocop:disable Style/NilComparison
88
+ value.is_a?(Numeric) ||
89
+ value.is_a?(Symbol) ||
90
+ value.is_a?(Hash) ||
91
+ value == true ||
92
+ value == false ||
93
+ value.respond_to?(:to_str)
94
+ return value
95
+ end
96
+
97
+ # Handle array-link things first to *not* call #to_params on them,
98
+ # as that will concatenation any Array to "a/b/c". Instead, we
99
+ # want to check one level of basic types only.
100
+ if value.respond_to?(:to_ary)
101
+ return nesting ? value.to_ary.map {|val| convert_param(val, nesting: false) } : value
102
+ end
103
+
104
+ # Handle Rails' #to_param for non-basic types
105
+ if value.respond_to?(:to_param)
106
+ return value.to_param
107
+ end
82
108
 
109
+ # Otherwise, pass raw value to Addressable::Template and let it
110
+ # explode.
83
111
  value
84
112
  end
85
113
 
@@ -29,12 +29,12 @@ module Restify
29
29
  #
30
30
  attr_reader :timeout
31
31
 
32
- def initialize(opts = {})
33
- @method = opts.fetch(:method, :get).downcase
34
- @uri = opts.fetch(:uri) { raise ArgumentError.new ':uri required.' }
35
- @data = opts.fetch(:data, nil)
36
- @timeout = opts.fetch(:timeout, 300)
37
- @headers = opts.fetch(:headers, {})
32
+ def initialize(uri:, method: :get, data: nil, timeout: 300, headers: {})
33
+ @uri = uri
34
+ @method = method.to_s.downcase
35
+ @data = data
36
+ @timeout = timeout
37
+ @headers = headers
38
38
 
39
39
  @headers['Content-Type'] ||= 'application/json' if json?
40
40
  end
@@ -71,9 +71,9 @@ module Restify
71
71
  @target = target
72
72
 
73
73
  if @target
74
- super "Operation on #{@target} timed out"
74
+ super("Operation on #{@target} timed out")
75
75
  else
76
- super 'Operation timed out'
76
+ super('Operation timed out')
77
77
  end
78
78
  end
79
79
  end
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Restify
4
4
  module VERSION
5
- MAJOR = 1
6
- MINOR = 15
7
- PATCH = 2
5
+ MAJOR = 2
6
+ MINOR = 0
7
+ PATCH = 1
8
8
  STAGE = nil
9
9
  STRING = [MAJOR, MINOR, PATCH, STAGE].compact.join('.').freeze
10
10
 
data/lib/restify.rb CHANGED
@@ -4,7 +4,6 @@ require 'forwardable'
4
4
 
5
5
  require 'restify/version'
6
6
 
7
- require 'hashie'
8
7
  require 'concurrent'
9
8
  require 'addressable/uri'
10
9
  require 'addressable/template'
@@ -1,36 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
+ require 'active_support'
5
+ require 'active_support/cache'
4
6
 
5
7
  describe Restify::Cache do
6
- subject { cache }
8
+ subject(:cache) { described_class.new(store) }
7
9
 
8
- let(:store) { double 'store' }
9
- let(:cache) { described_class.new store }
10
+ let(:store) { instance_double(ActiveSupport::Cache::Store) }
10
11
 
11
12
  describe '#call' do
12
- let(:request) { double 'request' }
13
- let(:promise0) { double 'promise0' }
14
- let(:promise1) { double 'promise1' }
15
- let(:response) { double 'response' }
13
+ let(:request) { instance_double(Restify::Request) }
14
+ let(:promise0) { instance_double(Restify::Promise, 'promise0') } # rubocop:disable RSpec/IndexedLet
15
+ let(:promise1) { instance_double(Restify::Promise, 'promise1') } # rubocop:disable RSpec/IndexedLet
16
+ let(:response) { instance_double(Restify::Response) }
16
17
 
17
18
  it 'yields with promises' do
18
- expect(promise0).to receive(:then).and_yield(response).and_return(promise1)
19
+ allow(promise0).to receive(:then).and_yield(response).and_return(promise1)
19
20
 
20
- expect(subject.call(request) { promise0 }).to eq promise1
21
+ expect(cache.call(request) { promise0 }).to eq promise1
21
22
  end
22
23
 
23
24
  it 'caches new responses' do
24
- expect(promise0).to receive(:then).and_yield(response)
25
+ allow(promise0).to receive(:then).and_yield(response)
26
+
27
+ # TODO: Do not stub inside tested object
25
28
  expect(cache).to receive(:cache).with(response)
26
29
 
27
- subject.call(request) { promise0 }
30
+ cache.call(request) { promise0 }
28
31
  end
29
32
 
30
33
  it 'returns with match' do
34
+ # TODO: Do not stub inside tested object
31
35
  expect(cache).to receive(:match).with(request).and_return(response)
32
36
 
33
- expect(subject.call(request)).to eq response
37
+ expect(cache.call(request)).to eq response
34
38
  end
35
39
  end
36
40
  end
@@ -20,7 +20,7 @@ describe Restify::Context do
20
20
  describe '#adapter' do
21
21
  subject { super().options[:adapter] }
22
22
 
23
- let(:kwargs) { {adapter: double('adapter')} }
23
+ let(:kwargs) { {adapter: instance_double(Restify::Adapter::Base)} }
24
24
 
25
25
  it 'adapter is not serialized' do
26
26
  expect(subject).to equal nil
@@ -30,7 +30,7 @@ describe Restify::Context do
30
30
  describe '#cache' do
31
31
  subject { super().options[:cache] }
32
32
 
33
- let(:kwargs) { {adapter: double('cache')} }
33
+ let(:kwargs) { {cache: Object.new} }
34
34
 
35
35
  it 'cache is not serialized' do
36
36
  expect(subject).to equal nil
@@ -52,7 +52,12 @@ describe Restify::Context do
52
52
  subject { load }
53
53
 
54
54
  let(:dump) { YAML.dump(context) }
55
- let(:load) { YAML.load(dump) } # rubocop:disable Security/YAMLLoad
55
+
56
+ if RUBY_VERSION >= '3.1'
57
+ let(:load) { YAML.safe_load(dump, permitted_classes: [Restify::Context, Symbol]) }
58
+ else
59
+ let(:load) { YAML.load(dump) }
60
+ end
56
61
 
57
62
  include_examples 'serialization'
58
63
  end
@@ -2,16 +2,13 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Restify::ResponseError do
6
- let(:response) { double 'response' }
5
+ describe Restify::ResponseError do # rubocop:disable RSpec/SpecFilePathFormat
6
+ let(:response) { instance_double(Restify::Response) }
7
7
  let(:message) { 'Error' }
8
8
  let(:uri) { 'http://localhost' }
9
9
 
10
10
  before do
11
- allow(response).to receive(:uri).and_return(uri)
12
- allow(response).to receive(:code).and_return(code)
13
- allow(response).to receive(:message).and_return(message)
14
- allow(response).to receive(:decoded_body).and_return({})
11
+ allow(response).to receive_messages(uri: uri, code: code, message: message, decoded_body: {})
15
12
  end
16
13
 
17
14
  describe '.from_code' do
@@ -20,61 +17,61 @@ describe Restify::ResponseError do
20
17
  context 'with 400 Bad Request' do
21
18
  let(:code) { 400 }
22
19
 
23
- it { is_expected.to be_a ::Restify::BadRequest }
20
+ it { is_expected.to be_a Restify::BadRequest }
24
21
  end
25
22
 
26
23
  context 'with 401 Unauthorized' do
27
24
  let(:code) { 401 }
28
25
 
29
- it { is_expected.to be_a ::Restify::Unauthorized }
26
+ it { is_expected.to be_a Restify::Unauthorized }
30
27
  end
31
28
 
32
29
  context 'with 404 Unauthorized' do
33
30
  let(:code) { 404 }
34
31
 
35
- it { is_expected.to be_a ::Restify::NotFound }
32
+ it { is_expected.to be_a Restify::NotFound }
36
33
  end
37
34
 
38
35
  context 'with 406 Not Acceptable' do
39
36
  let(:code) { 406 }
40
37
 
41
- it { is_expected.to be_a ::Restify::NotAcceptable }
38
+ it { is_expected.to be_a Restify::NotAcceptable }
42
39
  end
43
40
 
44
41
  context 'with 410 Gone' do
45
42
  let(:code) { 410 }
46
43
 
47
- it { is_expected.to be_a ::Restify::Gone }
44
+ it { is_expected.to be_a Restify::Gone }
48
45
  end
49
46
 
50
47
  context 'with 422 Unprocessable Entity' do
51
48
  let(:code) { 422 }
52
49
 
53
- it { is_expected.to be_a ::Restify::UnprocessableEntity }
50
+ it { is_expected.to be_a Restify::UnprocessableEntity }
54
51
  end
55
52
 
56
53
  context 'with 500 Internal Server Error' do
57
54
  let(:code) { 500 }
58
55
 
59
- it { is_expected.to be_a ::Restify::InternalServerError }
56
+ it { is_expected.to be_a Restify::InternalServerError }
60
57
  end
61
58
 
62
59
  context 'with 502 Bad Gateway' do
63
60
  let(:code) { 502 }
64
61
 
65
- it { is_expected.to be_a ::Restify::BadGateway }
62
+ it { is_expected.to be_a Restify::BadGateway }
66
63
  end
67
64
 
68
65
  context 'with 503 Service Unavailable' do
69
66
  let(:code) { 503 }
70
67
 
71
- it { is_expected.to be_a ::Restify::ServiceUnavailable }
68
+ it { is_expected.to be_a Restify::ServiceUnavailable }
72
69
  end
73
70
 
74
71
  context 'with 504 Gateway Timeout' do
75
72
  let(:code) { 504 }
76
73
 
77
- it { is_expected.to be_a ::Restify::GatewayTimeout }
74
+ it { is_expected.to be_a Restify::GatewayTimeout }
78
75
  end
79
76
  end
80
77
  end
@@ -16,23 +16,24 @@ describe Restify do
16
16
  end
17
17
 
18
18
  describe 'HEAD requests' do
19
- subject { Restify.new('http://localhost:9292/base').head(params).value! }
19
+ subject(:value) { Restify.new('http://localhost:9292/base').head(params:).value! }
20
20
 
21
21
  let(:params) { {} }
22
22
 
23
23
  it 'returns a resource with access to headers' do
24
- expect(subject.response.headers).to include('CONTENT_LENGTH' => '333')
24
+ expect(value.response.headers).to include('CONTENT_LENGTH' => '333')
25
25
  end
26
26
 
27
27
  it 'parses Link headers into relations' do
28
- expect(subject).to have_relation :neat
28
+ expect(value).to have_relation :neat
29
29
  end
30
30
 
31
31
  context 'with params' do
32
32
  let(:params) { {foo: 'bar'} }
33
33
 
34
34
  it 'adds them to the query string' do
35
- subject
35
+ value
36
+
36
37
  expect(
37
38
  request_stub.with(query: {foo: 'bar'}),
38
39
  ).to have_been_requested
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Restify do
6
+ subject(:echo) { resource.data }
7
+
8
+ let(:resource) { Restify.new('http://localhost:9292/echo').get.value! }
9
+
10
+ before do
11
+ expect(OTLE_EXPORTER.finished_spans).to be_empty
12
+ end
13
+
14
+ describe 'OpenTelemetry' do
15
+ it 'adds propagation header' do
16
+ expect(echo).to have_key('HTTP_TRACEPARENT')
17
+ end
18
+
19
+ it 'adds spans' do
20
+ resource
21
+
22
+ spans = OTLE_EXPORTER.finished_spans
23
+ expect(spans.size).to eq 2
24
+
25
+ spans[1].tap do |span|
26
+ expect(span.instrumentation_scope.name).to eq 'restify'
27
+ expect(span.instrumentation_scope.version).to eq Restify::VERSION.to_s
28
+ expect(span.attributes).to eq({
29
+ 'http.request.method' => 'GET',
30
+ 'http.response.status_code' => 200,
31
+ 'server.address' => 'localhost',
32
+ 'server.port' => 9292,
33
+ 'url.full' => 'http://localhost:9292/echo',
34
+ 'url.scheme' => 'http',
35
+ })
36
+ end
37
+
38
+ # Latest span has to be from the Ethon instrumentation and must
39
+ # have the Restify span as a parent.
40
+ spans[0].tap do |span|
41
+ expect(span.instrumentation_scope.name).to match(/Ethon/)
42
+ expect(span.parent_span_id).to eq spans[1].span_id
43
+ end
44
+ end
45
+ end
46
+ end
@@ -13,7 +13,7 @@ describe Restify do
13
13
  end
14
14
 
15
15
  describe 'Request body' do
16
- subject { Restify.new('http://localhost:9292/base').post(body, {}, {headers: headers}).value! }
16
+ subject(:value) { Restify.new('http://localhost:9292/base').post(body, headers:).value! }
17
17
 
18
18
  let(:headers) { {} }
19
19
 
@@ -21,7 +21,7 @@ describe Restify do
21
21
  let(:body) { {a: 'b', c: 'd'} }
22
22
 
23
23
  it 'is serialized as JSON' do
24
- subject
24
+ value
25
25
 
26
26
  expect(
27
27
  request_stub.with(body: '{"a":"b","c":"d"}'),
@@ -29,7 +29,7 @@ describe Restify do
29
29
  end
30
30
 
31
31
  it 'gets a JSON media type for free' do
32
- subject
32
+ value
33
33
 
34
34
  expect(
35
35
  request_stub.with(headers: {'Content-Type' => 'application/json'}),
@@ -40,7 +40,7 @@ describe Restify do
40
40
  let(:headers) { {'Content-Type' => 'application/vnd.api+json'} }
41
41
 
42
42
  it 'respects the override' do
43
- subject
43
+ value
44
44
 
45
45
  expect(
46
46
  request_stub.with(headers: {'Content-Type' => 'application/vnd.api+json'}),
@@ -53,7 +53,7 @@ describe Restify do
53
53
  let(:body) { 'a=b&c=d' }
54
54
 
55
55
  it 'is sent as provided' do
56
- subject
56
+ value
57
57
 
58
58
  expect(
59
59
  request_stub.with(body: 'a=b&c=d'),
@@ -61,10 +61,10 @@ describe Restify do
61
61
  end
62
62
 
63
63
  it 'does not get a JSON media type' do
64
- subject
64
+ value
65
65
 
66
66
  expect(
67
- request_stub.with {|req| req.headers['Content-Type'] !~ /json/ },
67
+ request_stub.with {|req| !req.headers['Content-Type'].include?('json') },
68
68
  ).to have_been_requested
69
69
  end
70
70
 
@@ -72,7 +72,7 @@ describe Restify do
72
72
  let(:headers) { {'Content-Type' => 'application/text'} }
73
73
 
74
74
  it 'respects the override' do
75
- subject
75
+ value
76
76
 
77
77
  expect(
78
78
  request_stub.with(headers: {'Content-Type' => 'application/text'}),
@@ -2,13 +2,13 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Restify, adapter: ::Restify::Adapter::Typhoeus do
5
+ describe Restify, adapter: 'Restify::Adapter::Typhoeus' do
6
6
  before do
7
7
  stub_request(:get, 'http://stubserver/base').to_timeout
8
8
  end
9
9
 
10
10
  describe 'Timeout' do
11
- subject(:request) { Restify.new('http://localhost:9292/base').get({}, timeout: 0.1).value! }
11
+ subject(:request) { Restify.new('http://localhost:9292/base').get(timeout: 0.1).value! }
12
12
 
13
13
  it 'throws a network error' do
14
14
  expect { request }.to raise_error Restify::NetworkError do |error|
@@ -20,8 +20,7 @@ describe Restify do
20
20
 
21
21
  it 'sends the headers only for that request' do
22
22
  root = context.get(
23
- {},
24
- {headers: {'Accept' => 'application/msgpack, application/json'}},
23
+ headers: {'Accept' => 'application/msgpack, application/json'},
25
24
  ).value!
26
25
 
27
26
  root.rel(:self).get.value!
@@ -53,8 +52,7 @@ describe Restify do
53
52
 
54
53
  it 'can overwrite headers for single requests' do
55
54
  root = context.get(
56
- {},
57
- {headers: {'Accept' => 'application/xml'}},
55
+ headers: {'Accept' => 'application/xml'},
58
56
  ).value!
59
57
 
60
58
  root.rel(:self).get.value!
@@ -69,8 +67,7 @@ describe Restify do
69
67
 
70
68
  it 'can add additional headers for single requests' do
71
69
  root = context.get(
72
- {},
73
- {headers: {'X-Custom' => 'foobar'}},
70
+ headers: {'X-Custom' => 'foobar'},
74
71
  ).value!
75
72
 
76
73
  root.rel(:self).get.value!
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe Restify do
6
6
  before do
7
7
  stub_request(:get, 'http://stubserver/base')
8
- .to_return(status: http_status, headers: headers)
8
+ .to_return(status: http_status, headers:)
9
9
  end
10
10
 
11
11
  let(:http_status) { '200 OK' }
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Restify do
6
+ before do
7
+ WebMock.enable!
8
+ end
9
+
10
+ after do
11
+ WebMock.disable!(except: %i[net_http])
12
+ end
13
+
14
+ describe 'WebMock' do
15
+ subject(:resource) { Restify.new('http://www.example.com/base').get.value! }
16
+
17
+ it 'can stub requests' do
18
+ stub_request(:any, 'http://www.example.com/base')
19
+
20
+ expect(resource.response.status).to eq(:ok)
21
+ end
22
+
23
+ it 'raises error for not stubbed requests' do
24
+ expect { resource }.to raise_error WebMock::NetConnectNotAllowedError
25
+ end
26
+ end
27
+ end
@@ -7,21 +7,21 @@ describe Restify::Global do
7
7
 
8
8
  describe '#new' do
9
9
  context 'with string URI' do
10
- subject { global.new uri, **options }
10
+ subject(:restify) { global.new(uri, **options) }
11
11
 
12
12
  let(:uri) { 'http://api.github.com/' }
13
13
  let(:options) { {accept: 'application.vnd.github.v3+json'} }
14
14
 
15
15
  it 'returns relation for URI' do
16
- expect(subject).to be_a Restify::Relation
17
- expect(subject.pattern).to eq uri
18
- expect(subject.context.uri.to_s).to eq uri
19
- expect(subject.context.options).to eq options
16
+ expect(restify).to be_a Restify::Relation
17
+ expect(restify.pattern).to eq uri
18
+ expect(restify.context.uri.to_s).to eq uri
19
+ expect(restify.context.options).to eq options
20
20
  end
21
21
  end
22
22
 
23
23
  context 'with registry symbol' do
24
- subject { global.new(name, **options) }
24
+ subject(:restify) { global.new(uri, **options) }
25
25
 
26
26
  let(:name) { :registry_item_name }
27
27
  let(:uri) { 'http://api.github.com/' }
@@ -31,10 +31,10 @@ describe Restify::Global do
31
31
  it 'returns relation for stored registry item' do
32
32
  Restify::Registry.store(name, uri, **options)
33
33
 
34
- expect(subject).to be_a Restify::Relation
35
- expect(subject.pattern).to eq uri
36
- expect(subject.context.uri.to_s).to eq uri
37
- expect(subject.context.options).to eq options
34
+ expect(restify).to be_a Restify::Relation
35
+ expect(restify.pattern).to eq uri
36
+ expect(restify.context.uri.to_s).to eq uri
37
+ expect(restify.context.options).to eq options
38
38
  end
39
39
  end
40
40
  end
@@ -4,27 +4,26 @@ require 'spec_helper'
4
4
 
5
5
  describe Restify::Processors::Base do
6
6
  let(:context) { Restify::Context.new('http://test.host/') }
7
- let(:response) { double 'response' }
7
+ let(:response) { instance_double(Restify::Response) }
8
8
 
9
9
  before do
10
- allow(response).to receive(:links).and_return []
11
- allow(response).to receive(:follow_location).and_return nil
10
+ allow(response).to receive_messages(links: [], follow_location: nil)
12
11
  end
13
12
 
14
13
  describe 'class' do
15
14
  describe '#accept?' do
16
- subject { described_class.accept? response }
15
+ subject(:accept) { described_class.accept?(response) }
17
16
 
18
17
  # If no other processor accepts the request, we have an explicit fallback
19
18
  # to the base processor.
20
19
  it 'does not accept any responses' do
21
- expect(subject).to be_falsey
20
+ expect(accept).to be_falsey
22
21
  end
23
22
  end
24
23
  end
25
24
 
26
25
  describe '#resource' do
27
- subject { described_class.new(context, response).resource }
26
+ subject(:resource) { described_class.new(context, response).resource }
28
27
 
29
28
  before { allow(response).to receive(:body).and_return(body) }
30
29
 
@@ -37,7 +36,7 @@ describe Restify::Processors::Base do
37
36
  end
38
37
 
39
38
  it { is_expected.to be_a Restify::Resource }
40
- it { expect(subject.response).to be response }
39
+ it { expect(resource.response).to be response }
41
40
  it { is_expected.to eq body }
42
41
  end
43
42
  end