hyperclient 0.8.5 → 0.8.6

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: 59e7c90ae5eff9f4fcc9b99b104bbde8ae457182
4
- data.tar.gz: d1c162933122ca4f64e3528f997056310672d03e
3
+ metadata.gz: 54fef5d6ab73927e7ac10dbccf6c1be3b4b7e32a
4
+ data.tar.gz: 41bf760d61b6f09bcf6a4526df9dcb04c56f1430
5
5
  SHA512:
6
- metadata.gz: 25c690009c59d36791adb84400db774a7713a752c6ca9daffe42cea2334ccea4b7fc008a174749d5db8496ed1f7542fa7881297ad390f0f218351340c4731d16
7
- data.tar.gz: 04bf4aa53c9ae55096b2eff9627006e22f3abd59af5732589080bd77173a6abe38d8bbc0fbe506d9f3cb0af1d3efe85b0cf8feaa59e3f6d5552192f1caac36ee
6
+ metadata.gz: b669fbd6b1be2cf46568da0e9351524602dc86eb0120168be5c1cbbf9cc22a50ee2f94985f315890507923db4d15f5350770a02b986fc7337bd4d0cec5e3c8ee
7
+ data.tar.gz: f7184b27bc26289af1e05b7f957a2ec44ecdd11bea8546ab608e875ee1c5f5f8d1b2efb8c80d9bd6c005710c4e3dc19c34edb450b4f39845aa10084acd65327a
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2016-12-21 20:00:37 +0000 using RuboCop version 0.42.0.
3
+ # on 2017-08-26 18:01:43 +0100 using RuboCop version 0.42.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -9,9 +9,9 @@
9
9
  # Offense count: 1
10
10
  # Configuration parameters: CountComments.
11
11
  Metrics/ClassLength:
12
- Max: 109
12
+ Max: 110
13
13
 
14
- # Offense count: 89
14
+ # Offense count: 97
15
15
  # Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
16
16
  # URISchemes: http, https
17
17
  Metrics/LineLength:
@@ -4,17 +4,16 @@ sudo: false
4
4
 
5
5
  matrix:
6
6
  include:
7
- - rvm: 2.3.1
7
+ - rvm: 2.4.1
8
+ - rvm: 2.4.1
8
9
  script:
9
10
  - bundle exec danger
10
- - rvm: 2.3.1
11
- - rvm: 2.3.0
12
- - rvm: 2.2.5
13
- - rvm: 2.4.0
11
+ - rvm: jruby-9.1.12.0
12
+ - rvm: jruby-head
13
+ - rvm: 2.2.7
14
+ - rvm: 2.3.4
14
15
  - rvm: rbx-2
15
16
  - rvm: ruby-head
16
- - rvm: jruby-head
17
- - rvm: jruby-9.1.7.0
18
17
  allow_failures:
19
18
  - rvm: ruby-head
20
19
  - rvm: jruby-head
