hyperclient 1.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +18 -0
  3. data/.github/workflows/coverage.yml +21 -0
  4. data/.github/workflows/danger-comment.yml +11 -0
  5. data/.github/workflows/danger.yml +13 -0
  6. data/.github/workflows/lint.yml +16 -0
  7. data/.github/workflows/test.yml +28 -0
  8. data/.gitignore +1 -0
  9. data/.rubocop.yml +5 -0
  10. data/.rubocop_todo.yml +40 -31
  11. data/AGENTS.md +26 -0
  12. data/CHANGELOG.md +21 -3
  13. data/CONTRIBUTING.md +11 -1
  14. data/Dangerfile +2 -0
  15. data/Gemfile +10 -7
  16. data/README.md +49 -44
  17. data/RELEASING.md +47 -41
  18. data/Rakefile +0 -8
  19. data/examples/oxford/README.md +42 -0
  20. data/examples/oxford/app.rb +48 -0
  21. data/examples/oxford/client.rb +13 -0
  22. data/examples/oxford/places.json +21 -0
  23. data/examples/oxford/server.rb +13 -0
  24. data/features/steps/api_navigation.rb +3 -3
  25. data/features/steps/default_config.rb +2 -2
  26. data/features/support/api.rb +22 -11
  27. data/features/support/env.rb +15 -1
  28. data/hyperclient.gemspec +4 -4
  29. data/lib/hyperclient/entry_point.rb +3 -3
  30. data/lib/hyperclient/link.rb +13 -4
  31. data/lib/hyperclient/resource.rb +13 -3
  32. data/lib/hyperclient/resource_collection.rb +1 -3
  33. data/lib/hyperclient/version.rb +1 -1
  34. data/test/hyperclient/attributes_test.rb +9 -0
  35. data/test/hyperclient/collection_test.rb +22 -0
  36. data/test/hyperclient/curie_test.rb +7 -0
  37. data/test/hyperclient/entry_point_test.rb +35 -13
  38. data/test/hyperclient/link_collection_test.rb +10 -0
  39. data/test/hyperclient/link_test.rb +128 -1
  40. data/test/hyperclient/resource_test.rb +36 -2
  41. data/test/hyperclient_test.rb +6 -5
  42. data/test/oxford_example_test.rb +52 -0
  43. data/test/test_helper.rb +19 -1
  44. metadata +25 -33
  45. data/.travis.yml +0 -24
  46. data/examples/splines_api.rb +0 -39
@@ -32,6 +32,7 @@ module Hyperclient
32
32
 
33
33
  describe 'plain link' do
34
34
  let(:plain_link) { links.self }
35
+
35
36
  it 'must be correct' do
36
37
  _(plain_link._url).must_equal '/productions/1'
37
38
  end
@@ -39,6 +40,7 @@ module Hyperclient
39
40
 
40
41
  describe 'templated link' do
41
42
  let(:templated_link) { links.search }
43
+
42
44
  it 'must expand' do
43
45
  _(templated_link._expand(search: 'gizmos')._url).must_equal '/productions/1?categories=gizmos'
44
46
  end
@@ -47,6 +49,7 @@ module Hyperclient
47
49
  describe 'curied link collection' do
48
50
  let(:curied_link) { links['image:thumbnail'] }
49
51
  let(:curie) { links._curies['image'] }
52
+
50
53
  it 'must expand' do
51
54
  _(curied_link._expand(version: 'small')._url).must_equal '/images/thumbnails/small.jpg'
52
55
  end
@@ -71,9 +74,16 @@ module Hyperclient
71
74
 
72
75
  describe 'null link value' do
73
76
  let(:null_link) { links.null_link }
77
+
74
78
  it 'must be nil' do
75
79
  _(null_link).must_be_nil
76
80
  end
77
81
  end
82
+
83
+ describe 'invalid collection' do
84
+ it 'raises an error when the collection does not respond to collect' do
85
+ _(proc { LinkCollection.new('invalid', {}, entry_point) }).must_raise RuntimeError
86
+ end
87
+ end
78
88
  end
79
89
  end
@@ -11,11 +11,13 @@ module Hyperclient
11
11
  describe prop do
12
12
  it 'returns the property value' do
13
13
  link = Link.new('key', { prop => 'value' }, entry_point)
