jsi 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/LICENSE.md +613 -0
- data/README.md +62 -37
- data/jsi.gemspec +8 -12
- data/lib/jsi.rb +11 -0
- data/lib/jsi/base.rb +196 -258
- data/lib/jsi/base/to_rb.rb +2 -0
- data/lib/jsi/jsi_coder.rb +20 -15
- data/lib/jsi/json-schema-fragments.rb +2 -0
- data/lib/jsi/json.rb +2 -0
- data/lib/jsi/json/node.rb +45 -88
- data/lib/jsi/json/pointer.rb +102 -5
- data/lib/jsi/metaschema.rb +7 -0
- data/lib/jsi/metaschema_node.rb +217 -0
- data/lib/jsi/pathed_node.rb +5 -0
- data/lib/jsi/schema.rb +146 -169
- data/lib/jsi/schema_classes.rb +112 -47
- data/lib/jsi/simple_wrap.rb +8 -3
- data/lib/jsi/typelike_modules.rb +31 -39
- data/lib/jsi/util.rb +27 -47
- data/lib/jsi/version.rb +1 -1
- data/lib/schemas/json-schema.org/draft-04/schema.rb +7 -0
- data/lib/schemas/json-schema.org/draft-06/schema.rb +7 -0
- data/resources/icons/AGPL-3.0.png +0 -0
- data/test/base_array_test.rb +174 -60
- data/test/base_hash_test.rb +179 -46
- data/test/base_test.rb +163 -94
- data/test/jsi_coder_test.rb +14 -14
- data/test/jsi_json_arraynode_test.rb +10 -10
- data/test/jsi_json_hashnode_test.rb +14 -14
- data/test/jsi_json_node_test.rb +83 -136
- data/test/jsi_typelike_as_json_test.rb +1 -1
- data/test/metaschema_node_test.rb +19 -0
- data/test/schema_module_test.rb +21 -0
- data/test/schema_test.rb +40 -50
- data/test/test_helper.rb +35 -3
- data/test/util_test.rb +8 -8
- metadata +24 -16
- data/LICENSE.txt +0 -21
data/test/base_test.rb
CHANGED
@@ -1,40 +1,41 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
|
-
NamedSchemaInstance = JSI.
|
3
|
+
NamedSchemaInstance = JSI::Schema.new({id: 'https://schemas.jsi.unth.net/test/base/named_schema'}).jsi_schema_class
|
4
|
+
|
5
|
+
# hitting .tap(&:name) causes JSI to assign a constant name from the ID,
|
6
|
+
# meaning the name NamedSchemaInstanceTwo is not known.
|
7
|
+
NamedSchemaInstanceTwo = JSI::Schema.new({id: 'https://schemas.jsi.unth.net/test/base/named_schema_two'}).jsi_schema_class.tap(&:name)
|
4
8
|
|
5
9
|
describe JSI::Base do
|
6
|
-
let(:document) { {} }
|
7
|
-
let(:path) { [] }
|
8
|
-
let(:pointer) { JSI::JSON::Pointer.new(path) }
|
9
|
-
let(:instance) { JSI::JSON::Node.new_by_type(document, pointer) }
|
10
10
|
let(:schema_content) { {} }
|
11
11
|
let(:schema) { JSI::Schema.new(schema_content) }
|
12
|
-
let(:
|
13
|
-
|
12
|
+
let(:instance) { {} }
|
13
|
+
let(:subject) { schema.new_jsi(instance) }
|
14
|
+
describe 'class .inspect' do
|
14
15
|
it 'is the same as Class#inspect on the base' do
|
15
16
|
assert_equal('JSI::Base', JSI::Base.inspect)
|
16
|
-
assert_equal('JSI::Base', JSI::Base.to_s)
|
17
17
|
end
|
18
|
-
it 'is
|
19
|
-
|
20
|
-
assert_match(%r(\AJSI::SchemaClasses\["[a-f0-9\-]+#"\]\z), subject.class.to_s)
|
18
|
+
it 'is (JSI Schema Class) for generated subclass without id' do
|
19
|
+
assert_equal("(JSI Schema Class: #)", subject.class.inspect)
|
21
20
|
end
|
22
21
|
describe 'with schema id' do
|
23
22
|
let(:schema_content) { {'id' => 'https://jsi/foo'} }
|
24
|
-
it 'is
|
25
|
-
assert_equal(
|
26
|
-
assert_equal(%q(JSI::SchemaClasses["https://jsi/foo#"]), subject.class.to_s)
|
23
|
+
it 'is (JSI Schema Class: ...) for generated subclass with id' do
|
24
|
+
assert_equal("(JSI Schema Class: https://jsi/foo#)", subject.class.inspect)
|
27
25
|
end
|
28
26
|
end
|
29
|
-
it 'is the constant name
|
27
|
+
it 'is the constant name plus id for a class assigned to a constant' do
|
30
28
|
assert_equal(%q(NamedSchemaInstance (https://schemas.jsi.unth.net/test/base/named_schema#)), NamedSchemaInstance.inspect)
|
31
|
-
|
29
|
+
end
|
30
|
+
it 'is not the constant name when the constant name has been generated from the schema_id' do
|
31
|
+
assert_equal("JSI::SchemaClasses::Xhttps___schemas_jsi_unth_net_test_base_named_schema_two_", NamedSchemaInstanceTwo.name)
|
32
|
+
assert_equal("(JSI Schema Class: https://schemas.jsi.unth.net/test/base/named_schema_two#)", NamedSchemaInstanceTwo.inspect)
|
32
33
|
end
|
33
34
|
end
|
34
35
|
describe 'class name' do
|
35
36
|
let(:schema_content) { {'id' => 'https://jsi/BaseTest'} }
|
36
37
|
it 'generates a class name from schema_id' do
|
37
|
-
assert_equal('JSI::SchemaClasses::
|
38
|
+
assert_equal('JSI::SchemaClasses::Xhttps___jsi_BaseTest_', subject.class.name)
|
38
39
|
end
|
39
40
|
it 'uses an existing name' do
|
40
41
|
assert_equal('NamedSchemaInstance', NamedSchemaInstance.name)
|
@@ -52,7 +53,7 @@ describe JSI::Base do
|
|
52
53
|
end
|
53
54
|
describe 'module for schema .inspect' do
|
54
55
|
it '.inspect' do
|
55
|
-
|
56
|
+
assert_equal("(JSI Schema Module: #)", JSI::SchemaClasses.module_for_schema(schema).inspect)
|
56
57
|
end
|
57
58
|
end
|
58
59
|
describe 'module for schema .schema' do
|
@@ -60,11 +61,6 @@ describe JSI::Base do
|
|
60
61
|
assert_equal(schema, JSI::SchemaClasses.module_for_schema(schema).schema)
|
61
62
|
end
|
62
63
|
end
|
63
|
-
describe 'SchemaClasses[]' do
|
64
|
-
it 'stores the class for the schema' do
|
65
|
-
assert_equal(JSI.class_for_schema(schema), JSI::SchemaClasses[schema.schema_id])
|
66
|
-
end
|
67
|
-
end
|
68
64
|
describe '.class_for_schema' do
|
69
65
|
it 'returns a class from a schema' do
|
70
66
|
class_for_schema = JSI.class_for_schema(schema)
|
@@ -73,13 +69,7 @@ describe JSI::Base do
|
|
73
69
|
assert_operator(class_for_schema, :<, JSI::Base)
|
74
70
|
end
|
75
71
|
it 'returns a class from a hash' do
|
76
|
-
assert_equal(JSI.class_for_schema(schema), JSI.class_for_schema(
|
77
|
-
end
|
78
|
-
it 'returns a class from a schema node' do
|
79
|
-
assert_equal(JSI.class_for_schema(schema), JSI.class_for_schema(schema.schema_node))
|
80
|
-
end
|
81
|
-
it 'returns a class from a Base' do
|
82
|
-
assert_equal(JSI.class_for_schema(schema), JSI.class_for_schema(JSI.class_for_schema({}).new(schema.schema_node)))
|
72
|
+
assert_equal(JSI.class_for_schema(schema), JSI.class_for_schema(schema_content))
|
83
73
|
end
|
84
74
|
end
|
85
75
|
describe 'JSI::SchemaClasses.module_for_schema' do
|
@@ -89,13 +79,7 @@ describe JSI::Base do
|
|
89
79
|
assert_equal(JSI::SchemaClasses.module_for_schema(schema), module_for_schema)
|
90
80
|
end
|
91
81
|
it 'returns a module from a hash' do
|
92
|
-
assert_equal(JSI::SchemaClasses.module_for_schema(schema), JSI::SchemaClasses.module_for_schema(schema.
|
93
|
-
end
|
94
|
-
it 'returns a module from a schema node' do
|
95
|
-
assert_equal(JSI::SchemaClasses.module_for_schema(schema), JSI::SchemaClasses.module_for_schema(schema.schema_node))
|
96
|
-
end
|
97
|
-
it 'returns a module from a Base' do
|
98
|
-
assert_equal(JSI::SchemaClasses.module_for_schema(schema), JSI::SchemaClasses.module_for_schema(JSI.class_for_schema({}).new(schema.schema_node)))
|
82
|
+
assert_equal(JSI::SchemaClasses.module_for_schema(schema), JSI::SchemaClasses.module_for_schema(schema.jsi_instance))
|
99
83
|
end
|
100
84
|
end
|
101
85
|
describe 'initialization' do
|
@@ -108,7 +92,7 @@ describe JSI::Base do
|
|
108
92
|
describe 'nil' do
|
109
93
|
let(:instance) { nil }
|
110
94
|
it 'initializes with nil instance' do
|
111
|
-
assert_equal(nil, subject.
|
95
|
+
assert_equal(nil, subject.jsi_instance)
|
112
96
|
assert(!subject.respond_to?(:to_ary))
|
113
97
|
assert(!subject.respond_to?(:to_hash))
|
114
98
|
end
|
@@ -116,7 +100,7 @@ describe JSI::Base do
|
|
116
100
|
describe 'arbitrary instance' do
|
117
101
|
let(:instance) { Object.new }
|
118
102
|
it 'initializes' do
|
119
|
-
assert_equal(instance, subject.
|
103
|
+
assert_equal(instance, subject.jsi_instance)
|
120
104
|
assert(!subject.respond_to?(:to_ary))
|
121
105
|
assert(!subject.respond_to?(:to_hash))
|
122
106
|
end
|
@@ -125,16 +109,16 @@ describe JSI::Base do
|
|
125
109
|
let(:instance) { {'foo' => 'bar'} }
|
126
110
|
let(:schema_content) { {'type' => 'object'} }
|
127
111
|
it 'initializes' do
|
128
|
-
assert_equal({'foo' => 'bar'}, subject.
|
112
|
+
assert_equal({'foo' => 'bar'}, subject.jsi_instance)
|
129
113
|
assert(!subject.respond_to?(:to_ary))
|
130
114
|
assert(subject.respond_to?(:to_hash))
|
131
115
|
end
|
132
116
|
end
|
133
|
-
describe 'JSI::JSON::
|
134
|
-
let(:
|
117
|
+
describe 'JSI::JSON::HashNode' do
|
118
|
+
let(:instance) { JSI::JSON::HashNode.new({'foo' => 'bar'}, JSI::JSON::Pointer.new([])) }
|
135
119
|
let(:schema_content) { {'type' => 'object'} }
|
136
120
|
it 'initializes' do
|
137
|
-
assert_equal(JSI::JSON::HashNode.new({'foo' => 'bar'}, JSI::JSON::Pointer.new([])), subject.
|
121
|
+
assert_equal(JSI::JSON::HashNode.new({'foo' => 'bar'}, JSI::JSON::Pointer.new([])), subject.jsi_instance)
|
138
122
|
assert(!subject.respond_to?(:to_ary))
|
139
123
|
assert(subject.respond_to?(:to_hash))
|
140
124
|
end
|
@@ -143,43 +127,43 @@ describe JSI::Base do
|
|
143
127
|
let(:instance) { ['foo'] }
|
144
128
|
let(:schema_content) { {'type' => 'array'} }
|
145
129
|
it 'initializes' do
|
146
|
-
assert_equal(['foo'], subject.
|
130
|
+
assert_equal(['foo'], subject.jsi_instance)
|
147
131
|
assert(subject.respond_to?(:to_ary))
|
148
132
|
assert(!subject.respond_to?(:to_hash))
|
149
133
|
end
|
150
134
|
end
|
151
|
-
describe 'JSI::JSON::
|
152
|
-
let(:
|
135
|
+
describe 'JSI::JSON::ArrayNode' do
|
136
|
+
let(:instance) { JSI::JSON::ArrayNode.new(['foo'], JSI::JSON::Pointer.new([])) }
|
153
137
|
let(:schema_content) { {'type' => 'array'} }
|
154
138
|
it 'initializes' do
|
155
|
-
assert_equal(JSI::JSON::ArrayNode.new(['foo'], JSI::JSON::Pointer.new([])), subject.
|
139
|
+
assert_equal(JSI::JSON::ArrayNode.new(['foo'], JSI::JSON::Pointer.new([])), subject.jsi_instance)
|
156
140
|
assert(subject.respond_to?(:to_ary))
|
157
141
|
assert(!subject.respond_to?(:to_hash))
|
158
142
|
end
|
159
143
|
end
|
160
144
|
describe 'another JSI::Base invalid' do
|
161
145
|
let(:schema_content) { {'type' => 'object'} }
|
162
|
-
let(:instance) {
|
146
|
+
let(:instance) { schema.new_jsi({'foo' => 'bar'}) }
|
163
147
|
it 'initializes with an error' do
|
164
148
|
err = assert_raises(TypeError) { subject }
|
165
|
-
|
149
|
+
assert_equal("assigning another JSI::Base instance to a (JSI Schema Class: #) instance is incorrect. received: \#{<JSI> \"foo\" => \"bar\"}", err.message)
|
166
150
|
end
|
167
151
|
end
|
168
152
|
describe 'Schema invalid' do
|
169
153
|
let(:instance) { JSI::Schema.new({}) }
|
170
154
|
it 'initializes with an error' do
|
171
155
|
err = assert_raises(TypeError) { subject }
|
172
|
-
|
156
|
+
assert_equal("assigning a schema to a (JSI Schema Class: #) instance is incorrect. received: \#{<JSI (JSI::JSONSchemaOrgDraft06) Schema>}", err.message)
|
173
157
|
end
|
174
158
|
end
|
175
159
|
end
|
176
160
|
describe '#parent_jsis, #parent_jsi' do
|
177
161
|
let(:schema_content) { {'properties' => {'foo' => {'properties' => {'bar' => {'properties' => {'baz' => {}}}}}}} }
|
178
|
-
let(:
|
162
|
+
let(:instance) { {'foo' => {'bar' => {'baz' => {}}}} }
|
179
163
|
describe 'no parent_jsis' do
|
180
164
|
it 'has none' do
|
181
165
|
assert_equal([], subject.parents)
|
182
|
-
assert_equal([], subject.parent_jsis
|
166
|
+
assert_equal([], subject.parent_jsis)
|
183
167
|
assert_equal(nil, subject.parent)
|
184
168
|
assert_equal(nil, subject.parent_jsi)
|
185
169
|
end
|
@@ -187,7 +171,7 @@ describe JSI::Base do
|
|
187
171
|
describe 'one parent_jsi' do
|
188
172
|
it 'has one' do
|
189
173
|
assert_equal([subject], subject.foo.parents)
|
190
|
-
assert_equal([subject], subject.foo.parent_jsis
|
174
|
+
assert_equal([subject], subject.foo.parent_jsis)
|
191
175
|
assert_equal(subject, subject.foo.parent)
|
192
176
|
assert_equal(subject, subject.foo.parent_jsi)
|
193
177
|
end
|
@@ -195,14 +179,14 @@ describe JSI::Base do
|
|
195
179
|
describe 'more parent_jsis' do
|
196
180
|
it 'has more' do
|
197
181
|
assert_equal([subject.foo.bar, subject.foo, subject], subject.foo.bar.baz.parents)
|
198
|
-
assert_equal([subject.foo.bar, subject.foo, subject], subject.foo.bar.baz.parent_jsis
|
182
|
+
assert_equal([subject.foo.bar, subject.foo, subject], subject.foo.bar.baz.parent_jsis)
|
199
183
|
assert_equal(subject.foo.bar, subject.foo.bar.baz.parent)
|
200
184
|
assert_equal(subject.foo.bar, subject.foo.bar.baz.parent_jsi)
|
201
185
|
end
|
202
186
|
end
|
203
187
|
end
|
204
188
|
describe '#each, Enumerable methods' do
|
205
|
-
let(:
|
189
|
+
let(:instance) { 'a string' }
|
206
190
|
it "raises NoMethodError calling each or Enumerable methods" do
|
207
191
|
assert_raises(NoMethodError) { subject.each { nil } }
|
208
192
|
assert_raises(NoMethodError) { subject.map { nil } }
|
@@ -217,8 +201,8 @@ describe JSI::Base do
|
|
217
201
|
assert_equal(instance, o)
|
218
202
|
new_instance
|
219
203
|
end
|
220
|
-
assert_equal(new_instance, modified.
|
221
|
-
assert_equal(instance, subject.
|
204
|
+
assert_equal(new_instance, modified.jsi_instance)
|
205
|
+
assert_equal(instance, subject.jsi_instance)
|
222
206
|
refute_equal(instance, modified)
|
223
207
|
end
|
224
208
|
end
|
@@ -228,8 +212,8 @@ describe JSI::Base do
|
|
228
212
|
assert_equal({}, o)
|
229
213
|
{'a' => 'b'}
|
230
214
|
end
|
231
|
-
assert_equal({'a' => 'b'}, modified.
|
232
|
-
assert_equal({}, subject.
|
215
|
+
assert_equal({'a' => 'b'}, modified.jsi_instance)
|
216
|
+
assert_equal({}, subject.jsi_instance)
|
233
217
|
refute_equal(instance, modified)
|
234
218
|
end
|
235
219
|
end
|
@@ -237,7 +221,7 @@ describe JSI::Base do
|
|
237
221
|
it 'yields the instance to modify' do
|
238
222
|
modified = subject.modified_copy { |o| o }
|
239
223
|
# this doesn't really need to be tested but ... whatever
|
240
|
-
assert_equal(subject.
|
224
|
+
assert_equal(subject.jsi_instance.object_id, modified.jsi_instance.object_id)
|
241
225
|
assert_equal(subject, modified)
|
242
226
|
refute_equal(subject.object_id, modified.object_id)
|
243
227
|
end
|
@@ -249,18 +233,15 @@ describe JSI::Base do
|
|
249
233
|
modified = subject.modified_copy do |o|
|
250
234
|
o.to_s
|
251
235
|
end
|
252
|
-
assert_equal('{}', modified.
|
253
|
-
assert_equal({}, subject.
|
236
|
+
assert_equal('{}', modified.jsi_instance)
|
237
|
+
assert_equal({}, subject.jsi_instance)
|
254
238
|
refute_equal(instance, modified)
|
255
239
|
# interesting side effect
|
256
240
|
assert(subject.respond_to?(:to_hash))
|
257
241
|
assert(!modified.respond_to?(:to_hash))
|
258
|
-
assert_equal(JSI::JSON::HashNode, subject.instance.class)
|
259
|
-
assert_equal(JSI::JSON::Node, modified.instance.class)
|
260
242
|
end
|
261
243
|
end
|
262
244
|
end
|
263
|
-
it('#fragment') { assert_equal('#', subject.fragment) }
|
264
245
|
describe 'validation' do
|
265
246
|
describe 'without errors' do
|
266
247
|
it '#fully_validate' do
|
@@ -273,6 +254,94 @@ describe JSI::Base do
|
|
273
254
|
assert_equal(true, subject.validate!)
|
274
255
|
end
|
275
256
|
end
|
257
|
+
describe 'with errors' do
|
258
|
+
let(:schema_content) {
|
259
|
+
{
|
260
|
+
'id' => 'https://schemas.jsi.unth.net/test/JSI::Base::validation::with errors',
|
261
|
+
'type' => 'object',
|
262
|
+
'properties' => {
|
263
|
+
'some_number' => {
|
264
|
+
'type' => 'number'
|
265
|
+
},
|
266
|
+
'a_required_property' => {
|
267
|
+
'type' => 'string'
|
268
|
+
}
|
269
|
+
}
|
270
|
+
}
|
271
|
+
}
|
272
|
+
let(:instance) { "this is a string" }
|
273
|
+
|
274
|
+
it '#validate' do
|
275
|
+
assert_equal(false, subject.validate)
|
276
|
+
end
|
277
|
+
it '#validate!' do
|
278
|
+
assert_raises JSON::Schema::ValidationError do
|
279
|
+
subject.validate!
|
280
|
+
end
|
281
|
+
end
|
282
|
+
describe 'fully_validate' do
|
283
|
+
it '#fully_validate ' do
|
284
|
+
assert_equal(["The property '#/' of type string did not match the following type: object in schema https://schemas.jsi.unth.net/test/JSI::Base::validation::with errors"], subject.fully_validate)
|
285
|
+
end
|
286
|
+
it '#fully_validate :errors_as_objects' do
|
287
|
+
expected = [
|
288
|
+
{
|
289
|
+
:schema => Addressable::URI.parse('https://schemas.jsi.unth.net/test/JSI::Base::validation::with errors'),
|
290
|
+
:fragment => "#/",
|
291
|
+
:message => "The property '#/' of type string did not match the following type: object in schema https://schemas.jsi.unth.net/test/JSI::Base::validation::with errors",
|
292
|
+
:failed_attribute=>"TypeV4"
|
293
|
+
}
|
294
|
+
]
|
295
|
+
assert_equal(expected, subject.fully_validate(:errors_as_objects => true))
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
describe 'at a depth' do
|
300
|
+
let(:schema_content) do
|
301
|
+
{
|
302
|
+
'id' => 'https://schemas.jsi.unth.net/test/JSI::Base::validation::at a depth',
|
303
|
+
'description' => 'hash schema',
|
304
|
+
'type' => 'object',
|
305
|
+
'properties' => {
|
306
|
+
'foo' => {'type' => 'object'},
|
307
|
+
'bar' => {},
|
308
|
+
'baz' => {'type' => 'array'},
|
309
|
+
},
|
310
|
+
'additionalProperties' => {'not' => {}},
|
311
|
+
}
|
312
|
+
end
|
313
|
+
|
314
|
+
describe 'without errors' do
|
315
|
+
let(:instance) { {'foo' => {'x' => 'y'}, 'bar' => [9], 'baz' => [true]} }
|
316
|
+
|
317
|
+
it '#fully_validate' do
|
318
|
+
assert_equal([], subject.foo.fully_validate)
|
319
|
+
assert_equal([], subject.bar.fully_validate)
|
320
|
+
end
|
321
|
+
it '#validate' do
|
322
|
+
assert_equal(true, subject.foo.validate)
|
323
|
+
assert_equal(true, subject.bar.validate)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
describe 'with errors' do
|
327
|
+
let(:instance) { {'foo' => [true], 'bar' => [9], 'baz' => {'x' => 'y'}, 'more' => {}} }
|
328
|
+
|
329
|
+
it '#fully_validate' do
|
330
|
+
assert_equal(["The property '#/' of type array did not match the following type: object in schema https://schemas.jsi.unth.net/test/JSI::Base::validation::at a depth"], subject.foo.fully_validate)
|
331
|
+
assert_equal([], subject.bar.fully_validate)
|
332
|
+
assert_equal(["The property '#/' of type object did not match the following type: array in schema https://schemas.jsi.unth.net/test/JSI::Base::validation::at a depth"], subject.baz.fully_validate)
|
333
|
+
assert_equal(["The property '#/' of type object matched the disallowed schema in schema https://schemas.jsi.unth.net/test/JSI::Base::validation::at a depth"], subject['more'].fully_validate)
|
334
|
+
assert_equal(["The property '#/foo' of type array did not match the following type: object in schema https://schemas.jsi.unth.net/test/JSI::Base::validation::at a depth", "The property '#/baz' of type object did not match the following type: array in schema https://schemas.jsi.unth.net/test/JSI::Base::validation::at a depth", "The property '#/more' of type object matched the disallowed schema in schema https://schemas.jsi.unth.net/test/JSI::Base::validation::at a depth"], subject.fully_validate)
|
335
|
+
end
|
336
|
+
it '#validate' do
|
337
|
+
assert_equal(false, subject.foo.validate)
|
338
|
+
assert_equal(true, subject.bar.validate)
|
339
|
+
assert_equal(false, subject.baz.validate)
|
340
|
+
assert_equal(false, subject['more'].validate)
|
341
|
+
assert_equal(false, subject.validate)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
276
345
|
end
|
277
346
|
describe 'property accessors' do
|
278
347
|
let(:schema_content) do
|
@@ -285,17 +354,17 @@ describe JSI::Base do
|
|
285
354
|
},
|
286
355
|
}
|
287
356
|
end
|
288
|
-
let(:
|
357
|
+
let(:instance) do
|
289
358
|
{'foo' => {'x' => 'y'}, 'bar' => [3.14159], 'baz' => true, 'qux' => []}
|
290
359
|
end
|
291
360
|
describe 'readers' do
|
292
361
|
it 'reads attributes described as properties' do
|
293
362
|
assert_equal({'x' => 'y'}, subject.foo.as_json)
|
294
|
-
|
363
|
+
assert_is_a(schema.properties['foo'].jsi_schema_module, subject.foo)
|
295
364
|
assert_respond_to(subject.foo, :to_hash)
|
296
365
|
refute_respond_to(subject.foo, :to_ary)
|
297
366
|
assert_equal([3.14159], subject.bar.as_json)
|
298
|
-
|
367
|
+
assert_is_a(schema.properties['bar'].jsi_schema_module, subject.bar)
|
299
368
|
refute_respond_to(subject.bar, :to_hash)
|
300
369
|
assert_respond_to(subject.bar, :to_ary)
|
301
370
|
assert_equal(true, subject.baz)
|
@@ -307,7 +376,7 @@ describe JSI::Base do
|
|
307
376
|
let(:instance) { nil }
|
308
377
|
it 'errors' do
|
309
378
|
err = assert_raises(NoMethodError) { subject.foo }
|
310
|
-
|
379
|
+
assert_equal(%q(cannot subcript (using token: "foo") from instance: nil), err.message)
|
311
380
|
end
|
312
381
|
end
|
313
382
|
describe 'properties with the same names as instance methods' do
|
@@ -322,12 +391,12 @@ describe JSI::Base do
|
|
322
391
|
'as_json' => {}, # Base::OverrideFromExtensions, extended on initialization
|
323
392
|
'each' => {}, # BaseHash / BaseArray
|
324
393
|
'instance_exec' => {}, # BasicObject
|
325
|
-
'
|
394
|
+
'jsi_instance' => {}, # Base
|
326
395
|
'schema' => {}, # module_for_schema singleton definition
|
327
396
|
},
|
328
397
|
}
|
329
398
|
end
|
330
|
-
let(:
|
399
|
+
let(:instance) do
|
331
400
|
{
|
332
401
|
'foo' => 'bar',
|
333
402
|
'initialize' => 'hi',
|
@@ -336,23 +405,22 @@ describe JSI::Base do
|
|
336
405
|
'as_json' => 'hi',
|
337
406
|
'each' => 'hi',
|
338
407
|
'instance_exec' => 'hi',
|
339
|
-
'
|
408
|
+
'jsi_instance' => 'hi',
|
340
409
|
'schema' => 'hi',
|
341
410
|
}
|
342
411
|
end
|
343
412
|
it 'does not define readers' do
|
344
|
-
assert_equal('bar', subject.foo)
|
345
|
-
assert_equal(JSI::SchemaClasses.module_for_schema(subject.schema, conflicting_modules: [JSI::Base, JSI::BaseArray, JSI::BaseHash]), subject.method(:foo).owner)
|
413
|
+
assert_equal('bar', subject.foo) # this one is defined
|
346
414
|
|
347
415
|
assert_equal(JSI::Base, subject.method(:initialize).owner)
|
348
416
|
assert_equal('hi', subject['initialize'])
|
349
|
-
|
417
|
+
assert_equal(%q(#{<JSI> "foo" => "bar", "initialize" => "hi", "inspect" => "hi", "pretty_inspect" => "hi", "as_json" => "hi", "each" => "hi", "instance_exec" => "hi", "jsi_instance" => "hi", "schema" => "hi"}), subject.inspect)
|
350
418
|
assert_equal('hi', subject['inspect'])
|
351
|
-
|
352
|
-
assert_equal(
|
419
|
+
assert_equal(%Q(\#{<JSI>\n "foo" => "bar",\n "initialize" => "hi",\n "inspect" => "hi",\n "pretty_inspect" => "hi",\n "as_json" => "hi",\n "each" => "hi",\n "instance_exec" => "hi",\n "jsi_instance" => "hi",\n "schema" => "hi"\n}\n), subject.pretty_inspect)
|
420
|
+
assert_equal(instance, subject.as_json)
|
353
421
|
assert_equal(subject, subject.each { })
|
354
422
|
assert_equal(2, subject.instance_exec { 2 })
|
355
|
-
assert_equal(instance, subject.
|
423
|
+
assert_equal(instance, subject.jsi_instance)
|
356
424
|
assert_equal(schema, subject.schema)
|
357
425
|
end
|
358
426
|
end
|
@@ -364,48 +432,49 @@ describe JSI::Base do
|
|
364
432
|
subject.foo = {'y' => 'z'}
|
365
433
|
|
366
434
|
assert_equal({'y' => 'z'}, subject.foo.as_json)
|
367
|
-
|
368
|
-
|
435
|
+
assert_is_a(schema.properties['foo'].jsi_schema_module, orig_foo)
|
436
|
+
assert_is_a(schema.properties['foo'].jsi_schema_module, subject.foo)
|
369
437
|
end
|
370
438
|
it 'modifies the instance, visible to other references to the same instance' do
|
371
|
-
orig_instance = subject.
|
439
|
+
orig_instance = subject.jsi_instance
|
372
440
|
|
373
441
|
subject.foo = {'y' => 'z'}
|
374
442
|
|
375
|
-
assert_equal(orig_instance, subject.
|
376
|
-
assert_equal({'y' => 'z'}, orig_instance['foo']
|
377
|
-
assert_equal({'y' => 'z'}, subject.
|
378
|
-
assert_equal(orig_instance.class, subject.
|
443
|
+
assert_equal(orig_instance, subject.jsi_instance)
|
444
|
+
assert_equal({'y' => 'z'}, orig_instance['foo'])
|
445
|
+
assert_equal({'y' => 'z'}, subject.jsi_instance['foo'])
|
446
|
+
assert_equal(orig_instance.class, subject.jsi_instance.class)
|
379
447
|
end
|
380
448
|
describe 'when the instance is not hashlike' do
|
381
449
|
let(:instance) { nil }
|
382
450
|
it 'errors' do
|
383
451
|
err = assert_raises(NoMethodError) { subject.foo = 0 }
|
384
|
-
|
452
|
+
assert_equal('cannot assign subcript (using token: "foo") to instance: nil', err.message)
|
385
453
|
end
|
386
454
|
end
|
387
455
|
end
|
388
456
|
end
|
389
457
|
describe '#inspect' do
|
390
458
|
# if the instance is hash-like, #inspect gets overridden
|
391
|
-
let(:
|
459
|
+
let(:instance) { Object.new }
|
392
460
|
it 'inspects' do
|
393
|
-
assert_match(%r(\A
|
461
|
+
assert_match(%r(\A\#<JSI\ \#<Object:[^<>]*>>\z), subject.inspect)
|
394
462
|
end
|
395
463
|
end
|
396
464
|
describe '#pretty_print' do
|
397
465
|
# if the instance is hash-like, #pretty_print gets overridden
|
398
|
-
let(:
|
466
|
+
let(:instance) { Object.new }
|
399
467
|
it 'pretty_prints' do
|
400
|
-
assert_match(%r(\A
|
468
|
+
assert_match(%r(\A\#<JSI\ \#<Object:[^<>]*>>\z), subject.pretty_inspect.chomp)
|
401
469
|
end
|
402
470
|
end
|
403
471
|
describe '#as_json' do
|
404
472
|
it '#as_json' do
|
405
|
-
assert_equal({'a' => 'b'}, JSI.
|
406
|
-
assert_equal({'a' => 'b'}, JSI.
|
407
|
-
assert_equal(
|
408
|
-
assert_equal(['a'], JSI.
|
473
|
+
assert_equal({'a' => 'b'}, JSI::Schema.new({}).new_jsi({'a' => 'b'}).as_json)
|
474
|
+
assert_equal({'a' => 'b'}, JSI::Schema.new({}).new_jsi(JSI::JSON::Node.new_doc({'a' => 'b'})).as_json)
|
475
|
+
assert_equal({'a' => 'b'}, JSI::Schema.new({'type' => 'object'}).new_jsi(JSI::JSON::Node.new_doc({'a' => 'b'})).as_json)
|
476
|
+
assert_equal(['a', 'b'], JSI::Schema.new({'type' => 'array'}).new_jsi(JSI::JSON::Node.new_doc(['a', 'b'])).as_json)
|
477
|
+
assert_equal(['a'], JSI::Schema.new({}).new_jsi(['a']).as_json(some_option: true))
|
409
478
|
end
|
410
479
|
end
|
411
480
|
describe 'equality between different classes of JSI::Base subclasses' do
|