diff --git a/test/anyof.test.js b/test/anyof.test.js index baa81060..b359761a 100644 --- a/test/anyof.test.js +++ b/test/anyof.test.js @@ -790,3 +790,23 @@ test('should build merged schemas twice', (t) => { t.assert.equal(stringify({ enums: 'BAR' }), '{"enums":"BAR"}') } }) + +test('invalid anyOf schema', (t) => { + t.plan(1) + + const schema = { + type: 'object', + properties: { + prop: { + anyOf: 'not array' // invalid, anyOf must be array + } + } + } + + try { + build(schema) + t.assert.fail('Should throw') + } catch (err) { + t.assert.ok(err.message.includes('schema is invalid')) + } +}) diff --git a/test/array.test.js b/test/array.test.js index dc643226..c00ef7e9 100644 --- a/test/array.test.js +++ b/test/array.test.js @@ -358,6 +358,28 @@ test('array items is a schema and additionalItems is false', (t) => { t.assert.equal(validate({ foo: ['foo', 'bar'] }), true) }) +test('array items is a list of schema and additionalItems is a schema', (t) => { + t.plan(1) + + const schema = { + type: 'object', + properties: { + foo: { + type: 'array', + items: [ + { type: 'string' } + ], + additionalItems: { type: 'number' } + } + } + } + + const stringify = build(schema) + const result = stringify({ foo: ['foo', 42] }) + + t.assert.equal(result, '{"foo":["foo",42]}') +}) + // https://github.com/fastify/fast-json-stringify/issues/279 test('object array with anyOf and symbol', (t) => { t.plan(1) diff --git a/test/debug-mode.test.js b/test/debug-mode.test.js index 3e998a73..f6756bfe 100644 --- a/test/debug-mode.test.js +++ b/test/debug-mode.test.js @@ -119,3 +119,24 @@ test('debug should restore the same serializer instance', t => { const compiled = fjs.restore(debugMode) t.assert.equal(compiled(3.95), 4) }) + +test('Serializer restoreFromState', t => { + t.plan(1) + + const Serializer = require('../lib/serializer') + const serializer = new Serializer() + const state = serializer.getState() + const restored = Serializer.restoreFromState(state) + t.assert.ok(restored instanceof Serializer) +}) + +test('Validator restoreFromState', t => { + t.plan(1) + + const Validator = require('../lib/validator') + const validator = new Validator() + validator.addSchema({ type: 'string' }, 'test') + const state = validator.getState() + const restored = Validator.restoreFromState(state) + t.assert.ok(restored instanceof Validator) +}) diff --git a/test/if-then-else.test.js b/test/if-then-else.test.js index dfe25e9b..804669e8 100644 --- a/test/if-then-else.test.js +++ b/test/if-then-else.test.js @@ -466,3 +466,75 @@ test('external recursive if/then/else', (t) => { const stringify = build(schema, { schema: { externalSchema } }) t.assert.equal(stringify(data), '{"a":{"base":"a","bar":"42"},"b":{"base":"b","baz":"43"}}') }) + +test('invalid if-then-else schema', (t) => { + t.plan(1) + + const schema = { + type: 'object', + if: { + type: 'object', + properties: { + kind: { type: 'string', enum: ['foobar'] } + } + }, + then: { + type: 'object', + properties: { + foo: { type: 'string' } + } + }, + else: { + type: 'object', + properties: 'invalid' // properties must be object + } + } + + try { + build(schema) + t.assert.fail('Should throw') + } catch (err) { + t.assert.ok(err.message.includes('schema is invalid')) + } +}) + +test('if-then-else with allOf', (t) => { + t.plan(2) + + const schema = { + type: 'object', + allOf: [ + { + type: 'object', + properties: { + base: { type: 'string' } + } + } + ], + if: { + type: 'object', + properties: { + kind: { type: 'string', enum: ['foobar'] } + } + }, + then: { + type: 'object', + properties: { + foo: { type: 'string' } + } + }, + else: { + type: 'object', + properties: { + bar: { type: 'string' } + } + } + } + + const stringify = build(schema) + const data = { base: 'test', kind: 'foobar', foo: 'value' } + const output = stringify(data) + + t.assert.doesNotThrow(() => JSON.parse(output)) + t.assert.equal(output, '{"base":"test","foo":"value"}') +}) diff --git a/test/invalidSchema.test.js b/test/invalidSchema.test.js index 4402484b..966b6d79 100644 --- a/test/invalidSchema.test.js +++ b/test/invalidSchema.test.js @@ -16,3 +16,23 @@ test('Should throw on invalid schema', t => { }) }, { message: /^"invalid" schema is invalid:.*/ }) }) + +test('invalid not schema', (t) => { + t.plan(1) + + const schema = { + type: 'object', + properties: { + prop: { + not: 'not object' // invalid, not must be object + } + } + } + + try { + build(schema) + t.assert.fail('Should throw') + } catch (err) { + t.assert.ok(err.message.includes('schema is invalid')) + } +}) diff --git a/test/oneof.test.js b/test/oneof.test.js index f3b29f4b..01c2f3bf 100644 --- a/test/oneof.test.js +++ b/test/oneof.test.js @@ -488,3 +488,23 @@ test('all array items does not match oneOf types', (t) => { t.assert.throws(() => stringify({ data: [null, false, true, undefined, [], {}] })) }) + +test('invalid oneOf schema', (t) => { + t.plan(1) + + const schema = { + type: 'object', + properties: { + prop: { + oneOf: 'not array' // invalid, oneOf must be array + } + } + } + + try { + build(schema) + t.assert.fail('Should throw') + } catch (err) { + t.assert.ok(err.message.includes('schema is invalid')) + } +}) diff --git a/test/ref.test.js b/test/ref.test.js index eae4703a..2f736445 100644 --- a/test/ref.test.js +++ b/test/ref.test.js @@ -2044,3 +2044,34 @@ test('ref internal - throw if schema has definition twice with different shape', t.assert.equal(err.message, 'There is already another anchor "#uri" in schema "test".') } }) + +test('ref nested', (t) => { + t.plan(2) + + const schema = { + definitions: { + def1: { + $ref: '#/definitions/def2' + }, + def2: { + type: 'string' + } + }, + type: 'object', + properties: { + str: { + $ref: '#/definitions/def1' + } + } + } + + const object = { + str: 'test' + } + + const stringify = build(schema) + const output = stringify(object) + + t.assert.doesNotThrow(() => JSON.parse(output)) + t.assert.equal(output, '{"str":"test"}') +})