14
+
14
15
  _(link.send("_#{prop}")).must_equal 'value'
15
16
  end
16
17
 
17
18
  it 'returns nil if the property is not present' do
18
19
  link = Link.new('key', {}, entry_point)
20
+
19
21
  _(link.send("_#{prop}")).must_be_nil
20
22
  end
21
23
  end
@@ -53,11 +55,13 @@ module Hyperclient
53
55
  describe 'required argument' do
54
56
  it 'builds a Link with the templated URI representation' do
55
57
  link = Link.new('key', { 'href' => '/orders/{id}', 'templated' => true }, entry_point)
58
+
56
59
  _(link._expand(id: '1')._url).must_equal '/orders/1'
57
60
  end
58
61
 
59
62
  it 'expands an uri template without variables' do
60
63
  link = Link.new('key', { 'href' => '/orders/{id}', 'templated' => true }, entry_point)
64
+
61
65
  _(link._expand._url).must_equal '/orders/'
62
66
  _(link._url).must_equal '/orders/'
63
67
  end
@@ -66,27 +70,32 @@ module Hyperclient
66
70
  describe 'query string argument' do
67
71
  it 'builds a Link with the templated URI representation' do
68
72
  link = Link.new('key', { 'href' => '/orders{?id}', 'templated' => true }, entry_point)
73
+
69
74
  _(link._expand(id: '1')._url).must_equal '/orders?id=1'
70
75
  end
71
76
 
72
77
  it 'expands an uri template without variables' do
73
78
  link = Link.new('key', { 'href' => '/orders{?id}', 'templated' => true }, entry_point)
79
+
74
80
  _(link._expand._url).must_equal '/orders'
75
81
  _(link._url).must_equal '/orders'
76
82
  end
77
83
 
78
84
  it 'does not expand unknown variables' do
79
85
  link = Link.new('key', { 'href' => '/orders{?id}', 'templated' => true }, entry_point)
86
+
80
87
  _(link._expand(unknown: '1')._url).must_equal '/orders'
81
88
  end
82
89
 
83
90
  it 'only expands known variables' do
84
91
  link = Link.new('key', { 'href' => '/orders{?id}', 'templated' => true }, entry_point)
92
+
85
93
  _(link._expand(unknown: '1', id: '2')._url).must_equal '/orders?id=2'
86
94
  end
87
95
 
88
96
  it 'only expands templated links' do
89
97
  link = Link.new('key', { 'href' => '/orders{?id}', 'templated' => false }, entry_point)
98
+
90
99
  _(link._expand(id: '1')._url).must_equal '/orders{?id}'
91
100
  end
92
101
  end
@@ -119,6 +128,7 @@ module Hyperclient
119
128
 
120
129
  it 'returns the link when no uri template' do
121
130
  link = Link.new('key', { 'href' => '/orders' }, entry_point)
131
+
122
132
  _(link._url).must_equal '/orders'
123
133
  end
124
134
 
@@ -141,9 +151,53 @@ module Hyperclient
141
151
 
142
152
  link._resource
143
153
  end
154
+
155
+ it 'fetches a fresh resource after a mutating request instead of returning the cached response (#107)' do
156
+ link = Link.new('key', { 'href' => '/productions/1' }, entry_point)
157
+
158
+ stub_request(entry_point.connection) do |stub|
159
+ stub.post('http://api.example.org/productions/1') { [201, {}, { 'status' => 'created' }] }
160
+ stub.get('http://api.example.org/productions/1') { [200, {}, { 'status' => 'fetched' }] }
161
+ end
162
+
163
+ link._post('foo' => 'bar')
164
+
165
+ _(link._resource.status).must_equal 'fetched'
166
+ end
144
167
  end
145
168
 
146
169
  describe 'get' do
