jsi 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +16 -7
- data/jsi.gemspec +3 -2
- data/lib/jsi/base.rb +2 -2
- data/lib/jsi/json/node.rb +6 -3
- data/lib/jsi/schema.rb +5 -23
- data/lib/jsi/typelike_modules.rb +8 -8
- data/lib/jsi/util.rb +6 -0
- data/lib/jsi/version.rb +1 -1
- data/test/test_helper.rb +2 -0
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2733de7b7f61d30765ac1bedb3229618d12ea45b693aef931a63691279d37e2
|
4
|
+
data.tar.gz: 2bd9989382540a0e4f28dba7e2a0d6f32061857ea7704d5fbea74f446de1bd54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a57a46d4920cfe7e7af9d2d4e3f2e9720578f44ea52951da68d6352633add8689b602bd13ec210d38234b86c19e3ba49554b8b3b9f71531a9e43a3d0ad5690ab
|
7
|
+
data.tar.gz: 7a3da59ac6a5598cd867082f3ce31e4e3058f525f33e0e02addb743608b79fb5e2bc4d323e2b57e80b4c6aa57297215013b13ec8a26513aeca1a3d930bdfa07f
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# JSI: JSON
|
1
|
+
# JSI: JSON Schema Instantiation
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/notEthan/jsi.svg?branch=master)](https://travis-ci.org/notEthan/jsi)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/github/notEthan/jsi/badge.svg)](https://coveralls.io/github/notEthan/jsi)
|
@@ -27,19 +27,28 @@ properties:
|
|
27
27
|
number: {type: "string"}
|
28
28
|
```
|
29
29
|
|
30
|
-
And here's the class for that schema
|
30
|
+
And here's how you'd normally instantiate the class for that schema using JSI:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
|
34
|
-
# you can copy/paste this line instead, to follow along in irb:
|
33
|
+
# this would usually use a YAML.load/JSON.parse/whatever; it's inlined for copypastability.
|
35
34
|
Contact = JSI.class_for_schema({"description" => "A Contact", "type" => "object", "properties" => {"name" => {"type" => "string"}, "phone" => {"type" => "array", "items" => {"type" => "object", "properties" => {"location" => {"type" => "string"}, "number" => {"type" => "string"}}}}}})
|
36
35
|
```
|
37
36
|
|
38
|
-
This definition gives you not just the Contact class, but classes for the whole nested structure.
|
37
|
+
This definition gives you not just the Contact class, but classes for the whole nested structure. To instantiate it, we need some JSON data (expressed here as YAML)
|
39
38
|
|
40
|
-
```
|
41
|
-
|
39
|
+
```yaml
|
40
|
+
name: bill
|
41
|
+
phone:
|
42
|
+
- location: home
|
43
|
+
number: "555"
|
44
|
+
nickname: big b
|
45
|
+
```
|
42
46
|
|
47
|
+
So, if we construct an instance like:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
# this would usually use a YAML.load/JSON.parse/whatever; it's inlined for copypastability.
|
51
|
+
bill = Contact.new({"name" => "bill", "phone" => [{"location" => "home", "number" => "555"}], "nickname" => "big b"})
|
43
52
|
# => #{<Contact Hash>
|
44
53
|
# "name" => "bill",
|
45
54
|
# "phone" => #[<JSI::SchemaClasses["23d8#/properties/phone"] Array>
|
data/jsi.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["Ethan"]
|
9
9
|
spec.email = ["ethan@unth.net"]
|
10
10
|
|
11
|
-
spec.summary = "JSI: JSON
|
12
|
-
spec.description = "JSI
|
11
|
+
spec.summary = "JSI: JSON Schema Instantiation"
|
12
|
+
spec.description = "JSI offers an Object-Oriented representation for JSON data using JSON Schemas"
|
13
13
|
spec.homepage = "https://github.com/notEthan/jsi"
|
14
14
|
spec.license = "MIT"
|
15
15
|
ignore_files = %w(.gitignore .travis.yml Gemfile test)
|
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "minitest", "~> 5.0"
|
29
29
|
spec.add_development_dependency "minitest-around"
|
30
30
|
spec.add_development_dependency "minitest-reporters"
|
31
|
+
spec.add_development_dependency "scorpio"
|
31
32
|
end
|
data/lib/jsi/base.rb
CHANGED
@@ -318,9 +318,9 @@ module JSI
|
|
318
318
|
end
|
319
319
|
end
|
320
320
|
|
321
|
-
# @return [String]
|
321
|
+
# @return [Array<String>]
|
322
322
|
def object_group_text
|
323
|
-
instance.respond_to?(:object_group_text) ? instance.object_group_text : instance.class.inspect
|
323
|
+
instance.respond_to?(:object_group_text) ? instance.object_group_text : [instance.class.inspect]
|
324
324
|
end
|
325
325
|
|
326
326
|
# @return [Object] a jsonifiable representation of the instance
|
data/lib/jsi/json/node.rb
CHANGED
@@ -182,19 +182,22 @@ module JSI
|
|
182
182
|
end
|
183
183
|
|
184
184
|
# meta-information about the object, outside the content. used by #inspect / #pretty_print
|
185
|
+
# @return [Array<String>]
|
185
186
|
def object_group_text
|
186
|
-
|
187
|
+
[
|
188
|
+
"fragment=#{node_ptr.fragment.inspect}",
|
189
|
+
] + (node_content.respond_to?(:object_group_text) ? node_content.object_group_text : [])
|
187
190
|
end
|
188
191
|
|
189
192
|
# a string representing this node
|
190
193
|
def inspect
|
191
|
-
"\#<#{self.class.inspect}
|
194
|
+
"\#<#{self.class.inspect}#{JSI.object_group_str(object_group_text)} #{node_content.inspect}>"
|
192
195
|
end
|
193
196
|
|
194
197
|
# pretty-prints a representation this node to the given printer
|
195
198
|
def pretty_print(q)
|
196
199
|
q.instance_exec(self) do |obj|
|
197
|
-
text "\#<#{obj.class.inspect}
|
200
|
+
text "\#<#{obj.class.inspect}#{JSI.object_group_str(obj.object_group_text)}"
|
198
201
|
group_sub {
|
199
202
|
nest(2) {
|
200
203
|
breakable ' '
|
data/lib/jsi/schema.rb
CHANGED
@@ -192,9 +192,8 @@ module JSI
|
|
192
192
|
# @return [Set] any object property names this schema indicates may be
|
193
193
|
# present on its instances. this includes, if present: keys of this
|
194
194
|
# schema's "properties" object; entries of this schema's array of
|
195
|
-
# "required" property keys. if this schema has
|
196
|
-
#
|
197
|
-
# described object property names.
|
195
|
+
# "required" property keys. if this schema has allOf subschemas, those
|
196
|
+
# schemas are checked (recursively) for their described object property names.
|
198
197
|
def described_object_property_names
|
199
198
|
memoize(:described_object_property_names) do
|
200
199
|
Set.new.tap do |property_names|
|
@@ -204,33 +203,16 @@ module JSI
|
|
204
203
|
if schema_node['required'].respond_to?(:to_ary)
|
205
204
|
property_names.merge(schema_node['required'].to_ary)
|
206
205
|
end
|
207
|
-
# we _could_ look at the properties of 'default' and each 'enum' but ... nah.
|
208
206
|
# we should look at dependencies (TODO).
|
209
|
-
|
210
|
-
schema_node[
|
211
|
-
property_names.merge(self.class.new(
|
207
|
+
if schema_node['allOf'].respond_to?(:to_ary)
|
208
|
+
schema_node['allOf'].map(&:deref).map do |allOf_node|
|
209
|
+
property_names.merge(self.class.new(allOf_node).described_object_property_names)
|
212
210
|
end
|
213
211
|
end
|
214
212
|
end
|
215
213
|
end
|
216
214
|
end
|
217
215
|
|
218
|
-
def default_value
|
219
|
-
if schema_node.key?('default')
|
220
|
-
if schema_node['default'].respond_to?(:to_ary) || schema_node['default'].respond_to?(:to_hash)
|
221
|
-
schema_class.new(schema_node['default'])
|
222
|
-
else
|
223
|
-
schema_node['default']
|
224
|
-
end
|
225
|
-
else
|
226
|
-
nil
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
def default_value?
|
231
|
-
schema_node.key?('default')
|
232
|
-
end
|
233
|
-
|
234
216
|
# @return [Array<String>] array of schema validation error messages for
|
235
217
|
# the given instance against this schema
|
236
218
|
def fully_validate_instance(other_instance)
|
data/lib/jsi/typelike_modules.rb
CHANGED
@@ -136,8 +136,8 @@ module JSI
|
|
136
136
|
# @return [String] basically the same #inspect as Hash, but has the
|
137
137
|
# class name and, if responsive, self's #object_group_text
|
138
138
|
def inspect
|
139
|
-
|
140
|
-
"\#{<#{self.class}#{
|
139
|
+
object_group_str = JSI.object_group_str(respond_to?(:object_group_text) ? self.object_group_text : [])
|
140
|
+
"\#{<#{self.class}#{object_group_str}>#{empty? ? '' : ' '}#{self.map { |k, v| "#{k.inspect} => #{v.inspect}" }.join(', ')}}"
|
141
141
|
end
|
142
142
|
|
143
143
|
# @return [String] see #inspect
|
@@ -149,8 +149,8 @@ module JSI
|
|
149
149
|
# @return [void]
|
150
150
|
def pretty_print(q)
|
151
151
|
q.instance_exec(self) do |obj|
|
152
|
-
|
153
|
-
text "\#{<#{obj.class}#{
|
152
|
+
object_group_str = JSI.object_group_str(obj.respond_to?(:object_group_text) ? obj.object_group_text : [])
|
153
|
+
text "\#{<#{obj.class}#{object_group_str}>"
|
154
154
|
group_sub {
|
155
155
|
nest(2) {
|
156
156
|
breakable(obj.any? { true } ? ' ' : '')
|
@@ -217,8 +217,8 @@ module JSI
|
|
217
217
|
# @return [String] basically the same #inspect as Array, but has the
|
218
218
|
# class name and, if responsive, self's #object_group_text
|
219
219
|
def inspect
|
220
|
-
|
221
|
-
"\#[<#{self.class}#{
|
220
|
+
object_group_str = JSI.object_group_str(respond_to?(:object_group_text) ? object_group_text : [])
|
221
|
+
"\#[<#{self.class}#{object_group_str}>#{empty? ? '' : ' '}#{self.map { |e| e.inspect }.join(', ')}]"
|
222
222
|
end
|
223
223
|
|
224
224
|
# @return [String] see #inspect
|
@@ -230,8 +230,8 @@ module JSI
|
|
230
230
|
# @return [void]
|
231
231
|
def pretty_print(q)
|
232
232
|
q.instance_exec(self) do |obj|
|
233
|
-
|
234
|
-
text "\#[<#{obj.class}#{
|
233
|
+
object_group_str = JSI.object_group_str(obj.respond_to?(:object_group_text) ? obj.object_group_text : [])
|
234
|
+
text "\#[<#{obj.class}#{object_group_str}>"
|
235
235
|
group_sub {
|
236
236
|
nest(2) {
|
237
237
|
breakable(obj.any? { true } ? ' ' : '')
|
data/lib/jsi/util.rb
CHANGED
@@ -68,6 +68,12 @@ module JSI
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
# @param object_group_text [Array<String>]
|
72
|
+
# @return [String]
|
73
|
+
def object_group_str(object_group_text)
|
74
|
+
object_group_text.compact.map { |t| " #{t}" }.join('')
|
75
|
+
end
|
76
|
+
|
71
77
|
# this is the Y-combinator, which allows anonymous recursive functions. for a simple example,
|
72
78
|
# to define a recursive function to return the length of an array:
|
73
79
|
#
|
data/lib/jsi/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json-schema
|
@@ -80,8 +80,22 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
|
84
|
-
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: scorpio
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: JSI offers an Object-Oriented representation for JSON data using JSON
|
98
|
+
Schemas
|
85
99
|
email:
|
86
100
|
- ethan@unth.net
|
87
101
|
executables: []
|
@@ -147,7 +161,7 @@ rubyforge_project:
|
|
147
161
|
rubygems_version: 2.7.8
|
148
162
|
signing_key:
|
149
163
|
specification_version: 4
|
150
|
-
summary: 'JSI: JSON
|
164
|
+
summary: 'JSI: JSON Schema Instantiation'
|
151
165
|
test_files:
|
152
166
|
- test/base_array_test.rb
|
153
167
|
- test/base_hash_test.rb
|