json_schema_tools 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/README.md +3 -2
- data/lib/schema_tools/modules/hash.rb +49 -32
- data/lib/schema_tools/version.rb +1 -1
- data/spec/schema_tools/hash_spec.rb +44 -18
- data/spec/schema_tools/modules/attributes_spec.rb +3 -2
- metadata +4 -4
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -160,11 +160,12 @@ Rather like a namespace? Good idea, but don't forget the class or module must
|
|
160
160
|
be defined.
|
161
161
|
|
162
162
|
```ruby
|
163
|
+
module SalesKing; end
|
163
164
|
SchemaTools::KlassFactory.build namespace: SalesKing
|
164
165
|
client = SalesKing::Client.new
|
165
166
|
```
|
166
167
|
|
167
|
-
Add a custom schema reader most likely
|
168
|
+
Add a custom schema reader most likely useful in conjunction with a custom path
|
168
169
|
|
169
170
|
```ruby
|
170
171
|
reader = SchemaTools::Reader.new
|
@@ -173,9 +174,9 @@ SchemaTools::KlassFactory.build reader: reader, path: HappyPdf::Schema.path
|
|
173
174
|
|
174
175
|
## Real world examples
|
175
176
|
|
176
|
-
* [HappyPdf json schema](https://github.com/happyPDF/happypdf_json_schema) .. api gem will follow
|
177
177
|
* [DocTag ruby gem](https://github.com/docTag/doctag_rb) and [DocTag json-schema](https://github.com/docTag/doctag_json_schema)
|
178
178
|
* [SalesKing json schema](https://github.com/salesking/sk_api_schema)
|
179
|
+
* [HappyPdf json schema](https://github.com/happyPDF/happypdf_json_schema) .. api gem will follow
|
179
180
|
* .. Your UseCase here
|
180
181
|
|
181
182
|
## Test
|
@@ -48,37 +48,10 @@ module SchemaTools
|
|
48
48
|
# iterate over the defined schema fields
|
49
49
|
schema['properties'].each do |field, prop|
|
50
50
|
next if fields && !fields.include?(field)
|
51
|
-
|
52
51
|
if prop['type'] == 'array'
|
53
|
-
|
54
|
-
data[field] = [] # always set an empty array
|
55
|
-
if obj.respond_to?( field ) && rel_objects = obj.send( field )
|
56
|
-
rel_objects.each do |rel_obj|
|
57
|
-
data[field] << if prop['properties'] && prop['properties']['$ref']
|
58
|
-
#got schema describing the objects
|
59
|
-
from_schema(rel_obj, opts)
|
60
|
-
else
|
61
|
-
rel_obj
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
52
|
+
data[field] = parse_list(obj, field, prop, opts)
|
66
53
|
elsif prop['type'] == 'object' # a singular related object
|
67
|
-
|
68
|
-
data[field] = nil # always set empty val
|
69
|
-
if obj.respond_to?( field ) && rel_obj = obj.send( field )
|
70
|
-
if prop['properties'] && prop['properties']['$ref']
|
71
|
-
data[field] = from_schema(rel_obj, opts)
|
72
|
-
else
|
73
|
-
# NO recursion directly get values from related object. Does
|
74
|
-
# NOT allow deeper nesting so you MUST define an own schema to be save
|
75
|
-
data[field] = {}
|
76
|
-
prop['properties'].each do |fld, prp|
|
77
|
-
data[field][fld] = rel_obj.send(fld) if obj.respond_to?(field)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
54
|
+
data[field] = parse_object(obj, field, prop, opts)
|
82
55
|
else # a simple field is only added if the object knows it
|
83
56
|
data[field] = obj.send(field) if obj.respond_to?(field)
|
84
57
|
end
|
@@ -90,10 +63,10 @@ module SchemaTools
|
|
90
63
|
hsh
|
91
64
|
end
|
92
65
|
|
66
|
+
private
|
67
|
+
|
93
68
|
# Parse the link section of the schema by replacing {id} in urls
|
94
|
-
#
|
95
|
-
# <Array[Hash{String=>String}]>::
|
96
|
-
# <nil>:: no links present
|
69
|
+
# @return [Array<Hash{String=>String}> | Nil]
|
97
70
|
def parse_links(obj, schema)
|
98
71
|
links = []
|
99
72
|
schema['links'] && schema['links'].each do |link|
|
@@ -104,6 +77,50 @@ module SchemaTools
|
|
104
77
|
links.empty? ? nil : links
|
105
78
|
end
|
106
79
|
|
80
|
+
# Parse a nested array property.
|
81
|
+
# @param [Object] obj the object in question
|
82
|
+
# @param [String] field name
|
83
|
+
# @param [Hash] prop fields schema properties
|
84
|
+
# @param [Hash] opts to_schema options
|
85
|
+
# @return [Array<Hash{String=>String}>]
|
86
|
+
def parse_list(obj, field, prop, opts)
|
87
|
+
res = []
|
88
|
+
if obj.respond_to?( field ) && rel_objects = obj.send( field )
|
89
|
+
rel_objects.each do |rel_obj|
|
90
|
+
res << if prop['properties'] && prop['properties']['$ref']
|
91
|
+
#got schema describing the objects
|
92
|
+
from_schema(rel_obj, opts)
|
93
|
+
else
|
94
|
+
rel_obj
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
res
|
99
|
+
end
|
100
|
+
|
101
|
+
# Parse a nested object property.
|
102
|
+
# @param [Object] obj the object in question
|
103
|
+
# @param [String] field name
|
104
|
+
# @param [Hash] prop fields schema properties
|
105
|
+
# @param [Hash] opts to_schema options
|
106
|
+
# @return [Array<Hash{String=>String}>]
|
107
|
+
def parse_object(obj, field, prop, opts)
|
108
|
+
res = nil
|
109
|
+
if obj.respond_to?( field ) && rel_obj = obj.send( field )
|
110
|
+
if prop['properties'] && prop['properties']['$ref']
|
111
|
+
res = from_schema(rel_obj, opts)
|
112
|
+
else
|
113
|
+
# NO recursion directly get values from related object. Does
|
114
|
+
# NOT allow deeper nesting so you MUST define an own schema to be save
|
115
|
+
res = { }
|
116
|
+
prop['properties'].each do |fld, prp|
|
117
|
+
res[fld] = rel_obj.send(fld) if rel_obj.respond_to?(fld)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
res
|
122
|
+
end
|
123
|
+
|
107
124
|
end
|
108
125
|
end
|
109
126
|
end
|
data/lib/schema_tools/version.rb
CHANGED
@@ -1,50 +1,77 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class Contact
|
4
4
|
attr_accessor :first_name, :last_name, :addresses, :id
|
5
|
-
|
5
|
+
end
|
6
6
|
|
7
7
|
describe SchemaTools::Hash do
|
8
8
|
|
9
9
|
context 'from_schema' do
|
10
|
-
let(:
|
10
|
+
let(:contact){Contact.new}
|
11
11
|
before :each do
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
contact.first_name = 'Peter'
|
13
|
+
contact.last_name = 'Paul'
|
14
|
+
contact.id = 'SomeID'
|
15
15
|
end
|
16
16
|
after :each do
|
17
17
|
SchemaTools::Reader.registry_reset
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'should return hash' do
|
21
|
-
hash = SchemaTools::Hash.from_schema(
|
22
|
-
hash['
|
21
|
+
hash = SchemaTools::Hash.from_schema(contact)
|
22
|
+
hash['contact']['last_name'].should == 'Paul'
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'should use custom schema path' do
|
26
26
|
custom_path = File.expand_path('../../fixtures', __FILE__)
|
27
|
-
hash = SchemaTools::Hash.from_schema(
|
28
|
-
hash['
|
27
|
+
hash = SchemaTools::Hash.from_schema(contact, path: custom_path)
|
28
|
+
hash['contact']['last_name'].should == 'Paul'
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'should use custom schema' do
|
32
|
-
hash = SchemaTools::Hash.from_schema(
|
32
|
+
hash = SchemaTools::Hash.from_schema(contact, class_name: :contact)
|
33
33
|
hash['contact']['last_name'].should == 'Paul'
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should use only give fields' do
|
37
|
-
hash = SchemaTools::Hash.from_schema(
|
38
|
-
hash['
|
39
|
-
hash['
|
40
|
-
hash['
|
41
|
-
hash['
|
37
|
+
hash = SchemaTools::Hash.from_schema(contact, fields: ['id', 'last_name'])
|
38
|
+
hash['contact'].keys.length.should == 2
|
39
|
+
hash['contact']['last_name'].should == contact.last_name
|
40
|
+
hash['contact']['id'].should == contact.id
|
41
|
+
hash['contact']['first_name'].should be_nil
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
context 'with nested object values' do
|
46
|
+
class Client
|
47
|
+
attr_accessor :first_name, :last_name, :addresses, :id
|
48
|
+
end
|
49
|
+
class Address
|
50
|
+
attr_accessor :city, :zip
|
51
|
+
end
|
52
|
+
|
53
|
+
let(:client){Client.new}
|
54
|
+
|
55
|
+
it 'should have empty nested array values' do
|
56
|
+
hash = SchemaTools::Hash.from_schema(client)
|
57
|
+
hash['client']['addresses'].should == []
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should have nested array values' do
|
61
|
+
a1 = Address.new
|
62
|
+
a1.city = 'Cologne'
|
63
|
+
a1.zip = 50733
|
64
|
+
client.addresses = [a1]
|
65
|
+
hash = SchemaTools::Hash.from_schema(client)
|
66
|
+
hash['client']['addresses'].should == [{"address"=>{"city"=>"Cologne", "zip"=>50733}}]
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
|
45
72
|
context 'with plain nested values' do
|
46
73
|
|
47
|
-
class Lead <
|
74
|
+
class Lead < Contact
|
48
75
|
attr_accessor :links_clicked, :conversion
|
49
76
|
end
|
50
77
|
|
@@ -52,7 +79,6 @@ describe SchemaTools::Hash do
|
|
52
79
|
attr_accessor :from, :to
|
53
80
|
end
|
54
81
|
|
55
|
-
|
56
82
|
let(:lead){Lead.new}
|
57
83
|
before :each do
|
58
84
|
lead.links_clicked = ['2012-12-12', '2012-12-15', '2012-12-16']
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class TestContact
|
4
4
|
include SchemaTools::Modules::Attributes
|
5
5
|
has_schema_attrs :client
|
6
6
|
end
|
@@ -13,7 +13,7 @@ end
|
|
13
13
|
describe SchemaTools::Modules::Attributes do
|
14
14
|
|
15
15
|
context 'included' do
|
16
|
-
subject {
|
16
|
+
subject { TestContact.new }
|
17
17
|
|
18
18
|
it 'should add getter methods' do
|
19
19
|
subject.should respond_to(:last_name)
|
@@ -25,6 +25,7 @@ describe SchemaTools::Modules::Attributes do
|
|
25
25
|
|
26
26
|
it 'should not add setter for readonly properties' do
|
27
27
|
subject.should_not respond_to('id=')
|
28
|
+
subject.should_not respond_to('created_at=')
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_schema_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -128,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
128
|
version: '0'
|
129
129
|
segments:
|
130
130
|
- 0
|
131
|
-
hash:
|
131
|
+
hash: 2491825896483527088
|
132
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
133
|
none: false
|
134
134
|
requirements:
|
@@ -137,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
137
|
version: '0'
|
138
138
|
segments:
|
139
139
|
- 0
|
140
|
-
hash:
|
140
|
+
hash: 2491825896483527088
|
141
141
|
requirements: []
|
142
142
|
rubyforge_project:
|
143
143
|
rubygems_version: 1.8.24
|