import { DiffTestCase, registerDiffTestCases, } from '../support/register-diff-test-cases'; describe('diff-schemas not', () => { describe('general', () => { const testCases: DiffTestCase[] = [ { description: 'all types but string is changed to equivalent not string', examples: ['foo', true], input: { a: { type: ['array', 'boolean', 'integer', 'null', 'number', 'object'], }, b: { not: { type: 'string', }, }, }, output: { added: false, removed: false, }, }, { description: 'double negation: nothing accepted to not not string', examples: ['foo', true], input: { a: false, b: { not: { not: { type: 'string', }, }, }, }, output: { added: { type: 'string', }, removed: false, }, }, ]; registerDiffTestCases(testCases); }); describe('arrays', () => { const testCases: DiffTestCase[] = [ { description: 'from array with minItems constraint to array with the complement of that constraint', examples: [[], [1], [1, 2], [1, 2, 3], 'foo'], input: { a: { minItems: 2, type: 'array', }, b: { not: { minItems: 2, }, type: 'array', }, }, output: { added: { maxItems: 1, type: 'array', }, removed: { minItems: 2, type: 'array', }, }, }, { description: 'from array with items constraint to array with the complement of that constraint', examples: [[], [1], ['a'], ['a', 2], 'foo'], input: { a: { items: { type: 'string', }, type: 'array', }, b: { not: { items: { type: 'string', }, }, type: 'array', }, }, output: { added: { not: { items: { type: 'string', }, type: 'array', }, type: 'array', }, removed: { items: { type: 'string', }, type: 'array', }, }, }, { description: 'from array with minItems constraint to complement of entire schema', examples: [[], [1], [1, 2], [1, 2, 3], 'foo'], input: { a: { minItems: 2, type: 'array', }, b: { not: { minItems: 2, type: 'array', }, }, }, output: { added: { maxItems: 1, type: ['array', 'boolean', 'null', 'number', 'object', 'string'], }, removed: { minItems: 2, type: 'array', }, }, }, { description: 'two schemas containing different complemented partial arrays', examples: [ [], [1], ['a'], [true], ['a', 2], ['a', true], [2, true], ['a', 2, true], 'foo', ], input: { a: { not: { items: { type: 'string', }, }, type: 'array', }, b: { not: { items: { type: 'number', }, }, type: 'array', }, }, output: { added: { items: { type: 'string', }, not: { items: { type: 'number', }, type: 'array', }, type: 'array', }, removed: { items: { type: 'number', }, not: { items: { type: 'string', }, type: 'array', }, type: 'array', }, }, }, { description: 'array with items constraint changed to all types and a not constraint in arrays', examples: [ [], ['a'], [1], [true], [{}], ['a', 1], ['a', true], ['a', {}], [1, true], [1, {}], [true, {}], ['a', 1, true], ['a', 1, {}], ['a', true, {}], [1, true, {}], ['a', 1, true, {}], 'foo', true, 1, {}, ], input: { a: { items: { type: ['string', 'number'], }, type: 'array', }, b: { not: { items: { type: 'boolean', }, type: 'array', }, }, }, output: { added: { not: { anyOf: [ { items: { type: 'boolean', }, type: 'array', }, { items: { type: ['number', 'string'], }, type: 'array', }, ], }, type: ['array', 'boolean', 'null', 'number', 'object', 'string'], }, removed: { items: false, type: 'array', }, }, }, { description: 'DeMorgans with all and some arrays', examples: [[], [1], ['a'], ['a', 2], [true], 'foo', true], input: { a: { not: { allOf: [ { type: ['string', 'array'] }, { type: 'array', items: { type: 'string' } }, ], }, }, b: { anyOf: [ { not: { type: ['string', 'array'] } }, { not: { type: 'array', items: { type: 'string' } } }, ], }, }, output: { added: false, removed: false, }, }, { description: 'DeMorgans with some and some arrays', examples: [[], [1], ['a'], ['a', 2], [true], 'foo'], input: { a: { not: { allOf: [ { type: 'array', items: { type: 'string' } }, { type: 'array', items: { type: 'number' } }, ], }, }, b: { anyOf: [ { not: { type: 'array', items: { type: 'string' } } }, { not: { type: 'array', items: { type: 'number' } } }, ], }, }, output: { added: false, removed: false, }, }, ]; registerDiffTestCases(testCases); }); describe('objects', () => { const testCases: DiffTestCase[] = [ { description: 'from object with minProperties constraint to object with complement of that constraint', examples: [{}, { a: 1 }, { a: 1, b: 2 }, { a: 1, b: 2, c: 3 }, 'foo'], input: { a: { minProperties: 2, type: 'object', }, b: { not: { minProperties: 2, }, type: 'object', }, }, output: { added: { maxProperties: 1, type: 'object', }, removed: { minProperties: 2, type: 'object', }, }, }, { description: 'from object with additionalProperties to object with complement of that constraint', examples: [{}, { a: 1 }, { a: 'a' }, { a: 1, b: 'b' }, 'foo'], input: { a: { additionalProperties: { type: 'string', }, type: 'object', }, b: { not: { additionalProperties: { type: 'string', }, }, type: 'object', }, }, output: { added: { not: { additionalProperties: { type: 'string', }, type: 'object', }, type: 'object', }, removed: { additionalProperties: { type: 'string', }, type: 'object', }, }, }, { description: 'two schemas containing different complemented partial objects', examples: [ {}, { p1: 'foo' }, { p1: 1 }, { p1: true }, { p1: 'foo', p2: 1 }, { p1: 'foo', p2: true }, { p1: 1, p2: true }, { p1: 'foo', p2: 1, p3: true }, 'foo', ], input: { a: { not: { additionalProperties: { type: 'string', }, }, type: 'object', }, b: { not: { additionalProperties: { type: 'number', }, }, type: 'object', }, }, output: { added: { additionalProperties: { type: 'string', }, not: { additionalProperties: { type: 'number', }, type: 'object', }, type: 'object', }, removed: { additionalProperties: { type: 'number', }, not: { additionalProperties: { type: 'string', }, type: 'object', }, type: 'object', }, }, }, { description: 'a schema containing a contradiction between additionalProperties involving not + anyOf', examples: [ {}, { p1: 'foo' }, { p1: 1 }, { p1: true }, { p1: 'foo', p2: 1 }, { p1: 'foo', p2: true }, { p1: 1, p2: true }, { p1: 'foo', p2: 1, p3: true }, 'foo', ], input: { a: { additionalProperties: { type: 'string', }, not: { anyOf: [ { additionalProperties: { type: 'string', }, }, { additionalProperties: { type: 'number', }, }, ], }, type: 'object', }, b: false, }, output: { added: false, removed: false, }, }, ]; registerDiffTestCases(testCases); }); describe('numbers', () => { const testCases: DiffTestCase[] = [ { description: 'from numbers with integer constraint to numbers with the complement of that constraint', examples: [1, 1.5, 'foo'], input: { a: { type: 'integer', }, b: { not: { type: 'integer', }, type: 'number', }, }, output: { added: { not: { type: 'integer', }, type: 'number', }, removed: { type: 'integer', }, }, }, { description: 'from numbers with integer to double negation of integer', examples: [1, 1.5, 'foo'], input: { a: { type: 'integer', }, b: { not: { not: { type: 'integer', }, }, type: 'number', }, }, output: { added: false, removed: false, }, }, ]; registerDiffTestCases(testCases); }); });