fast-json-stringify 5.0.5 → 5.2.0
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.
- package/.github/workflows/benchmark.yml +12 -12
- package/.github/workflows/ci.yml +2 -0
- package/benchmark/bench.js +54 -0
- package/index.js +85 -102
- package/package.json +6 -5
- package/ref-resolver.js +84 -0
- package/serializer.js +21 -12
- package/standalone.js +8 -8
- package/test/basic.test.js +13 -0
- package/test/const.test.js +235 -8
- package/test/date.test.js +100 -4
- package/test/debug-mode.test.js +10 -4
- package/test/nullable.test.js +97 -0
- package/test/ref.test.js +55 -0
- package/test/typesArray.test.js +29 -0
- package/validator.js +75 -0
- package/ajv.js +0 -37
package/standalone.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
|
|
4
|
-
function buildStandaloneCode (options,
|
|
4
|
+
function buildStandaloneCode (options, validator, contextFunctionCode) {
|
|
5
5
|
const serializerCode = fs.readFileSync(path.join(__dirname, 'serializer.js')).toString()
|
|
6
6
|
let buildAjvCode = ''
|
|
7
7
|
let defaultAjvSchema = ''
|
|
8
|
-
const defaultMeta =
|
|
8
|
+
const defaultMeta = validator.ajv.defaultMeta()
|
|
9
9
|
if (typeof defaultMeta === 'string') {
|
|
10
10
|
defaultAjvSchema = defaultMeta
|
|
11
11
|
} else {
|
|
12
12
|
defaultAjvSchema = defaultMeta.$id || defaultMeta.id
|
|
13
13
|
}
|
|
14
|
-
const shouldUseAjv = contextFunctionCode.indexOf('
|
|
14
|
+
const shouldUseAjv = contextFunctionCode.indexOf('validator') !== -1
|
|
15
15
|
// we need to export the custom json schema
|
|
16
16
|
let ajvSchemasCode = ''
|
|
17
17
|
if (shouldUseAjv) {
|
|
18
|
-
ajvSchemasCode += `const
|
|
19
|
-
for (const [id, schema] of Object.entries(
|
|
18
|
+
ajvSchemasCode += `const validator = new Validator(${JSON.stringify(options.ajv || {})})\n`
|
|
19
|
+
for (const [id, schema] of Object.entries(validator.ajv.schemas)) {
|
|
20
20
|
// should skip ajv default schema
|
|
21
21
|
if (id === defaultAjvSchema) continue
|
|
22
|
-
ajvSchemasCode += `ajv.addSchema(${JSON.stringify(schema.schema)}, "${id}")\n`
|
|
22
|
+
ajvSchemasCode += `validator.ajv.addSchema(${JSON.stringify(schema.schema)}, "${id}")\n`
|
|
23
23
|
}
|
|
24
|
-
buildAjvCode = fs.readFileSync(path.join(__dirname, '
|
|
25
|
-
buildAjvCode = buildAjvCode.replace("'use strict'", '').replace('module.exports =
|
|
24
|
+
buildAjvCode = fs.readFileSync(path.join(__dirname, 'validator.js')).toString()
|
|
25
|
+
buildAjvCode = buildAjvCode.replace("'use strict'", '').replace('module.exports = SchemaValidator', '')
|
|
26
26
|
}
|
|
27
27
|
return `
|
|
28
28
|
'use strict'
|
package/test/basic.test.js
CHANGED
|
@@ -359,3 +359,16 @@ test('render a single quote as JSON', (t) => {
|
|
|
359
359
|
t.equal(output, JSON.stringify(toStringify))
|
|
360
360
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
361
361
|
})
|
|
362
|
+
|
|
363
|
+
test('returns JSON.stringify if schema type is boolean', t => {
|
|
364
|
+
t.plan(1)
|
|
365
|
+
|
|
366
|
+
const schema = {
|
|
367
|
+
type: 'array',
|
|
368
|
+
items: true
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
const array = [1, true, 'test']
|
|
372
|
+
const stringify = build(schema)
|
|
373
|
+
t.equal(stringify(array), JSON.stringify(array))
|
|
374
|
+
})
|
package/test/const.test.js
CHANGED
|
@@ -24,6 +24,184 @@ test('schema with const string', (t) => {
|
|
|
24
24
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
25
25
|
})
|
|
26
26
|
|
|
27
|
+
test('schema with const string and different input', (t) => {
|
|
28
|
+
t.plan(2)
|
|
29
|
+
|
|
30
|
+
const schema = {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {
|
|
33
|
+
foo: { const: 'bar' }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const validate = validator(schema)
|
|
38
|
+
const stringify = build(schema)
|
|
39
|
+
const output = stringify({
|
|
40
|
+
foo: 'baz'
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
t.equal(output, '{"foo":"bar"}')
|
|
44
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
test('schema with const string and different type input', (t) => {
|
|
48
|
+
t.plan(2)
|
|
49
|
+
|
|
50
|
+
const schema = {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
foo: { const: 'bar' }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const validate = validator(schema)
|
|
58
|
+
const stringify = build(schema)
|
|
59
|
+
const output = stringify({
|
|
60
|
+
foo: 1
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
t.equal(output, '{"foo":"bar"}')
|
|
64
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('schema with const string and no input', (t) => {
|
|
68
|
+
t.plan(2)
|
|
69
|
+
|
|
70
|
+
const schema = {
|
|
71
|
+
type: 'object',
|
|
72
|
+
properties: {
|
|
73
|
+
foo: { const: 'bar' }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const validate = validator(schema)
|
|
78
|
+
const stringify = build(schema)
|
|
79
|
+
const output = stringify({})
|
|
80
|
+
|
|
81
|
+
t.equal(output, '{}')
|
|
82
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('schema with const number', (t) => {
|
|
86
|
+
t.plan(2)
|
|
87
|
+
|
|
88
|
+
const schema = {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
foo: { const: 1 }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const validate = validator(schema)
|
|
96
|
+
const stringify = build(schema)
|
|
97
|
+
const output = stringify({
|
|
98
|
+
foo: 1
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
t.equal(output, '{"foo":1}')
|
|
102
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
test('schema with const number and different input', (t) => {
|
|
106
|
+
t.plan(2)
|
|
107
|
+
|
|
108
|
+
const schema = {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
foo: { const: 1 }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const validate = validator(schema)
|
|
116
|
+
const stringify = build(schema)
|
|
117
|
+
const output = stringify({
|
|
118
|
+
foo: 2
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
t.equal(output, '{"foo":1}')
|
|
122
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
test('schema with const bool', (t) => {
|
|
126
|
+
t.plan(2)
|
|
127
|
+
|
|
128
|
+
const schema = {
|
|
129
|
+
type: 'object',
|
|
130
|
+
properties: {
|
|
131
|
+
foo: { const: true }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const validate = validator(schema)
|
|
136
|
+
const stringify = build(schema)
|
|
137
|
+
const output = stringify({
|
|
138
|
+
foo: true
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
t.equal(output, '{"foo":true}')
|
|
142
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('schema with const number', (t) => {
|
|
146
|
+
t.plan(2)
|
|
147
|
+
|
|
148
|
+
const schema = {
|
|
149
|
+
type: 'object',
|
|
150
|
+
properties: {
|
|
151
|
+
foo: { const: 1 }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const validate = validator(schema)
|
|
156
|
+
const stringify = build(schema)
|
|
157
|
+
const output = stringify({
|
|
158
|
+
foo: 1
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
t.equal(output, '{"foo":1}')
|
|
162
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
test('schema with const null', (t) => {
|
|
166
|
+
t.plan(2)
|
|
167
|
+
|
|
168
|
+
const schema = {
|
|
169
|
+
type: 'object',
|
|
170
|
+
properties: {
|
|
171
|
+
foo: { const: null }
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const validate = validator(schema)
|
|
176
|
+
const stringify = build(schema)
|
|
177
|
+
const output = stringify({
|
|
178
|
+
foo: null
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
t.equal(output, '{"foo":null}')
|
|
182
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
test('schema with const array', (t) => {
|
|
186
|
+
t.plan(2)
|
|
187
|
+
|
|
188
|
+
const schema = {
|
|
189
|
+
type: 'object',
|
|
190
|
+
properties: {
|
|
191
|
+
foo: { const: [1, 2, 3] }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const validate = validator(schema)
|
|
196
|
+
const stringify = build(schema)
|
|
197
|
+
const output = stringify({
|
|
198
|
+
foo: [1, 2, 3]
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
t.equal(output, '{"foo":[1,2,3]}')
|
|
202
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
203
|
+
})
|
|
204
|
+
|
|
27
205
|
test('schema with const object', (t) => {
|
|
28
206
|
t.plan(2)
|
|
29
207
|
|
|
@@ -44,6 +222,56 @@ test('schema with const object', (t) => {
|
|
|
44
222
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
45
223
|
})
|
|
46
224
|
|
|
225
|
+
test('schema with const and null as type', (t) => {
|
|
226
|
+
t.plan(4)
|
|
227
|
+
|
|
228
|
+
const schema = {
|
|
229
|
+
type: 'object',
|
|
230
|
+
properties: {
|
|
231
|
+
foo: { type: ['string', 'null'], const: 'baz' }
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const validate = validator(schema)
|
|
236
|
+
const stringify = build(schema)
|
|
237
|
+
const output = stringify({
|
|
238
|
+
foo: null
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
t.equal(output, '{"foo":null}')
|
|
242
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
243
|
+
|
|
244
|
+
const output2 = stringify({ foo: 'baz' })
|
|
245
|
+
t.equal(output2, '{"foo":"baz"}')
|
|
246
|
+
t.ok(validate(JSON.parse(output2)), 'valid schema')
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
test('schema with const as nullable', (t) => {
|
|
250
|
+
t.plan(4)
|
|
251
|
+
|
|
252
|
+
const schema = {
|
|
253
|
+
type: 'object',
|
|
254
|
+
properties: {
|
|
255
|
+
foo: { nullable: true, const: 'baz' }
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const validate = validator(schema)
|
|
260
|
+
const stringify = build(schema)
|
|
261
|
+
const output = stringify({
|
|
262
|
+
foo: null
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
t.equal(output, '{"foo":null}')
|
|
266
|
+
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
267
|
+
|
|
268
|
+
const output2 = stringify({
|
|
269
|
+
foo: 'baz'
|
|
270
|
+
})
|
|
271
|
+
t.equal(output2, '{"foo":"baz"}')
|
|
272
|
+
t.ok(validate(JSON.parse(output2)), 'valid schema')
|
|
273
|
+
})
|
|
274
|
+
|
|
47
275
|
test('schema with const and invalid object', (t) => {
|
|
48
276
|
t.plan(2)
|
|
49
277
|
|
|
@@ -55,13 +283,12 @@ test('schema with const and invalid object', (t) => {
|
|
|
55
283
|
required: ['foo']
|
|
56
284
|
}
|
|
57
285
|
|
|
286
|
+
const validate = validator(schema)
|
|
58
287
|
const stringify = build(schema)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
t.ok(err)
|
|
66
|
-
}
|
|
288
|
+
const result = stringify({
|
|
289
|
+
foo: { foo: 'baz' }
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
t.equal(result, '{"foo":{"foo":"bar"}}')
|
|
293
|
+
t.ok(validate(JSON.parse(result)), 'valid schema')
|
|
67
294
|
})
|
package/test/date.test.js
CHANGED
|
@@ -308,7 +308,7 @@ test('serializing null value', t => {
|
|
|
308
308
|
})
|
|
309
309
|
|
|
310
310
|
t.test('type::array', t => {
|
|
311
|
-
t.plan(
|
|
311
|
+
t.plan(6)
|
|
312
312
|
|
|
313
313
|
t.test('format::date-time', t => {
|
|
314
314
|
t.plan(2)
|
|
@@ -348,13 +348,13 @@ test('serializing null value', t => {
|
|
|
348
348
|
t.notOk(validate(JSON.parse(output)), 'an empty string is not a date format')
|
|
349
349
|
})
|
|
350
350
|
|
|
351
|
-
t.test('format::
|
|
351
|
+
t.test('format::date', t => {
|
|
352
352
|
t.plan(2)
|
|
353
353
|
|
|
354
354
|
const prop = {
|
|
355
355
|
updatedAt: {
|
|
356
356
|
type: ['string'],
|
|
357
|
-
format: '
|
|
357
|
+
format: 'date'
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
360
|
|
|
@@ -364,7 +364,66 @@ test('serializing null value', t => {
|
|
|
364
364
|
} = serialize(createSchema(prop), input)
|
|
365
365
|
|
|
366
366
|
t.equal(output, '{"updatedAt":""}')
|
|
367
|
-
t.notOk(validate(JSON.parse(output)), 'an empty string is not a
|
|
367
|
+
t.notOk(validate(JSON.parse(output)), 'an empty string is not a date format')
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
t.test('format::time, Date object', t => {
|
|
371
|
+
t.plan(1)
|
|
372
|
+
|
|
373
|
+
const schema = {
|
|
374
|
+
oneOf: [
|
|
375
|
+
{
|
|
376
|
+
type: 'object',
|
|
377
|
+
properties: {
|
|
378
|
+
updatedAt: {
|
|
379
|
+
type: ['string', 'number'],
|
|
380
|
+
format: 'time'
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const date = new Date()
|
|
388
|
+
const input = { updatedAt: date }
|
|
389
|
+
const { output } = serialize(schema, input)
|
|
390
|
+
|
|
391
|
+
t.equal(output, JSON.stringify({ updatedAt: DateTime.fromJSDate(date).toFormat('HH:mm:ss') }))
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
t.test('format::time, Date object', t => {
|
|
395
|
+
t.plan(1)
|
|
396
|
+
|
|
397
|
+
const schema = {
|
|
398
|
+
oneOf: [
|
|
399
|
+
{
|
|
400
|
+
type: ['string', 'number'],
|
|
401
|
+
format: 'time'
|
|
402
|
+
}
|
|
403
|
+
]
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const date = new Date()
|
|
407
|
+
const { output } = serialize(schema, date)
|
|
408
|
+
|
|
409
|
+
t.equal(output, `"${DateTime.fromJSDate(date).toFormat('HH:mm:ss')}"`)
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
t.test('format::time, Date object', t => {
|
|
413
|
+
t.plan(1)
|
|
414
|
+
|
|
415
|
+
const schema = {
|
|
416
|
+
oneOf: [
|
|
417
|
+
{
|
|
418
|
+
type: ['string', 'number'],
|
|
419
|
+
format: 'time'
|
|
420
|
+
}
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const { output } = serialize(schema, 42)
|
|
425
|
+
|
|
426
|
+
t.equal(output, JSON.stringify(42))
|
|
368
427
|
})
|
|
369
428
|
})
|
|
370
429
|
|
|
@@ -429,3 +488,40 @@ test('serializing null value', t => {
|
|
|
429
488
|
})
|
|
430
489
|
})
|
|
431
490
|
})
|
|
491
|
+
|
|
492
|
+
test('Validate Date object as string type', (t) => {
|
|
493
|
+
t.plan(1)
|
|
494
|
+
|
|
495
|
+
const schema = {
|
|
496
|
+
oneOf: [
|
|
497
|
+
{ type: 'string' }
|
|
498
|
+
]
|
|
499
|
+
}
|
|
500
|
+
const toStringify = new Date()
|
|
501
|
+
|
|
502
|
+
const stringify = build(schema)
|
|
503
|
+
const output = stringify(toStringify)
|
|
504
|
+
|
|
505
|
+
t.equal(output, JSON.stringify(toStringify))
|
|
506
|
+
})
|
|
507
|
+
|
|
508
|
+
test('nullable date', (t) => {
|
|
509
|
+
t.plan(1)
|
|
510
|
+
|
|
511
|
+
const schema = {
|
|
512
|
+
anyOf: [
|
|
513
|
+
{
|
|
514
|
+
format: 'date',
|
|
515
|
+
type: 'string',
|
|
516
|
+
nullable: true
|
|
517
|
+
}
|
|
518
|
+
]
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const stringify = build(schema)
|
|
522
|
+
|
|
523
|
+
const data = new Date()
|
|
524
|
+
const result = stringify(data)
|
|
525
|
+
|
|
526
|
+
t.same(result, `"${DateTime.fromJSDate(data).toISODate()}"`)
|
|
527
|
+
})
|
package/test/debug-mode.test.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const test = require('tap').test
|
|
4
4
|
const fjs = require('..')
|
|
5
|
+
|
|
5
6
|
const Ajv = require('ajv').default
|
|
7
|
+
const Validator = require('../validator')
|
|
6
8
|
|
|
7
9
|
function build (opts) {
|
|
8
10
|
return fjs({
|
|
@@ -18,31 +20,34 @@ function build (opts) {
|
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
test('activate debug mode', t => {
|
|
21
|
-
t.plan(
|
|
23
|
+
t.plan(4)
|
|
22
24
|
const debugMode = build({ debugMode: true })
|
|
23
25
|
|
|
24
26
|
t.type(debugMode, 'object')
|
|
25
27
|
t.ok(debugMode.ajv instanceof Ajv)
|
|
28
|
+
t.ok(debugMode.validator instanceof Validator)
|
|
26
29
|
t.type(debugMode.code, 'string')
|
|
27
30
|
})
|
|
28
31
|
|
|
29
32
|
test('activate debug mode truthy', t => {
|
|
30
|
-
t.plan(
|
|
33
|
+
t.plan(4)
|
|
31
34
|
|
|
32
35
|
const debugMode = build({ debugMode: 'yes' })
|
|
33
36
|
|
|
34
37
|
t.type(debugMode, 'object')
|
|
35
38
|
t.type(debugMode.code, 'string')
|
|
36
39
|
t.ok(debugMode.ajv instanceof Ajv)
|
|
40
|
+
t.ok(debugMode.validator instanceof Validator)
|
|
37
41
|
})
|
|
38
42
|
|
|
39
43
|
test('to string auto-consistent', t => {
|
|
40
|
-
t.plan(
|
|
44
|
+
t.plan(5)
|
|
41
45
|
const debugMode = build({ debugMode: 1 })
|
|
42
46
|
|
|
43
47
|
t.type(debugMode, 'object')
|
|
44
48
|
t.type(debugMode.code, 'string')
|
|
45
49
|
t.ok(debugMode.ajv instanceof Ajv)
|
|
50
|
+
t.ok(debugMode.validator instanceof Validator)
|
|
46
51
|
|
|
47
52
|
const compiled = fjs.restore(debugMode)
|
|
48
53
|
const tobe = JSON.stringify({ firstName: 'Foo' })
|
|
@@ -50,7 +55,7 @@ test('to string auto-consistent', t => {
|
|
|
50
55
|
})
|
|
51
56
|
|
|
52
57
|
test('to string auto-consistent with ajv', t => {
|
|
53
|
-
t.plan(
|
|
58
|
+
t.plan(5)
|
|
54
59
|
|
|
55
60
|
const debugMode = fjs({
|
|
56
61
|
title: 'object with multiple types field',
|
|
@@ -69,6 +74,7 @@ test('to string auto-consistent with ajv', t => {
|
|
|
69
74
|
t.type(debugMode, 'object')
|
|
70
75
|
t.type(debugMode.code, 'string')
|
|
71
76
|
t.ok(debugMode.ajv instanceof Ajv)
|
|
77
|
+
t.ok(debugMode.validator instanceof Validator)
|
|
72
78
|
|
|
73
79
|
const compiled = fjs.restore(debugMode)
|
|
74
80
|
const tobe = JSON.stringify({ str: 'Foo' })
|
package/test/nullable.test.js
CHANGED
|
@@ -444,3 +444,100 @@ test('large array of nullable booleans with default mechanism', (t) => {
|
|
|
444
444
|
t.same(result, JSON.stringify(data))
|
|
445
445
|
t.same(JSON.parse(result), data)
|
|
446
446
|
})
|
|
447
|
+
|
|
448
|
+
test('nullable type in the schema', (t) => {
|
|
449
|
+
t.plan(2)
|
|
450
|
+
|
|
451
|
+
const schema = {
|
|
452
|
+
type: ['object', 'null'],
|
|
453
|
+
properties: {
|
|
454
|
+
foo: {
|
|
455
|
+
type: 'string'
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const stringify = build(schema)
|
|
461
|
+
|
|
462
|
+
const data = { foo: 'bar' }
|
|
463
|
+
|
|
464
|
+
t.same(stringify(data), JSON.stringify(data))
|
|
465
|
+
t.same(stringify(null), JSON.stringify(null))
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
test('throw an error if the value doesn\'t match the type', (t) => {
|
|
469
|
+
t.plan(2)
|
|
470
|
+
|
|
471
|
+
const schema = {
|
|
472
|
+
type: 'object',
|
|
473
|
+
additionalProperties: false,
|
|
474
|
+
required: ['data'],
|
|
475
|
+
properties: {
|
|
476
|
+
data: {
|
|
477
|
+
type: 'array',
|
|
478
|
+
minItems: 1,
|
|
479
|
+
items: {
|
|
480
|
+
oneOf: [
|
|
481
|
+
{
|
|
482
|
+
type: 'string'
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
type: 'number'
|
|
486
|
+
}
|
|
487
|
+
]
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
const stringify = build(schema)
|
|
494
|
+
|
|
495
|
+
const validData = { data: [1, 'testing'] }
|
|
496
|
+
t.equal(stringify(validData), JSON.stringify(validData))
|
|
497
|
+
|
|
498
|
+
const invalidData = { data: [false, 'testing'] }
|
|
499
|
+
t.throws(() => stringify(invalidData))
|
|
500
|
+
})
|
|
501
|
+
|
|
502
|
+
test('nullable value in oneOf', (t) => {
|
|
503
|
+
t.plan(1)
|
|
504
|
+
|
|
505
|
+
const schema = {
|
|
506
|
+
type: 'object',
|
|
507
|
+
properties: {
|
|
508
|
+
data: {
|
|
509
|
+
oneOf: [
|
|
510
|
+
{
|
|
511
|
+
type: 'array',
|
|
512
|
+
items: {
|
|
513
|
+
type: 'object',
|
|
514
|
+
properties: {
|
|
515
|
+
id: { type: 'integer', minimum: 1 }
|
|
516
|
+
},
|
|
517
|
+
additionalProperties: false,
|
|
518
|
+
required: ['id']
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
type: 'array',
|
|
523
|
+
items: {
|
|
524
|
+
type: 'object',
|
|
525
|
+
properties: {
|
|
526
|
+
job: { type: 'string', nullable: true }
|
|
527
|
+
},
|
|
528
|
+
additionalProperties: false,
|
|
529
|
+
required: ['job']
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
]
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
required: ['data'],
|
|
536
|
+
additionalProperties: false
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const stringify = build(schema)
|
|
540
|
+
|
|
541
|
+
const data = { data: [{ job: null }] }
|
|
542
|
+
t.equal(stringify(data), JSON.stringify(data))
|
|
543
|
+
})
|
package/test/ref.test.js
CHANGED
|
@@ -1926,3 +1926,58 @@ test('anyOf inside allOf', (t) => {
|
|
|
1926
1926
|
|
|
1927
1927
|
t.equal(output, JSON.stringify(object))
|
|
1928
1928
|
})
|
|
1929
|
+
|
|
1930
|
+
test('should resolve absolute $refs', (t) => {
|
|
1931
|
+
t.plan(1)
|
|
1932
|
+
|
|
1933
|
+
const externalSchema = {
|
|
1934
|
+
FooSchema: {
|
|
1935
|
+
$id: 'FooSchema',
|
|
1936
|
+
type: 'object',
|
|
1937
|
+
properties: {
|
|
1938
|
+
type: {
|
|
1939
|
+
anyOf: [
|
|
1940
|
+
{ type: 'string', const: 'bar' },
|
|
1941
|
+
{ type: 'string', const: 'baz' }
|
|
1942
|
+
]
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
const schema = { $ref: 'FooSchema' }
|
|
1949
|
+
|
|
1950
|
+
const object = { type: 'bar' }
|
|
1951
|
+
const stringify = build(schema, { schema: externalSchema })
|
|
1952
|
+
const output = stringify(object)
|
|
1953
|
+
|
|
1954
|
+
t.equal(output, JSON.stringify(object))
|
|
1955
|
+
})
|
|
1956
|
+
|
|
1957
|
+
test('nested schema should overwrite anchor scope', (t) => {
|
|
1958
|
+
t.plan(2)
|
|
1959
|
+
|
|
1960
|
+
const externalSchema = {
|
|
1961
|
+
root: {
|
|
1962
|
+
$id: 'root',
|
|
1963
|
+
definitions: {
|
|
1964
|
+
subschema: {
|
|
1965
|
+
$id: 'subschema',
|
|
1966
|
+
definitions: {
|
|
1967
|
+
anchorSchema: {
|
|
1968
|
+
$id: '#anchor',
|
|
1969
|
+
type: 'string'
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
const data = 'test'
|
|
1978
|
+
const stringify = build({ $ref: 'subschema#anchor' }, { schema: externalSchema })
|
|
1979
|
+
const output = stringify(data)
|
|
1980
|
+
|
|
1981
|
+
t.equal(output, JSON.stringify(data))
|
|
1982
|
+
t.throws(() => build({ $ref: 'root#anchor' }, { schema: externalSchema }))
|
|
1983
|
+
})
|
package/test/typesArray.test.js
CHANGED
|
@@ -438,6 +438,35 @@ test('object that is simultaneously a string and a json switched', (t) => {
|
|
|
438
438
|
t.equal(valueObj, '{"simultaneously":{"foo":"hello"}}')
|
|
439
439
|
})
|
|
440
440
|
|
|
441
|
+
test('class instance that is simultaneously a string and a json', (t) => {
|
|
442
|
+
t.plan(2)
|
|
443
|
+
|
|
444
|
+
const schema = {
|
|
445
|
+
type: 'object',
|
|
446
|
+
properties: {
|
|
447
|
+
simultaneously: {
|
|
448
|
+
type: ['string', 'object'],
|
|
449
|
+
properties: {
|
|
450
|
+
foo: { type: 'string' }
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
class Test {
|
|
457
|
+
toString () { return 'hello' }
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const likeObjectId = new Test()
|
|
461
|
+
|
|
462
|
+
const stringify = build(schema)
|
|
463
|
+
const valueStr = stringify({ simultaneously: likeObjectId })
|
|
464
|
+
t.equal(valueStr, '{"simultaneously":"hello"}')
|
|
465
|
+
|
|
466
|
+
const valueObj = stringify({ simultaneously: { foo: likeObjectId } })
|
|
467
|
+
t.equal(valueObj, '{"simultaneously":{"foo":"hello"}}')
|
|
468
|
+
})
|
|
469
|
+
|
|
441
470
|
test('should throw an error when type is array and object is null', (t) => {
|
|
442
471
|
t.plan(1)
|
|
443
472
|
const schema = {
|