import { TypeAssertion, ObjectAssertion, AdditionalPropsMember, ValidationContext, ErrorMessages } from '../types'; import { validate, getType } from '../validator'; import { compile } from '../compiler'; import { serialize, deserialize } from '../serializer'; describe("compiler-8", function() { const myMessages: ErrorMessages = { invalidDefinition: ':invalidDefinition: %{name} %{parentType}', required: ':required: %{name} %{parentType}', typeUnmatched: ':typeUnmatched: %{name} %{parentType} %{expectedType}', additionalPropUnmatched: ':additionalPropUnmatched %{name} %{parentType}', repeatQtyUnmatched: ':repeatQtyUnmatched: %{name} %{parentType} %{repeatQty}', sequenceUnmatched: ':sequenceUnmatched: %{name} %{parentType}', valueRangeUnmatched: ':valueRangeUnmatched: %{name} %{parentType} %{minValue} %{maxValue}', valuePatternUnmatched: ':valuePatternUnmatched: %{name} %{parentType} %{pattern}', valueLengthUnmatched: ':valueLengthUnmatched: %{name} %{parentType} %{minLength} %{maxLength}', valueUnmatched: ':valueUnmatched: %{name} %{parentType} %{expectedValue}', }; function mkmsgobj(s: string): ErrorMessages { const m: ErrorMessages = { invalidDefinition: s + myMessages.invalidDefinition, required: s + myMessages.required, typeUnmatched: s + myMessages.typeUnmatched, repeatQtyUnmatched: s + myMessages.repeatQtyUnmatched, sequenceUnmatched: s + myMessages.sequenceUnmatched, valueRangeUnmatched: s + myMessages.valueRangeUnmatched, valuePatternUnmatched: s + myMessages.valuePatternUnmatched, valueLengthUnmatched: s + myMessages.valueLengthUnmatched, valueUnmatched: s + myMessages.valueUnmatched, }; return m; } function mkmsg(s: string): string { return JSON.stringify(mkmsgobj(s)); } it("compiler-error-reporting-reporter-2-1", function() { // no tests (single type test pattern of compiler-error-reporting-reporter-1-1) }); it("compiler-error-reporting-reporter-2-2", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = string; `), compile(` export type A = @msg(${mkmsg('A')}) string; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate(1, getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'TypeUnmatched', message: 'A:typeUnmatched: ? A string', dataPath: 'A', constraints: {}, value: 1, }]); } }); it("compiler-error-reporting-reporter-2-2b", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = string; `), compile(` export type A = @msg(${mkmsg('A')}) string; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate([1], getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'TypeUnmatched', message: 'A:typeUnmatched: ? A string', // TODO: dataPath: 'A', constraints: {}, }]); } }); it("compiler-error-reporting-reporter-2-2c", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = string[]; `), compile(` export type A = @msg(${mkmsg('A')}) (string[]); `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate('1', getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'TypeUnmatched', message: 'A:typeUnmatched: ? A (repeated string)', // TODO: dataPath: 'A', constraints: {}, value: '1', }]); } }); it("compiler-error-reporting-reporter-2-2d", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = string[]; `), compile(` export type A = @msg(${mkmsg('A')}) (string[]); `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate([1], getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'TypeUnmatched', message: '"repeated item of ?" of "A" should be type "string".', // TODO: custom error message is ignored dataPath: 'A.(0:repeated)', constraints: {}, value: 1, }]); } }); it("compiler-error-reporting-reporter-2-2e", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = [string]; `), compile(` export type A = @msg(${mkmsg('A')}) [string]; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate('1', getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'TypeUnmatched', message: 'A:typeUnmatched: ? A (sequence)', // TODO: dataPath: 'A', constraints: {}, value: '1', }]); } }); it("compiler-error-reporting-reporter-2-2f", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = [string]; `), compile(` export type A = @msg(${mkmsg('A')}) [string]; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate([1], getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'TypeUnmatched', message: '"sequence item of ?" of "A" should be type "string".', // TODO: custom error message is ignored dataPath: 'A.(0:sequence)', constraints: {}, value: 1, }]); } }); it("compiler-error-reporting-reporter-2-3", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = @range(3, 5) number; `), compile(` export type A = @msg(${mkmsg('A')}) @range(3, 5) number; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate(1, getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'ValueRangeUnmatched', message: 'A:valueRangeUnmatched: ? A 3 5', // TODO: dataPath: 'A', constraints: {minValue: 3, maxValue: 5}, value: 1, }]); } }); it("compiler-error-reporting-reporter-2-4", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = @minLength(3) @maxLength(5) string; `), compile(` export type A = @msg(${mkmsg('A')}) @minLength(3) @maxLength(5) string; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate('1', getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'ValueLengthUnmatched', message: 'A:valueLengthUnmatched: ? A 3 5', dataPath: 'A', constraints: {minLength: 3, maxLength: 5}, value: '1', }]); } }); it("compiler-error-reporting-reporter-2-5", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = @match(/^[0-9]+$/) string; `), compile(` export type A = @msg(${mkmsg('A')}) @match(/^[0-9]+$/) string; `)]; for (const schema of schemas) { for (const ty of [getType(deserialize(serialize(schema)), 'A'), getType(schema, 'A')]) { const ctx: Partial = { checkAll: true, schema, }; expect(validate('A', ty, ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'ValuePatternUnmatched', message: 'A:valuePatternUnmatched: ? A /^[0-9]+$/', dataPath: 'A', constraints: {pattern: '/^[0-9]+$/'}, value: 'A', }]); } } }); it("compiler-error-reporting-reporter-2-5b", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = @match(/^[0-9]+$/gi) string; `), compile(` export type A = @msg(${mkmsg('A')}) @match(/^[0-9]+$/gi) string; `)]; for (const schema of schemas) { for (const ty of [getType(deserialize(serialize(schema)), 'A'), getType(schema, 'A')]) { const ctx: Partial = { checkAll: true, schema, }; expect(validate('A', ty, ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'ValuePatternUnmatched', message: 'A:valuePatternUnmatched: ? A /^[0-9]+$/gi', dataPath: 'A', constraints: {pattern: '/^[0-9]+$/gi'}, value: 'A', }]); } } }); it("compiler-error-reporting-reporter-2-6", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = 5; `), compile(` export type A = @msg(${mkmsg('A')}) 5; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate(4, getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'ValueUnmatched', message: 'A:valueUnmatched: ? A 5', dataPath: 'A', constraints: {}, value: 4, }]); } }); it("compiler-error-reporting-reporter-2-7a", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = [...]; `), compile(` export type A = @msg(${mkmsg('A')}) [...]; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate([1], getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'TypeUnmatched', // TODO: expect SequenceUnmatched? message: '"sequence item of ?" of "A" should be type "string".', // TODO: custom error message is ignored dataPath: 'A.(0:sequence)', constraints: {min: 3, max: 5}, }]); } }); it("compiler-error-reporting-reporter-2-7b", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = [...]; `), compile(` export type A = @msg(${mkmsg('A')}) [...]; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate(['1', '2'], getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'RepeatQtyUnmatched', message: '"sequence item of ?" of "A" should repeat 3..5 times.', // TODO: custom error message is ignored dataPath: 'A.(2:sequence)', constraints: {min: 3, max: 5}, }]); } }); it("compiler-error-reporting-reporter-2-7c", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = [string?]; `), compile(` export type A = @msg(${mkmsg('A')}) [string?]; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate([1], getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'SequenceUnmatched', message: 'A:sequenceUnmatched: ? A', dataPath: 'A', constraints: {}, }]); } }); it("compiler-error-reporting-reporter-2-7d", function() { const schemas = [compile(` @msg(${mkmsg('A')}) export type A = [string?]; `), compile(` export type A = @msg(${mkmsg('A')}) [string?]; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, }; expect(validate(['1', '2'], getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'RepeatQtyUnmatched', message: '"sequence item of ?" of "A" should repeat 0..1 times.', // TODO: custom error message is ignored dataPath: 'A.(2:sequence)', constraints: {}, }]); } }); it("compiler-error-reporting-reporter-3", function() { const schemas = [compile(` export type A = string; `)]; for (const schema of schemas) { const ctx: Partial = { checkAll: true, schema, errorMessages: mkmsgobj('G'), }; expect(validate(1, getType(schema, 'A'), ctx)).toEqual(null); expect(ctx.errors).toEqual([{ code: 'TypeUnmatched', message: 'G:typeUnmatched: ? A string', dataPath: 'A', constraints: {}, value: 1, }]); } }); });