excon-hypermedia 0.4.3 → 0.5.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: 912319706191a6c2866f3c5e8a7f9d6c16631149
4
- data.tar.gz: 5309fb839091943003bb4dfe9be37c908fc0410d
3
+ metadata.gz: 6bc648cfd5761dfb1236aada3be47b061620a3ad
4
+ data.tar.gz: f0fc534b110a5de92cbe548a4dbe5eb4bcb6f5e6
5
5
  SHA512:
6
- metadata.gz: 0d196a5a238fba1fcfae2ed1cf3287c2f5b42f1ee9bd837c5e4b93c13407a511b2566cc1bcec76524752121ef464427737cdad05c69d2dbdc76292e36fb924b5
7
- data.tar.gz: b6f03792762adcc3e2d41af35bbdb8f6a2c21afbe3c09f72df20f7cc8ae29285777a726f0cca10dbdf373f73ebdcaf3824c342ad57f4489fe232d2c5f5289fa7
6
+ metadata.gz: 83c3ec47d43ce609a789f2bf0ae0281822ae0b4ba25b00596516ef7ed54e9ecc8ab4f3e834e642172b4a1560da4c8184aa4f6a6ac611f63dc84f22e19b4ee226
7
+ data.tar.gz: 74fb5d0362acce99b511533c487d18612c81f0c8b455d62633c6fd52e74eb8a262429e6873913e5a5f60e5efae9fdda15132c1602b38a3597e02e0573bf929ea
data/.wercker.yml CHANGED
@@ -1,5 +1,29 @@
1
- box: ruby:2.3
2
- build:
1
+ ruby-latest:
2
+ box: ruby:latest
3
+ steps:
4
+ - bundle-install
5
+ - script:
6
+ name: tests
7
+ code: bundle exec rake
8
+
9
+ ruby-23:
10
+ box: ruby:2.3
11
+ steps:
12
+ - bundle-install
13
+ - script:
14
+ name: tests
15
+ code: bundle exec rake
16
+
17
+ ruby-22:
18
+ box: ruby:2.2
19
+ steps:
20
+ - bundle-install
21
+ - script:
22
+ name: tests
23
+ code: bundle exec rake
24
+
25
+ ruby-21:
26
+ box: ruby:2.1
3
27
  steps:
4
28
  - bundle-install
5
29
  - script:
