hal-interpretation 1.7.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -1
- data/lib/hal_interpretation/dsl.rb +77 -0
- data/lib/hal_interpretation/version.rb +1 -1
- data/spec/hal_interpretation_spec.rb +22 -4
- 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: f58aa8729b4937c393264c78c95d632709da9466
|
4
|
+
data.tar.gz: 56ba264b40ef29039d9e43b036f294686e7355ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f837c0d54a4761ad9b0cee0f62c7ab01217daefe2533dea6afac51a5f82b66bb5e9b82ce4f385a72ef00dd6efff364c7e30e02268bb6f226c6f75381c27be740
|
7
|
+
data.tar.gz: 01f37e998c2e7cd8740065c0e664806b4c7710765c8ff6af89737896609dfb87297775510087aa4628ccd79dfccd281a2cb9a6581b746c85260e145b5297e39a
|
data/README.md
CHANGED
@@ -42,6 +42,19 @@ class UserHalInterpreter
|
|
42
42
|
# type is present.
|
43
43
|
extract_link :up
|
44
44
|
|
45
|
+
# Extract the target of the rel link and assign a HAL representation to the person
|
46
|
+
# attribute of the model. Reports a problem if more than one link of this
|
47
|
+
# type is present.
|
48
|
+
extract_related :profile, rel: "http://xmlns.com/foaf/0.1/Person",
|
49
|
+
coercion: ->(profile_repr) { CustomInterpretation.new(profile_repr) }
|
50
|
+
|
51
|
+
# Extract the target of the rel link and assign a HAL representation
|
52
|
+
# set to the cohorts attribute of the model. Reports a problem if
|
53
|
+
# more than one link of this type is present.
|
54
|
+
extract_relateds :cohorts, rel: "http://xmlns.com/foaf/0.1/knows",
|
55
|
+
coercion: ->(cohort_repr_set) {
|
56
|
+
cohort_repr_set.map {|repr| CustomInterpretation.new(repr) }
|
57
|
+
}
|
45
58
|
|
46
59
|
def initialize
|
47
60
|
@cur_seq_num = 0
|
@@ -65,6 +78,7 @@ This interpreter will work for documents that look like the following
|
|
65
78
|
},
|
66
79
|
"birthday": "1980-08-31",
|
67
80
|
"_links": {
|
81
|
+
"http://xmlns.com/foaf/0.1/Person": { "href": "http://example.com/bob" },
|
68
82
|
"http://xmlns.com/foaf/0.1/knows": [
|
69
83
|
{ "href": "http://example.com/alice" },
|
70
84
|
{ "href": "http://example.com/mallory" }
|
@@ -85,6 +99,7 @@ or
|
|
85
99
|
},
|
86
100
|
"birthday": "1980-08-31",
|
87
101
|
"_links": {
|
102
|
+
"http://xmlns.com/foaf/0.1/Person": { "href": "http://example.com/bob" },
|
88
103
|
"http://xmlns.com/foaf/0.1/knows": [
|
89
104
|
{ "href": "http://example.com/alice" },
|
90
105
|
{ "href": "http://example.com/mallory" }
|
@@ -99,6 +114,7 @@ or
|
|
99
114
|
},
|
100
115
|
"birthday": "1979-02-16",
|
101
116
|
"_links": {
|
117
|
+
"http://xmlns.com/foaf/0.1/Person": { "href": "http://example.com/alice },
|
102
118
|
"http://xmlns.com/foaf/0.1/knows": [
|
103
119
|
{ "href": "http://example.com/bob" },
|
104
120
|
{ "href": "http://example.com/mallory" }
|
@@ -197,4 +213,4 @@ Or install it yourself as:
|
|
197
213
|
|
198
214
|
[semver]: http://semver.org/
|
199
215
|
[json pointer]: http://tools.ietf.org/html/rfc6901
|
200
|
-
[collections]: https://tools.ietf.org/html/rfc6573
|
216
|
+
[collections]: https://tools.ietf.org/html/rfc6573
|
@@ -119,9 +119,86 @@ module HalInterpretation
|
|
119
119
|
coercion: opts[:coercion]
|
120
120
|
end
|
121
121
|
|
122
|
+
# Declare that an attribute should be extracted from the HAL
|
123
|
+
# document's links (or embeddeds) as a representation.
|
124
|
+
#
|
125
|
+
# attr_name - name of the attribute on the model to extract to as
|
126
|
+
# a representation
|
127
|
+
#
|
128
|
+
# opts - hash of named arguments
|
129
|
+
#
|
130
|
+
# :rel - rel of link to extract. Default: attr_name
|
131
|
+
#
|
132
|
+
# :coercion - callable with which the raw URL should transformed
|
133
|
+
# before being stored in the model
|
134
|
+
#
|
135
|
+
# Examples
|
136
|
+
#
|
137
|
+
# extract_repr :author,
|
138
|
+
# rel: "http://xmlns.com/foaf/0.1/Person"
|
139
|
+
#
|
140
|
+
# extracts the targets of the `.../Person` link and stores the
|
141
|
+
# corresponding HAL representation object in the `author`
|
142
|
+
# attribute of the model.
|
143
|
+
#
|
144
|
+
# extract_repr :author, rel: "http://xmlns.com/foaf/0.1/Person",
|
145
|
+
# coercion: ->(person_repr) {
|
146
|
+
# MyInterpretation.new(person_repr)
|
147
|
+
# }
|
148
|
+
#
|
149
|
+
# looks up the author pointed to by the rel and uses coercion to
|
150
|
+
# initialize a custom object stored on the model that uses the
|
151
|
+
# representation
|
152
|
+
def extract_related(attr_name, opts={})
|
153
|
+
extract_related_with_blk(attr_name, opts) {|r, rel| r.related(rel){[]}.first }
|
154
|
+
end
|
155
|
+
|
156
|
+
# Declare that an attribute should be extracted from the HAL
|
157
|
+
# document's links (or embeddeds) as a representation set.
|
158
|
+
#
|
159
|
+
# attr_name - name of the attribute on the model to extract to as
|
160
|
+
# a representation set
|
161
|
+
#
|
162
|
+
# opts - hash of named arguments
|
163
|
+
#
|
164
|
+
# :rel - rel of link to extract. Default: attr_name
|
165
|
+
#
|
166
|
+
# :coercion - callable with which the raw URL should transformed
|
167
|
+
# before being stored in the model
|
168
|
+
#
|
169
|
+
# Examples
|
170
|
+
#
|
171
|
+
# extract_reprs :authors,
|
172
|
+
# rel: "http://exampe.com/authors"
|
173
|
+
#
|
174
|
+
# extracts the targets of the `.../authors` link and stores the
|
175
|
+
# corresponding HAL representation set object in the `authors`
|
176
|
+
# attribute of the model.
|
177
|
+
#
|
178
|
+
# extract_reprs :authors, rel: "http://example.com/authors",
|
179
|
+
# coercion: ->(person_repr_set) {
|
180
|
+
# person_repr_set.map {|repr| MyInterpretation.new(repr)}
|
181
|
+
# }
|
182
|
+
#
|
183
|
+
# looks up the authors pointed to by the rel and uses coercion to
|
184
|
+
# initialize an array of custom objects stored on the model that
|
185
|
+
# uses the representation set
|
186
|
+
def extract_relateds(attr_name, opts={})
|
187
|
+
extract_related_with_blk(attr_name, opts) {|r, rel| r.related(rel){[]} }
|
188
|
+
end
|
189
|
+
|
122
190
|
|
123
191
|
protected
|
124
192
|
|
193
|
+
def extract_related_with_blk(attr_name, opts={}, &blk)
|
194
|
+
rel = opts.fetch(:rel) { attr_name }.to_s
|
195
|
+
path = "/_links/" + json_path_escape(rel)
|
196
|
+
|
197
|
+
extract attr_name, from: path,
|
198
|
+
with: ->(r) { blk.call(r, rel) },
|
199
|
+
coercion: opts[:coercion]
|
200
|
+
end
|
201
|
+
|
125
202
|
def json_path_escape(rel)
|
126
203
|
rel.gsub('~', '~0').gsub('/', '~1')
|
127
204
|
end
|
@@ -6,6 +6,7 @@ require "rspec/collection_matchers"
|
|
6
6
|
describe HalInterpretation do
|
7
7
|
subject(:interpreter_class) {
|
8
8
|
test_item_class = self.test_item_class
|
9
|
+
|
9
10
|
Class.new do
|
10
11
|
include HalInterpretation
|
11
12
|
item_class test_item_class
|
@@ -17,6 +18,8 @@ describe HalInterpretation do
|
|
17
18
|
extract_links :friend_ids, rel: "http://xmlns.com/foaf/0.1/knows",
|
18
19
|
coercion: ->(urls) { urls.map{|u| u.split("/").last } }
|
19
20
|
extract_link :archives_url_tmpl, rel: "archives"
|
21
|
+
extract_related :profile, rel: "http://xmlns.com/foaf/0.1/Person"
|
22
|
+
extract_relateds :cohorts, rel: "http://xmlns.com/foaf/0.1/knows"
|
20
23
|
|
21
24
|
def initialize(*args)
|
22
25
|
@cur_seq_num = 0
|
@@ -26,7 +29,8 @@ describe HalInterpretation do
|
|
26
29
|
def next_seq_num
|
27
30
|
@cur_seq_num += 1
|
28
31
|
end
|
29
|
-
end
|
32
|
+
end
|
33
|
+
}
|
30
34
|
|
31
35
|
let(:interpreter) { interpreter_class.new_from_json(json_doc) }
|
32
36
|
|
@@ -41,6 +45,7 @@ describe HalInterpretation do
|
|
41
45
|
}
|
42
46
|
,"_links": {
|
43
47
|
"up": { "href": "/foo" },
|
48
|
+
"http://xmlns.com/foaf/0.1/Person": { "href": "http://example.com/foo" },
|
44
49
|
"http://xmlns.com/foaf/0.1/knows": [
|
45
50
|
{ "href": "http://example.com/bob" },
|
46
51
|
{ "href": "http://example.com/alice" }
|
@@ -60,6 +65,8 @@ describe HalInterpretation do
|
|
60
65
|
specify { expect(interpreter.item.up).to eq "/foo" }
|
61
66
|
specify { expect(interpreter.item.bday).to eq Time.utc(2013,12,11,10,9,8) }
|
62
67
|
specify { expect(interpreter.item.seq).to eq 1 }
|
68
|
+
specify { expect(interpreter.item.profile).to be_kind_of HalClient::Representation }
|
69
|
+
specify { expect(interpreter.item.cohorts).to be_kind_of HalClient::RepresentationSet }
|
63
70
|
specify { expect(interpreter.item.friend_ids).to eq ["bob", "alice"] }
|
64
71
|
specify { expect(interpreter.item.archives_url_tmpl)
|
65
72
|
.to eq "http://example.com/old{?since,until}" }
|
@@ -93,6 +100,7 @@ describe HalInterpretation do
|
|
93
100
|
}
|
94
101
|
,"_embedded": {
|
95
102
|
"up": { "_links": { "self": { "href": "/foo" } } },
|
103
|
+
"http://xmlns.com/foaf/0.1/Person": { "href": "http://example.com/foo" },
|
96
104
|
"http://xmlns.com/foaf/0.1/knows": [
|
97
105
|
{ "_links": { "self":{ "href": "http://example.com/bob" } } },
|
98
106
|
{ "_links": { "self":{ "href": "http://example.com/alice" } } }
|
@@ -103,6 +111,8 @@ describe HalInterpretation do
|
|
103
111
|
|
104
112
|
specify { expect(interpreter.item.up).to eq "/foo" }
|
105
113
|
specify { expect(interpreter.item.friend_ids).to eq ["bob", "alice"] }
|
114
|
+
specify { expect(interpreter.item.profile).to be_kind_of HalClient::Representation }
|
115
|
+
specify { expect(interpreter.item.cohorts).to be_kind_of HalClient::RepresentationSet }
|
106
116
|
end
|
107
117
|
end
|
108
118
|
|
@@ -114,14 +124,20 @@ describe HalInterpretation do
|
|
114
124
|
,"geo": {
|
115
125
|
"latitude": 39.1
|
116
126
|
}
|
117
|
-
,"_links": {
|
127
|
+
,"_links": {
|
128
|
+
"http://xmlns.com/foaf/0.1/Person": { "href": "http://example.com/foo" },
|
129
|
+
"up": {"href": "/foo"}
|
130
|
+
}
|
118
131
|
}
|
119
132
|
,{ "name": "bar"
|
120
133
|
,"bday": "2013-12-11T10:09:08Z"
|
121
134
|
,"geo": {
|
122
135
|
"latitude": 39.2
|
123
136
|
}
|
124
|
-
,"_links": {
|
137
|
+
,"_links": {
|
138
|
+
"http://xmlns.com/foaf/0.1/Person": { "href": "http://example.com/bar" },
|
139
|
+
"up": {"href": "/bar"}
|
140
|
+
}
|
125
141
|
}]
|
126
142
|
}
|
127
143
|
}
|
@@ -133,6 +149,8 @@ describe HalInterpretation do
|
|
133
149
|
specify { expect(interpreter.items).to include item_named "bar" }
|
134
150
|
specify { expect(interpreter.items[0].seq).to eq 1 }
|
135
151
|
specify { expect(interpreter.items[1].seq).to eq 2 }
|
152
|
+
specify { expect(interpreter.items[0].profile).to be_kind_of HalClient::Representation }
|
153
|
+
specify { expect(interpreter.items[1].profile).to be_kind_of HalClient::Representation }
|
136
154
|
|
137
155
|
specify { expect{interpreter.item}
|
138
156
|
.to raise_error HalInterpretation::InvalidRepresentationError }
|
@@ -279,7 +297,7 @@ describe HalInterpretation do
|
|
279
297
|
include ActiveModel::Validations
|
280
298
|
|
281
299
|
attr_accessor :name, :latitude, :up, :bday, :seq, :hair, :friend_ids,
|
282
|
-
:archives_url_tmpl
|
300
|
+
:archives_url_tmpl, :profile, :cohorts
|
283
301
|
|
284
302
|
def initialize
|
285
303
|
yield self
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hal-interpretation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hal-client
|