170
+ %w[application/hal+json application/json].each do |content_type|
171
+ it "parses a #{content_type} response into a resource" do
172
+ link = Link.new('key', { 'href' => '/productions/1' }, entry_point)
173
+
174
+ stub_request(entry_point.connection) do |stub|
175
+ stub.get('http://api.example.org/productions/1') do
176
+ [200, { 'Content-Type' => content_type },
177
+ '{"title":"Production","_links":{"self":{"href":"/productions/1"}}}']
178
+ end
179
+ end
180
+
181
+ resource = link._get
182
+
183
+ _(resource.title).must_equal 'Production'
184
+ _(resource._links.self._url).must_equal '/productions/1'
185
+ _(resource._response.body).must_be_kind_of Hash
186
+ end
187
+ end
188
+
189
+ it 'raises a parsing error for an invalid JSON response' do
190
+ link = Link.new('key', { 'href' => '/productions/1' }, entry_point)
191
+
192
+ stub_request(entry_point.connection) do |stub|
193
+ stub.get('http://api.example.org/productions/1') do
194
+ [200, { 'Content-Type' => 'application/hal+json' }, '{"title":']
195
+ end
196
+ end
197
+
198
+ _(-> { link._get }).must_raise Faraday::ParsingError
199
+ end
200
+
147
201
  it 'sends a GET request with the link url' do
148
202
  link = Link.new('key', { 'href' => '/productions/1' }, entry_point)
149
203
 
@@ -266,7 +320,7 @@ module Hyperclient
266
320
  link = Link.new('key', { 'href' => '/productions/1' }, 'foo')
267
321
 
268
322
  _(link.inspect).must_include 'Link'
269
- _(link.inspect).must_include '"href"=>"/productions/1"'
323
+ _(link.inspect).must_include({ 'href' => '/productions/1' }.inspect)
270
324
  end
271
325
  end
272
326
 
@@ -313,6 +367,37 @@ module Hyperclient
313
367
 
314
368
  _(resource.next._links.next._url).must_equal 'http://api.example.org/page3'
315
369
  end
370
+
371
+ it 'iterates over paginated, embedded items across pages' do
372
+ resource = Resource.new({ '_links' => { 'orders' => { 'href' => '/orders' } } }, entry_point)
373
+
374
+ stub_request(entry_point.connection) do |stub|
375
+ stub.get('http://api.example.org/orders') do
376
+ [200, {}, { '_links' => { 'next' => { 'href' => 'http://api.example.org/orders?page=2' } },
377
+ '_embedded' => { 'orders' => [{ 'id' => 1 }] } }]
378
+ end
379
+ stub.get('http://api.example.org/orders?page=2') do
380
+ [200, {}, { '_embedded' => { 'orders' => [{ 'id' => 2 }] } }]
381
+ end
382
+ end
383
+
384
+ ids = resource._links.orders.map(&:id)
385
+
386
+ _(ids).must_equal [1, 2]
387
+ end
388
+
389
+ it 'returns an Enumerator when called without a block' do
390
+ resource = Resource.new({ '_links' => { 'orders' => { 'href' => '/orders' } } }, entry_point)
391
+
392
+ stub_request(entry_point.connection) do |stub|
393
+ stub.get('http://api.example.org/orders') { [200, {}, { '_embedded' => { 'orders' => [{ 'id' => 1 }] } }] }
394
+ end
395
+
396
+ enum = resource._links.orders.each
397
+
398
+ _(enum).must_be_kind_of Enumerator
399
+ _(enum.to_a.first.id).must_equal 1
400
+ end
316
401
  end
317
402
 
318
403
  describe 'resource' do
@@ -341,13 +426,55 @@ module Hyperclient
341
426
  it 'responds to missing methods' do
342
427
  resource.expects(:respond_to?).with('orders').returns(false)
343
428
  resource.expects(:respond_to?).with('embedded').returns(true)
429
+
344
430
  _(link.respond_to?(:embedded)).must_equal true
345
431
  end
346
432
 
433
+ it 'responds to missing methods that delegate to another resource' do
434
+ delegate = mock('Delegate')
435
+ resource.expects(:respond_to?).with('orders').returns(true)
436
+ resource.expects(:send).with('orders').returns(delegate)
437
+ delegate.expects(:respond_to?).with('foo').returns(true)
438
+
439
+ _(link.respond_to?(:foo)).must_equal true
440
+ end
441
+
347
442
  it 'does not delegate to_ary to resource' do
348
443
  resource.expects(:to_ary).never
444
+
349
445
  _([[link, link]].flatten).must_equal [link, link]
350
446
  end
