hal-client 3.16.0 → 3.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e97fd75dd9bb812c2cdf28bcd0a9a316a94bb71
4
- data.tar.gz: d260178d87921fe2031ae62a33952cdbbc7019a7
3
+ metadata.gz: 4c738c6f35a8c627363d55bde0e10116bf46eb1b
4
+ data.tar.gz: 32b562905f475064e94fbf2128222292dc44bc4c
5
5
  SHA512:
6
- metadata.gz: 6cd9c0e7192d66633ec12c0409a4cde8a8b6fb413965671f7590dd9bc77778399da2be2cc229567066a422d317c94eab89e7822869744ade921be700ee1c14f3
7
- data.tar.gz: 77e05a49bc31a09950cce202d93936e9eea97c1776229b3d7c43f89e647bafa5618d97a3f099693622f295eecdac0c9cfe55cd3fc751564a1e3f1db60d5ad85c
6
+ metadata.gz: cf65e375001c9c167d557fe6345c58cdb07d5d70d63da052d7ce82392f9805002cbe6e91c703879fbe3f3c7cede65a2c88a74cf0943fa7fd4e825ad52541a263
7
+ data.tar.gz: 6749283d49cc6f3aa0ae7f37e5aeda09c08ad875d4206a8250fbac21200ca7afc09e42a6388bdd392bb8e667b88b574751771f1d6275e92892d725a663b9a9c9
data/.gitignore CHANGED
@@ -18,3 +18,4 @@ spec/reports
18
18
  test/tmp
19
19
  test/version_tmp
20
20
  tmp
21
+ spec/examples.txt
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml CHANGED
@@ -6,4 +6,7 @@ rvm:
6
6
  - "2.1.0"
7
7
  - "2.2.0"
8
8
  - rbx-2.7
9
-
9
+
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: rbx-2.7
data/hal-client.gemspec CHANGED
@@ -24,7 +24,8 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 1.5"
26
26
  spec.add_development_dependency "rake", "~> 10.1"
27
- spec.add_development_dependency "rspec", "~> 3.0.0.beta"
27
+ spec.add_development_dependency "rspec", "~> 3.5"
28
28
  spec.add_development_dependency "webmock", ["~> 1.17", ">= 1.17.4"]
29
29
  spec.add_development_dependency "rspec-collection_matchers"
30
+ spec.add_development_dependency "pry"
30
31
  end
@@ -2,6 +2,13 @@ class HalClient
2
2
 
3
3
  # Encapsulates a "_links" section.
4
4
  class LinksSection
5
+
6
+ NO_RELATED_RESOURCE = ->(link_rel) {
7
+ raise KeyError, "No resources are related via `#{link_rel}`"
8
+ }
9
+
10
+ private_constant :NO_RELATED_RESOURCE
11
+
5
12
  # section - json hash for the links section
6
13
  # base_url - base URL with which to resolve relative URLs
7
14
  def initialize(section, opts={} )
@@ -27,9 +34,7 @@ class HalClient
27
34
  # Raises KeyError if the specified link_rel is not present and no
28
35
  # default_value or default_proc are provided.
29
36
  def hrefs(link_rel, &default_proc)
30
- default_proc ||= ->(link_rel){
31
- raise KeyError, "No resources are related via `#{link_rel}`"
32
- }
37
+ default_proc ||= NO_RELATED_RESOURCE
33
38
 
34
39
  return default_proc.call(link_rel) unless section.key? link_rel
35
40
 
@@ -15,6 +15,20 @@ class HalClient
15
15
  # https://tools.ietf.org/html/draft-kelly-json-hal-07#section-4.1
16
16
  RESERVED_PROPERTIES = ['_links', '_embedded'].freeze
17
17
 
18
+ NO_RELATED_RESOURCE = ->(link_rel) {
19
+ raise KeyError, "No resources are related via `#{link_rel}`"
20
+ }
21
+
22
+ NO_EMBED_FOUND = ->(link_rel) {
23
+ raise KeyError, "#{link_rel} embed not found"
24
+ }
25
+
26
+ NO_LINK_FOUND = ->(link_rel, _options) {
27
+ raise KeyError, "#{link_rel} link not found"
28
+ }
29
+
30
+ private_constant :NO_RELATED_RESOURCE, :NO_EMBED_FOUND, :NO_LINK_FOUND
31
+
18
32
  # Create a new Representation
19
33
  #
20
34
  # options - name parameters
@@ -145,11 +159,7 @@ class HalClient
145
159
  #
146
160
  # link_rel - The link rel of interest
147
161
  def related?(link_rel)
148
- _ = related link_rel
149
- true
150
-
151
- rescue KeyError
152
- false
162
+ !!(linked(link_rel) { false } || embedded(link_rel) { false })
153
163
  end
154
164
  alias_method :has_related?, :related?
155
165
 
@@ -166,9 +176,7 @@ class HalClient
166
176
  # Raises KeyError if the specified link does not exist
167
177
  # and no default_proc is provided.
168
178
  def related(link_rel, options = {}, &default_proc)
169
- default_proc ||= ->(link_rel){
170
- raise KeyError, "No resources are related via `#{link_rel}`"
171
- }
179
+ default_proc ||= NO_RELATED_RESOURCE
172
180
 
173
181
  embedded = embedded(link_rel) { nil }
174
182
  linked = linked(link_rel, options) { nil }
@@ -231,9 +239,7 @@ class HalClient
231
239
  # Raises KeyError if the specified link does not exist
232
240
  # and no default_proc is provided.
233
241
  def raw_related_hrefs(link_rel, &default_proc)
234
- default_proc ||= ->(link_rel){
235
- raise KeyError, "No resources are related via `#{link_rel}`"
236
- }
242
+ default_proc ||= NO_RELATED_RESOURCE
237
243
 
238
244
  embedded = embedded(link_rel) { nil }
239
245
  linked = links.hrefs(link_rel) { nil }
@@ -346,23 +352,19 @@ class HalClient
346
352
  end
347
353
 
348
354
  def embedded(link_rel, &default_proc)
349
- default_proc ||= ->(link_rel) {
350
- fail KeyError, "#{link_rel} embed not found"
351
- }
355
+ default_proc ||= NO_EMBED_FOUND
352
356
 
353
357
  relations = embedded_section.fetch(link_rel) { MISSING }
354
358
  return default_proc.call(link_rel) if relations == MISSING
355
359
 
356
360
  (boxed relations).map{|it| Representation.new hal_client: hal_client, parsed_json: it}
357
361
 
358
- rescue InvalidRepresentationError => err
362
+ rescue InvalidRepresentationError
359
363
  fail InvalidRepresentationError, "/_embedded/#{jpointer_esc(link_rel)} is not a valid representation"
360
364
  end
361
365
 
362
- def linked(link_rel, options, &default_proc)
363
- default_proc ||= ->(link_rel,_options) {
364
- fail KeyError, "#{link_rel} link not found"
365
- }
366
+ def linked(link_rel, options = {}, &default_proc)
367
+ default_proc ||= NO_LINK_FOUND
366
368
 
367
369
  relations = links.hrefs(link_rel) { MISSING }
368
370
  return default_proc.call(link_rel, options) if relations == MISSING
@@ -376,7 +378,7 @@ class HalClient
376
378
  end }
377
379
  .map {|href| Representation.new href: href, hal_client: hal_client }
378
380
 
379
- rescue InvalidRepresentationError => err
381
+ rescue InvalidRepresentationError
380
382
  fail InvalidRepresentationError, "/_links/#{jpointer_esc(link_rel)} is not a valid link"
381
383
  end
382
384
 
@@ -1,3 +1,3 @@
1
1
  class HalClient
2
- VERSION = "3.16.0"
2
+ VERSION = "3.17.0"
3
3
  end
data/lib/hal_client.rb CHANGED
@@ -44,6 +44,7 @@ class HalClient
44
44
  @base_client ||= options[:base_client]
45
45
  @logger = options.fetch(:logger, NullLogger.new)
46
46
  @timeout = options.fetch(:timeout, Float::INFINITY)
47
+ @base_client_with_headers = {}
47
48
 
48
49
  default_message_request_headers.set('Accept', options[:accept]) if
49
50
  options[:accept]
@@ -185,7 +186,7 @@ class HalClient
185
186
  begin
186
187
  Representation.new(hal_client: self, parsed_json: MultiJson.load(resp.to_s),
187
188
  href: location)
188
- rescue MultiJson::ParseError, InvalidRepresentationError => e
189
+ rescue MultiJson::ParseError, InvalidRepresentationError
189
190
  if location
190
191
  # response doesn't have a HAL body but we know what resource
191
192
  # was created so we can be helpful.
@@ -213,13 +214,9 @@ class HalClient
213
214
  # options
214
215
  # :override_headers -
215
216
  def client_for_get(options={})
216
- override_headers = options[:override_headers]
217
+ headers = default_message_request_headers.merge(options[:override_headers])
217
218
 
218
- if !override_headers
219
- @client_for_get ||= base_client.with_headers(default_message_request_headers)
220
- else
221
- client_for_get.with_headers(override_headers)
222
- end
219
+ base_client_with_headers(headers)
223
220
  end
224
221
 
225
222
  # Returns the HTTP client to be used to make post requests.
@@ -227,19 +224,24 @@ class HalClient
227
224
  # options
228
225
  # :override_headers -
229
226
  def client_for_post(options={})
230
- override_headers = options[:override_headers]
227
+ headers = default_entity_and_message_request_headers.merge(options[:override_headers])
231
228
 
232
- if !override_headers
233
- @client_for_post ||=
234
- base_client.with_headers(default_entity_and_message_request_headers)
235
- else
236
- client_for_post.with_headers(override_headers)
237
- end
229
+ base_client_with_headers(headers)
238
230
  end
239
231
 
240
232
  # Returns an HTTP client.
241
233
  def base_client
242
- @base_client ||= HTTP::Client.new(follow: true)
234
+ @base_client ||= begin
235
+ logger.debug 'Created base_client'
236
+ HTTP::Client.new(follow: true)
237
+ end
238
+ end
239
+
240
+ def base_client_with_headers(headers)
241
+ @base_client_with_headers[headers.to_h] ||= begin
242
+ logger.debug { "Created base_client with headers #{headers.inspect}" }
243
+ base_client.with_headers(headers)
244
+ end
243
245
  end
244
246
 
245
247
  attr_reader :default_entity_request_headers, :default_message_request_headers
@@ -249,10 +251,6 @@ class HalClient
249
251
  default_message_request_headers.merge(default_entity_request_headers)
250
252
  end
251
253
 
252
- def default_entity_request_headers
253
- @default_entity_request_headers
254
- end
255
-
256
254
  def entity_header_field?(field_name)
257
255
  [:content_type, /^content-type$/i].any?{|pat| pat === field_name}
258
256
  end
@@ -1,8 +1,6 @@
1
- require_relative "../spec_helper"
2
-
3
1
  require 'hal_client/collection'
4
2
 
5
- describe HalClient::Collection do
3
+ RSpec.describe HalClient::Collection do
6
4
  # BACKGROUND
7
5
 
8
6
  shared_context "multi-item, multi-page" do
@@ -81,7 +79,7 @@ describe HalClient::Collection do
81
79
  context do
82
80
  include_context "multi-item, multi-page"
83
81
 
84
- specify { expect { collection.count }.to raise_exception }
82
+ specify { expect { collection.count }.to raise_exception(NotImplementedError) }
85
83
  end
86
84
  end
87
85
 
@@ -1,8 +1,6 @@
1
- require_relative "../spec_helper"
2
-
3
1
  require 'hal_client/curie_resolver'
4
2
 
5
- describe HalClient::CurieResolver do
3
+ RSpec.describe HalClient::CurieResolver do
6
4
  describe "#new" do
7
5
  it "takes an array of curie definitions" do
8
6
  expect(described_class.new([f_ns, b_ns])).to be_kind_of described_class
@@ -1,10 +1,8 @@
1
1
  require 'hal-client'
2
2
 
3
- require_relative "../spec_helper"
4
-
5
3
  require "hal_client/link"
6
4
 
7
- describe HalClient::Link do
5
+ RSpec.describe HalClient::Link do
8
6
 
9
7
  subject(:link) { described_class.new(rel: rel_1, target: repr_1) }
10
8
 
@@ -1,7 +1,6 @@
1
- require "spec_helper"
2
1
  require 'hal-client'
3
2
 
