oat 0.2.5 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +8 -3
- data/gemfiles/Gemfile.as-1.4.4 +1 -0
- data/gemfiles/Gemfile.as-2.3.x +1 -0
- data/gemfiles/Gemfile.as-3.0.x +1 -0
- data/gemfiles/Gemfile.as-3.1.x +1 -0
- data/gemfiles/Gemfile.as-3.2.x +1 -0
- data/lib/oat/adapter.rb +2 -2
- data/lib/oat/adapters/hal.rb +4 -2
- data/lib/oat/adapters/json_api.rb +41 -6
- data/lib/oat/adapters/siren.rb +1 -1
- data/lib/oat/version.rb +1 -1
- data/spec/adapters/json_api_spec.rb +137 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d46e82b85714a233bfeb43fb7fd17484ab5b1bfc
|
4
|
+
data.tar.gz: e5d24b98474b575a26e39f0d5b37f32bd24ba51a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 588c0d3d4f3f9feacafed50afba811aa7972b5922147084bb85431c998d86e40787fadd5d9c49ddd27fa227dfd20e698f82605cee1f2134e87a4b1056b21159e
|
7
|
+
data.tar.gz: 8bcace9c58e4c84a973aeaa42b457cdcce1e796562489f978b39c7fa400fe5acd7cfde7b9aa69e0c5213a2cb55bdbff39c37b6065a0dbb4a38bd8b7d96d1976f
|
data/README.md
CHANGED
@@ -113,6 +113,11 @@ class ProductSerializer < Oat::Serializer
|
|
113
113
|
end
|
114
114
|
```
|
115
115
|
|
116
|
+
### Defining Links
|
117
|
+
|
118
|
+
Links to other resources can be added by using `link` with a name and an options hash. Most adapters expect just an href in the options hash, but some might support additional properties.
|
119
|
+
Some adapters also suport passing `templated: true` in the options hash to indicate special treatment of a link template.
|
120
|
+
|
116
121
|
## Adapters
|
117
122
|
|
118
123
|
Using the included [HAL](http://stateless.co/hal_specification.html) adapter, the `ProductSerializer` above would render the following JSON:
|
@@ -464,7 +469,7 @@ class CustomAdapter < Oat::Adapter
|
|
464
469
|
end
|
465
470
|
|
466
471
|
def entity(name, obj, serializer_class = nil, &block)
|
467
|
-
data[:nested_documents] = serializer_from_block_or_class(obj, serializer_class, &block)
|
472
|
+
data[:nested_documents] = serializer_from_block_or_class(obj, serializer_class, &block).to_hash
|
468
473
|
end
|
469
474
|
|
470
475
|
... etc
|
@@ -524,7 +529,7 @@ class SocialAdapter < Oat::Adapter
|
|
524
529
|
|
525
530
|
def friends(friend_list, serializer_class = nil, &block)
|
526
531
|
data[:friends] = friend_list.map do |obj|
|
527
|
-
serializer_from_block_or_class(obj, serializer_class, &block)
|
532
|
+
serializer_from_block_or_class(obj, serializer_class, &block).to_hash
|
528
533
|
end
|
529
534
|
end
|
530
535
|
end
|
@@ -582,7 +587,7 @@ Or install it yourself as:
|
|
582
587
|
|
583
588
|
## TODO / contributions welcome
|
584
589
|
|
585
|
-
* JsonAPI
|
590
|
+
* JsonAPI top-level meta
|
586
591
|
* testing module that can be used for testing spec-compliance in user apps?
|
587
592
|
|
588
593
|
## Contributing
|
data/gemfiles/Gemfile.as-1.4.4
CHANGED
data/gemfiles/Gemfile.as-2.3.x
CHANGED
data/gemfiles/Gemfile.as-3.0.x
CHANGED
data/gemfiles/Gemfile.as-3.1.x
CHANGED
data/gemfiles/Gemfile.as-3.2.x
CHANGED
data/lib/oat/adapter.rb
CHANGED
@@ -29,9 +29,9 @@ module Oat
|
|
29
29
|
serializer_class.adapter self.class
|
30
30
|
s = serializer_class.new(obj, serializer.context.merge(context_options), serializer.adapter_class, serializer.top)
|
31
31
|
serializer.instance_exec(obj, s, &block)
|
32
|
-
s
|
32
|
+
s
|
33
33
|
else
|
34
|
-
serializer_class.new(obj, serializer.context.merge(context_options), serializer.adapter_class, serializer.top)
|
34
|
+
serializer_class.new(obj, serializer.context.merge(context_options), serializer.adapter_class, serializer.top)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/lib/oat/adapters/hal.rb
CHANGED
@@ -15,12 +15,14 @@ module Oat
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def entity(name, obj, serializer_class = nil, context_options = {}, &block)
|
18
|
-
|
18
|
+
entity_serializer = serializer_from_block_or_class(obj, serializer_class, context_options, &block)
|
19
|
+
data[:_embedded][name] = entity_serializer ? entity_serializer.to_hash : nil
|
19
20
|
end
|
20
21
|
|
21
22
|
def entities(name, collection, serializer_class = nil, context_options = {}, &block)
|
22
23
|
data[:_embedded][name] = collection.map do |obj|
|
23
|
-
serializer_from_block_or_class(obj, serializer_class, context_options, &block)
|
24
|
+
entity_serializer = serializer_from_block_or_class(obj, serializer_class, context_options, &block)
|
25
|
+
entity_serializer ? entity_serializer.to_hash : nil
|
24
26
|
end
|
25
27
|
end
|
26
28
|
alias_method :collection, :entities
|
@@ -9,11 +9,13 @@ end
|
|
9
9
|
|
10
10
|
module Oat
|
11
11
|
module Adapters
|
12
|
+
|
12
13
|
class JsonAPI < Oat::Adapter
|
13
14
|
|
14
15
|
def initialize(*args)
|
15
16
|
super
|
16
17
|
@entities = {}
|
18
|
+
@link_templates = {}
|
17
19
|
end
|
18
20
|
|
19
21
|
def type(*types)
|
@@ -21,9 +23,34 @@ module Oat
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def link(rel, opts = {})
|
24
|
-
|
26
|
+
if opts.is_a?(Hash)
|
27
|
+
templated = opts.delete(:templated)
|
28
|
+
if templated
|
29
|
+
link_template(rel, opts[:href])
|
30
|
+
else
|
31
|
+
check_link_keys(opts)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
data[:links][rel] = opts
|
25
35
|
end
|
26
36
|
|
37
|
+
def check_link_keys(opts)
|
38
|
+
unsupported_opts = opts.keys - [:href, :id, :ids, :type]
|
39
|
+
|
40
|
+
unless unsupported_opts.empty?
|
41
|
+
raise ArgumentError, "Unsupported opts: #{unsupported_opts.join(", ")}"
|
42
|
+
end
|
43
|
+
if opts.has_key?(:id) && opts.has_key?(:ids)
|
44
|
+
raise ArgumentError, "ops canot contain both :id and :ids"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
private :check_link_keys
|
48
|
+
|
49
|
+
def link_template(key, value)
|
50
|
+
@link_templates[key] = value
|
51
|
+
end
|
52
|
+
private :link_template
|
53
|
+
|
27
54
|
def properties(&block)
|
28
55
|
data.merge! yield_props(&block)
|
29
56
|
end
|
@@ -35,9 +62,10 @@ module Oat
|
|
35
62
|
def entity(name, obj, serializer_class = nil, context_options = {}, &block)
|
36
63
|
ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block)
|
37
64
|
if ent
|
65
|
+
ent_hash = ent.to_hash
|
38
66
|
entity_hash[name.to_s.pluralize.to_sym] ||= []
|
39
|
-
|
40
|
-
entity_hash[name.to_s.pluralize.to_sym] <<
|
67
|
+
data[:links][name] = ent_hash[:id]
|
68
|
+
entity_hash[name.to_s.pluralize.to_sym] << ent_hash
|
41
69
|
end
|
42
70
|
end
|
43
71
|
|
@@ -50,8 +78,9 @@ module Oat
|
|
50
78
|
entity_hash[link_name] ||= []
|
51
79
|
ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block)
|
52
80
|
if ent
|
53
|
-
|
54
|
-
|
81
|
+
ent_hash = ent.to_hash
|
82
|
+
data[:links][link_name] << ent_hash[:id]
|
83
|
+
entity_hash[link_name] << ent_hash
|
55
84
|
end
|
56
85
|
end
|
57
86
|
end
|
@@ -62,7 +91,7 @@ module Oat
|
|
62
91
|
|
63
92
|
collection.each do |obj|
|
64
93
|
ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block)
|
65
|
-
data[:resource_collection] << ent if ent
|
94
|
+
data[:resource_collection] << ent.to_hash if ent
|
66
95
|
end
|
67
96
|
end
|
68
97
|
|
@@ -78,6 +107,7 @@ module Oat
|
|
78
107
|
h[root_name] = [data]
|
79
108
|
end
|
80
109
|
h[:linked] = @entities if @entities.keys.any?
|
110
|
+
h[:links] = @link_templates if @link_templates.keys.any?
|
81
111
|
return h
|
82
112
|
end
|
83
113
|
end
|
@@ -94,6 +124,11 @@ module Oat
|
|
94
124
|
end
|
95
125
|
end
|
96
126
|
|
127
|
+
def entity_without_root(obj, serializer_class = nil, &block)
|
128
|
+
ent = serializer_from_block_or_class(obj, serializer_class, &block)
|
129
|
+
ent.to_hash.values.first.first if ent
|
130
|
+
end
|
131
|
+
|
97
132
|
end
|
98
133
|
end
|
99
134
|
end
|
data/lib/oat/adapters/siren.rb
CHANGED
@@ -28,7 +28,7 @@ module Oat
|
|
28
28
|
|
29
29
|
def entity(name, obj, serializer_class = nil, context_options = {}, &block)
|
30
30
|
ent = serializer_from_block_or_class(obj, serializer_class, context_options, &block)
|
31
|
-
data[:entities] << ent if ent
|
31
|
+
data[:entities] << ent.to_hash if ent
|
32
32
|
end
|
33
33
|
|
34
34
|
def entities(name, collection, serializer_class = nil, context_options = {}, &block)
|
data/lib/oat/version.rb
CHANGED
@@ -25,7 +25,9 @@ describe Oat::Adapters::JsonAPI do
|
|
25
25
|
|
26
26
|
it 'contains the correct user links' do
|
27
27
|
expect(users.first.fetch(:links)).to include(
|
28
|
-
:self =>
|
28
|
+
:self => {
|
29
|
+
:href => "http://foo.bar.com/#{user.id}"
|
30
|
+
},
|
29
31
|
# these links are added by embedding entities
|
30
32
|
:manager => manager.id,
|
31
33
|
:friends => [friend.id]
|
@@ -51,8 +53,9 @@ describe Oat::Adapters::JsonAPI do
|
|
51
53
|
|
52
54
|
it 'contains the correct links' do
|
53
55
|
expect(linked_friends.first.fetch(:links)).to include(
|
54
|
-
:self =>
|
55
|
-
|
56
|
+
:self => {
|
57
|
+
:href => "http://foo.bar.com/#{friend.id}"
|
58
|
+
}
|
56
59
|
)
|
57
60
|
end
|
58
61
|
end
|
@@ -66,7 +69,7 @@ describe Oat::Adapters::JsonAPI do
|
|
66
69
|
:id => manager.id,
|
67
70
|
:name => manager.name,
|
68
71
|
:age => manager.age,
|
69
|
-
:links => { :self => "http://foo.bar.com/#{manager.id}" }
|
72
|
+
:links => { :self => { :href => "http://foo.bar.com/#{manager.id}"} }
|
70
73
|
)
|
71
74
|
end
|
72
75
|
end
|
@@ -84,6 +87,116 @@ describe Oat::Adapters::JsonAPI do
|
|
84
87
|
end
|
85
88
|
end
|
86
89
|
|
90
|
+
context 'object links' do
|
91
|
+
context "as string" do
|
92
|
+
let(:serializer_class) do
|
93
|
+
Class.new(Oat::Serializer) do
|
94
|
+
schema do
|
95
|
+
type 'users'
|
96
|
+
link :self, "45"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'renders just the string' do
|
102
|
+
expect(hash.fetch(:users).first.fetch(:links)).to eq({
|
103
|
+
:self => "45"
|
104
|
+
})
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'as array' do
|
109
|
+
let(:serializer_class) do
|
110
|
+
Class.new(Oat::Serializer) do
|
111
|
+
schema do
|
112
|
+
type 'users'
|
113
|
+
link :self, ["45", "46", "47"]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'renders the array' do
|
119
|
+
expect(hash.fetch(:users).first.fetch(:links)).to eq({
|
120
|
+
:self => ["45", "46", "47"]
|
121
|
+
})
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'as hash' do
|
126
|
+
context 'with single id' do
|
127
|
+
let(:serializer_class) do
|
128
|
+
Class.new(Oat::Serializer) do
|
129
|
+
schema do
|
130
|
+
type 'users'
|
131
|
+
link :self, :href => "http://foo.bar.com/#{item.id}", :id => item.id.to_s, :type => 'user'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'renders all the keys' do
|
137
|
+
expect(hash.fetch(:users).first.fetch(:links)).to eq({
|
138
|
+
:self => {
|
139
|
+
:href => "http://foo.bar.com/#{user.id}",
|
140
|
+
:id => user.id.to_s,
|
141
|
+
:type => 'user'
|
142
|
+
}
|
143
|
+
})
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'with ids' do
|
148
|
+
let(:serializer_class) do
|
149
|
+
Class.new(Oat::Serializer) do
|
150
|
+
schema do
|
151
|
+
type 'users'
|
152
|
+
link :self, :href => "http://foo.bar.com/1,2,3", :ids => ["1", "2", "3"], :type => 'user'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'renders all the keys' do
|
158
|
+
expect(hash.fetch(:users).first.fetch(:links)).to eq({
|
159
|
+
:self => {
|
160
|
+
:href => "http://foo.bar.com/1,2,3",
|
161
|
+
:ids => ["1", "2", "3"],
|
162
|
+
:type => 'user'
|
163
|
+
}
|
164
|
+
})
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'with id and ids' do
|
169
|
+
let(:serializer_class) do
|
170
|
+
Class.new(Oat::Serializer) do
|
171
|
+
schema do
|
172
|
+
type 'users'
|
173
|
+
link :self, :id => "45", :ids => ["1", "2", "3"]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
it "errs" do
|
179
|
+
expect{hash}.to raise_error(ArgumentError)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'with invalid keys' do
|
184
|
+
let(:serializer_class) do
|
185
|
+
Class.new(Oat::Serializer) do
|
186
|
+
schema do
|
187
|
+
type 'users'
|
188
|
+
link :self, :not_a_valid_key => "value"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
it "errs" do
|
194
|
+
expect{hash}.to raise_error(ArgumentError)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
87
200
|
context 'with a nil entity relationship' do
|
88
201
|
let(:manager) { nil }
|
89
202
|
let(:users) { hash.fetch(:users) }
|
@@ -169,7 +282,7 @@ describe Oat::Adapters::JsonAPI do
|
|
169
282
|
|
170
283
|
it 'contains the correct user links' do
|
171
284
|
expect(users.first.fetch(:links)).to include(
|
172
|
-
:self => "http://foo.bar.com/#{user.id}",
|
285
|
+
:self => {:href => "http://foo.bar.com/#{user.id}"},
|
173
286
|
# these links are added by embedding entities
|
174
287
|
:manager => manager.id,
|
175
288
|
:friends => [friend.id]
|
@@ -185,12 +298,30 @@ describe Oat::Adapters::JsonAPI do
|
|
185
298
|
:id => manager.id,
|
186
299
|
:name => manager.name,
|
187
300
|
:age => manager.age,
|
188
|
-
:links => { :self => "http://foo.bar.com/#{manager.id}" }
|
301
|
+
:links => { :self => {:href =>"http://foo.bar.com/#{manager.id}"} }
|
189
302
|
)
|
190
303
|
end
|
191
304
|
end
|
192
305
|
end
|
306
|
+
end
|
307
|
+
|
308
|
+
context 'link_template' do
|
309
|
+
let(:serializer_class) do
|
310
|
+
Class.new(Oat::Serializer) do
|
311
|
+
schema do
|
312
|
+
type 'users'
|
313
|
+
link "user.managers", :href => "http://foo.bar.com/{user.id}/managers", :templated => true
|
314
|
+
link "user.friends", :href => "http://foo.bar.com/{user.id}/friends", :templated => true
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
193
318
|
|
319
|
+
it 'renders them top level' do
|
320
|
+
expect(hash.fetch(:links)).to eq({
|
321
|
+
"user.managers" => "http://foo.bar.com/{user.id}/managers",
|
322
|
+
"user.friends" => "http://foo.bar.com/{user.id}/friends"
|
323
|
+
})
|
324
|
+
end
|
194
325
|
end
|
195
326
|
end
|
196
327
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ismael Celis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|