447
+
448
+ it 'delegates through delegate_method when the resource responds but returns nil' do
449
+ delegate = mock('Delegate')
450
+ resource.expects(:respond_to?).with('foo').returns(true)
451
+ resource.expects(:send).with(:foo).returns(nil)
452
+ resource.expects(:respond_to?).with('orders').returns(true)
453
+ resource.expects(:send).with('orders').returns(delegate)
454
+ delegate.expects(:respond_to?).with('foo').returns(true)
455
+ delegate.expects(:send).with(:foo).returns('delegated result')
456
+
457
+ _(link.foo).must_equal 'delegated result'
458
+ end
459
+
460
+ it 'returns nil from delegate_method when the resource has no matching key' do
461
+ keyless_link = Link.new(nil, { 'href' => 'http://myapi.org/orders' }, entry_point)
462
+ resource.expects(:respond_to?).with('foo').returns(true)
463
+ resource.expects(:send).with(:foo).returns(nil)
464
+
465
+ _(keyless_link.foo).must_be_nil
466
+ end
467
+
468
+ it 'returns nil from delegate_method when the delegate does not respond to the method' do
469
+ delegate = mock('Delegate')
470
+ resource.expects(:respond_to?).with('foo').returns(true)
471
+ resource.expects(:send).with(:foo).returns(nil)
472
+ resource.expects(:respond_to?).with('orders').returns(true)
473
+ resource.expects(:send).with('orders').returns(delegate)
474
+ delegate.expects(:respond_to?).with('foo').returns(false)
475
+
476
+ _(link.foo).must_be_nil
477
+ end
351
478
  end
352
479
  end
353
480
  end
@@ -13,7 +13,7 @@ module Hyperclient
13
13
  end
14
14
 
15
15
  it 'initializes its attributes' do
16
- Attributes.expects(:new).with(foo: :bar)
16
+ Attributes.expects(:new).with({ foo: :bar })
17
17
 
18
18
  Resource.new({ foo: :bar }, entry_point)
19
19
  end
@@ -60,7 +60,9 @@ module Hyperclient
60
60
 
61
61
  describe '_links' do
62
62
  it '_expand' do
63
- resource = Resource.new({ '_links' => { 'orders' => { 'href' => '/orders/{id}', 'templated' => true } } }, entry_point)
63
+ resource = Resource.new({ '_links' => { 'orders' => { 'href' => '/orders/{id}', 'templated' => true } } },
64
+ entry_point)
65
+
64
66
  _(resource._links.orders._expand(id: 1)._url).must_equal '/orders/1'
65
67
  _(resource.orders._expand(id: 1)._url).must_equal '/orders/1'
66
68
  _(resource.orders(id: 1)._url).must_equal '/orders/1'
@@ -93,16 +95,19 @@ module Hyperclient
93
95
  describe 'method_missing' do
94
96
  it 'delegates to attributes' do
95
97
  resource._attributes.expects(:foo).returns('bar')
98
+
96
99
  _(resource.foo).must_equal 'bar'
97
100
  end
98
101
 
99
102
  it 'delegates to links' do
100
103
  resource._links.expects(:foo).returns('bar')
104
+
101
105
  _(resource.foo).must_equal 'bar'
102
106
  end
103
107
 
104
108
  it 'delegates to embedded' do
105
109
  resource._embedded.expects(:foo).returns('bar')
110
+
106
111
  _(resource.foo).must_equal 'bar'
107
112
  end
108
113
 
@@ -110,11 +115,13 @@ module Hyperclient
110
115
  resource._attributes.expects('respond_to?').with('foo').returns(false)
111
116
  resource._links.expects('respond_to?').with('foo').returns(false)
112
117
  resource._embedded.expects('respond_to?').with('foo').returns(false)
118
+
113
119
  _(-> { resource.foo }).must_raise NoMethodError
114
120
  end
115
121
 
116
122
  it 'delegates []' do
117
123
  resource._attributes.expects(:foo).returns('bar')
124
+
118
125
  _(resource['foo']).must_equal 'bar'
119
126
  end
120
127
 
@@ -132,6 +139,7 @@ module Hyperclient
132
139
  describe 'with a default value' do
133
140
  it 'returns the value for keys that exist' do
134
141
  resource._attributes.expects(:foo).returns('bar')
142
+
135
143
  _(resource.fetch('foo', 'default value')).must_equal 'bar'
136
144
  end
