jsi 0.2.0 → 0.2.1
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 +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
|
[](https://travis-ci.org/notEthan/jsi)
|
4
4
|
[](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
|