data/README.md CHANGED
@@ -10,6 +10,8 @@ Teaches [Excon][] how to talk to [HyperMedia APIs][hypermedia].
10
10
  * [relations](#relations)
11
11
  * [properties](#properties)
12
12
  * [embedded](#embedded)
13
+ * [Hypertext Cache Pattern](#hypertext-cache-pattern)
14
+ * [shortcuts](#shortcuts)
13
15
  * [License](#license)
14
16
 
15
17
  ## Installation
@@ -254,8 +256,51 @@ For more information on this concept, see the [formal specification][_embedded].
254
256
  Embedded resources work the same as the top-level resource:
255
257
 
256
258
  ```ruby
257
- product._embedded.pump.class # => Excon::HyperMedia::ResourceObject
258
- product._embedded.pump.weight # => '2kg'
259
+ product.resource._embedded.pump.class # => Excon::HyperMedia::ResourceObject
260
+ product.resource._embedded.pump.weight # => '2kg'
261
+ ```
262
+
263
+ ### Hypertext Cache Pattern
264
+
265
+ You can leverage embedded resources to dynamically reduce the number of requests
266
+ you have to make to get the desired results, improving the efficiency and
267
+ performance of the application. This technique is called
268
+ "[Hypertext Cache Pattern][hcp]".
269
+
270
+ When you enable `hcp`, the library detects if a requested resource is already
271
+ embedded, and will use that resource as a mocked response, eliminating any extra
272
+ request to get the resource:
273
+
274
+ ```ruby
275
+ pump = product.rel('pump', hcp: true).get
276
+
277
+ pump[:hcp] # => true
278
+ pump.remote_ip # => '127.0.0.1'
279
+ pump.resource.weight # => '2kg'
280
+ ```
281
+
282
+ This feature only works if you are sure the embedded resource is equal to the
283
+ resource returned by the link relation. Because of this requirement, the default
284
+ configuration has `hcp` disabled, you can either enable it per request (which
285
+ also enables it for future requests in the chain), or enable it globally:
286
+
287
+ ```ruby
288
+ Excon.defaults[:hcp] = true
289
+ ```
290
+
291
+ ### shortcuts
292
+
293
+ While the above examples shows the clean separation between the different
294
+ concepts like `response`, `resource`, `links`, `properties` and `emeds`.
295
+
296
+ Traversing these objects always starts from the response object. To make moving
297
+ around a bit faster, there are several methods available on the
298
+ `Excon::Response` object for ease-of-use:
299
+
300
+ ```ruby
301
+ product.links.class # => Excon::HyperMedia::ResourceObject::Links
302
+ product.properties.class # => Excon::HyperMedia::ResourceObject::Properties
303
+ product.embedded.class # => Excon::HyperMedia::ResourceObject::Embedded
259
304
  ```
260
305
 
261
306
  ## License
@@ -267,3 +312,4 @@ The gem is available as open source under the terms of the [MIT License](http://
267
312
  [excon-addressable]: https://github.com/JeanMertz/excon-addressable
268
313
  [options]: https://github.com/excon/excon#options
269
314
  [_embedded]: https://tools.ietf.org/html/draft-kelly-json-hal-08#section-4.1.2
315
+ [hcp]: https://tools.ietf.org/html/draft-kelly-json-hal-06#section-8.3
@@ -17,13 +17,14 @@ Gem::Specification.new do |spec|
17
17
  spec.files = `git ls-files -z`.split("\x0")
18
18
  spec.require_paths = %w(lib)
19
19
 
20
- spec.add_development_dependency 'bundler', '~> 1.12'
20
+ spec.add_development_dependency 'bundler', '~> 1.9'
21
21
  spec.add_development_dependency 'rake', '~> 10.0'
22
22
  spec.add_development_dependency 'minitest', '~> 5.0'
23
23
  spec.add_development_dependency 'rubocop', '~> 0.40'
24
24
  spec.add_development_dependency 'pry', '~> 0.10'
25
25
  spec.add_development_dependency 'm', '~> 1.5'
26
26
 
27
+ spec.add_dependency 'backport_dig' if RUBY_VERSION < '2.3'
27
28
  spec.add_dependency 'excon', '~> 0.49'
28
29
  spec.add_dependency 'excon-addressable', '~> 0.3'
29
30
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :no-doc:
4
+ module Excon
5
+ module HyperMedia
6
+ class Error < StandardError; end
7
+
8
+ UnknownRelationError = Class.new(Error)
9
+ end
10
+ end
@@ -12,7 +12,7 @@ module Excon
12
12
  include Enumerable
13
13
 
14
14
  def initialize(collection = {})
15
- @collection ||= collection
15
+ @collection ||= collection.to_h
16
16
  to_properties
17
17
  end
18
18
 
@@ -34,6 +34,21 @@ module Excon
34
34
 
35
35
  private
36
36
 
37
+ # method_missing
38
+ #
39
+ # Collections can be accessed using both the "dot notation" and the hash
40
+ # notation:
41
+ #
42
+ # collection.hello_world
43
+ # collection['hello_world']
44
+ #
45
+ # The second notation returns `nil` on missing keys, the first should do
46
+ # as well.
47
+ #
48
+ def method_missing(_)
49
+ nil
50
+ end
51
+
37
52
  def to_properties
38
53
  collection.each do |key, value|
39
54
  key = key.downcase
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'backport_dig' if RUBY_VERSION < '2.3'
4
+
3
5
  Excon.defaults[:middlewares].delete(Excon::Addressable::Middleware)
4
6
  Excon.defaults[:middlewares].unshift(Excon::Addressable::Middleware)
5
7
 
@@ -14,6 +16,12 @@ module Excon
14
16
  # will be left alone by this middleware.
15
17
  #
16
18
  class Middleware < Excon::Middleware::Base
19
+ def request_call(datum)
20
+ orig_stack = @stack
21
+ @stack = Excon::HyperMedia::Middlewares::HypertextCachePattern.new(orig_stack)
22
+ super
23
+ end
24
+
17
25
  def response_call(datum)
18
26
  return super unless (content_type = datum.dig(:response, :headers, 'Content-Type').to_s)
19
27
 
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Excon
4
+ module HyperMedia
5
+ module Middlewares
6
+ # HypertextCachePattern
7
+ #
8
+ # This middleware handles hcp-enabled requests.
9
+ #
10
+ # @see: https://tools.ietf.org/html/draft-kelly-json-hal-06#section-8.3
11
+ #
12
+ class HypertextCachePattern < Excon::Middleware::Base
13
+ attr_reader :datum
14
+
15
+ def request_call(datum)
16
+ @datum = datum
17
+
18
+ return super unless datum[:hcp] == true && datum[:method] == :get && find_embedded
19
+
20
+ datum[:response] = {
21
+ body: @embedded.to_json,
22
+ hcp: true,
23
+ headers: content_type_header,
24
+ remote_ip: '127.0.0.1',
25
+ status: 200
26
+ }
27
+
28
+ super
29
+ end
30
+
31
+ private
32
+
33
+ def find_embedded
34
+ datum.dig(:hcp_params, :embedded).to_h.each do |_, object|
35
+ break if (@embedded = object_to_embedded(object))
36
+ end
37
+
38
+ @embedded
39
+ end
40
+
41
+ def object_to_embedded(object)
42
+ uri = ::Addressable::URI.new(datum.tap { |h| h.delete(:port) })
43
+
44
+ if object.respond_to?(:to_ary)
45
+ object.find { |hash| hash.dig('_links', 'self', 'href') == uri.to_s }
46
+ elsif object.dig('_links', 'self', 'href') == uri.to_s
47
+ object
48
+ end
49
+ end
50
+
51
+ def content_type_header
52
+ return {} unless (header = datum.dig(:hcp_params, :content_type))
53
+
54
+ { 'Content-Type' => header }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -15,14 +15,6 @@ module Excon
15
15
 
16
16
  def initialize(data)
17
17
  @data = data
18
-
19
- _properties.each do |key, value|
20
- key = key.downcase
21
- next unless /[@$"]/ !~ key.to_sym.inspect
22
-
23
- singleton_class.class_eval { attr_reader key }
24
- instance_variable_set("@#{key}", value.respond_to?(:keys) ? Properties.new(value) : value)
25
- end
26
18
  end
27
19
 
28
20
  def _properties
@@ -64,6 +56,10 @@ module Excon
64
56
  def [](key)
65
57
  _properties[key]
66
58
  end
59
+
60
+ def method_missing(method_name, *_)
61
+ _properties.send(method_name)
62
+ end
67
63
  end
68
64
  end
69
65
  end
@@ -18,12 +18,15 @@ module Excon
18
18
  #
19
19
  # Correctly handle the hypermedia request.
20
20
  #
21
- def handle(method_name, *params)
21
+ def handle(method_name, *params) # rubocop:disable Metrics/CyclomaticComplexity
22
22
  return false unless enabled?
23
23
 
24
24
  case method_name
25
- when :resource then resource
26
- when :rel then rel(params.shift, params)
25
+ when :resource then resource
26
+ when :_links, :links then resource._links
27
+ when :_embedded, :embedded then resource._embedded
28
+ when :_properties, :properties then resource._properties
29
+ when :rel then rel(params.shift, params)
27
30
  else false
28
31
  end
29
32
  end
@@ -49,11 +52,27 @@ module Excon
49
52
  end
50
53
 
51
54
  def rel(name, params)
52
- link = resource._links.send(name)
53
- options = params.first.to_h.merge(hypermedia: true)
55
+ raise ArgumentError, 'missing relation name' unless name
56
+
57
+ unless (link = resource._links[name])
58
+ raise UnknownRelationError, "unknown relation: #{name}"
59
+ end
60
+
61
+ options = rel_params(params.first.to_h)
54
62
 
55
63
  link.respond_to?(:to_ary) ? link.map { |l| l.rel(options) } : link.rel(options)
56
64
  end
65
+
66
+ def rel_params(params)
67
+ params.merge(
68
+ hypermedia: true,
69
+ hcp: (params[:hcp].nil? ? response.data[:hcp] : params[:hcp]),
70
+ hcp_params: {
71
+ content_type: response.headers['Content-Type'],
72
+ embedded: resource._embedded
73
+ }
74
+ )
75
+ end
57
76
  end
58
77
  end
59
78
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Excon
4
4
  module HyperMedia
5
- VERSION = '0.4.3'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
@@ -3,9 +3,11 @@
3
3
  require 'excon'
4
4
  require 'excon/addressable'
5
5
 
6
+ require 'excon/hypermedia/errors'
6
7
  require 'excon/hypermedia/helpers/collection'
7
8
  require 'excon/hypermedia/link_object'
8
9
  require 'excon/hypermedia/middleware'
10
+ require 'excon/hypermedia/middlewares/hypertext_cache_pattern'
9
11
  require 'excon/hypermedia/resource_object'
10
12
  require 'excon/hypermedia/response'
11
13
  require 'excon/hypermedia/version'
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../test_helper'
4
+
5
+ module Excon
6
+ # EdgeCaseTest
7
+ #
8
+ # Validate edge cases (or: non-happy path)
9
+ #
10
+ class EdgeCaseTest < HyperMediaTest
11
+ def setup
12
+ Excon.defaults[:mock] = true
13
+ Excon.defaults[:middlewares].push(Excon::HyperMedia::Middleware)
14
+
15
+ response = { headers: { 'Content-Type' => 'application/hal+json' } }
16
+ Excon.stub({ path: '/api.json' }, response.merge(body: api_body))
17
+ Excon.stub({ path: '/empty_json' }, response.merge(body: '{}'))
18
+ end
19
+
20
+ def teardown
21
+ Excon.stubs.clear
22
+ Excon.defaults[:middlewares].delete(Excon::HyperMedia::Middleware)
23
+ end
24
+
25
+ def api
26
+ Excon.get('https://www.example.org/api.json')
27
+ end
28
+
29
+ def test_missing_middleware
30
+ Excon.defaults[:middlewares].delete(Excon::HyperMedia::Middleware)
31
+
32
+ assert_raises(NoMethodError) { api.rel }
33
+ end
34
+
35
+ def test_rel_missing_name
36
+ ex = assert_raises(ArgumentError) { api.rel }
37
+ assert_equal 'missing relation name', ex.message
38
+ end
39
+
40
+ def test_rel_missing_arguments
41
+ assert_equal Excon::Connection, api.rel('self').class
42
+ end
43
+
44
+ def test_rel_unknown_relation
45
+ ex = assert_raises(Excon::HyperMedia::UnknownRelationError) { api.rel('invalid') }
46
+ assert_equal 'unknown relation: invalid', ex.message
47
+ end
48
+
49
+ def test_missing_links
50
+ resource = Excon.get('https://www.example.org/empty_json').resource
51
+
52
+ assert_equal({}, resource._links.to_h)
53
+ end
54
+
55
+ def test_missing_embedded
56
+ resource = Excon.get('https://www.example.org/empty_json').resource
57
+
58
+ assert_equal({}, resource._embedded.to_h)
59
+ end
60
+
61
+ def test_missing_properties
62
+ resource = Excon.get('https://www.example.org/empty_json').resource
63
+
64
+ assert_equal({}, resource._properties.to_h)
65
+ end
66
+
67
+ def test_unknown_property
68
+ resource = Excon.get('https://www.example.org/api.json').resource
69
+
70
+ assert_equal nil, resource._properties.invalid
71
+ assert_equal nil, resource._properties['invalid']
72
+ end
73
+
74
+ def test_unknown_link
75
+ resource = Excon.get('https://www.example.org/empty_json').resource
76
+
77
+ assert_equal nil, resource._links.invalid
78
+ assert_equal nil, resource._links['invalid']
79
+ end
80
+
81
+ def test_unknown_embed
82
+ resource = Excon.get('https://www.example.org/api.json').resource
83
+
84
+ assert_equal nil, resource._embedded.invalid
85
+ assert_equal nil, resource._embedded['invalid']
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../test_helper'
4
+
5
+ module Excon
6
+ # HCPTest
7
+ #
8
+ # Validate the workings of `Excon::HyperResource::Middlewares::HypertextCachePattern`.
9
+ #
10
+ class HCPTest < HyperMediaTest
11
+ def response
12
+ @response ||= Excon.get('https://example.org/product/bicycle')
13
+ end
14
+
15
+ def test_non_hcp_response
16
+ assert_equal nil, response[:hcp]
17
+ end
18
+
19
+ def test_hcp_response
20
+ assert response.rel('pump', hcp: true).get[:hcp]
21
+ end
22
+
23
+ def test_hcp_response_with_missing_embedding
24
+ api = Excon.get('https://www.example.org/api.json')
25
+ response = api.rel('product', expand: { uid: 'bicycle' }, rel: true).get
26
+
27
+ assert_equal nil, response[:hcp]
28
+ end
29
+
30
+ def test_hcp_response_with_embedded_array
31
+ wheels = response.rel('wheels', hcp: true)
32
+
33
+ assert wheels.map(&:get).all? { |res| res[:hcp] }
34
+ end
35
+
36
+ def test_nested_hcp_responses
37
+ pump = response.rel('pump', hcp: true).get
38
+ response = pump.rel('parts', expand: { uid: 'bicycle' }).get
39
+
40
+ assert response[:hcp]
41
+ end
42
+
43
+ def test_hcp_not_working_for_non_get_requests
44
+ assert_equal nil, response.rel('pump', hcp: true).post[:hcp]
45
+ end
46
+
47
+ def test_hcp_resource
48
+ resource = response.rel('pump', hcp: true).get.resource
49
+
50
+ assert_equal Excon::HyperMedia::ResourceObject, resource.class
51
+ end
52
+
53
+ def test_hcp_links
54
+ resource = response.rel('pump', hcp: true).get.resource
55
+
56
+ assert_equal data(:parts)['_links']['self']['href'], resource._links.parts.href
57
+ end
58
+ end
59
+ end
@@ -48,10 +48,6 @@ module Excon
48
48
  assert response.body.include?('https://www.example.org/product/bicycle')
49
49
  end
50
50
 
51
- def test_invalid_relation
52
- assert_raises(NoMethodError) { api.rel('invalid') }
53
- end
54
-
55
51
  def test_link
56
52
  response = api.rel('product', expand: { uid: 'bicycle' }).get
57
53
 
@@ -18,7 +18,7 @@ module Excon
18
18
  end
19
19
 
20
20
  def full
21
- <<~EOF
21
+ <<-EOF
22
22
  {
23
23
  "href": "https://www.example.org/goodbye/{receiver}",
24
24
  "templated": "true",
@@ -10,7 +10,7 @@ module Excon
10
10
  #
11
11
  class LinksTest < Minitest::Test
12
12
  def body
13
- <<~EOF
13
+ <<-EOF
14
14
  {
15
15
  "_links": {
16
16
  "self": {
@@ -10,7 +10,7 @@ module Excon
10
10
  #
11
11
  class PropertiesTest < Minitest::Test
12
12
  def body
13
- <<~EOF
13
+ <<-EOF
14
14
  {
15
15
  "size": "49CM",
16
16
  "bike-type": "Mountain Bike",
@@ -10,7 +10,7 @@ module Excon
10
10
  #
11
11
  class ResourceObjectTest < Minitest::Test
12
12
  def body
13
- <<~EOF
13
+ <<-EOF
14
14
  {
15
15
  "_links": {
16
16
  "hello": {
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../test_helper'
4
+
5
+ module Excon
6
+ # ResourceObjectTest
7
+ #
8
+ # Validate the workings of `Excon::HyperResource::ResourceObject`.
9
+ #
10
+ class ResponseTest < HyperMediaTest
11
+ def response
12
+ @response ||= Excon.get('https://example.org/product/bicycle')
13
+ end
14
+
15
+ def test_response
16
+ assert_equal Excon::Response, response.class
17
+ end
18
+
19
+ def test_links
20
+ assert_equal response.resource._links, response.links
21
+ assert_equal response.resource._links, response._links
22
+ end
23
+
24
+ def test_embedded
25
+ assert_equal response.resource._embedded, response.embedded
26
+ assert_equal response.resource._embedded, response._embedded
27
+ end
28
+
29
+ def test_properties
30
+ assert_equal response.resource._properties, response.properties
31
+ assert_equal response.resource._properties, response._properties
32
+ end
33
+ end
34
+ end
data/test/test_helper.rb CHANGED
@@ -21,7 +21,8 @@ module Excon
21
21
  Excon.stub({ method: :get, path: '/product/bicycle' }, response.merge(body: bicycle_body))
22
22
  Excon.stub({ method: :get, path: '/product/bicycle/wheels/front' }, response.merge(body: front_wheel_body))
23
23
  Excon.stub({ method: :get, path: '/product/bicycle/wheels/rear' }, response.merge(body: rear_wheel_body))
24
- Excon.stub({ method: :get, path: '/product/pump' }, response.merge(body: pump_body))
24
+ Excon.stub({ path: '/product/pump' }, response.merge(body: pump_body))
25
+ Excon.stub({ method: :get, path: '/product/pump/parts' }, response.merge(body: parts_body))
25
26
  Excon.stub({ method: :get, path: '/product/handlebar' }, response.merge(body: handlebar_body))
26
27
  Excon.stub({ method: :get, path: '/api_v2.json' }, body: api_body, headers: { 'Content-Type' => 'application/json' })
27
28
  end
@@ -37,7 +38,7 @@ module Excon
37
38
  end
38
39
 
39
40
  def api_body
40
- <<~EOF
41
+ <<-EOF
41
42
  {
42
43
  "_links": {
43
44
  "self": {
@@ -53,7 +54,7 @@ module Excon
53
54
  end
54
55
 
55
56
  def bicycle_body
56
- <<~EOF
57
+ <<-EOF
57
58
  {
58
59
  "_links": {
59
60
  "self": {
@@ -90,7 +91,7 @@ module Excon
90
91
  end
91
92
 
92
93
  def handlebar_body
93
- <<~EOF
94
+ <<-EOF
94
95
  {
95
96
  "_links": {
96
97
  "self": {
@@ -105,22 +106,42 @@ module Excon
105
106
  end
106
107
 
107
108
  def pump_body
108
- <<~EOF
109
+ <<-EOF
109
110
  {
110
111
  "_links": {
111
112
  "self": {
112
113
  "href": "https://www.example.org/product/pump"
114
+ },
115
+ "parts": {
116
+ "href": "https://www.example.org/product/pump/parts"
113
117
  }
114
118
  },
115
119
  "weight": "2kg",
116
120
  "type": "Floor Pump",
117
- "valve-type": "Presta"
121
+ "valve-type": "Presta",
122
+ "_embedded": {
123
+ "parts": #{parts_body}
124
+ }
125
+
126
+ }
127
+ EOF
128
+ end
129
+
130
+ def parts_body
131
+ <<-EOF
132
+ {
133
+ "_links": {
134
+ "self": {
135
+ "href": "https://www.example.org/product/pump/parts"
136
+ }
137
+ },
138
+ "count": 47
118
139
  }
119
140
  EOF
120
141
  end
121
142
 
122
143
  def rear_wheel_body
123
- <<~EOF
144
+ <<-EOF
124
145
  {
125
146
  "_links": {
126
147
  "self": {
@@ -134,7 +155,7 @@ module Excon
134
155
  end
135
156
 
136
157
  def front_wheel_body
137
- <<~EOF
158
+ <<-EOF
138
159
  {
139
160
  "_links": {
140
161
  "self": {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: excon-hypermedia
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-27 00:00:00.000000000 Z
12
+ date: 2016-05-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '1.12'
20
+ version: '1.9'
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '1.12'
27
+ version: '1.9'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -140,21 +140,26 @@ files:
140
140
  - Rakefile
141
141
  - excon-hypermedia.gemspec
142
142
  - lib/excon/hypermedia.rb
143
+ - lib/excon/hypermedia/errors.rb
143
144
  - lib/excon/hypermedia/ext/response.rb
144
145
  - lib/excon/hypermedia/helpers/collection.rb
145
146
  - lib/excon/hypermedia/link_object.rb
146
147
  - lib/excon/hypermedia/middleware.rb
148
+ - lib/excon/hypermedia/middlewares/hypertext_cache_pattern.rb
147
149
  - lib/excon/hypermedia/resource_object.rb
148
150
  - lib/excon/hypermedia/resource_object/embedded.rb
149
151
  - lib/excon/hypermedia/resource_object/links.rb
150
152
  - lib/excon/hypermedia/resource_object/properties.rb
151
153
  - lib/excon/hypermedia/response.rb
152
154
  - lib/excon/hypermedia/version.rb
155
+ - test/excon/edgecase_test.rb
156
+ - test/excon/hcp_test.rb
153
157
  - test/excon/integration_test.rb
154
158
  - test/excon/link_object_test.rb
155
159
  - test/excon/links_test.rb
156
160
  - test/excon/properties_test.rb
157
161
  - test/excon/resource_object_test.rb
162
+ - test/excon/response_test.rb
158
163
  - test/test_helper.rb
159
164
  homepage: https://github.com/JeanMertz/excon-hypermedia
160
165
  licenses: