hal-interpretation 1.7.0 → 1.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee39c1fec5913e271d4fab7531f9ff40b6623dc9
4
- data.tar.gz: 5c21413e4a4be9e30d16eb3cc8e6a00644154731
3
+ metadata.gz: f58aa8729b4937c393264c78c95d632709da9466
4
+ data.tar.gz: 56ba264b40ef29039d9e43b036f294686e7355ca
5
5
  SHA512:
6
- metadata.gz: 7cbe1d536193dd6f563c43823b7828ebe5975ba039201b5189960b033f12dfb72c04b767a95e8765c21736e661aee117b64fb95f769afc4f38fa7f626255ee01
7
- data.tar.gz: eb3d579ce01aea81b727c59df2457c509765759ef0bc884492afe3adf57d746de99a43a639c2c44f0b95c6fcf5c998020189f8e0cb62552065c5ab4754ac5f8f
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
@@ -1,3 +1,3 @@
1
1
  module HalInterpretation
2
- VERSION = "1.7.0"
2
+ VERSION = "1.8.0"
3
3
  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": { "up": {"href": "/foo"} }
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": { "up": {"href": "/bar"} }
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.7.0
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-01-12 00:00:00.000000000 Z
11
+ date: 2015-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hal-client