137
145
 
@@ -143,6 +151,7 @@ module Hyperclient
143
151
  describe 'with a block' do
144
152
  it 'returns the value for keys that exist' do
145
153
  resource._attributes.expects(:foo).returns('bar')
154
+
146
155
  _(resource.fetch('foo') { 'default value' }).must_equal 'bar'
147
156
  end
148
157
 
@@ -219,5 +228,30 @@ module Hyperclient
219
228
  end
220
229
  end
221
230
  end
231
+
232
+ describe 'inspect' do
233
+ it 'outputs a custom-friendly output' do
234
+ resource = Resource.new({ '_links' => { 'self' => { 'href' => '/orders/523' } }, 'title' => 'Order' },
235
+ entry_point)
236
+
237
+ _(resource.inspect).must_include 'Resource'
238
+ _(resource.inspect).must_include 'self_link:'
239
+ _(resource.inspect).must_include 'attributes:'
240
+ end
241
+ end
242
+
243
+ describe '#to_h and #to_hash' do
244
+ let(:resource) do
245
+ Resource.new({ '_links' => {}, 'title' => 'Order', 'total' => 42 }, entry_point)
246
+ end
247
+
248
+ it 'returns the attributes as a Hash from #to_hash' do
249
+ _(resource.to_hash).must_equal('title' => 'Order', 'total' => 42)
250
+ end
251
+
252
+ it 'returns the same result from #to_h as #to_hash' do
253
+ _(resource.to_h).must_equal(resource.to_hash)
254
+ end
255
+ end
222
256
  end
223
257
  end
@@ -13,7 +13,7 @@ describe Hyperclient do
13
13
  let(:client) do
14
14
  Hyperclient.new('http://api.example.org') do |client|
15
15
  client.connection(default: true) do |conn|
16
- conn.use Faraday::Request::OAuth
16
+ conn.use Faraday::Request::Instrumentation
17
17
  end
18
18
  client.headers['Access-Token'] = 'token'
19
19
  end
@@ -31,11 +31,12 @@ describe Hyperclient do
31
31
 
32
32
  it 'creates a Faraday connection with the default block plus any additional handlers' do
33
33
  handlers = client.connection.builder.handlers
34
- _(handlers).must_include Faraday::Request::OAuth
34
+
35
+ _(handlers).must_include Faraday::Request::Instrumentation
35
36
  _(handlers).must_include Faraday::Response::RaiseError
36
- _(handlers).must_include FaradayMiddleware::FollowRedirects
37
- _(handlers).must_include FaradayMiddleware::EncodeHalJson
38
- _(handlers).must_include FaradayMiddleware::ParseHalJson
37
+ _(handlers).must_include Faraday::FollowRedirects::Middleware
38
+ _(handlers).must_include Faraday::HalJson::Request
39
+ _(handlers).must_include Faraday::HalJson::Response
39
40
  end
40
41
  end
41
42
  end
