import { TypeAssertion, ObjectAssertion, AdditionalPropsMember, ValidationContext } from '../types'; import { validate, getType } from '../validator'; import { compile } from '../compiler'; import { serialize, deserialize } from '../serializer'; describe("compiler-6", function() { it("compiler-error-reporting-1", function() { const schema = compile(` @msgId('MSG_A') interface A { @msgId('MSG_A.a1') a1: string; @msgId('MSG_A.a2') a2?: number; /** Comment A.a3 */ @msgId('MSG_A.a3') a3: string[]; /** Comment A.a4 */ @msgId('MSG_A.a4') [propNames: string]: any; } /** Comment B */ @msgId('MSG_B') interface B { @msgId('MSG_B.b1') b1: boolean; /** Comment B.b2 */ @msgId('MSG_B.b2') b2: A; } @msgId('MSG_C') interface C extends A { @msgId('MSG_C.c1') c1: string; } /** Comment D */ @msgId('MSG_D') type D = string; /** Comment E */ @msgId('MSG_E') enum E { P, Q, R, } `); { expect(Array.from(schema.keys())).toEqual([ 'A', 'B', 'C', 'D', 'E', ]); } { // const ty = getType(schema, 'A'); for (const ty of [getType(deserialize(serialize(schema)), 'A'), getType(schema, 'A')]) { expect(false).toEqual(schema.get('A')?.exported as any); const rhs: TypeAssertion = { name: 'A', typeName: 'A', kind: 'object', members: [ ['a1', { name: 'a1', kind: 'primitive', primitiveName: 'string', messageId: 'MSG_A.a1', }], ['a2', { name: 'a2', kind: 'optional', optional: { kind: 'primitive', primitiveName: 'number', messageId: 'MSG_A.a2', }, messageId: 'MSG_A.a2', }], ['a3', { name: 'a3', kind: 'repeated', min: null, max: null, repeated: { kind: 'primitive', primitiveName: 'string', }, messageId: 'MSG_A.a3', }, false, 'Comment A.a3'], ], additionalProps: [ [['string'], { kind: 'any', messageId: 'MSG_A.a4', }, false, 'Comment A.a4'], ], messageId: 'MSG_A', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'B'); for (const ty of [getType(deserialize(serialize(schema)), 'B'), getType(schema, 'B')]) { expect(false).toEqual(schema.get('B')?.exported as any); const rhs: TypeAssertion = { name: 'B', typeName: 'B', kind: 'object', members: [ ['b1', { name: 'b1', kind: 'primitive', primitiveName: 'boolean', messageId: 'MSG_B.b1', }], ['b2', { name: 'b2', typeName: 'A', kind: 'object', members: [...(getType(schema, 'A') as ObjectAssertion).members], additionalProps: [...((getType(schema, 'A') as ObjectAssertion).additionalProps as AdditionalPropsMember[])], messageId: 'MSG_B.b2', }, false, 'Comment B.b2'], ], messageId: 'MSG_B', docComment: 'Comment B', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'C'); for (const ty of [getType(deserialize(serialize(schema)), 'C'), getType(schema, 'C')]) { expect(false).toEqual(schema.get('C')?.exported as any); const rhs: TypeAssertion = { name: 'C', typeName: 'C', kind: 'object', members: [ ['c1', { name: 'c1', kind: 'primitive', primitiveName: 'string', messageId: 'MSG_C.c1', }], ['a1', { name: 'a1', kind: 'primitive', primitiveName: 'string', messageId: 'MSG_A.a1', }, true], ['a2', { name: 'a2', kind: 'optional', optional: { kind: 'primitive', primitiveName: 'number', messageId: 'MSG_A.a2', }, messageId: 'MSG_A.a2', }, true], ['a3', { name: 'a3', kind: 'repeated', min: null, max: null, repeated: { kind: 'primitive', primitiveName: 'string', }, messageId: 'MSG_A.a3', }, true, 'Comment A.a3'], ], baseTypes: [ getType(schema, 'A') as any, ], additionalProps: [ [['string'], { kind: 'any', messageId: 'MSG_A.a4', }, true, 'Comment A.a4'] ], messageId: 'MSG_C', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'D'); for (const ty of [getType(deserialize(serialize(schema)), 'D'), getType(schema, 'D')]) { expect(false).toEqual(schema.get('D')?.exported as any); const rhs: TypeAssertion = { name: 'D', typeName: 'D', kind: 'primitive', primitiveName: 'string', messageId: 'MSG_D', docComment: 'Comment D', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'E'); for (const ty of [getType(deserialize(serialize(schema)), 'E'), getType(schema, 'E')]) { expect(false).toEqual(schema.get('E')?.exported as any); const rhs: TypeAssertion = { name: 'E', typeName: 'E', kind: 'enum', values: [ ['P', 0], ['Q', 1], ['R', 2], ], messageId: 'MSG_E', docComment: 'Comment E', }; expect(ty).toEqual(rhs); } } }); it("compiler-error-reporting-2", function() { const schema = compile(` @msgId('MSG_A') export interface A { @msgId('MSG_A.a1') a1: string; @msgId('MSG_A.a2') a2?: number; /** Comment A.a3 */ @msgId('MSG_A.a3') a3: string[]; /** Comment A.a4 */ @msgId('MSG_A.a4') [propNames: string]: any; } /** Comment B */ @msgId('MSG_B') export interface B { @msgId('MSG_B.b1') b1: boolean; /** Comment B.b2 */ @msgId('MSG_B.b2') b2: A; } @msgId('MSG_C') export interface C extends A { @msgId('MSG_C.c1') c1: string; } /** Comment D */ @msgId('MSG_D') export type D = string; /** Comment E */ @msgId('MSG_E') export enum E { P, Q, R, } `); { expect(Array.from(schema.keys())).toEqual([ 'A', 'B', 'C', 'D', 'E', ]); } { // const ty = getType(schema, 'A'); for (const ty of [getType(deserialize(serialize(schema)), 'A'), getType(schema, 'A')]) { expect(true).toEqual(schema.get('A')?.exported as any); const rhs: TypeAssertion = { name: 'A', typeName: 'A', kind: 'object', members: [ ['a1', { name: 'a1', kind: 'primitive', primitiveName: 'string', messageId: 'MSG_A.a1', }], ['a2', { name: 'a2', kind: 'optional', optional: { kind: 'primitive', primitiveName: 'number', messageId: 'MSG_A.a2', }, messageId: 'MSG_A.a2', }], ['a3', { name: 'a3', kind: 'repeated', min: null, max: null, repeated: { kind: 'primitive', primitiveName: 'string', }, messageId: 'MSG_A.a3', }, false, 'Comment A.a3'], ], additionalProps: [ [['string'], { kind: 'any', messageId: 'MSG_A.a4', }, false, 'Comment A.a4'], ], messageId: 'MSG_A', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'B'); for (const ty of [getType(deserialize(serialize(schema)), 'B'), getType(schema, 'B')]) { expect(true).toEqual(schema.get('B')?.exported as any); const rhs: TypeAssertion = { name: 'B', typeName: 'B', kind: 'object', members: [ ['b1', { name: 'b1', kind: 'primitive', primitiveName: 'boolean', messageId: 'MSG_B.b1', }], ['b2', { name: 'b2', typeName: 'A', kind: 'object', members: [...(getType(schema, 'A') as ObjectAssertion).members], additionalProps: [...((getType(schema, 'A') as ObjectAssertion).additionalProps as AdditionalPropsMember[])], messageId: 'MSG_B.b2', }, false, 'Comment B.b2'], ], messageId: 'MSG_B', docComment: 'Comment B', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'C'); for (const ty of [getType(deserialize(serialize(schema)), 'C'), getType(schema, 'C')]) { expect(true).toEqual(schema.get('C')?.exported as any); const rhs: TypeAssertion = { name: 'C', typeName: 'C', kind: 'object', members: [ ['c1', { name: 'c1', kind: 'primitive', primitiveName: 'string', messageId: 'MSG_C.c1', }], ['a1', { name: 'a1', kind: 'primitive', primitiveName: 'string', messageId: 'MSG_A.a1', }, true], ['a2', { name: 'a2', kind: 'optional', optional: { kind: 'primitive', primitiveName: 'number', messageId: 'MSG_A.a2', }, messageId: 'MSG_A.a2', }, true], ['a3', { name: 'a3', kind: 'repeated', min: null, max: null, repeated: { kind: 'primitive', primitiveName: 'string', }, messageId: 'MSG_A.a3', }, true, 'Comment A.a3'], ], baseTypes: [ getType(schema, 'A') as any, ], additionalProps: [ [['string'], { kind: 'any', messageId: 'MSG_A.a4', }, true, 'Comment A.a4'] ], messageId: 'MSG_C', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'D'); for (const ty of [getType(deserialize(serialize(schema)), 'D'), getType(schema, 'D')]) { expect(true).toEqual(schema.get('D')?.exported as any); const rhs: TypeAssertion = { name: 'D', typeName: 'D', kind: 'primitive', primitiveName: 'string', messageId: 'MSG_D', docComment: 'Comment D', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'E'); for (const ty of [getType(deserialize(serialize(schema)), 'E'), getType(schema, 'E')]) { expect(true).toEqual(schema.get('E')?.exported as any); const rhs: TypeAssertion = { name: 'E', typeName: 'E', kind: 'enum', values: [ ['P', 0], ['Q', 1], ['R', 2], ], messageId: 'MSG_E', docComment: 'Comment E', }; expect(ty).toEqual(rhs); } } }); it("compiler-error-reporting-3", function() { const schema = compile(` @msg('MSG_A') interface A { @msg('MSG_A.a1') a1: string; @msg('MSG_A.a2') a2?: number; /** Comment A.a3 */ @msg('MSG_A.a3') a3: string[]; /** Comment A.a4 */ @msg('MSG_A.a4') [propNames: string]: any; } /** Comment B */ @msg('MSG_B') interface B { @msg('MSG_B.b1') b1: boolean; /** Comment B.b2 */ @msg('MSG_B.b2') b2: A; } @msg('MSG_C') interface C extends A { @msg('MSG_C.c1') c1: string; } /** Comment D */ @msg('MSG_D') type D = string; /** Comment E */ @msg('MSG_E') enum E { P, Q, R, } `); { expect(Array.from(schema.keys())).toEqual([ 'A', 'B', 'C', 'D', 'E', ]); } { // const ty = getType(schema, 'A'); for (const ty of [getType(deserialize(serialize(schema)), 'A'), getType(schema, 'A')]) { expect(false).toEqual(schema.get('A')?.exported as any); const rhs: TypeAssertion = { name: 'A', typeName: 'A', kind: 'object', members: [ ['a1', { name: 'a1', kind: 'primitive', primitiveName: 'string', message: 'MSG_A.a1', }], ['a2', { name: 'a2', kind: 'optional', optional: { kind: 'primitive', primitiveName: 'number', message: 'MSG_A.a2', }, message: 'MSG_A.a2', }], ['a3', { name: 'a3', kind: 'repeated', min: null, max: null, repeated: { kind: 'primitive', primitiveName: 'string', }, message: 'MSG_A.a3', }, false, 'Comment A.a3'], ], additionalProps: [ [['string'], { kind: 'any', message: 'MSG_A.a4', }, false, 'Comment A.a4'], ], message: 'MSG_A', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'B'); for (const ty of [getType(deserialize(serialize(schema)), 'B'), getType(schema, 'B')]) { expect(false).toEqual(schema.get('B')?.exported as any); const rhs: TypeAssertion = { name: 'B', typeName: 'B', kind: 'object', members: [ ['b1', { name: 'b1', kind: 'primitive', primitiveName: 'boolean', message: 'MSG_B.b1', }], ['b2', { name: 'b2', typeName: 'A', kind: 'object', members: [...(getType(schema, 'A') as ObjectAssertion).members], additionalProps: [...((getType(schema, 'A') as ObjectAssertion).additionalProps as AdditionalPropsMember[])], message: 'MSG_B.b2', }, false, 'Comment B.b2'], ], message: 'MSG_B', docComment: 'Comment B', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'C'); for (const ty of [getType(deserialize(serialize(schema)), 'C'), getType(schema, 'C')]) { expect(false).toEqual(schema.get('C')?.exported as any); const rhs: TypeAssertion = { name: 'C', typeName: 'C', kind: 'object', members: [ ['c1', { name: 'c1', kind: 'primitive', primitiveName: 'string', message: 'MSG_C.c1', }], ['a1', { name: 'a1', kind: 'primitive', primitiveName: 'string', message: 'MSG_A.a1', }, true], ['a2', { name: 'a2', kind: 'optional', optional: { kind: 'primitive', primitiveName: 'number', message: 'MSG_A.a2', }, message: 'MSG_A.a2', }, true], ['a3', { name: 'a3', kind: 'repeated', min: null, max: null, repeated: { kind: 'primitive', primitiveName: 'string', }, message: 'MSG_A.a3', }, true, 'Comment A.a3'], ], baseTypes: [ getType(schema, 'A') as any, ], additionalProps: [ [['string'], { kind: 'any', message: 'MSG_A.a4', }, true, 'Comment A.a4'] ], message: 'MSG_C', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'D'); for (const ty of [getType(deserialize(serialize(schema)), 'D'), getType(schema, 'D')]) { expect(false).toEqual(schema.get('D')?.exported as any); const rhs: TypeAssertion = { name: 'D', typeName: 'D', kind: 'primitive', primitiveName: 'string', message: 'MSG_D', docComment: 'Comment D', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'E'); for (const ty of [getType(deserialize(serialize(schema)), 'E'), getType(schema, 'E')]) { expect(false).toEqual(schema.get('E')?.exported as any); const rhs: TypeAssertion = { name: 'E', typeName: 'E', kind: 'enum', values: [ ['P', 0], ['Q', 1], ['R', 2], ], message: 'MSG_E', docComment: 'Comment E', }; expect(ty).toEqual(rhs); } } }); it("compiler-error-reporting-4", function() { const schema = compile(` @msg('MSG_A') export interface A { @msg('MSG_A.a1') a1: string; @msg('MSG_A.a2') a2?: number; /** Comment A.a3 */ @msg('MSG_A.a3') a3: string[]; /** Comment A.a4 */ @msg('MSG_A.a4') [propNames: string]: any; } /** Comment B */ @msg('MSG_B') export interface B { @msg('MSG_B.b1') b1: boolean; /** Comment B.b2 */ @msg('MSG_B.b2') b2: A; } @msg('MSG_C') export interface C extends A { @msg('MSG_C.c1') c1: string; } /** Comment D */ @msg('MSG_D') export type D = string; /** Comment E */ @msg('MSG_E') export enum E { P, Q, R, } `); { expect(Array.from(schema.keys())).toEqual([ 'A', 'B', 'C', 'D', 'E', ]); } { // const ty = getType(schema, 'A'); for (const ty of [getType(deserialize(serialize(schema)), 'A'), getType(schema, 'A')]) { expect(true).toEqual(schema.get('A')?.exported as any); const rhs: TypeAssertion = { name: 'A', typeName: 'A', kind: 'object', members: [ ['a1', { name: 'a1', kind: 'primitive', primitiveName: 'string', message: 'MSG_A.a1', }], ['a2', { name: 'a2', kind: 'optional', optional: { kind: 'primitive', primitiveName: 'number', message: 'MSG_A.a2', }, message: 'MSG_A.a2', }], ['a3', { name: 'a3', kind: 'repeated', min: null, max: null, repeated: { kind: 'primitive', primitiveName: 'string', }, message: 'MSG_A.a3', }, false, 'Comment A.a3'], ], additionalProps: [ [['string'], { kind: 'any', message: 'MSG_A.a4', }, false, 'Comment A.a4'], ], message: 'MSG_A', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'B'); for (const ty of [getType(deserialize(serialize(schema)), 'B'), getType(schema, 'B')]) { expect(true).toEqual(schema.get('B')?.exported as any); const rhs: TypeAssertion = { name: 'B', typeName: 'B', kind: 'object', members: [ ['b1', { name: 'b1', kind: 'primitive', primitiveName: 'boolean', message: 'MSG_B.b1', }], ['b2', { name: 'b2', typeName: 'A', kind: 'object', members: [...(getType(schema, 'A') as ObjectAssertion).members], additionalProps: [...((getType(schema, 'A') as ObjectAssertion).additionalProps as AdditionalPropsMember[])], message: 'MSG_B.b2', }, false, 'Comment B.b2'], ], message: 'MSG_B', docComment: 'Comment B', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'C'); for (const ty of [getType(deserialize(serialize(schema)), 'C'), getType(schema, 'C')]) { expect(true).toEqual(schema.get('C')?.exported as any); const rhs: TypeAssertion = { name: 'C', typeName: 'C', kind: 'object', members: [ ['c1', { name: 'c1', kind: 'primitive', primitiveName: 'string', message: 'MSG_C.c1', }], ['a1', { name: 'a1', kind: 'primitive', primitiveName: 'string', message: 'MSG_A.a1', }, true], ['a2', { name: 'a2', kind: 'optional', optional: { kind: 'primitive', primitiveName: 'number', message: 'MSG_A.a2', }, message: 'MSG_A.a2', }, true], ['a3', { name: 'a3', kind: 'repeated', min: null, max: null, repeated: { kind: 'primitive', primitiveName: 'string', }, message: 'MSG_A.a3', }, true, 'Comment A.a3'], ], baseTypes: [ getType(schema, 'A') as any, ], additionalProps: [ [['string'], { kind: 'any', message: 'MSG_A.a4', }, true, 'Comment A.a4'] ], message: 'MSG_C', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'D'); for (const ty of [getType(deserialize(serialize(schema)), 'D'), getType(schema, 'D')]) { expect(true).toEqual(schema.get('D')?.exported as any); const rhs: TypeAssertion = { name: 'D', typeName: 'D', kind: 'primitive', primitiveName: 'string', message: 'MSG_D', docComment: 'Comment D', }; expect(ty).toEqual(rhs); } } { // const ty = getType(schema, 'E'); for (const ty of [getType(deserialize(serialize(schema)), 'E'), getType(schema, 'E')]) { expect(true).toEqual(schema.get('E')?.exported as any); const rhs: TypeAssertion = { name: 'E', typeName: 'E', kind: 'enum', values: [ ['P', 0], ['Q', 1], ['R', 2], ], message: 'MSG_E', docComment: 'Comment E', }; expect(ty).toEqual(rhs); } } }); });