json-api-vanilla 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +20 -0
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/Makefile +4 -1
- data/lib/json-api-vanilla/parser.rb +29 -11
- data/lib/json-api-vanilla/version.rb +1 -1
- data/spec/json-api-vanilla/diff_spec.rb +45 -0
- data/spec/json-api-vanilla/example.json +11 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5d5c4ce7ba0c6ce976f23618d9611dd1eb015b3f063e07b5821865a77aa14aba
|
4
|
+
data.tar.gz: 75d8c20b9c83073b2673d6bbff1ccc0251a65eeda5d92978a58500845019791a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad7299a1a5481f9a2bdfe2c5bb42b01aa5fd6e1a015d2ab426f90ae67a9ceda40894ab9fa147fbea5fed8c411a9947652acdac1e5d46ca2600d42e9c1b1c167f
|
7
|
+
data.tar.gz: c5a6e7aebb023f9fa25eb1e1d374549096687abeff8a2f7b1c36351df4a3003dae4668bff732f2726380e6fb46b8e7f34ad34cf57ab5e7c166ed47ba4bc788ac
|
@@ -0,0 +1,20 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v1
|
12
|
+
- name: Set up Ruby 2.6
|
13
|
+
uses: actions/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: 2.6.x
|
16
|
+
- name: Build and test with Rake
|
17
|
+
run: |
|
18
|
+
gem install bundler
|
19
|
+
bundle install --jobs 4 --retry 3
|
20
|
+
make test
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Makefile
CHANGED
@@ -58,23 +58,17 @@ module JSON::Api::Vanilla
|
|
58
58
|
|
59
59
|
obj_hashes.each do |o_hash|
|
60
60
|
klass = prepare_class(o_hash, superclass, container)
|
61
|
-
obj = klass
|
62
|
-
|
63
|
-
obj.id = o_hash['id']
|
64
|
-
if o_hash['attributes']
|
65
|
-
o_hash['attributes'].each do |key, value|
|
66
|
-
set_key(obj, key, value, original_keys)
|
67
|
-
end
|
68
|
-
end
|
61
|
+
obj = prepare_object(o_hash, klass, original_keys)
|
62
|
+
|
69
63
|
if o_hash['links']
|
70
64
|
links[obj] = o_hash['links']
|
71
65
|
end
|
66
|
+
|
72
67
|
objects[[obj.type, obj.id]] = obj
|
73
68
|
end
|
74
69
|
|
75
70
|
# Now that all objects have been created, we can link everything together.
|
76
71
|
obj_hashes.each do |o_hash|
|
77
|
-
klass = container.const_get(ruby_class_name(o_hash['type']).to_sym)
|
78
72
|
obj = objects[[o_hash['type'], o_hash['id']]]
|
79
73
|
if o_hash['relationships']
|
80
74
|
o_hash['relationships'].each do |key, value|
|
@@ -83,10 +77,22 @@ module JSON::Api::Vanilla
|
|
83
77
|
if data.is_a?(Array)
|
84
78
|
# One-to-many relationship.
|
85
79
|
ref = data.map do |ref_hash|
|
86
|
-
objects[[ref_hash['type'], ref_hash['id']]]
|
80
|
+
_ref = objects[[ref_hash['type'], ref_hash['id']]]
|
81
|
+
|
82
|
+
if _ref.nil?
|
83
|
+
klass = prepare_class(ref_hash, superclass, container)
|
84
|
+
_ref = prepare_object(ref_hash, klass)
|
85
|
+
end
|
86
|
+
|
87
|
+
_ref
|
87
88
|
end
|
88
89
|
else
|
89
90
|
ref = objects[[data['type'], data['id']]]
|
91
|
+
|
92
|
+
if ref.nil?
|
93
|
+
klass = prepare_class(data, superclass, container)
|
94
|
+
ref = prepare_object(data, klass)
|
95
|
+
end
|
90
96
|
end
|
91
97
|
end
|
92
98
|
|
@@ -116,7 +122,7 @@ module JSON::Api::Vanilla
|
|
116
122
|
|
117
123
|
def self.prepare_class(hash, superclass, container)
|
118
124
|
name = ruby_class_name(hash['type']).to_sym
|
119
|
-
if container.
|
125
|
+
if container.constants.include?(name)
|
120
126
|
klass = container.const_get(name)
|
121
127
|
else
|
122
128
|
klass = generate_object(name, superclass, container)
|
@@ -131,6 +137,18 @@ module JSON::Api::Vanilla
|
|
131
137
|
klass
|
132
138
|
end
|
133
139
|
|
140
|
+
def self.prepare_object(hash, klass, original_keys = {})
|
141
|
+
(klass.new).tap do |obj|
|
142
|
+
obj.type = hash['type']
|
143
|
+
obj.id = hash['id']
|
144
|
+
if hash['attributes']
|
145
|
+
hash['attributes'].each do |key, value|
|
146
|
+
set_key(obj, key, value, original_keys)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
134
152
|
def self.generate_object(ruby_name, superclass, container)
|
135
153
|
klass = Class.new(superclass)
|
136
154
|
container.const_set(ruby_name, klass)
|
@@ -20,6 +20,14 @@ describe JSON::Api::Vanilla do
|
|
20
20
|
expect(doc.links[doc.data]['self']).to eql("http://example.com/articles")
|
21
21
|
end
|
22
22
|
|
23
|
+
it "should read objects that are only in relationships of included" do
|
24
|
+
expect(doc.data.first.comments.first.post.id).to eql("42")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should read objects that are only in relationships of included when it is an array" do
|
28
|
+
expect(doc.data.first.comments.first.tags[0].id).to eql("42")
|
29
|
+
end
|
30
|
+
|
23
31
|
it "should find objects by type and id" do
|
24
32
|
expect(doc.find('comments', '5').body).to eql("First!")
|
25
33
|
end
|
@@ -97,4 +105,41 @@ describe JSON::Api::Vanilla do
|
|
97
105
|
JSON::Api::Vanilla.naive_validate(data: [])
|
98
106
|
end.to_not raise_error
|
99
107
|
end
|
108
|
+
|
109
|
+
describe '.prepare_class' do
|
110
|
+
let(:container) {Module.new}
|
111
|
+
let(:superclass) {Class.new}
|
112
|
+
let(:hash) {{'type' => 'test-classes'}}
|
113
|
+
subject {described_class.prepare_class(hash, superclass, container)}
|
114
|
+
|
115
|
+
context 'when same name class in global scope' do
|
116
|
+
class TestClasses
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should create dynamic class in container' do
|
120
|
+
subject
|
121
|
+
expect(container.constants).to include(:TestClasses)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '.prepare_object' do
|
127
|
+
let(:data) do
|
128
|
+
{
|
129
|
+
'type' => 'example',
|
130
|
+
'id' => '1',
|
131
|
+
'attributes' => {
|
132
|
+
'name' => 'example name'
|
133
|
+
}
|
134
|
+
}
|
135
|
+
end
|
136
|
+
let(:klass) { described_class.prepare_class(data, Class.new, Module.new) }
|
137
|
+
subject { described_class.prepare_object(data, klass) }
|
138
|
+
|
139
|
+
it 'creates an object with the attributes mapped' do
|
140
|
+
expect(subject.type).to eql(data['type'])
|
141
|
+
expect(subject.id).to eql(data['id'])
|
142
|
+
expect(subject.name).to eql(data['attributes']['name'])
|
143
|
+
end
|
144
|
+
end
|
100
145
|
end
|
@@ -56,6 +56,17 @@
|
|
56
56
|
"relationships": {
|
57
57
|
"author": {
|
58
58
|
"data": { "type": "people", "id": "2" }
|
59
|
+
},
|
60
|
+
"tags": {
|
61
|
+
"data": [
|
62
|
+
{ "type": "tag", "id": "42" }
|
63
|
+
]
|
64
|
+
},
|
65
|
+
"post": {
|
66
|
+
"data": {
|
67
|
+
"type": "post",
|
68
|
+
"id": "42"
|
69
|
+
}
|
59
70
|
}
|
60
71
|
},
|
61
72
|
"links": {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json-api-vanilla
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thaddée Tyl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Given a JSON API string, we parse it and return a document that can be
|
14
14
|
browsed — as if the objects defined in the file were plain old Ruby objects.
|
@@ -18,6 +18,7 @@ executables: []
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- ".github/workflows/ruby.yml"
|
21
22
|
- ".gitignore"
|
22
23
|
- ContributorAgreement.txt
|
23
24
|
- Gemfile
|
@@ -54,7 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
55
|
version: '0'
|
55
56
|
requirements: []
|
56
57
|
rubyforge_project:
|
57
|
-
rubygems_version: 2.6
|
58
|
+
rubygems_version: 2.7.6
|
58
59
|
signing_key:
|
59
60
|
specification_version: 4
|
60
61
|
summary: Deserialize JSON API formats into vanilla Ruby objects.
|