@@ -1,3 +1,10 @@
1
+ ### 0.8.6 (August 27, 2017)
2
+
3
+ * [#122](https://github.com/codegram/hyperclient/pull/122): Improve error message when server returns invalid data - [@ivoanjo](https://github.com/ivoanjo).
4
+ * [#125](https://github.com/codegram/hyperclient/pull/125): Add table of contents to readme and add note asking users to add their projects to the wiki - [@ivoanjo](https://github.com/ivoanjo).
5
+ * [#127](https://github.com/codegram/hyperclient/pull/127): Minor fixes: Fix warnings, and pry-byebug to dev Gemfile and tweak rubocop execution - [@ivoanjo](https://github.com/ivoanjo).
6
+ * [#128](https://github.com/codegram/hyperclient/pull/128): Fix link delegation returning nil for field with value false - [@ivoanjo](https://github.com/ivoanjo).
7
+
1
8
  ### 0.8.5 (July 5, 2017)
2
9
 
3
10
  * [#120](https://github.com/codegram/hyperclient/pull/120): Replace non-working homepage link in gemspec - [@ivoanjo](https://github.com/ivoanjo).
data/Gemfile CHANGED
@@ -8,6 +8,7 @@ group :development do
8
8
  gem 'guard-minitest'
9
9
  gem 'guard-spinach'
10
10
  gem 'pry'
11
+ gem 'pry-byebug', platforms: :ruby
11
12
  end
12
13
 
13
14
  group :development, :test do
data/README.md CHANGED
@@ -8,11 +8,29 @@
8
8
 
9
9
  Hyperclient is a Hypermedia API client written in Ruby. It fully supports [JSON HAL](http://stateless.co/hal_specification.html).
10
10
 
11
- ## Usage
11
+ * [Hyperclient](#hyperclient)
12
+ * [Usage](#usage)
13
+ * [API Client](#api-client)
14
+ * [Resources and Attributes](#resources-and-attributes)
15
+ * [Links and Embedded Resources](#links-and-embedded-resources)
16
+ * [Templated Links](#templated-links)
17
+ * [Curies](#curies)
18
+ * [Attributes](#attributes)
19
+ * [HTTP](#http)
20
+ * [Asynchronous requests](#asynchronous-requests)
21
+ * [Testing Using Hyperclient](#testing-using-hyperclient)
22
+ * [Reference](#reference)
23
+ * [Hyperclient Users](#hyperclient-users)
24
+ * [Contributing](#contributing)
25
+ * [License](#license)
26
+
27
+ <sub><sup>ToC created with [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)</sup></sub>
28
+
29
+ # Usage
12
30
 
13
31
  The examples in this README use the [Splines Demo API](https://github.com/ruby-grape/grape-with-roar) running [here](https://grape-with-roar.herokuapp.com/api). If you're upgrading from a previous version, please make sure to read [UPGRADING](UPGRADING.md).
14
32
 
15
- ### API Client
33
+ ## API Client
16
34
 
17
35
  Create an API client.
18
36
 
@@ -85,7 +103,7 @@ api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api')
85
103
  api.connection.use :http_cache
86
104
  ```
87
105
 
88
- ### Resources and Attributes
106
+ ## Resources and Attributes
89
107
 
90
108
  Hyperclient will fetch and discover the resources from your API.
91
109
 
@@ -104,7 +122,7 @@ api.splines.each do |spline|
104
122
  end
105
123
  ```
106
124
 
107
- ### Links and Embedded Resources
125
+ ## Links and Embedded Resources
108
126
 
109
127
  The splines example above followed a link called "splines". While you can, you do not need to specify the HAL navigational structure, including links or embedded resources. Hyperclient will resolve these for you. If you prefer, you can explicitly navigate the link structure via `_links`. In the following example the "splines" link leads to a collection of embedded splines. Invoking `api.splines` is equivalent to `api._links.splines._embedded.splines`.
110
128
 
@@ -112,7 +130,7 @@ The splines example above followed a link called "splines". While you can, you d
112
130
  api._links.splines
113
131
  ```
114
132
 
115
- ### Templated Links
133
+ ## Templated Links
116
134
 
117
135
  Templated links require variables to be expanded. For example, the demo API has a link called "spline" that requires a spline "uuid".
118
136
 
@@ -125,7 +143,7 @@ Invoking `api.spline(uuid: 'uuid').reticulated` is equivalent to `api._links.spl
125
143
 
126
144
  The client is responsible for supplying all the necessary parameters. Templated links don't do any strict parameter name checking and don't support required vs. optional parameters. Parameters not declared by the API will be dropped and will not have any effect when passed to `_expand`.
127
145
 
128
- ### Curies
146
+ ## Curies
129
147
 
130
148
  Curies are a suggested means by which to link documentation of a given resource. For example, the demo API contains very long links to images that use an "images" curie.
131
149
 
@@ -134,7 +152,7 @@ puts spline['image:thumbnail'] # => https://grape-with-roar.herokuapp.com/api/sp
134
152
  puts spline.links._curies['image'].expand('thumbnail') # => /docs/images/thumbnail
135
153
  ```
136
154
 
137
- ### Attributes
155
+ ## Attributes
138
156
 
139
157
  Resource attributes can also be accessed as a hash.
140
158
 
@@ -144,7 +162,7 @@ puts spline.to_h # => {"uuid" => "uuid", "reticulated" => true}
144
162
 
145
163
  The above is equivalent to `spline._attributes.to_h`.
146
164
 
147
- ### HTTP
165
+ ## HTTP
148
166
 
149
167
  Hyperclient uses [Faraday](http://github.com/lostisland/faraday) under the hood to perform HTTP calls. You can call any valid HTTP method on any resource.
150
168
 
@@ -187,7 +205,7 @@ spline._delete
187
205
 
188
206
  HTTP methods always return a new instance of Resource.
189
207
 
190
- ### Asynchronous requests
208
+ ## Asynchronous requests
191
209
 
192
210
  By default, Hyperclient requests are performed asynchronously in a background thread pool via the [Futuroscope](https://github.com/codegram/futuroscope) gem. You can control the size of this pool by setting the `min_workers` and `max_workers` settings:
193
211
 
@@ -204,7 +222,7 @@ api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api') do |client|
204
222
  end
205
223
  ```
206
224
 
207
- ## Testing Using Hyperclient
225
+ # Testing Using Hyperclient
208
226
 
209
227
  You can combine RSpec, Faraday::Adapter::Rack and Hyperclient to test your HAL API without having to ever examine the raw JSON response.
210
228
 
@@ -233,14 +251,18 @@ end
233
251
 
234
252
  For a complete example refer to [this Splines Demo API test](https://github.com/ruby-grape/grape-with-roar/blob/master/spec/api/splines_endpoint_with_hyperclient_spec.rb).
235
253
 
236
- ## Reference
254
+ # Reference
237
255
 
238
256
  [Hyperclient API Reference](http://rubydoc.org/github/codegram/hyperclient/master/frames).
239
257
 
240
- ## Contributing
258
+ # Hyperclient Users
259
+
260
+ Using Hyperclient? Add your project to our wiki, please: <https://github.com/codegram/hyperclient/wiki>.
261
+
262
+ # Contributing
241
263
 
242
264
  Hyperclient is work of [many people](https://github.com/codegram/hyperclient/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/codegram/hyperclient/pulls), [propose features and discuss issues](https://github.com/codegram/hyperclient/issues). See [CONTRIBUTING](CONTRIBUTING.md) for details.
243
265
 
244
- ## License
266
+ # License
245
267
 
246
268
  MIT License, see [LICENSE](LICENSE) for details. Copyright 2012-2014 [Codegram Technologies](http://codegram.com).
data/Rakefile CHANGED
@@ -38,4 +38,4 @@ end
38
38
  require 'rubocop/rake_task'
39
39
  RuboCop::RakeTask.new(:rubocop)
40
40
 
41
- task default: [:rubocop, :test, :spinach]
41
+ task default: [:test, :spinach, :rubocop]
@@ -12,7 +12,7 @@ class Spinach::Features::DefaultConfig < Spinach::FeatureSteps
12
12
  end
13
13
 
14
14
  step 'I send some data to the API' do
15
- stub_request(:post, 'http://api.example.org/posts')
15
+ stub_request(:post, 'http://api.example.org/posts').to_return(headers: { 'Content-Type' => 'application/hal+json' })
16
16
  assert_equal 200, api._links.posts._post(title: 'My first blog post')._response.status
17
17
  end
18
18
 
@@ -4,7 +4,7 @@ require File.expand_path('../lib/hyperclient/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ['Oriol Gual']
6
6
  gem.email = ['oriol.gual@gmail.com']
7
- gem.description = 'HyperClient is a Ruby Hypermedia API client.'
7
+ gem.description = 'Hyperclient is a Ruby Hypermedia API client.'
8
8
  gem.summary = ''
9
9
  gem.homepage = 'https://github.com/codegram/hyperclient/'
10
10
  gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
@@ -41,6 +41,8 @@ module Hyperclient
41
41
  @options = { async: true }
42
42
  @connection = nil
43
43
  @resource = nil
44
+ @key = nil
45
+ @uri_variables = nil
44
46
  yield self if block_given?
45
47
  end
46
48
 
@@ -126,7 +126,8 @@ module Hyperclient
126
126
  # Internal: Delegate the method further down the API if the resource cannot serve it.
127
127
  def method_missing(method, *args, &block)
128
128
  if _resource.respond_to?(method.to_s)
129
- _resource.send(method, *args, &block) || delegate_method(method, *args, &block)
129
+ result = _resource.send(method, *args, &block)
130
+ result.nil? ? delegate_method(method, *args, &block) : result
130
131
  else
131
132
  super
132
133
  end
@@ -1,6 +1,17 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module Hyperclient
4
+ # Public: Exception that is raised when passing in invalid representation data
5
+ # for the resource.
6
+ class InvalidRepresentationError < ArgumentError
7
+ attr_reader :representation
8
+
9
+ def initialize(error_description, representation)
10
+ super(error_description)
11
+ @representation = representation
12
+ end
13
+ end
14
+
4
15
  # Public: Represents a resource from your API. Its responsability is to
5
16
  # ease the way you access its attributes, links and embedded resources.
6
17
  class Resource
@@ -29,8 +40,9 @@ module Hyperclient
29
40
  # representation - The hash with the HAL representation of the Resource.
30
41
  # entry_point - The EntryPoint object to inject the configutation.
31
42
  def initialize(representation, entry_point, response = nil)
32
- representation = representation ? representation.dup : {}
43
+ representation = validate(representation)
33
44
  links = representation['_links'] || {}
45
+
34
46
  @_links = LinkCollection.new(links, links['curies'], entry_point)
35
47
  @_embedded = ResourceCollection.new(representation['_embedded'], entry_point)
36
48
  @_attributes = Attributes.new(representation)
@@ -68,6 +80,21 @@ module Hyperclient
68
80
 
69
81
  private
70
82
 
83
+ # Internal: Ensures the received representation is a valid Hash-lookalike.
84
+ def validate(representation)
85
+ return {} unless representation
86
+
87
+ if representation.respond_to?(:to_hash)
88
+ representation.to_hash.dup
89
+ else
90
+ raise InvalidRepresentationError.new(
91
+ "Invalid representation for resource (got #{representation.class}, expected Hash). " \
92
+ "Is your web server returning JSON HAL data with a 'Content-Type: application/hal+json' header?",
93
+ representation
94
+ )
95
+ end
96
+ end
97
+
71
98
  # Internal: Returns the self Link of the Resource. Used to handle the HTTP
72
99
  # methods.
73
100
  def _self_link
@@ -1,3 +1,3 @@
1
1
  module Hyperclient
2
- VERSION = '0.8.5'.freeze
2
+ VERSION = '0.8.6'.freeze
3
3
  end
@@ -479,6 +479,16 @@ module Hyperclient
479
479
  resource.orders.first.id.must_equal 1
480
480
  end
481
481
 
482
+ it 'can handle false values in the response' do
483
+ resource = Resource.new({ '_links' => { 'orders' => { 'href' => '/orders' } } }, entry_point)
484
+
485
+ stub_request(entry_point.connection) do |stub|
486
+ stub.get('http://api.example.org/orders') { [200, {}, { 'any' => false }] }
487
+ end
488
+
489
+ resource.orders.any.must_equal false
490
+ end
491
+
482
492
  it "doesn't delegate when link key doesn't match" do
483
493
  resource = Resource.new({ '_links' => { 'foos' => { 'href' => '/orders' } } }, entry_point)
484
494
 
@@ -40,6 +40,12 @@ module Hyperclient
40
40
 
41
41
  resource._response.body.must_equal body
42
42
  end
43
+
44
+ describe 'with an invalid representation' do
45
+ it 'raises an InvalidRepresentationError' do
46
+ proc { Resource.new('invalid representation data', entry_point) }.must_raise InvalidRepresentationError
47
+ end
48
+ end
43
49
  end
44
50
 
45
51
  describe '_links' do
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: 0.8.5
4
+ version: 0.8.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oriol Gual
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-05 00:00:00.000000000 Z
11
+ date: 2017-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -108,7 +108,7 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description: HyperClient is a Ruby Hypermedia API client.
111
+ description: Hyperclient is a Ruby Hypermedia API client.
112
112
  email:
113
113
  - oriol.gual@gmail.com
114
114
  executables: []
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
183
  version: '0'
184
184
  requirements: []
185
185
  rubyforge_project:
186
- rubygems_version: 2.6.11
186
+ rubygems_version: 2.6.12
187
187
  signing_key:
188
188
  specification_version: 4
189
189
  summary: ''