You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
322 lines
5.6 KiB
322 lines
5.6 KiB
'use strict'
|
|
|
|
const moment = require('moment')
|
|
const test = require('tap').test
|
|
const validator = require('is-my-json-valid')
|
|
const build = require('..')
|
|
|
|
function buildTest (schema, toStringify) {
|
|
test(`render a ${schema.title} as JSON`, (t) => {
|
|
t.plan(3)
|
|
|
|
const validate = validator(schema)
|
|
const stringify = build(schema)
|
|
const output = stringify(toStringify)
|
|
|
|
t.same(JSON.parse(output), toStringify)
|
|
t.equal(output, JSON.stringify(toStringify))
|
|
t.ok(validate(JSON.parse(output)), 'valid schema')
|
|
})
|
|
}
|
|
|
|
buildTest({
|
|
title: 'string array',
|
|
type: 'object',
|
|
properties: {
|
|
ids: {
|
|
type: 'array',
|
|
items: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
ids: ['test']
|
|
})
|
|
|
|
buildTest({
|
|
title: 'number array',
|
|
type: 'object',
|
|
properties: {
|
|
ids: {
|
|
type: 'array',
|
|
items: {
|
|
type: 'number'
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
ids: [1]
|
|
})
|
|
|
|
buildTest({
|
|
title: 'mixed array',
|
|
type: 'object',
|
|
properties: {
|
|
ids: {
|
|
type: 'array',
|
|
items: [
|
|
{
|
|
type: 'null'
|
|
},
|
|
{
|
|
type: 'string'
|
|
},
|
|
{
|
|
type: 'integer'
|
|
},
|
|
{
|
|
type: 'number'
|
|
},
|
|
{
|
|
type: 'boolean'
|
|
},
|
|
{
|
|
type: 'object',
|
|
properties: {
|
|
a: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
type: 'array',
|
|
items: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}, {
|
|
ids: [null, 'test', 1, 1.1, true, { a: 'test' }, ['test']]
|
|
})
|
|
|
|
buildTest({
|
|
title: 'repeated types',
|
|
type: 'object',
|
|
properties: {
|
|
ids: {
|
|
type: 'array',
|
|
items: [
|
|
{
|
|
type: 'number'
|
|
},
|
|
{
|
|
type: 'number'
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}, { ids: [1, 2] })
|
|
|
|
buildTest({
|
|
title: 'pattern properties array',
|
|
type: 'object',
|
|
properties: {
|
|
args: {
|
|
type: 'array',
|
|
items: [
|
|
{
|
|
type: 'object',
|
|
patternProperties: {
|
|
'.*': {
|
|
type: 'string'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
type: 'object',
|
|
patternProperties: {
|
|
'.*': {
|
|
type: 'number'
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}, { args: [{ a: 'test' }, { b: 1 }] })
|
|
|
|
buildTest({
|
|
title: 'array with weird key',
|
|
type: 'object',
|
|
properties: {
|
|
'@data': {
|
|
type: 'array',
|
|
items: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
'@data': ['test']
|
|
})
|
|
|
|
test('invalid items throw', (t) => {
|
|
t.plan(1)
|
|
const schema = {
|
|
type: 'object',
|
|
properties: {
|
|
args: {
|
|
type: 'array',
|
|
items: [
|
|
{
|
|
type: 'object',
|
|
patternProperties: {
|
|
'.*': {
|
|
type: 'string'
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
const stringify = build(schema)
|
|
t.throws(() => stringify({ args: ['invalid'] }))
|
|
})
|
|
|
|
test('moment array', (t) => {
|
|
t.plan(1)
|
|
const schema = {
|
|
type: 'object',
|
|
properties: {
|
|
times: {
|
|
type: 'array',
|
|
items: {
|
|
type: 'string',
|
|
format: 'date-time'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const stringify = build(schema)
|
|
const value = stringify({
|
|
times: [moment('2018-04-21T07:52:31.017Z')]
|
|
})
|
|
t.equal(value, '{"times":["2018-04-21T07:52:31.017Z"]}')
|
|
})
|
|
|
|
buildTest({
|
|
title: 'item types in array default to any',
|
|
type: 'object',
|
|
properties: {
|
|
foo: {
|
|
type: 'array'
|
|
}
|
|
}
|
|
}, {
|
|
foo: [1, 'string', {}, null]
|
|
})
|
|
|
|
test('array items is a list of schema and additionalItems is true, just the described item is validated', (t) => {
|
|
t.plan(1)
|
|
|
|
const schema = {
|
|
type: 'object',
|
|
properties: {
|
|
foo: {
|
|
type: 'array',
|
|
items: [
|
|
{
|
|
type: 'string'
|
|
}
|
|
],
|
|
additionalItems: true
|
|
}
|
|
}
|
|
}
|
|
|
|
const stringify = build(schema)
|
|
const result = stringify({
|
|
foo: [
|
|
'foo',
|
|
'bar',
|
|
1
|
|
]
|
|
})
|
|
|
|
t.equal(result, '{"foo":["foo","bar",1]}')
|
|
})
|
|
|
|
test('array items is a list of schema and additionalItems is false', (t) => {
|
|
t.plan(1)
|
|
|
|
const schema = {
|
|
type: 'object',
|
|
properties: {
|
|
foo: {
|
|
type: 'array',
|
|
items: [
|
|
{
|
|
type: 'string'
|
|
}
|
|
],
|
|
additionalItems: false
|
|
}
|
|
}
|
|
}
|
|
|
|
const stringify = build(schema)
|
|
|
|
try {
|
|
stringify({
|
|
foo: [
|
|
'foo',
|
|
'bar'
|
|
]
|
|
})
|
|
t.fail()
|
|
} catch (error) {
|
|
t.ok(/does not match schema definition./.test(error.message))
|
|
}
|
|
})
|
|
|
|
// https://github.com/fastify/fast-json-stringify/issues/279
|
|
test('object array with anyOf and symbol', (t) => {
|
|
t.plan(1)
|
|
const ArrayKind = Symbol('ArrayKind')
|
|
const ObjectKind = Symbol('LiteralKind')
|
|
const UnionKind = Symbol('UnionKind')
|
|
const LiteralKind = Symbol('LiteralKind')
|
|
const StringKind = Symbol('StringKind')
|
|
|
|
const schema = {
|
|
kind: ArrayKind,
|
|
type: 'array',
|
|
items: {
|
|
kind: ObjectKind,
|
|
type: 'object',
|
|
properties: {
|
|
name: {
|
|
kind: StringKind,
|
|
type: 'string'
|
|
},
|
|
option: {
|
|
kind: UnionKind,
|
|
anyOf: [
|
|
{
|
|
kind: LiteralKind,
|
|
type: 'string',
|
|
enum: ['Foo']
|
|
},
|
|
{
|
|
kind: LiteralKind,
|
|
type: 'string',
|
|
enum: ['Bar']
|
|
}
|
|
]
|
|
}
|
|
},
|
|
required: ['name', 'option']
|
|
}
|
|
}
|
|
const stringify = build(schema)
|
|
const value = stringify([
|
|
{ name: 'name-0', option: 'Foo' },
|
|
{ name: 'name-1', option: 'Bar' }
|
|
])
|
|
t.equal(value, '[{"name":"name-0","option":"Foo"},{"name":"name-1","option":"Bar"}]')
|
|
})
|