jsonapi-object-mapper 0.8.1 → 0.9.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/CHANGELOG.md +8 -0
- data/lib/jsonapi-object-mapper/deserialize/collection.rb +20 -6
- data/lib/jsonapi-object-mapper/deserialize/dsl.rb +6 -2
- data/lib/jsonapi-object-mapper/deserialize/resource.rb +9 -2
- data/lib/jsonapi-object-mapper/parser/document.rb +20 -4
- data/lib/jsonapi-object-mapper/version.rb +1 -1
- data/spec/deserialize/collection_spec.rb +19 -0
- data/spec/deserialize/link_examples.rb +28 -0
- data/spec/deserialize/resource_spec.rb +12 -0
- data/spec/spec_helper.rb +1 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b23420a89f5d55965dafc872b3a84b78562d654981c7f3ff1f1524a90b42b8b7
|
4
|
+
data.tar.gz: 817b0c84ab3638e11a4b7540ccffdf3f8bd7dea40f046c884a77ada0d39712b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 001f695018d0ac217632c7f070789e378377b371113ec0ae13f1871cda73d088ad92d4980d28d0d5f04c23d4b3dd9f09818108a786732436cb454b560ce31273
|
7
|
+
data.tar.gz: e12ddd6228e415944ac1c8b19f62a7f64ca53ce62cf08a6e6beb77eff67a0625f968d80e4b8d6f840f8e9485a26a5340233df2eb36839051150ac26af888ae64
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
## 0.9.0 - August 5th 2018
|
2
|
+
- Added document `links` support.
|
3
|
+
|
4
|
+
## 0.0.0 to 0.8.1
|
5
|
+
- Added initial support for parsing `has_many`, `has_one` / `belongs_to` relationships into class functions
|
6
|
+
- Added initial support for parsing relationship resources with a responses `included` block. Using the `embed_with` option for relationships.
|
7
|
+
- Added initial support for parsing data attributes into class functions.
|
8
|
+
- Added Error handling support
|
@@ -9,7 +9,7 @@ module JsonAPIObjectMapper
|
|
9
9
|
include Enumerable
|
10
10
|
include JsonAPIObjectMapper::Parser::Errors
|
11
11
|
|
12
|
-
|
12
|
+
attr_reader :collection_data, :links
|
13
13
|
|
14
14
|
def_delegators :@collection_data, :first, :last, :[]
|
15
15
|
|
@@ -17,11 +17,12 @@ module JsonAPIObjectMapper
|
|
17
17
|
raise InvalidResource unless klass.is_a?(Class)
|
18
18
|
raise InvalidParser unless parser.is_a?(JsonAPIObjectMapper::Parser::Document)
|
19
19
|
@errors = parser.errors
|
20
|
+
@links = parser.links
|
20
21
|
@collection_data =
|
21
22
|
if document_invalid?
|
22
23
|
[]
|
23
24
|
else
|
24
|
-
Array(parser.
|
25
|
+
Array(parser.document_data).map do |doc|
|
25
26
|
klass.new(parser, document: doc)
|
26
27
|
end
|
27
28
|
end.freeze
|
@@ -29,15 +30,28 @@ module JsonAPIObjectMapper
|
|
29
30
|
freeze
|
30
31
|
end
|
31
32
|
|
32
|
-
def to_hash
|
33
|
-
@collection_data.map(&:to_hash)
|
34
|
-
end
|
35
|
-
|
36
33
|
def each
|
37
34
|
@collection_data.each do |data|
|
38
35
|
yield data
|
39
36
|
end
|
40
37
|
end
|
38
|
+
|
39
|
+
def inspect
|
40
|
+
"#<#{self.class}:0x#{object_id.to_s(16)}, "\
|
41
|
+
"@errors=#{@errors.inspect}, "\
|
42
|
+
"@links=#{@links.inspect}, "\
|
43
|
+
"@data=#{@collection_data.map(&:inspect)}>"\
|
44
|
+
end
|
45
|
+
alias to_s inspect
|
46
|
+
|
47
|
+
def to_hash
|
48
|
+
{}.tap do |hash|
|
49
|
+
hash[:data] = @collection_data.map(&:to_hash)
|
50
|
+
hash[:links] = @links.to_h unless @links.nil?
|
51
|
+
hash[:errors] = @errors unless valid?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
alias to_h to_hash
|
41
55
|
end
|
42
56
|
end
|
43
57
|
end
|
@@ -77,9 +77,13 @@ module JsonAPIObjectMapper
|
|
77
77
|
end
|
78
78
|
alias to_h to_hash
|
79
79
|
|
80
|
-
def
|
81
|
-
|
80
|
+
def inspect
|
81
|
+
"#<#{self.class}:0x#{object_id.to_s(16)}, "\
|
82
|
+
"@errors = #{@errors.inspect}, "\
|
83
|
+
"attributes = #{@_class_attributes.inspect}, "\
|
84
|
+
"relationships = #{@_class_relationships.inspect}>"
|
82
85
|
end
|
86
|
+
alias to_s inspect
|
83
87
|
|
84
88
|
protected
|
85
89
|
|
@@ -10,6 +10,8 @@ module JsonAPIObjectMapper
|
|
10
10
|
include JsonAPIObjectMapper::Parser::Errors
|
11
11
|
extend DSL
|
12
12
|
|
13
|
+
attr_reader :links
|
14
|
+
|
13
15
|
class << self
|
14
16
|
attr_accessor :rel_has_one_blocks, :rel_has_many_blocks, :rel_options, :attr_blocks, :id_block, :type_block
|
15
17
|
end
|
@@ -34,7 +36,7 @@ module JsonAPIObjectMapper
|
|
34
36
|
|
35
37
|
def self.load(document)
|
36
38
|
parser = JsonAPIObjectMapper::Parser::Document.new(document)
|
37
|
-
if parser.
|
39
|
+
if parser.contains_data_array? || parser.invalid?
|
38
40
|
Collection.new(parser, klass: self)
|
39
41
|
else
|
40
42
|
new(parser)
|
@@ -48,6 +50,7 @@ module JsonAPIObjectMapper
|
|
48
50
|
|
49
51
|
if document_valid?
|
50
52
|
@includes = parser.includes
|
53
|
+
@links = parser_links(parser)
|
51
54
|
@data = document_data(parser, document)
|
52
55
|
@id = @data["id"]
|
53
56
|
@type = @data["type"]
|
@@ -66,7 +69,11 @@ module JsonAPIObjectMapper
|
|
66
69
|
private
|
67
70
|
|
68
71
|
def document_data(parser, document)
|
69
|
-
document.nil? ?
|
72
|
+
document.nil? ? parser.document_data : (document["data"] || document)
|
73
|
+
end
|
74
|
+
|
75
|
+
def parser_links(parser)
|
76
|
+
parser.links unless parser.contains_data_array?
|
70
77
|
end
|
71
78
|
|
72
79
|
def deserialize!
|
@@ -8,19 +8,35 @@ module JsonAPIObjectMapper
|
|
8
8
|
class Document
|
9
9
|
include Errors
|
10
10
|
|
11
|
-
|
11
|
+
attr_reader :document, :includes, :links
|
12
12
|
|
13
13
|
def initialize(document)
|
14
|
-
|
15
|
-
@includes
|
16
|
-
@
|
14
|
+
parsed_document = (document.is_a?(String) ? ::Oj.load(document) : document)
|
15
|
+
@includes = IncludedResources.load(parsed_document.delete("included"))
|
16
|
+
@links = deserialize_links(parsed_document.delete("links")).freeze
|
17
|
+
@document = parsed_document.freeze
|
18
|
+
@errors = deserialize_errors!.freeze
|
17
19
|
freeze
|
18
20
|
end
|
19
21
|
|
22
|
+
def document_data
|
23
|
+
@document["data"] || @document
|
24
|
+
end
|
25
|
+
|
26
|
+
def contains_data_array?
|
27
|
+
document_data.is_a?(Array)
|
28
|
+
end
|
29
|
+
|
20
30
|
def deserialize_errors!
|
21
31
|
return [] unless @document.key?("errors")
|
22
32
|
Set.new(@document["errors"]) { |error| OpenStruct.new(error) }
|
23
33
|
end
|
34
|
+
|
35
|
+
def deserialize_links(links)
|
36
|
+
links&.each_with_object(OpenStruct.new) do |(key, value), struct|
|
37
|
+
struct[key.to_s.tr("-", "_")] = value
|
38
|
+
end
|
39
|
+
end
|
24
40
|
end
|
25
41
|
end
|
26
42
|
end
|
@@ -79,6 +79,25 @@ module JsonAPIObjectMapper
|
|
79
79
|
expect(result.source).to include("pointer" => "name")
|
80
80
|
end
|
81
81
|
end
|
82
|
+
|
83
|
+
context "Links" do
|
84
|
+
let(:foo_bar_klass) { Class.new(JsonAPIObjectMapper::Deserialize::Resource) }
|
85
|
+
subject { described_class.new(parser, klass: foo_bar_klass).links }
|
86
|
+
|
87
|
+
context "Results do not include links" do
|
88
|
+
it { is_expected.to be_nil }
|
89
|
+
end
|
90
|
+
|
91
|
+
it_behaves_like "it contains links" do
|
92
|
+
let!(:payload) { payload_links.merge("data" => [{ "id" => "1", "type" => "foobar" }]) }
|
93
|
+
|
94
|
+
it "Should not include links in the children of data resources" do
|
95
|
+
results = described_class.new(parser, klass: foo_bar_klass)
|
96
|
+
expect(results.first.id).to eq("1")
|
97
|
+
expect(results.first.links).to be_nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
82
101
|
end
|
83
102
|
end
|
84
103
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "it contains links" do
|
6
|
+
let(:payload_links) do
|
7
|
+
{
|
8
|
+
"links" => {
|
9
|
+
"total-pages" => 14,
|
10
|
+
"self" => "https://some-random-api.com/search?name=me?page=2",
|
11
|
+
"first" => "https://some-random-api.com/search?name=me?page=1",
|
12
|
+
"last" => "https://some-random-api.com/search?name=me?page=14",
|
13
|
+
"prev" => "https://some-random-api.com/search?name=me?page=1",
|
14
|
+
"next" => "https://some-random-api.com/search?name=me?page=3",
|
15
|
+
},
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:payload) { payload_links }
|
20
|
+
|
21
|
+
it { is_expected.to be_a(OpenStruct).and(be_frozen) }
|
22
|
+
its(:total_pages) { is_expected.to eq(14) }
|
23
|
+
its(:self) { is_expected.to eq("https://some-random-api.com/search?name=me?page=2") }
|
24
|
+
its(:first) { is_expected.to eq("https://some-random-api.com/search?name=me?page=1") }
|
25
|
+
its(:last) { is_expected.to eq("https://some-random-api.com/search?name=me?page=14") }
|
26
|
+
its(:prev) { is_expected.to eq("https://some-random-api.com/search?name=me?page=1") }
|
27
|
+
its(:next) { is_expected.to eq("https://some-random-api.com/search?name=me?page=3") }
|
28
|
+
end
|
@@ -191,6 +191,18 @@ module JsonAPIObjectMapper
|
|
191
191
|
end
|
192
192
|
end
|
193
193
|
end
|
194
|
+
|
195
|
+
describe "Links" do
|
196
|
+
let(:foo_bar_klass) { Class.new(described_class) }
|
197
|
+
subject { foo_bar_klass.load(payload).links }
|
198
|
+
|
199
|
+
it_behaves_like "it contains links"
|
200
|
+
|
201
|
+
context "Response does not contain links" do
|
202
|
+
let(:payload) { {} }
|
203
|
+
it { is_expected.to be_nil }
|
204
|
+
end
|
205
|
+
end
|
194
206
|
end
|
195
207
|
end
|
196
208
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-object-mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- George Protacio-Karaszi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-its
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.2'
|
69
83
|
description: Digests JSON-API responses to plain old ruby objects
|
70
84
|
email:
|
71
85
|
- georgekaraszi@gmail.com
|
@@ -73,6 +87,7 @@ executables: []
|
|
73
87
|
extensions: []
|
74
88
|
extra_rdoc_files: []
|
75
89
|
files:
|
90
|
+
- CHANGELOG.md
|
76
91
|
- README.md
|
77
92
|
- lib/jsonapi-object-mapper.rb
|
78
93
|
- lib/jsonapi-object-mapper/deserialize/collection.rb
|
@@ -84,6 +99,7 @@ files:
|
|
84
99
|
- lib/jsonapi-object-mapper/parser/included_resources.rb
|
85
100
|
- lib/jsonapi-object-mapper/version.rb
|
86
101
|
- spec/deserialize/collection_spec.rb
|
102
|
+
- spec/deserialize/link_examples.rb
|
87
103
|
- spec/deserialize/resource_spec.rb
|
88
104
|
- spec/jsonapi_object_mapper_spec.rb
|
89
105
|
- spec/spec_helper.rb
|
@@ -113,6 +129,7 @@ specification_version: 4
|
|
113
129
|
summary: Digests JSON-API responses to plain old ruby objects
|
114
130
|
test_files:
|
115
131
|
- spec/deserialize/collection_spec.rb
|
132
|
+
- spec/deserialize/link_examples.rb
|
116
133
|
- spec/deserialize/resource_spec.rb
|
117
134
|
- spec/jsonapi_object_mapper_spec.rb
|
118
135
|
- spec/spec_helper.rb
|