yaks 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +15 -6
- data/ADDING_FORMATS.md +13 -0
- data/CHANGELOG.md +12 -0
- data/IDENTIFIERS.md +113 -0
- data/lib/yaks/collection_mapper.rb +1 -2
- data/lib/yaks/collection_resource.rb +1 -1
- data/lib/yaks/config.rb +10 -8
- data/lib/yaks/mapper/link.rb +4 -5
- data/lib/yaks/mapper.rb +6 -2
- data/lib/yaks/null_resource.rb +6 -2
- data/lib/yaks/primitivize.rb +1 -1
- data/lib/yaks/resource.rb +8 -5
- data/lib/yaks/serializer/hal.rb +1 -1
- data/lib/yaks/serializer/json_api.rb +16 -11
- data/lib/yaks/serializer.rb +4 -5
- data/lib/yaks/version.rb +1 -1
- data/spec/acceptance/acceptance_spec.rb +1 -1
- data/spec/acceptance/models.rb +3 -1
- data/spec/integration/map_to_resource_spec.rb +2 -1
- data/spec/json/confucius.hal.json +5 -1
- data/spec/json/confucius.json_api.json +3 -0
- data/spec/support/deep_eql.rb +6 -0
- data/spec/support/shared_contexts.rb +9 -2
- data/spec/unit/yaks/collection_mapper_spec.rb +32 -4
- data/spec/unit/yaks/collection_resource_spec.rb +8 -3
- data/spec/unit/yaks/mapper/has_many_spec.rb +10 -2
- data/spec/unit/yaks/mapper/has_one_spec.rb +3 -1
- data/spec/unit/yaks/mapper/link_spec.rb +12 -5
- data/spec/unit/yaks/mapper_spec.rb +18 -19
- data/spec/unit/yaks/null_resource_spec.rb +32 -0
- data/spec/unit/yaks/primitivize_spec.rb +77 -0
- data/spec/unit/yaks/resource/link_spec.rb +21 -0
- data/spec/unit/yaks/resource_spec.rb +26 -7
- data/spec/unit/yaks/serializer/hal_spec.rb +1 -1
- metadata +34 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b888259337e9fa643458e613fda2f50e561a72e
|
4
|
+
data.tar.gz: e6ff86a9a5d402b857041f1a676b81f6324078d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: edfa665288d44ed62d397beeb2419092b7220129475c77f5cbce4413a981f1d57f44578faf27e3a77da3c6a818a3b5bc0f5bbeaeaa966aeab82d55f6b1960694
|
7
|
+
data.tar.gz: 7391bc4fab6497ce52c6353db032786df91ab01730cd8486aed53179321ebd3c9baf49a54509edbcddd14796b1daefecc98903b0bfd8b9fe94753cb4fe2f1490
|
data/.travis.yml
CHANGED
@@ -1,16 +1,25 @@
|
|
1
1
|
language: ruby
|
2
|
-
script:
|
2
|
+
script: bundle exec $RUN
|
3
3
|
rvm:
|
4
4
|
- 1.9.3
|
5
5
|
- 2.0.0
|
6
|
-
- 2.1.
|
7
|
-
- rbx
|
8
|
-
- jruby
|
6
|
+
- 2.1.2
|
9
7
|
- ruby-head
|
8
|
+
- rbx-2
|
9
|
+
- jruby
|
10
10
|
- jruby-head
|
11
|
+
env:
|
12
|
+
- RUN=rspec
|
13
|
+
- RUN=rake
|
11
14
|
matrix:
|
12
15
|
allow_failures:
|
13
|
-
- rvm: rbx
|
14
|
-
- rvm: jruby
|
15
16
|
- rvm: ruby-head
|
16
17
|
- rvm: jruby-head
|
18
|
+
- env: RUN=rake
|
19
|
+
exclude:
|
20
|
+
- rvm: jruby
|
21
|
+
env: RUN=rake
|
22
|
+
- rvm: jruby-head
|
23
|
+
env: RUN=rake
|
24
|
+
- rvm: rbx-2
|
25
|
+
env: RUN=rake
|
data/ADDING_FORMATS.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Adding Extra Output Formats to Yaks
|
2
|
+
|
3
|
+
Individual output formats are each handled by a dedicated `Yaks::Serializer` class. These take a `Yaks::Resource` as input, and turn it into the requested output format.
|
4
|
+
|
5
|
+
A `Yaks::Resource` is created by "mapping" domain models by a `Yaks::Mapper`. In a `Yaks::Mapper` subclass a DSL is available to specify how to extract different types of information, for example attributes or links, and store them in a generalized way in a `Resource`.
|
6
|
+
|
7
|
+
Different formats have different features. Simple formats might just represent attributes, links, and subresources, other formats have queries, forms, or RDF identifiers. If a format represents data of a different nature, then the first step is to decide on a good and straightforward syntax to specify how to derive this data. This can then be stored in a `Yaks::Resource`, and formats that support it can use it, other formats can ignore it.
|
8
|
+
|
9
|
+
This is already the case, JSON-API ignores links for example.
|
10
|
+
|
11
|
+
So adding an output format is generally straightforward, as long as the information that the output format supports is already available in `Yaks::Resource`. In that case adding a `Yaks::Serializer::YourFormat` is all that is needed.
|
12
|
+
|
13
|
+
If the format has features that are not yet available then syntax needs to be added for those features. The guiding idea there is to try and find more than one format with the given feature, to make sure the intermediate abstraction is general and not tied to the specifics and vocabulary of a single format.
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
### Development
|
2
|
+
[full changelog](http://github.com/plexus/yaks/compare/v0.4.2...master)
|
3
|
+
|
4
|
+
### v0.4.2
|
5
|
+
|
6
|
+
* JSON-API: render self links as href attributes
|
7
|
+
* HAL: render has_one returning nil as null, not as {}
|
8
|
+
* Keep track of the mapper stack, useful for figuring out if mapping the top level response or not, or for accessing parent
|
9
|
+
* Change Serializer.new(resource, options).serialize to Serializer.new(options).call(resource) for cosistency of "pipeline" interface
|
10
|
+
* Make Yaks::CollectionMapper#collection overridable for pagination
|
11
|
+
* Don't render links from custom link methods (link :foo, :method_that_generates_url) that return nil
|
12
|
+
|
1
13
|
# v0.4.1
|
2
14
|
|
3
15
|
* Change how env is passed to yaks.serialize to match docs
|
data/IDENTIFIERS.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# Identifiers
|
2
|
+
|
3
|
+
In Yaks, and Hypermedia message formats in general, a number of different types of identifiers are used. Some are full URIs and correspond with well defined specs. Some are just short identifers that are easy to program with.
|
4
|
+
|
5
|
+
Understanding these types of identifiers is key to creating a unifying model of a "Resource" that can be shared across output formats. We want to unify as much as possible across formats, without conflating things that are really not the same.
|
6
|
+
|
7
|
+
This document reflects my current limited understanding of things, based on possibly incorrect assumptions. Feedback is more than welcome.
|
8
|
+
|
9
|
+
## rels
|
10
|
+
|
11
|
+
As used in HTML and Atom, these identifiers say what the relationship is between a resource and another resource it links to. There is a [registry of names](http://www.iana.org/assignments/link-relations/link-relations.xhtml), e.g. self, next, profile, stylesheet. Custom rels need to be fully qualified URLs. Keep in mind that these are simply opaque identifiers, but by using a known protocol like http they can be used to point at documentation.
|
12
|
+
|
13
|
+
Some examples
|
14
|
+
|
15
|
+
```
|
16
|
+
copyright
|
17
|
+
stylesheet
|
18
|
+
http://api.example.com/rel/author
|
19
|
+
http://api.example.com/api-docs/relationships#comment
|
20
|
+
custom_scheme:foo
|
21
|
+
/order
|
22
|
+
```
|
23
|
+
|
24
|
+
The last example is a relative URL, which would have to be expanded against the source URL of the document it is mentioned in.
|
25
|
+
|
26
|
+
In Yaks both links and subresources are specified with their rel(ationship).
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class PersonMapper < Yaks::Mapper
|
30
|
+
link :self, '/people/{id}'
|
31
|
+
link 'http://api.example.com/rels#friends', '/people/{id}/friends'
|
32
|
+
|
33
|
+
has_one :address, rel: 'http://api.example.com/rels#address'
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
For subresources the rel can be omitted, in which case it will be inferred based on the rel_template:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
$yaks = Yaks.new do
|
41
|
+
rel_template 'http://api.example.com/rels/{dest}'
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
Links and subresources are rendered keyed by rel in HAL and Collection+JSON. JSON-API renders `self` links as the `href` of a resource.
|
46
|
+
|
47
|
+
## profiles
|
48
|
+
|
49
|
+
A specific IANA registered rel type is profile.
|
50
|
+
|
51
|
+
> Profile: Identifying that a resource representation conforms to a certain profile, without affecting the non-profile semantics of the resource representation.
|
52
|
+
|
53
|
+
Profile basically adds a layer of semantics on top of the hypermedia message format (e.g. HAL, Collection+JSON), which in turns defines semantics on top of a serialization format (JSON, XML, EDN). Loosely speaking it could be seen as the "type" or "class". For example if you know the profile of a resource, you might know you can expect to find a "name", "date_of_birth", or "post_body" field.
|
54
|
+
|
55
|
+
## "type"
|
56
|
+
|
57
|
+
Despite the appealing rigor of having fully qualified URIs to identify things, sometimes you just want to call a person a `person`. In Yaks we call these short identifier the *type* for lack of a better word. In some cases, notably JSON-API, they are used literally in the output. More often they are used to derive full URIs based on a template.
|
58
|
+
|
59
|
+
The type of a mapper is inferred from its class name, but can be set explicitly as well.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
class CatMapper < Yaks::Mapper
|
63
|
+
end
|
64
|
+
|
65
|
+
# type = "cat"
|
66
|
+
```
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
class CatMapper < Yaks::Mapper
|
70
|
+
type 'feline'
|
71
|
+
end
|
72
|
+
|
73
|
+
# type => "feline"
|
74
|
+
```
|
75
|
+
|
76
|
+
## rdf class
|
77
|
+
|
78
|
+
RDF (Resource Description Framework) is a set of specifications for use in "semantic web" applications. RDF is based on "ontologies" that precisely define a "vocabulary" of "classes" and "predicates". An example class identifier for all Merlot wines could be
|
79
|
+
|
80
|
+
> http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#Merlot
|
81
|
+
|
82
|
+
(source [wikipedia](http://en.wikipedia.org/wiki/Resource_Description_Framework))
|
83
|
+
|
84
|
+
Not currently used by Yaks, but might become important when implementing support for JSON-LD or other RDF serialization formats.
|
85
|
+
|
86
|
+
## CURIES
|
87
|
+
|
88
|
+
CURIES are "compact uris". The HAL format uses this so it can have the rigor of fully specified rels, with the ease of use of short-name "type" identifiers. The mechanism is similar to how one specifies and uses XML namespaces.
|
89
|
+
|
90
|
+
From the HAL spec:
|
91
|
+
|
92
|
+
```json
|
93
|
+
{
|
94
|
+
"_links": {
|
95
|
+
"self": { "href": "/orders" },
|
96
|
+
"curies": [{ "name": "ea", "href": "http://example.com/docs/rels/{rel}", "templated": true }],
|
97
|
+
"next": { "href": "/orders?page=2" },
|
98
|
+
"ea:find": {
|
99
|
+
"href": "/orders{?id}",
|
100
|
+
"templated": true
|
101
|
+
},
|
102
|
+
"ea:admin": [{
|
103
|
+
"href": "/admins/2",
|
104
|
+
"title": "Fred"
|
105
|
+
}, {
|
106
|
+
"href": "/admins/5",
|
107
|
+
"title": "Kate"
|
108
|
+
}]
|
109
|
+
}
|
110
|
+
}
|
111
|
+
```
|
112
|
+
|
113
|
+
In this case "ea:find" is just a shorthand for "http://example.com/docs/rels/find".
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module Yaks
|
4
4
|
class CollectionMapper < Mapper
|
5
|
-
attr_reader :collection
|
6
5
|
alias collection object
|
7
6
|
|
8
7
|
def initialize(context)
|
@@ -24,7 +23,7 @@ module Yaks
|
|
24
23
|
type: collection_type,
|
25
24
|
links: map_links,
|
26
25
|
attributes: map_attributes,
|
27
|
-
members: collection.map do |obj|
|
26
|
+
members: collection().map do |obj|
|
28
27
|
mapper_for_model(obj).new(context).call(obj)
|
29
28
|
end
|
30
29
|
}
|
data/lib/yaks/config.rb
CHANGED
@@ -70,10 +70,10 @@ module Yaks
|
|
70
70
|
def serializer_class(opts, env)
|
71
71
|
if env.key? 'HTTP_ACCEPT'
|
72
72
|
accept = Rack::Accept::Charset.new(env['HTTP_ACCEPT'])
|
73
|
-
mime_type = accept.best_of(
|
74
|
-
return
|
73
|
+
mime_type = accept.best_of(Serializer.mime_types.values)
|
74
|
+
return Serializer.by_mime_type(mime_type) if mime_type
|
75
75
|
end
|
76
|
-
|
76
|
+
Serializer.by_name(opts.fetch(:format) { @default_format })
|
77
77
|
end
|
78
78
|
|
79
79
|
def format_name(opts)
|
@@ -92,12 +92,14 @@ module Yaks
|
|
92
92
|
env = opts.fetch(:env, {})
|
93
93
|
context = {
|
94
94
|
policy: policy,
|
95
|
-
env: env
|
95
|
+
env: env,
|
96
|
+
mapper_stack: []
|
96
97
|
}
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
98
|
+
|
99
|
+
mapper = opts.fetch(:mapper) { policy.derive_mapper_from_object(object) }.new(context)
|
100
|
+
serializer = serializer_class(opts, env).new(format_options[format_name(opts)])
|
101
|
+
|
102
|
+
[ mapper, serializer, *steps ].inject(object) {|memo, step| step.call(memo) }
|
101
103
|
end
|
102
104
|
alias serialize call
|
103
105
|
end
|
data/lib/yaks/mapper/link.rb
CHANGED
@@ -63,11 +63,10 @@ module Yaks
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def map_to_resource_link(mapper)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
)
|
66
|
+
uri = expand_with(mapper.method(:load_attribute))
|
67
|
+
return if uri.nil?
|
68
|
+
|
69
|
+
Resource::Link.new(rel, uri, resource_link_options(mapper))
|
71
70
|
end
|
72
71
|
|
73
72
|
def expand_with(lookup)
|
data/lib/yaks/mapper.rb
CHANGED
@@ -22,6 +22,10 @@ module Yaks
|
|
22
22
|
context.fetch(:env)
|
23
23
|
end
|
24
24
|
|
25
|
+
def mapper_stack
|
26
|
+
context.fetch(:mapper_stack)
|
27
|
+
end
|
28
|
+
|
25
29
|
def call(object)
|
26
30
|
@object = object
|
27
31
|
|
@@ -42,7 +46,7 @@ module Yaks
|
|
42
46
|
end
|
43
47
|
|
44
48
|
def map_links
|
45
|
-
links.map
|
49
|
+
links.map(&send_with_args(:map_to_resource_link, self)).compact
|
46
50
|
end
|
47
51
|
|
48
52
|
def map_subresources
|
@@ -52,7 +56,7 @@ module Yaks
|
|
52
56
|
rel, subresource = association.create_subresource(
|
53
57
|
self,
|
54
58
|
method(:load_association),
|
55
|
-
context
|
59
|
+
context.merge(mapper_stack: mapper_stack + [self])
|
56
60
|
)
|
57
61
|
memo[rel] = subresource
|
58
62
|
end
|
data/lib/yaks/null_resource.rb
CHANGED
@@ -3,11 +3,11 @@ module Yaks
|
|
3
3
|
include Enumerable
|
4
4
|
|
5
5
|
def initialize(opts = {})
|
6
|
-
@collection = opts.fetch(:collection
|
6
|
+
@collection = opts.fetch(:collection) { false }
|
7
7
|
end
|
8
8
|
|
9
9
|
def each
|
10
|
-
|
10
|
+
to_enum
|
11
11
|
end
|
12
12
|
|
13
13
|
def attributes
|
@@ -31,5 +31,9 @@ module Yaks
|
|
31
31
|
def collection?
|
32
32
|
@collection
|
33
33
|
end
|
34
|
+
|
35
|
+
def null_resource?
|
36
|
+
true
|
37
|
+
end
|
34
38
|
end
|
35
39
|
end
|
data/lib/yaks/primitivize.rb
CHANGED
data/lib/yaks/resource.rb
CHANGED
@@ -24,15 +24,18 @@ module Yaks
|
|
24
24
|
yield self
|
25
25
|
end
|
26
26
|
|
27
|
-
def collection?
|
28
|
-
false
|
29
|
-
end
|
30
|
-
|
31
27
|
def self_link
|
32
28
|
links.find do |link|
|
33
|
-
link.rel
|
29
|
+
link.rel.equal? :self
|
34
30
|
end
|
35
31
|
end
|
36
32
|
|
33
|
+
def collection?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def null_resource?
|
38
|
+
false
|
39
|
+
end
|
37
40
|
end
|
38
41
|
end
|
data/lib/yaks/serializer/hal.rb
CHANGED
@@ -7,23 +7,28 @@ module Yaks
|
|
7
7
|
|
8
8
|
include FP
|
9
9
|
|
10
|
-
def call
|
11
|
-
|
12
|
-
pluralize(resource.type) => resource.map(&method(:serialize_resource))
|
13
|
-
}
|
10
|
+
def call(resource)
|
11
|
+
main_collection = resource.map(&method(:serialize_resource))
|
14
12
|
|
15
|
-
|
16
|
-
|
13
|
+
{ pluralize(resource.type) => main_collection }.tap do |serialized|
|
14
|
+
linked = resource.each_with_object({}) do |res, hsh|
|
15
|
+
serialize_linked_subresources(res.subresources, hsh)
|
16
|
+
end
|
17
|
+
serialized.merge!(linked: linked) unless linked.empty?
|
17
18
|
end
|
18
|
-
serialized = serialized.merge('linked' => linked)
|
19
|
-
|
20
|
-
serialized
|
21
19
|
end
|
22
|
-
alias serialize call
|
23
20
|
|
24
21
|
def serialize_resource(resource)
|
25
22
|
result = resource.attributes
|
26
|
-
|
23
|
+
|
24
|
+
unless resource.subresources.empty?
|
25
|
+
result[:links] = serialize_links(resource.subresources)
|
26
|
+
end
|
27
|
+
|
28
|
+
if resource.self_link && !result.key?(:href)
|
29
|
+
result[:href] = resource.self_link.uri
|
30
|
+
end
|
31
|
+
|
27
32
|
result
|
28
33
|
end
|
29
34
|
|
data/lib/yaks/serializer.rb
CHANGED
@@ -3,17 +3,16 @@ module Yaks
|
|
3
3
|
extend Forwardable
|
4
4
|
include Util
|
5
5
|
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :options
|
7
7
|
def_delegators :resource, :links, :attributes, :subresources
|
8
8
|
|
9
|
-
protected :
|
9
|
+
protected :links, :attributes, :subresources, :options
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
@resource = resource
|
11
|
+
def initialize(options = {})
|
13
12
|
@options = YAKS_DEFAULT_OPTIONS.merge(options)
|
14
13
|
end
|
15
14
|
|
16
|
-
def call
|
15
|
+
def call(resource)
|
17
16
|
serialize_resource(resource)
|
18
17
|
end
|
19
18
|
alias serialize call
|
data/lib/yaks/version.rb
CHANGED
@@ -4,7 +4,7 @@ require_relative './models'
|
|
4
4
|
|
5
5
|
RSpec.shared_examples_for 'JSON output format' do |yaks, format, name|
|
6
6
|
let(:input) { load_yaml_fixture(name) }
|
7
|
-
let(:output) { load_json_fixture
|
7
|
+
let(:output) { load_json_fixture("#{name}.#{format}") }
|
8
8
|
|
9
9
|
subject { yaks.serialize(input) }
|
10
10
|
|
data/spec/acceptance/models.rb
CHANGED
@@ -24,7 +24,9 @@ end
|
|
24
24
|
class ScholarMapper < LiteratureBaseMapper
|
25
25
|
attributes :id, :name, :pinyin, :latinized
|
26
26
|
has_many :works
|
27
|
-
|
27
|
+
|
28
|
+
link 'http://literature.example.com/rels/quotes', 'http://literature.example.com/quotes/?author={downcased_pinyin}&q={query}', expand: [:downcased_pinyin]
|
29
|
+
link :self, 'http://literature.example.com/authors/{downcased_pinyin}'
|
28
30
|
|
29
31
|
def downcased_pinyin
|
30
32
|
object.pinyin.downcase
|
@@ -2,9 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe 'Mapping domain models to Resource objects' do
|
4
4
|
include_context 'fixtures'
|
5
|
+
include_context 'yaks context'
|
5
6
|
|
6
7
|
subject { mapper.call(john) }
|
7
|
-
let(:mapper) { FriendMapper.new(
|
8
|
+
let(:mapper) { FriendMapper.new(yaks_context) }
|
8
9
|
|
9
10
|
it { should be_a Yaks::Resource }
|
10
11
|
its(:type) { should eql 'friend' }
|
@@ -5,7 +5,11 @@
|
|
5
5
|
"latinized": "Confucius",
|
6
6
|
"_links": {
|
7
7
|
"self": { "href": "http://literature.example.com/authors/kongzi" },
|
8
|
-
"profile": { "href": "http://literature.example.com/profiles/scholar" }
|
8
|
+
"profile": { "href": "http://literature.example.com/profiles/scholar" },
|
9
|
+
"http://literature.example.com/rels/quotes": {
|
10
|
+
"href": "http://literature.example.com/quotes/?author=kongzi&q={query}",
|
11
|
+
"templated": true
|
12
|
+
}
|
9
13
|
},
|
10
14
|
"_embedded": {
|
11
15
|
"http://literature.example.com/rel/works": [
|
@@ -2,6 +2,7 @@
|
|
2
2
|
"scholars": [
|
3
3
|
{
|
4
4
|
"id": 9,
|
5
|
+
"href": "http://literature.example.com/scholar/9",
|
5
6
|
"name": "孔子",
|
6
7
|
"pinyin": "Kongzi",
|
7
8
|
"latinized": "Confucius",
|
@@ -14,6 +15,7 @@
|
|
14
15
|
"works": [
|
15
16
|
{
|
16
17
|
"id": 11,
|
18
|
+
"href": "http://literature.example.com/work/11",
|
17
19
|
"chinese_name": "論語",
|
18
20
|
"english_name": "Analects",
|
19
21
|
"links": {
|
@@ -23,6 +25,7 @@
|
|
23
25
|
},
|
24
26
|
{
|
25
27
|
"id": 12,
|
28
|
+
"href": "http://literature.example.com/work/12",
|
26
29
|
"chinese_name": "易經",
|
27
30
|
"english_name": "Commentaries to the Yi-jing",
|
28
31
|
"links": {}
|
data/spec/support/deep_eql.rb
CHANGED
@@ -45,6 +45,7 @@ module Matchers
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def compare(key)
|
48
|
+
#require 'pry' ; binding.pry
|
48
49
|
push key
|
49
50
|
if target[key] != expectation[key]
|
50
51
|
if [Hash, Array].any?{|klz| target[key].is_a? klz }
|
@@ -88,6 +89,11 @@ module Matchers
|
|
88
89
|
else
|
89
90
|
failure_message("expected Array got #{@target.inspect}")
|
90
91
|
end
|
92
|
+
|
93
|
+
else
|
94
|
+
if target != expectation
|
95
|
+
failure_message("expected #{expectation.inspect}, got #{@target.inspect}")
|
96
|
+
end
|
91
97
|
end
|
92
98
|
|
93
99
|
result
|
@@ -1,4 +1,4 @@
|
|
1
|
-
shared_context 'collection resource' do
|
1
|
+
RSpec.shared_context 'collection resource' do
|
2
2
|
let(:resource) do
|
3
3
|
Yaks::CollectionResource.new(
|
4
4
|
links: links,
|
@@ -10,7 +10,14 @@ shared_context 'collection resource' do
|
|
10
10
|
let(:members) { [] }
|
11
11
|
end
|
12
12
|
|
13
|
-
shared_context '
|
13
|
+
RSpec.shared_context 'yaks context' do
|
14
|
+
let(:policy) { Yaks::DefaultPolicy.new }
|
15
|
+
let(:rack_env) { {} }
|
16
|
+
let(:mapper_stack) { [] }
|
17
|
+
let(:yaks_context) { { policy: policy, env: rack_env, mapper_stack: mapper_stack } }
|
18
|
+
end
|
19
|
+
|
20
|
+
RSpec.shared_context 'plant collection resource' do
|
14
21
|
include_context 'collection resource'
|
15
22
|
|
16
23
|
let(:links) { [ plants_self_link, plants_profile_link ] }
|
@@ -3,11 +3,14 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Yaks::CollectionMapper do
|
4
4
|
include_context 'fixtures'
|
5
5
|
|
6
|
-
subject(:mapper) {
|
6
|
+
subject(:mapper) { mapper_class.new(context) }
|
7
|
+
let(:mapper_class) { described_class }
|
8
|
+
|
7
9
|
let(:context) {
|
8
10
|
{ member_mapper: member_mapper,
|
9
11
|
policy: policy,
|
10
|
-
env: {}
|
12
|
+
env: {},
|
13
|
+
mapper_stack: []
|
11
14
|
}
|
12
15
|
}
|
13
16
|
let(:collection) { [] }
|
@@ -29,8 +32,6 @@ RSpec.describe Yaks::CollectionMapper do
|
|
29
32
|
let(:member_mapper) { PetMapper }
|
30
33
|
|
31
34
|
it 'should map the members' do
|
32
|
-
mapper.call(collection)
|
33
|
-
|
34
35
|
expect(mapper.call(collection)).to eql Yaks::CollectionResource.new(
|
35
36
|
type: 'pet',
|
36
37
|
links: [],
|
@@ -87,4 +88,31 @@ RSpec.describe Yaks::CollectionMapper do
|
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
91
|
+
describe 'overriding #collection' do
|
92
|
+
let(:mapper_class) do
|
93
|
+
Class.new(described_class) do
|
94
|
+
type 'pet'
|
95
|
+
|
96
|
+
def collection
|
97
|
+
super.drop(1)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
let(:collection) { [boingboing, wassup]}
|
103
|
+
let(:member_mapper) { PetMapper }
|
104
|
+
|
105
|
+
it 'should use the redefined collection method' do
|
106
|
+
expect(mapper.call(collection)).to eql Yaks::CollectionResource.new(
|
107
|
+
type: 'pet',
|
108
|
+
links: [],
|
109
|
+
attributes: {},
|
110
|
+
members: [
|
111
|
+
Yaks::Resource.new(type: 'pet', attributes: {:id => 3, :species => "cat", :name => "wassup"})
|
112
|
+
],
|
113
|
+
members_rel: 'rel:src=collection&dest=pets'
|
114
|
+
)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
90
118
|
end
|
@@ -4,7 +4,8 @@ RSpec.describe Yaks::CollectionResource do
|
|
4
4
|
subject(:collection) { described_class.new(init_opts) }
|
5
5
|
let(:init_opts) { {} }
|
6
6
|
|
7
|
-
its(:collection?)
|
7
|
+
its(:collection?) { should be true }
|
8
|
+
its(:null_resource?) { should be false }
|
8
9
|
|
9
10
|
context 'with nothing passed in the contstructor' do
|
10
11
|
its(:type) { should be_nil }
|
@@ -12,6 +13,7 @@ RSpec.describe Yaks::CollectionResource do
|
|
12
13
|
its(:attributes) { should eql({}) }
|
13
14
|
its(:members) { should eql [] }
|
14
15
|
its(:subresources) { should eql({}) }
|
16
|
+
its(:members_rel) { should eql('members') }
|
15
17
|
end
|
16
18
|
|
17
19
|
context 'with a full constructor' do
|
@@ -29,7 +31,8 @@ RSpec.describe Yaks::CollectionResource do
|
|
29
31
|
links: [Yaks::Resource::Link.new(:self, 'http://order/10', {})],
|
30
32
|
attributes: { customer: 'John Doe', price: 10.00 }
|
31
33
|
)
|
32
|
-
]
|
34
|
+
],
|
35
|
+
members_rel: 'http://api.example.org/rels/orders'
|
33
36
|
}
|
34
37
|
}
|
35
38
|
|
@@ -48,9 +51,10 @@ RSpec.describe Yaks::CollectionResource do
|
|
48
51
|
)
|
49
52
|
]
|
50
53
|
}
|
54
|
+
its(:members_rel) { should eq 'http://api.example.org/rels/orders'}
|
51
55
|
|
52
56
|
its(:subresources) { should eql(
|
53
|
-
'
|
57
|
+
'http://api.example.org/rels/orders' => Yaks::CollectionResource.new(
|
54
58
|
type: 'order',
|
55
59
|
attributes: { total: 10.00 },
|
56
60
|
links: [
|
@@ -64,6 +68,7 @@ RSpec.describe Yaks::CollectionResource do
|
|
64
68
|
attributes: { customer: 'John Doe', price: 10.00 }
|
65
69
|
)
|
66
70
|
],
|
71
|
+
members_rel: 'http://api.example.org/rels/orders'
|
67
72
|
)
|
68
73
|
)
|
69
74
|
}
|
@@ -1,7 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Yaks::Mapper::HasMany do
|
4
|
-
|
4
|
+
include_context 'yaks context'
|
5
|
+
|
6
|
+
let(:closet_mapper) { closet_mapper_class.new(yaks_context) }
|
7
|
+
|
8
|
+
let(:closet_mapper_class) do
|
5
9
|
Class.new(Yaks::Mapper) do
|
6
10
|
type 'closet'
|
7
11
|
has_many :shoes,
|
@@ -10,6 +14,10 @@ RSpec.describe Yaks::Mapper::HasMany do
|
|
10
14
|
end
|
11
15
|
end
|
12
16
|
|
17
|
+
subject(:shoe_association) { closet_mapper.associations.first }
|
18
|
+
|
19
|
+
its(:singular_name) { should eq 'shoe' }
|
20
|
+
|
13
21
|
let(:closet) {
|
14
22
|
double(
|
15
23
|
:shoes => [
|
@@ -20,7 +28,7 @@ RSpec.describe Yaks::Mapper::HasMany do
|
|
20
28
|
}
|
21
29
|
|
22
30
|
it 'should map the subresources' do
|
23
|
-
expect(closet_mapper.
|
31
|
+
expect(closet_mapper.call(closet).subresources).to eql(
|
24
32
|
"http://foo/shoes" => Yaks::CollectionResource.new(
|
25
33
|
type: 'shoe',
|
26
34
|
members: [
|
@@ -3,9 +3,9 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Yaks::Mapper::HasOne do
|
4
4
|
AuthorMapper = Class.new(Yaks::Mapper) { attributes :name }
|
5
5
|
|
6
|
+
subject(:has_one) { described_class.new(:author, mapper, 'http://rel', Yaks::Undefined) }
|
6
7
|
let(:name) { 'William S. Burroughs' }
|
7
8
|
let(:mapper) { AuthorMapper }
|
8
|
-
let(:has_one) { described_class.new(:author, mapper, 'http://rel', Yaks::Undefined) }
|
9
9
|
let(:author) { double(:name => name) }
|
10
10
|
let(:policy) {
|
11
11
|
double(
|
@@ -16,6 +16,8 @@ RSpec.describe Yaks::Mapper::HasOne do
|
|
16
16
|
}
|
17
17
|
let(:context) {{policy: policy, env: {}}}
|
18
18
|
|
19
|
+
its(:singular_name) { should eq 'author' }
|
20
|
+
|
19
21
|
it 'should map to a single Resource' do
|
20
22
|
expect(has_one.map_resource(author, context)).to eq Yaks::Resource.new(type: 'author', attributes: {name: name})
|
21
23
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Yaks::Mapper::Link do
|
4
|
+
include_context 'yaks context'
|
5
|
+
|
4
6
|
subject(:link) { described_class.new(rel, template, options) }
|
5
7
|
|
6
8
|
let(:rel) { :next }
|
@@ -11,8 +13,6 @@ RSpec.describe Yaks::Mapper::Link do
|
|
11
13
|
its(:uri_template) { should eq URITemplate.new(template) }
|
12
14
|
its(:expand?) { should be true }
|
13
15
|
|
14
|
-
let(:policy) { Yaks::DefaultPolicy.new }
|
15
|
-
let(:context) { { policy: policy, env: {} } }
|
16
16
|
|
17
17
|
describe '#rel?' do
|
18
18
|
it 'should return true if the relation matches' do
|
@@ -81,11 +81,11 @@ RSpec.describe Yaks::Mapper::Link do
|
|
81
81
|
|
82
82
|
its(:rel) { should eq :next }
|
83
83
|
|
84
|
-
let(:object) { Struct.new(:x
|
84
|
+
let(:object) { Struct.new(:x, :y, :returns_nil).new(3, 4, nil) }
|
85
85
|
|
86
86
|
let(:mapper) do
|
87
|
-
Yaks::Mapper.new(
|
88
|
-
mapper.call(object)
|
87
|
+
Yaks::Mapper.new(yaks_context).tap do |mapper|
|
88
|
+
mapper.call(object) # set @object
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
@@ -152,6 +152,13 @@ RSpec.describe Yaks::Mapper::Link do
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
|
+
context 'with a link generation method that returns nil' do
|
156
|
+
let(:template) { :returns_nil }
|
157
|
+
|
158
|
+
it 'should return nil' do
|
159
|
+
expect(resource_link).to be_nil
|
160
|
+
end
|
161
|
+
end
|
155
162
|
end
|
156
163
|
|
157
164
|
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Yaks::Mapper do
|
4
|
-
|
4
|
+
include_context 'yaks context'
|
5
|
+
|
6
|
+
subject(:mapper) { mapper_class.new(yaks_context) }
|
5
7
|
let(:resource) { mapper.call(instance) }
|
6
8
|
|
7
9
|
let(:mapper_class) { Class.new(Yaks::Mapper) { type 'foo' } }
|
8
10
|
let(:instance) { double(foo: 'hello', bar: 'world') }
|
9
|
-
let(:policy) { nil }
|
10
|
-
let(:options) { {} }
|
11
|
-
let(:context) {{policy: policy, env: {}}}
|
12
11
|
|
13
|
-
|
12
|
+
its(:env) { should equal rack_env }
|
13
|
+
|
14
|
+
context 'with attributes' do
|
14
15
|
before do
|
15
16
|
mapper_class.attributes :foo, :bar
|
16
17
|
end
|
@@ -38,7 +39,7 @@ RSpec.describe Yaks::Mapper do
|
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
41
|
-
|
42
|
+
context 'with links' do
|
42
43
|
before do
|
43
44
|
mapper_class.link :profile, 'http://foo/bar'
|
44
45
|
end
|
@@ -73,7 +74,7 @@ RSpec.describe Yaks::Mapper do
|
|
73
74
|
end
|
74
75
|
end
|
75
76
|
|
76
|
-
|
77
|
+
context 'with subresources' do
|
77
78
|
let(:instance) { double(widget: widget) }
|
78
79
|
let(:widget) { double(type: 'super_widget') }
|
79
80
|
let(:widget_mapper) { Class.new(Yaks::Mapper) { type 'widget' } }
|
@@ -150,25 +151,23 @@ RSpec.describe Yaks::Mapper do
|
|
150
151
|
end
|
151
152
|
end
|
152
153
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
attributes :fooattr, :bar
|
154
|
+
context 'when the mapper implements a method with the attribute name' do
|
155
|
+
before do
|
156
|
+
mapper_class.class_eval do
|
157
|
+
attributes :fooattr, :bar
|
158
158
|
|
159
|
-
|
160
|
-
|
161
|
-
end
|
159
|
+
def fooattr
|
160
|
+
"#{object.foo} my friend"
|
162
161
|
end
|
163
162
|
end
|
163
|
+
end
|
164
164
|
|
165
|
-
|
166
|
-
|
167
|
-
end
|
165
|
+
it 'should get the attribute from the mapper' do
|
166
|
+
expect(resource.attributes).to eq(fooattr: 'hello my friend', bar: 'world')
|
168
167
|
end
|
169
168
|
end
|
170
169
|
|
171
|
-
|
170
|
+
context 'with a nil subject' do
|
172
171
|
it 'should return a NullResource when the subject is nil' do
|
173
172
|
expect(mapper.call(nil)).to be_a Yaks::NullResource
|
174
173
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Yaks::NullResource do
|
4
|
+
subject(:null_resource) { described_class.new }
|
5
|
+
|
6
|
+
its(:attributes) { should eq Hash[] }
|
7
|
+
its(:links) { should eq [] }
|
8
|
+
its(:subresources) { should eq Hash[] }
|
9
|
+
its(:collection?) { should be false }
|
10
|
+
its(:null_resource?) { should be true }
|
11
|
+
|
12
|
+
it { should respond_to :[] }
|
13
|
+
|
14
|
+
its(:type) { should be_nil }
|
15
|
+
|
16
|
+
describe '#each' do
|
17
|
+
its(:each) { should be_a Enumerator }
|
18
|
+
|
19
|
+
it 'should not yield anything' do
|
20
|
+
null_resource.each { fail }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should contain nothing' do
|
25
|
+
expect( null_resource[:key] ).to be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when a collection' do
|
29
|
+
subject(:null_resource) { described_class.new( collection: true ) }
|
30
|
+
its(:collection?) { should be true }
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Yaks::Primitivize do
|
4
|
+
subject(:primitivizer) { described_class.create }
|
5
|
+
|
6
|
+
describe '.create' do
|
7
|
+
it 'should map String, true, false, nil, numbers to themselves' do
|
8
|
+
[
|
9
|
+
'hello',
|
10
|
+
true,
|
11
|
+
false,
|
12
|
+
nil,
|
13
|
+
100,
|
14
|
+
99.99,
|
15
|
+
-95.33333
|
16
|
+
].each do |object|
|
17
|
+
expect(primitivizer.call(object)).to eql object
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should stringify symbols' do
|
22
|
+
expect(primitivizer.call(:foo)).to eql 'foo'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should recursively handle hashes' do
|
26
|
+
expect(primitivizer.call(
|
27
|
+
:foo => {:wassup => :friends, 123 => '456'}
|
28
|
+
)).to eql('foo' => {'wassup' => 'friends', 123 => '456'})
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should handle arrays recursively' do
|
32
|
+
expect(primitivizer.call(
|
33
|
+
[:foo, [:wassup, :friends], 123, '456']
|
34
|
+
)).to eql( ['foo', ['wassup', 'friends'], 123, '456'] )
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#call' do
|
39
|
+
require 'ostruct'
|
40
|
+
|
41
|
+
let(:funny_object) {
|
42
|
+
OpenStruct.new('a' => 'b')
|
43
|
+
}
|
44
|
+
|
45
|
+
it 'should raise an error when passed an unkown type' do
|
46
|
+
def funny_object.inspect
|
47
|
+
"I am funny"
|
48
|
+
end
|
49
|
+
|
50
|
+
expect { primitivizer.call(funny_object) }.to raise_error "don't know how to turn OpenStruct (I am funny) into a primitive"
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with custom mapping' do
|
54
|
+
require 'matrix'
|
55
|
+
|
56
|
+
let(:primitivizer) do
|
57
|
+
described_class.new.tap do |p|
|
58
|
+
p.map Vector do |vec|
|
59
|
+
vec.map do |i|
|
60
|
+
call(i)
|
61
|
+
end.to_a
|
62
|
+
end
|
63
|
+
|
64
|
+
p.map Symbol do |sym|
|
65
|
+
sym.to_s.length
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should evaluate in the context of primitivize' do
|
71
|
+
expect( primitivizer.call( Vector[:foo, :baxxx, :bazz] ) ).to eql( [3, 5, 4] )
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Yaks::Resource::Link do
|
4
|
+
subject(:link) { described_class.new(rel, uri, options) }
|
5
|
+
let(:rel) { :foo_rel }
|
6
|
+
let(:uri) { 'http://api.example.org/rel/foo' }
|
7
|
+
let(:options) { {name: 'jimmy', title: 'mr. spectacular' } }
|
8
|
+
|
9
|
+
its(:rel) { should eql :foo_rel }
|
10
|
+
its(:uri) { should eql 'http://api.example.org/rel/foo' }
|
11
|
+
its(:options) { should eql(name: 'jimmy', title: 'mr. spectacular') }
|
12
|
+
|
13
|
+
its(:name) { should eql('jimmy') }
|
14
|
+
its(:title) { should eql('mr. spectacular') }
|
15
|
+
its(:templated?) { should be false }
|
16
|
+
|
17
|
+
context 'with explicit templated option' do
|
18
|
+
let(:options) { super().merge(templated: true) }
|
19
|
+
its(:templated?) { should be true }
|
20
|
+
end
|
21
|
+
end
|
@@ -4,10 +4,13 @@ RSpec.describe Yaks::Resource do
|
|
4
4
|
subject(:resource) { described_class.new(init_opts) }
|
5
5
|
let(:init_opts) { {} }
|
6
6
|
|
7
|
-
its(:type)
|
8
|
-
its(:attributes)
|
9
|
-
its(:links)
|
10
|
-
its(:subresources)
|
7
|
+
its(:type) { should be_nil }
|
8
|
+
its(:attributes) { should eql({}) }
|
9
|
+
its(:links) { should eql [] }
|
10
|
+
its(:subresources) { should eql({}) }
|
11
|
+
its(:self_link) { should be_nil }
|
12
|
+
its(:null_resource?) { should be false }
|
13
|
+
its(:collection?) { should be false }
|
11
14
|
|
12
15
|
context 'with a type' do
|
13
16
|
let(:init_opts) { { type: 'post' } }
|
@@ -23,16 +26,32 @@ RSpec.describe Yaks::Resource do
|
|
23
26
|
end
|
24
27
|
|
25
28
|
context 'with links' do
|
26
|
-
let(:init_opts) {
|
27
|
-
|
29
|
+
let(:init_opts) {
|
30
|
+
{
|
31
|
+
links: [
|
32
|
+
Yaks::Resource::Link.new(:profile, '/foo/bar/profile', {}),
|
33
|
+
Yaks::Resource::Link.new(:self, '/foo/bar', {})
|
34
|
+
]
|
35
|
+
}
|
36
|
+
}
|
37
|
+
its(:links) { should eql [
|
38
|
+
Yaks::Resource::Link.new(:profile, '/foo/bar/profile', {}),
|
39
|
+
Yaks::Resource::Link.new(:self, '/foo/bar', {})
|
40
|
+
]
|
41
|
+
}
|
42
|
+
|
43
|
+
its(:self_link) { should eql Yaks::Resource::Link.new(:self, '/foo/bar', {}) }
|
28
44
|
end
|
29
45
|
|
30
46
|
context 'with subresources' do
|
31
47
|
let(:init_opts) { { subresources: { 'comments' => [Yaks::Resource.new(type: 'comment')] } } }
|
32
48
|
its(:subresources) { should eql 'comments' => [Yaks::Resource.new(type: 'comment')] }
|
49
|
+
|
50
|
+
it 'should return an enumerator for #each' do
|
51
|
+
expect(resource.each.with_index.to_a).to eq [ [resource, 0] ]
|
52
|
+
end
|
33
53
|
end
|
34
54
|
|
35
|
-
its(:collection?) { should equal false }
|
36
55
|
|
37
56
|
it 'should act as a collection of one' do
|
38
57
|
expect(resource.each.to_a).to eql [resource]
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Yaks::Serializer::Hal do
|
4
4
|
include_context 'plant collection resource'
|
5
5
|
|
6
|
-
subject { Yaks::Primitivize.create.call(described_class.new(resource)
|
6
|
+
subject { Yaks::Primitivize.create.call(described_class.new.call(resource)) }
|
7
7
|
|
8
8
|
it { should eq(load_json_fixture('hal_plant_collection')) }
|
9
9
|
end
|
metadata
CHANGED
@@ -1,125 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yaks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arne Brasseur
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inflection
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: concord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 0.1.4
|
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
40
|
version: 0.1.4
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: uri_template
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 0.6.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.6.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rack-accept
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.4.5
|
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
68
|
version: 0.4.5
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: virtus
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '2.99'
|
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
96
|
version: '2.99'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rake
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: mutant-rspec
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
@@ -140,28 +140,28 @@ dependencies:
|
|
140
140
|
name: rspec-its
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: benchmark-ips
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- -
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- -
|
164
|
+
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
167
|
description: Serialize to hypermedia. HAL, JSON-API, etc.
|
@@ -172,10 +172,12 @@ extensions: []
|
|
172
172
|
extra_rdoc_files:
|
173
173
|
- README.md
|
174
174
|
files:
|
175
|
-
- .gitignore
|
176
|
-
- .travis.yml
|
175
|
+
- ".gitignore"
|
176
|
+
- ".travis.yml"
|
177
|
+
- ADDING_FORMATS.md
|
177
178
|
- CHANGELOG.md
|
178
179
|
- Gemfile
|
180
|
+
- IDENTIFIERS.md
|
179
181
|
- LICENSE
|
180
182
|
- README.md
|
181
183
|
- Rakefile
|
@@ -239,6 +241,9 @@ files:
|
|
239
241
|
- spec/unit/yaks/mapper/has_one_spec.rb
|
240
242
|
- spec/unit/yaks/mapper/link_spec.rb
|
241
243
|
- spec/unit/yaks/mapper_spec.rb
|
244
|
+
- spec/unit/yaks/null_resource_spec.rb
|
245
|
+
- spec/unit/yaks/primitivize_spec.rb
|
246
|
+
- spec/unit/yaks/resource/link_spec.rb
|
242
247
|
- spec/unit/yaks/resource_spec.rb
|
243
248
|
- spec/unit/yaks/serializer/hal_spec.rb
|
244
249
|
- spec/unit/yaks/serializer_spec.rb
|
@@ -256,12 +261,12 @@ require_paths:
|
|
256
261
|
- lib
|
257
262
|
required_ruby_version: !ruby/object:Gem::Requirement
|
258
263
|
requirements:
|
259
|
-
- -
|
264
|
+
- - ">="
|
260
265
|
- !ruby/object:Gem::Version
|
261
266
|
version: '0'
|
262
267
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
263
268
|
requirements:
|
264
|
-
- -
|
269
|
+
- - ">="
|
265
270
|
- !ruby/object:Gem::Version
|
266
271
|
version: '0'
|
267
272
|
requirements: []
|
@@ -301,6 +306,9 @@ test_files:
|
|
301
306
|
- spec/unit/yaks/mapper/has_one_spec.rb
|
302
307
|
- spec/unit/yaks/mapper/link_spec.rb
|
303
308
|
- spec/unit/yaks/mapper_spec.rb
|
309
|
+
- spec/unit/yaks/null_resource_spec.rb
|
310
|
+
- spec/unit/yaks/primitivize_spec.rb
|
311
|
+
- spec/unit/yaks/resource/link_spec.rb
|
304
312
|
- spec/unit/yaks/resource_spec.rb
|
305
313
|
- spec/unit/yaks/serializer/hal_spec.rb
|
306
314
|
- spec/unit/yaks/serializer_spec.rb
|