@@ -0,0 +1,52 @@
1
+ require 'test_helper'
2
+ require 'hyperclient'
3
+ require 'webmock'
4
+ require 'stringio'
5
+ require_relative '../examples/oxford/app'
6
+
7
+ describe OxfordExample::App do
8
+ let(:app) { OxfordExample::App.new }
9
+
10
+ before do
11
+ WebMock.enable!
12
+ WebMock.stub_request(:any, %r{\Ahttp://127\.0\.0\.1:9292/}).to_return do |request|
13
+ status, headers, body = app.call('REQUEST_METHOD' => request.method.to_s.upcase,
14
+ 'PATH_INFO' => request.uri.path)
15
+ { status: status, headers: headers, body: body.join }
16
+ end
17
+ end
18
+
19
+ after do
20
+ WebMock.reset!
21
+ WebMock.disable!
22
+ end
23
+
24
+ it 'runs the documented client without external requests' do
25
+ output, = capture_io { load File.expand_path('../examples/oxford/client.rb', __dir__) }
26
+
27
+ _(output).must_include 'Balliol College: Broad Street OX1 3BJ'
28
+ _(output).must_include 'Followed primary_place: Balliol College'
29
+ _(output).must_include 'Archived depiction URL (not fetched):'
30
+ _(output).must_include 'CURIE: /docs/places'
31
+ end
32
+
33
+ it 'supports explicit navigation, hash attributes, and embedded resources' do
34
+ api = Hyperclient.new('http://127.0.0.1:9292/')
35
+ place = api._links.places._embedded.places.first
36
+
37
+ _(place[:name]).must_equal 'Balliol College'
38
+ _(place.to_h['id']).must_equal 'oxpoints:23232339'
39
+ _(place._embedded.files.first.type).must_equal 'depiction'
40
+ _(api._links['oxford:places']._embedded.places.first.name).must_equal 'Balliol College'
41
+ end
42
+
43
+ it 'serves HAL, rejects writes, and reports missing resources' do
44
+ status, headers, = app.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/')
45
+
46
+ _(status).must_equal 200
47
+ _(headers['content-type']).must_equal 'application/hal+json'
48
+ _(app.call('REQUEST_METHOD' => 'POST', 'PATH_INFO' => '/').first).must_equal 405
49
+ _(app.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/missing').first).must_equal 404
50
+ _(app.call('REQUEST_METHOD' => 'HEAD', 'PATH_INFO' => '/').last).must_equal []
51
+ end
52
+ end
data/test/test_helper.rb CHANGED
@@ -1,11 +1,29 @@
1
1
  $LOAD_PATH << 'lib'
2
2
 
3
+ if ENV['COVERAGE']
4
+ require 'simplecov'
5
+ require 'simplecov-lcov'
6
+ SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
7
+ SimpleCov::Formatter::LcovFormatter.config do |c|
8
+ c.report_with_single_file = true
9
+ c.lcov_file_name = 'lcov.info'
10
+ c.single_report_path = 'coverage/lcov.info'
11
+ end
12
+ SimpleCov.start do
13
+ add_filter '/test/'
14
+ add_filter '/features/'
15
+ end
16
+ end
17
+
3
18
  require 'minitest/autorun'
4
19
  require 'minitest/pride'
5
20
  require 'mocha/minitest'
6
21
  require 'json'
7
22
 
8
- MiniTest::Test.class_eval do
23
+ require 'faraday'
24
+ require 'faraday/request/instrumentation'
25
+
26
+ Minitest::Assertions.class_eval do
9
27
  def stub_request(conn, adapter_class = Faraday::Adapter::Test, &stubs_block)
10
28
  adapter_handler = conn.builder.handlers.find { |h| h.klass < Faraday::Adapter }
11
29
  if adapter_handler
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyperclient
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oriol Gual
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-02 00:00:00.000000000 Z
11
+ date: 2026-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -30,16 +30,16 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.0
33
+ version: '2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.9.0
40
+ version: '2'
41
41
  - !ruby/object:Gem::Dependency
42
- name: faraday_hal_middleware
42
+ name: faraday-follow_redirects
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,19 +53,19 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: faraday_middleware
56
+ name: faraday_hal_middleware
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '0.2'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '0.2'
69
69
  description: Hyperclient is a Ruby Hypermedia API client.
70
70
  email:
71
71
  - oriol.gual@gmail.com
@@ -73,11 +73,17 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".github/dependabot.yml"
77
+ - ".github/workflows/coverage.yml"
78
+ - ".github/workflows/danger-comment.yml"
79
+ - ".github/workflows/danger.yml"
80
+ - ".github/workflows/lint.yml"
81
+ - ".github/workflows/test.yml"
76
82
  - ".gitignore"
77
83
  - ".rubocop.yml"
78
84
  - ".rubocop_todo.yml"
79
- - ".travis.yml"
80
85
  - ".yardopts"
86
+ - AGENTS.md
81
87
  - CHANGELOG.md
82
88
  - CONTRIBUTING.md
83
89
  - Dangerfile
@@ -88,7 +94,11 @@ files:
88
94
  - RELEASING.md
89
95
  - Rakefile
90
96
  - UPGRADING.md
91
- - examples/splines_api.rb
97
+ - examples/oxford/README.md
98
+ - examples/oxford/app.rb
99
+ - examples/oxford/client.rb
100
+ - examples/oxford/places.json
101
+ - examples/oxford/server.rb
92
102
  - features/api_navigation.feature
93
103
  - features/default_config.feature
94
104
  - features/steps/api_navigation.rb
@@ -119,10 +129,12 @@ files:
119
129
  - test/hyperclient/resource_collection_test.rb
120
130
  - test/hyperclient/resource_test.rb
121
131
  - test/hyperclient_test.rb
132
+ - test/oxford_example_test.rb
122
133
  - test/test_helper.rb
123
134
  homepage: https://github.com/codegram/hyperclient/
124
135
  licenses: []
125
- metadata: {}
136
+ metadata:
137
+ rubygems_mfa_required: 'true'
126
138
  post_install_message:
127
139
  rdoc_options: []
128
140
  require_paths:
@@ -138,28 +150,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
150
  - !ruby/object:Gem::Version
139
151
  version: '0'
140
152
  requirements: []
141
- rubygems_version: 3.1.3
153
+ rubygems_version: 3.5.16
142
154
  signing_key:
143
155
  specification_version: 4
144
156
  summary: ''
145
- test_files:
146
- - features/api_navigation.feature
147
- - features/default_config.feature
148
- - features/steps/api_navigation.rb
149
- - features/steps/default_config.rb
150
- - features/support/api.rb
151
- - features/support/env.rb
152
- - features/support/fixtures.rb
153
- - test/fixtures/collection.json
154
- - test/fixtures/element.json
155
- - test/fixtures/root.json
156
- - test/hyperclient/attributes_test.rb
157
- - test/hyperclient/collection_test.rb
158
- - test/hyperclient/curie_test.rb
159
- - test/hyperclient/entry_point_test.rb
160
- - test/hyperclient/link_collection_test.rb
161
- - test/hyperclient/link_test.rb
162
- - test/hyperclient/resource_collection_test.rb
163
- - test/hyperclient/resource_test.rb
164
- - test/hyperclient_test.rb
165
- - test/test_helper.rb
157
+ test_files: []
data/.travis.yml DELETED
@@ -1,24 +0,0 @@
1
- language: ruby
2
-
3
- sudo: false
4
-
5
- matrix:
6
- include:
7
- - rvm: 2.6.6
8
- env: FARADAY_VERSION=0.9.0
9
- - rvm: 2.6.6
10
- env: FARADAY_VERSION=0.17.0
11
- - rvm: 2.6.6
12
- env: FARADAY_VERSION="~> 1.0"
13
- - rvm: 2.6.6
14
- script:
15
- - bundle exec danger
16
- - rvm: 2.3.8
17
- - rvm: jruby-9.2.7.0
18
- - rvm: jruby-head
19
- - rvm: ruby-head
20
- allow_failures:
21
- - rvm: ruby-head
22
- - rvm: jruby-head
23
-
24
- bundler_args: --without development
@@ -1,39 +0,0 @@
1
- require 'hyperclient'
2
-
3
- puts "Using Hyperclient #{Hyperclient::VERSION} ..."
4
-
5
- # create a new client
6
- api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api')
7
-
8
- # enumerate splines
9
- api.splines.each do |spline|
10
- puts spline.uuid.to_s
11
- puts " reticulated: #{spline.reticulated ? 'yes' : 'no'}"
12
- puts " thumbnail: #{spline['images:thumbnail']}"
13
- end
14
-
15
- api._links.splines._embedded.splines.each do |_spline|
16
- # ... equivalent to the above
17
- end
18
-
19
- puts '*' * 10
20
-
21
- # retrieve an existing spline
22
- spline = api.spline(uuid: 123)
23
- puts "Spline #{spline.uuid} is #{spline.reticulated ? 'reticulated' : 'not reticulated'}."
24
-
25
- # puts api._links.spline._expand(uuid: 'uuid')._resource._attributes.reticulated
26
-
27
- # spline.to_h
28
-
29
- # create a new spline
30
- spline = api.splines._post(spline: { reticulated: true })
31
- puts "Created a #{spline.reticulated ? 'reticulated' : 'unreticulated'} spline #{spline.uuid}."
32
-
33
- # update an existing spline
34
- spline = api.spline(uuid: 123)._put(spline: { reticulated: true })
35
- puts "Updated spline #{spline.uuid}, now #{spline.reticulated ? 'reticulated' : 'not reticulated'}."
36
-
37
- # delete an existing spline
38
- spline = api.spline(uuid: 123)._delete
39
- puts "Deleted spline #{spline.uuid}."