4
- describe HalClient::LinksSection, "namespaces embedded" do
3
+ RSpec.describe HalClient::LinksSection, "namespaces embedded" do
5
4
  subject(:section) {
6
5
  described_class.new(raw_section,
7
6
  base_url: Addressable::URI.parse("http://example.com/foo"))
@@ -21,7 +20,7 @@ describe HalClient::LinksSection, "namespaces embedded" do
21
20
 
22
21
  specify { expect(section.hrefs(fully_qualified_second_rel))
23
22
  .to contain_exactly "http://example.com/bar", "http://example.com/baz" }
24
-
23
+
25
24
  specify { expect(section.hrefs("ns2:second"))
26
25
  .to contain_exactly "http://example.com/bar", "http://example.com/baz" }
27
26
 
@@ -56,7 +55,7 @@ describe HalClient::LinksSection, "namespaces embedded" do
56
55
  end
57
56
  end
58
57
 
59
- describe HalClient::LinksSection, "invalid" do
58
+ RSpec.describe HalClient::LinksSection, "invalid" do
60
59
  subject(:section) {
61
60
  described_class.new(raw_section,
62
61
  base_url: Addressable::URI.parse("http://example.com/"))
@@ -69,4 +68,4 @@ describe HalClient::LinksSection, "invalid" do
69
68
  { "bareurl" => "http://example.com/boom" }
70
69
  }
71
70
 
72
- end
71
+ end
@@ -1,4 +1,3 @@
1
- require_relative "../spec_helper"
2
1
  require "hal_client/representation_editor"
3
2
 
4
3
  RSpec.describe HalClient::RepresentationEditor do
@@ -1,14 +1,12 @@
1
- require_relative '../spec_helper'
2
-
3
1
  require 'hal_client'
4
2
  require 'hal_client/representation'
5
3
  require 'hal_client/representation_set'
6
4
 
7
- describe HalClient::RepresentationSet do
5
+ RSpec.describe HalClient::RepresentationSet do
8
6
  describe "#new" do
9
7
  let!(:return_val) { described_class.new([foo_repr, bar_repr]) }
10
- it { should be_kind_of described_class }
11
- it { should have(2).items }
8
+ it { is_expected.to be_kind_of described_class }
9
+ it { is_expected.to have(2).items }
12
10
  end
13
11
 
14
12
  subject(:repr_set) { described_class.new([foo_repr, bar_repr]) }
@@ -41,25 +39,25 @@ describe HalClient::RepresentationSet do
41
39
  describe "#related" do
42
40
  context "single target in each member" do
43
41
  subject(:returned_val) { repr_set.related("spouse") }
44
- it { should include_representation_of "http://example.com/foo-spouse" }
45
- it { should include_representation_of "http://example.com/bar-spouse" }
46
- it { should have(2).items }
42
+ it { is_expected.to include_representation_of "http://example.com/foo-spouse" }
43
+ it { is_expected.to include_representation_of "http://example.com/bar-spouse" }
44
+ it { is_expected.to have(2).items }
47
45
  end
48
46
 
49
47
  context "multiple targets" do
50
48
  subject(:returned_val) { repr_set.related("sibling") }
51
- it { should include_representation_of "http://example.com/foo-brother" }
52
- it { should include_representation_of "http://example.com/foo-sister" }
53
- it { should include_representation_of "http://example.com/bar-brother" }
54
- it { should have(3).items }
49
+ it { is_expected.to include_representation_of "http://example.com/foo-brother" }
50
+ it { is_expected.to include_representation_of "http://example.com/foo-sister" }
51
+ it { is_expected.to include_representation_of "http://example.com/bar-brother" }
52
+ it { is_expected.to have(3).items }
55
53
  end
56
54
 
57
55
  context "templated" do
58
56
  subject(:returned_val) { repr_set.related("cousin", distance: "first") }
59
- it { should include_representation_of "http://example.com/foo-first-cousin" }
60
- it { should include_representation_of "http://example.com/bar-paternal-first-cousin" }
61
- it { should include_representation_of "http://example.com/bar-maternal-first-cousin" }
62
- it { should have(3).items }
57
+ it { is_expected.to include_representation_of "http://example.com/foo-first-cousin" }
58
+ it { is_expected.to include_representation_of "http://example.com/bar-paternal-first-cousin" }
59
+ it { is_expected.to include_representation_of "http://example.com/bar-maternal-first-cousin" }
60
+ it { is_expected.to have(3).items }
63
61
  end
64
62
  end
65
63
 
@@ -1,8 +1,6 @@
1
- require_relative "../spec_helper"
2
-
3
1
  require "hal_client/representation"
4
2
 
5
- describe HalClient::Representation do
3
+ RSpec.describe HalClient::Representation do
6
4
  let(:raw_repr) { <<-HAL }
7
5
  { "prop1": 1
8
6
  ,"prop2": 2
@@ -176,12 +174,12 @@ HAL
176
174
  describe "#fetch" do
177
175
  context "for existent property" do
178
176
  subject { repr.fetch "prop1" }
179
- it { should eq 1 }
177
+ it { is_expected.to eq 1 }
180
178
  end
181
179
 
182
180
  context "for existent link" do
183
181
  subject { repr.fetch "link1" }
184
- it { should have(1).item }
182
+ it { is_expected.to have(1).item }
185
183
  it "includes related resource representation" do
186
184
  expect(subject.first.href).to eq "http://example.com/bar"
187
185
  end
@@ -189,7 +187,7 @@ HAL
189
187
 
190
188
  context "for existent embedded" do
191
189
  subject { repr.fetch "embed1" }
192
- it { should have(1).item }
190
+ it { is_expected.to have(1).item }
193
191
  it "includes related resource representation" do
194
192
  expect(subject.first.href).to eq "http://example.com/baz"
195
193
  end
@@ -203,63 +201,63 @@ HAL
203
201
 
204
202
  context "non-existent item w/ default value" do
205
203
  subject { repr.fetch "wat", "whatevs" }
206
- it { should eq "whatevs" }
204
+ it { is_expected.to eq "whatevs" }
207
205
  end
208
206
 
209
207
  context "non-existent item w/ default value generator" do
210
208
  subject { repr.fetch("wat"){|key| key+"gen" } }
211
- it { should eq "watgen" }
209
+ it { is_expected.to eq "watgen" }
212
210
  end
213
211
  end
214
212
 
215
213
  describe "#[]" do
216
214
  context "for existent property" do
217
215
  subject { repr["prop1"] }
218
- it { should eq 1 }
216
+ it { is_expected.to eq 1 }
219
217
  end
220
218
 
221
219
  context "for existent link" do
222
220
  subject { repr["link1"] }
223
- it { should have(1).item }
224
- it { should include_representation_of "http://example.com/bar" }
221
+ it { is_expected.to have(1).item }
222
+ it { is_expected.to include_representation_of "http://example.com/bar" }
225
223
  end
226
224
 
227
225
  context "for existent embedded" do
228
226
  subject { repr["embed1"] }
229
- it { should have(1).item }
230
- it { should include_representation_of "http://example.com/baz" }
227
+ it { is_expected.to have(1).item }
228
+ it { is_expected.to include_representation_of "http://example.com/baz" }
231
229
  end
232
230
 
233
231
  context "non-existent item w/o default" do
234
232
  subject { repr["wat"] }
235
- it { should be_nil }
233
+ it { is_expected.to be_nil }
236
234
  end
237
235
  end
238
236
 
239
237
  describe "#related" do
240
238
  context "for existent link" do
241
239
  subject { repr.related "link1" }
242
- it { should have(1).item }
243
- it { should include_representation_of "http://example.com/bar" }
240
+ it { is_expected.to have(1).item }
241
+ it { is_expected.to include_representation_of "http://example.com/bar" }
244
242
  end
245
243
 
246
244
  context "for existent compound link" do
247
245
  subject { repr.related "link3" }
248
- it { should have(2).item }
249
- it { should include_representation_of "http://example.com/link3-a" }
250
- it { should include_representation_of "http://example.com/link3-b" }
246
+ it { is_expected.to have(2).item }
247
+ it { is_expected.to include_representation_of "http://example.com/link3-a" }
248
+ it { is_expected.to include_representation_of "http://example.com/link3-b" }
251
249
  end
252
250
 
253
251
  context "for existent templated link" do
254
252
  subject { repr.related "templated", name: "bob" }
255
- it { should have(1).item }
256
- it { should include_representation_of "http://example.com/people?name=bob" }
253
+ it { is_expected.to have(1).item }
254
+ it { is_expected.to include_representation_of "http://example.com/people?name=bob" }
257
255
  end
258
256
 
259
257
  context "for existent embedded" do
260
258
  subject { repr.related "embed1" }
261
- it { should have(1).item }
262
- it { should include_representation_of "http://example.com/baz" }
259
+ it { is_expected.to have(1).item }
260
+ it { is_expected.to include_representation_of "http://example.com/baz" }
263
261
  end
264
262
 
265
263
  context "non-existent item w/o default" do
@@ -319,17 +317,17 @@ HAL
319
317
 
320
318
  describe "#related return value" do
321
319
  subject(:return_val) { repr.related("http://example.com/rels/bar") }
322
- it { should include_representation_of "http://example.com/bar" }
320
+ it { is_expected.to include_representation_of "http://example.com/bar" }
323
321
  end
324
322
 
325
323
  describe "#[] return value" do
326
324
  subject(:return_val) { repr["http://example.com/rels/bar"] }
327
- it { should include_representation_of "http://example.com/bar" }
325
+ it { is_expected.to include_representation_of "http://example.com/bar" }
328
326
  end
329
327
 
330
328
  describe "#related_hrefs return value" do
331
329
  subject(:return_val) { repr.related_hrefs("http://example.com/rels/bar") }
332
- it { should include "http://example.com/bar" }
330
+ it { is_expected.to include "http://example.com/bar" }
333
331
  end
334
332
  end
335
333
 
@@ -347,17 +345,17 @@ HAL
347
345
 
348
346
  describe "#related return value " do
349
347
  subject(:return_val) { repr.related("http://example.com/rels/embed1") }
350
- it { should include_representation_of "http://example.com/embed1" }
348
+ it { is_expected.to include_representation_of "http://example.com/embed1" }
351
349
  end
352
350
 
353
351
  describe "#[] return value " do
354
352
  subject(:return_val) { repr["http://example.com/rels/embed1"] }
355
- it { should include_representation_of "http://example.com/embed1" }
353
+ it { is_expected.to include_representation_of "http://example.com/embed1" }
356
354
  end
357
355
 
358
356
  describe "#related_hrefs return value " do
359
357
  subject(:return_val) { repr.related_hrefs("http://example.com/rels/embed1") }
360
- it { should include "http://example.com/embed1" }
358
+ it { is_expected.to include "http://example.com/embed1" }
361
359
  end
362
360
  end
363
361
 
@@ -409,8 +407,8 @@ HAL
409
407
  end
410
408
 
411
409
  context "non-collection" do
412
- specify { expect{repr.as_enum}.to raise_error }
413
- specify { expect{repr.to_enum}.to raise_error }
410
+ specify { expect{repr.as_enum}.to raise_error(HalClient::NotACollectionError) }
411
+ specify { expect{repr.to_enum}.to raise_error(HalClient::NotACollectionError) }
414
412
  end
415
413
 
416
414
  # Background
@@ -473,7 +471,7 @@ HAL
473
471
 
474
472
  end
475
473
 
476
- describe HalClient::Representation, "w/o hal_client" do
474
+ RSpec.describe HalClient::Representation, "w/o hal_client" do
477
475
  subject(:repr) { described_class.new(parsed_json: MultiJson.load(raw_repr)) }
478
476
 
479
477
  specify { expect(subject.href).to eq "http://example.com/foo" }
@@ -1,17 +1,17 @@
1
- require_relative "./spec_helper"
2
1
  require "hal_client"
2
+ require 'http'
3
3
 
4
- describe HalClient do
4
+ RSpec.describe HalClient do
5
5
  describe ".new()" do
6
6
  subject { HalClient.new }
7
- it { should be_kind_of HalClient }
7
+ it { is_expected.to be_kind_of HalClient }
8
8
  end
9
9
 
10
10
  subject(:client) { HalClient.new }
11
11
 
12
12
  describe '.new w/ custom accept' do
13
13
  subject { HalClient.new(accept: "application/vnd.myspecialmediatype") }
14
- it { should be_kind_of HalClient }
14
+ it { is_expected.to be_kind_of HalClient }
15
15
  end
16
16
 
17
17
  describe "#get(<url>)" do
@@ -24,7 +24,7 @@ describe HalClient do
24
24
 
25
25
  describe "request" do
26
26
  subject { request }
27
- it("should have been made") { should have_been_made }
27
+ it("should have been made") { is_expected.to have_been_made }
28
28
 
29
29
  it "sends accept header" do
30
30
  expect(request.with(headers: {'Accept' => /application\/hal\+json/i})).
@@ -87,6 +87,43 @@ describe HalClient do
87
87
  end
88
88
  end
89
89
 
90
+ context "client reuse" do
91
+ let(:return_val) { nil }
92
+ let(:base_client) { instance_double('HTTP::Client') }
93
+ let(:real_client) { HTTP::Client.new }
94
+ subject(:client) { HalClient.new(base_client: base_client) }
95
+
96
+ it 'creates a base client with headers' do
97
+ expect(base_client).to receive(:with_headers) do |headers|
98
+ expect(headers.to_h).to include('Accept' => 'application/hal+json;q=0')
99
+
100
+ real_client
101
+ end
102
+
103
+ client.get "http://example.com/foo"
104
+ end
105
+
106
+ it 'reuses base client with headers instances' do
107
+ expect(base_client).to receive(:with_headers) do |headers|
108
+ expect(headers.to_h).to include('Accept' => 'application/hal+json;q=0', 'Foo' => 'Bar')
109
+
110
+ real_client
111
+ end.once
112
+
113
+ client.get("http://example.com/foo", 'Foo' => 'Bar')
114
+
115
+ expect(base_client).to receive(:with_headers) do |headers|
116
+ expect(headers.to_h).to include('Accept' => 'application/hal+json;q=0', 'Hello' => 'World')
117
+
118
+ real_client
119
+ end.once
120
+
121
+ client.get("http://example.com/foo", 'Hello' => 'World')
122
+
123
+ client.get("http://example.com/foo", 'Foo' => 'Bar')
124
+ client.get("http://example.com/foo", 'Hello' => 'World')
125
+ end
126
+ end
90
127
  end
91
128
 
92
129
  context "server takes too long" do
@@ -173,7 +210,7 @@ describe HalClient do
173
210
 
174
211
  describe "request" do
175
212
  subject { request }
176
- it("should have been made") { should have_been_made }
213
+ it("should have been made") { is_expected.to have_been_made }
177
214
 
178
215
  it "sends accept header" do
179
216
  expect(request.with(headers: {'Accept' => /application\/hal\+json/})).
@@ -211,7 +248,7 @@ describe HalClient do
211
248
  describe "request" do
212
249
  before do return_val end
213
250
  subject { post_request }
214
- it("should have been made") { should have_been_made }
251
+ it("should have been made") { is_expected.to have_been_made }
215
252
 
216
253
  it "sends content type header" do
217
254
  expect(post_request.with(headers: {'Content-Type' => 'application/hal+json'})).
@@ -223,7 +260,7 @@ describe HalClient do
223
260
  let(:return_val) { client.post url, post_data, "Content-Type" => "text/plain" }
224
261
  before do return_val end
225
262
  subject { post_request }
226
- it("should have been made") { should have_been_made }
263
+ it("should have been made") { is_expected.to have_been_made }
227
264
 
228
265
  it "sends content type header" do
229
266
  expect(post_request.with(headers: {'Content-Type' => 'text/plain'})).
@@ -280,6 +317,43 @@ describe HalClient do
280
317
  expect(logger.info_entries.first).to include "http://example.com/foo"
281
318
  end
282
319
  end
320
+
321
+ context "client reuse" do
322
+ let(:base_client) { instance_double('HTTP::Client') }
323
+ let(:real_client) { HTTP::Client.new }
324
+ subject(:client) { HalClient.new(base_client: base_client) }
325
+
326
+ it 'creates a base client with headers' do
327
+ expect(base_client).to receive(:with_headers) do |headers|
328
+ expect(headers.to_h).to include('Accept' => 'application/hal+json;q=0')
329
+
330
+ real_client
331
+ end
332
+
333
+ client.post(url, post_data)
334
+ end
335
+
336
+ it 'reuses base client with headers instances' do
337
+ expect(base_client).to receive(:with_headers) do |headers|
338
+ expect(headers.to_h).to include('Accept' => 'application/hal+json;q=0', 'Foo' => 'Bar')
339
+
340
+ real_client
341
+ end.once
342
+
343
+ client.post(url, post_data, 'Foo' => 'Bar')
344
+
345
+ expect(base_client).to receive(:with_headers) do |headers|
346
+ expect(headers.to_h).to include('Accept' => 'application/hal+json;q=0', 'Hello' => 'World')
347
+
348
+ real_client
349
+ end.once
350
+
351
+ client.post(url, post_data, 'Hello' => 'World')
352
+
353
+ client.post(url, post_data, 'Foo' => 'Bar')
354
+ client.post(url, post_data, 'Hello' => 'World')
355
+ end
356
+ end
283
357
  end
284
358
 
285
359
  describe ".post(<url>)" do
@@ -291,7 +365,7 @@ describe HalClient do
291
365
 
292
366
  describe "request" do
293
367
  subject { post_request }
294
- it("should have been made") { should have_been_made }
368
+ it("should have been made") { is_expected.to have_been_made }
295
369
 
296
370
  it "sends accept header" do
297
371
  expect(post_request.with(headers: {'Content-Type' => 'application/hal+json'})).
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,78 @@
1
+ # This file was generated by the `rspec --init` command.
2
+ #
3
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
4
+ RSpec.configure do |config|
5
+ config.expect_with :rspec do |expectations|
6
+ # This option will default to `true` in RSpec 4.
7
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
8
+ end
9
+
10
+ config.mock_with :rspec do |mocks|
11
+ # Prevents you from mocking or stubbing a method that does not exist on
12
+ # a real object. This is generally recommended, and will default to
13
+ # `true` in RSpec 4.
14
+ mocks.verify_partial_doubles = true
15
+ end
16
+
17
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
18
+ # have no way to turn it off -- the option exists only for backwards
19
+ # compatibility in RSpec 3). It causes shared context metadata to be
20
+ # inherited by the metadata hash of host groups and examples, rather than
21
+ # triggering implicit auto-inclusion in groups with matching metadata.
22
+ config.shared_context_metadata_behavior = :apply_to_host_groups
23
+
24
+ # This allows you to limit a spec run to individual examples or groups
25
+ # you care about by tagging them with `:focus` metadata. When nothing
26
+ # is tagged with `:focus`, all examples get run. RSpec also provides
27
+ # aliases for `it`, `describe`, and `context` that include `:focus`
28
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
29
+ config.filter_run_when_matching :focus
30
+
31
+ # Allows RSpec to persist some state between runs in order to support
32
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
33
+ # you configure your source control system to ignore this file.
34
+ config.example_status_persistence_file_path = "spec/examples.txt"
35
+
36
+ # Limits the available syntax to the non-monkey patched syntax that is
37
+ # recommended.
38
+ config.disable_monkey_patching!
39
+
40
+ # This setting enables warnings. It's recommended, but in some cases may
41
+ # be too noisy due to issues in dependencies.
42
+ config.warnings = true
43
+
44
+ # Many RSpec users commonly either run the entire suite or an individual
45
+ # file, and it's useful to allow more verbose output when running an
46
+ # individual spec file.
47
+ if config.files_to_run.one?
48
+ # Use the documentation formatter for detailed output,
49
+ # unless a formatter has already been configured
50
+ # (e.g. via a command-line flag).
51
+ config.default_formatter = 'doc'
52
+ end
53
+
54
+ # Print the n slowest examples and example groups at the
55
+ # end of the spec run, to help surface which specs are running
56
+ # particularly slow.
57
+ config.profile_examples = 5
58
+
59
+ # Run specs in random order to surface order dependencies. If you find an
60
+ # order dependency and want to debug it, you can fix the order by providing
61
+ # the seed, which is printed after each run.
62
+ # --seed 1234
63
+ config.order = :random
64
+
65
+ # Seed global randomization in this process using the `--seed` CLI option.
66
+ # Setting this allows you to use `--seed` to deterministically reproduce
67
+ # test failures related to randomization by passing the same `--seed` value
68
+ # as the one that triggered the failure.
69
+ Kernel.srand config.seed
70
+ end
71
+
72
+ # hal_client-specific additions
73
+
1
74
  $LOAD_PATH << Pathname(__FILE__).dirname + "../lib"
2
75
 
3
- require 'rspec'
4
76
  require 'webmock/rspec'
5
77
  require 'multi_json'
6
78
  require 'rspec/collection_matchers'
@@ -9,4 +81,4 @@ require 'support/custom_matchers'
9
81
 
10
82
  RSpec.configure do |config|
11
83
  config.include CustomMatchers
12
- end
84
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hal-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.16.0
4
+ version: 3.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-20 00:00:00.000000000 Z
11
+ date: 2016-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 3.0.0.beta
89
+ version: '3.5'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 3.0.0.beta
96
+ version: '3.5'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: webmock
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -128,6 +128,20 @@ dependencies:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: pry
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
131
145
  description: An easy to use interface for REST APIs that use HAL.
132
146
  email:
133
147
  - pezra@barelyenough.org
@@ -136,6 +150,7 @@ extensions: []
136
150
  extra_rdoc_files: []
137
151
  files:
138
152
  - ".gitignore"
153
+ - ".rspec"
139
154
  - ".travis.yml"
140
155
  - Gemfile
141
156
  - LICENSE.txt
@@ -198,4 +213,3 @@ test_files:
198
213
  - spec/hal_client_spec.rb
199
214
  - spec/spec_helper.rb
200
215
  - spec/support/custom_matchers.rb
201
- has_rdoc: