import { TypeAssertion , ValidationContext } from '../types' ; import { validate , getType } from '../validator' ; import { pick , patch } from '../picker' ; import { compile } from '../compiler' ; import { generateTypeScriptCode } from '../codegen' ; import { serialize , deserialize } from '../serializer' ; describe ( "compiler-9" , function ( ) { it ( "compiler-import-statement-1" , function ( ) { const schemas = [ compile ( `
            import from 'foo';
            import * as foo from 'foo';
            import {\na, b as bb} from 'foo';
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ '__$$$gensym_0$$$__' , '__$$$gensym_1$$$__' , '__$$$gensym_2$$$__' , ] ) ; } for ( const schema of schemas ) { { const rhs = { kind : 'never' , passThruCodeBlock : `import from 'foo';` , } ; const ty = getType ( schema , '__$$$gensym_0$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `import * as foo from 'foo';` , } ; const ty = getType ( schema , '__$$$gensym_1$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `import {\na, b as bb} from 'foo';` , } ; const ty = getType ( schema , '__$$$gensym_2$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { expect ( generateTypeScriptCode ( schema ) . trim ( ) ) . toEqual ( `import from 'foo';\n\n` + `import * as foo from 'foo';\n\n` + `import {\na, b as bb} from 'foo';` ) ; } } } ) ; it ( "compiler-declare-statement-1" , function ( ) { const schemas = [ compile ( `
            declare var x: number;
            declare let y: number[];
            declare const z: \nnumber[][];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ '__$$$gensym_0$$$__' , '__$$$gensym_1$$$__' , '__$$$gensym_2$$$__' , ] ) ; } for ( const schema of schemas ) { { const rhs = { kind : 'never' , passThruCodeBlock : `declare var x: number;` , } ; const ty = getType ( schema , '__$$$gensym_0$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `declare let y: number[];` , } ; const ty = getType ( schema , '__$$$gensym_1$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `declare const z: \nnumber[][];` , } ; const ty = getType ( schema , '__$$$gensym_2$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { expect ( generateTypeScriptCode ( schema ) . trim ( ) ) . toEqual ( `declare var x: number;\n\n` + `declare let y: number[];\n\n` + `declare const z: \nnumber[][];` ) ; } } } ) ; it ( "compiler-declare-statement-1b" , function ( ) { const schemas = [ compile ( `
            /** comment1 */
            declare var x: number;
            /** comment2 */
            declare let y: number[];
            /** comment3 */
            declare const z: \nnumber[][];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ '__$$$gensym_0$$$__' , '__$$$gensym_1$$$__' , '__$$$gensym_2$$$__' , ] ) ; } for ( const schema of schemas ) { { const rhs = { kind : 'never' , passThruCodeBlock : `declare var x: number;` , docComment : 'comment1' , } ; const ty = getType ( schema , '__$$$gensym_0$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `declare let y: number[];` , docComment : 'comment2' , } ; const ty = getType ( schema , '__$$$gensym_1$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `declare const z: \nnumber[][];` , docComment : 'comment3' , } ; const ty = getType ( schema , '__$$$gensym_2$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { expect ( generateTypeScriptCode ( schema ) . trim ( ) ) . toEqual ( `/** comment1 */\ndeclare var x: number;\n\n` + `/** comment2 */\ndeclare let y: number[];\n\n` + `/** comment3 */\ndeclare const z: \nnumber[][];` ) ; } } } ) ; it ( "compiler-declare-statement-2" , function ( ) { const schemas = [ compile ( `
            export declare var x: number;
            export declare let y: number[];
            export declare const z: \nnumber[][];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ '__$$$gensym_0$$$__' , '__$$$gensym_1$$$__' , '__$$$gensym_2$$$__' , ] ) ; } for ( const schema of schemas ) { { const rhs = { kind : 'never' , passThruCodeBlock : `export declare var x: number;` , } ; const ty = getType ( schema , '__$$$gensym_0$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `export declare let y: number[];` , } ; const ty = getType ( schema , '__$$$gensym_1$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `export declare const z: \nnumber[][];` , } ; const ty = getType ( schema , '__$$$gensym_2$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { expect ( generateTypeScriptCode ( schema ) . trim ( ) ) . toEqual ( `export declare var x: number;\n\n` + `export declare let y: number[];\n\n` + `export declare const z: \nnumber[][];` ) ; } } } ) ; it ( "compiler-declare-statement-2b" , function ( ) { const schemas = [ compile ( `
            /** comment1 */
            export declare var x: number;
            /** comment2 */
            export declare let y: number[];
            /** comment3 */
            export declare const z: \nnumber[][];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ '__$$$gensym_0$$$__' , '__$$$gensym_1$$$__' , '__$$$gensym_2$$$__' , ] ) ; } for ( const schema of schemas ) { { const rhs = { kind : 'never' , passThruCodeBlock : `export declare var x: number;` , docComment : 'comment1' , } ; const ty = getType ( schema , '__$$$gensym_0$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `export declare let y: number[];` , docComment : 'comment2' , } ; const ty = getType ( schema , '__$$$gensym_1$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { const rhs = { kind : 'never' , passThruCodeBlock : `export declare const z: \nnumber[][];` , docComment : 'comment3' , } ; const ty = getType ( schema , '__$$$gensym_2$$$__' ) ; expect ( ty ) . toEqual ( rhs ) ; } { expect ( generateTypeScriptCode ( schema ) . trim ( ) ) . toEqual ( `/** comment1 */\nexport declare var x: number;\n\n` + `/** comment2 */\nexport declare let y: number[];\n\n` + `/** comment3 */\nexport declare const z: \nnumber[][];` ) ; } } } ) ; it ( "compiler-directives-1" , function ( ) { const schemas = [ compile ( `
            /// @tynder-external P, Q, R
            // @tynder-external S

            type X = Q;
            interface Y { a: R; }
        ` ) , compile ( `
            /* @tynder-external P, Q, R */
            /* @tynder-external
            S
            */

            type X = Q;
            interface Y { a: R; }
        ` ) , compile ( `
            external P, Q, R;
            external S;

            type X = Q;
            interface Y { a: R; }
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'P' , 'Q' , 'R' , 'S' , 'X' , 'Y' , ] ) ; expect ( Array . from ( schemas [ 1 ] . keys ( ) ) ) . toEqual ( [ 'P' , 'Q' , 'R' , 'S' , 'X' , 'Y' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'P' , typeName : 'P' , kind : 'any' , noOutput : true , } ; const ty = getType ( schema , 'P' ) ; expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( 3 , ty ) ) . toEqual ( { value : 3 } ) ; } { const rhs = { name : 'X' , typeName : 'X' , originalTypeName : 'Q' , kind : 'any' , } ; const ty = getType ( schema , 'X' ) ; expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( 3 , ty ) ) . toEqual ( { value : 3 } ) ; } { const rhs = { name : 'Y' , typeName : 'Y' , kind : 'object' , members : [ [ 'a' , { name : 'a' , typeName : 'R' , kind : 'any' , } ] ] , } ; const ty = getType ( schema , 'Y' ) ; expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( { a : 3 } , ty ) ) . toEqual ( { value : { a : 3 } } ) ; expect ( validate < any > ( { b : 3 } , ty ) ) . toEqual ( null ) ; } } } ) ; it ( "compiler-primitive" , function ( ) { const schema = compile ( `
            type FooA = any;
            type FooB = unknown;
            type FooC = never;
        ` ) ; { expect ( Array . from ( schema . keys ( ) ) ) . toEqual ( [ 'FooA' , 'FooB' , 'FooC' , ] ) ; } { const rhs = { name : 'FooA' , typeName : 'FooA' , kind : 'any' , } ; const ty = getType ( schema , 'FooA' ) ; expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( 0 , ty ) ) . toEqual ( { value : 0 } ) ; expect ( validate < any > ( 1 , ty ) ) . toEqual ( { value : 1 } ) ; expect ( validate < any > ( BigInt ( 0 ) , ty ) ) . toEqual ( { value : BigInt ( 0 ) } ) ; expect ( validate < any > ( BigInt ( 1 ) , ty ) ) . toEqual ( { value : BigInt ( 1 ) } ) ; expect ( validate < any > ( '' , ty ) ) . toEqual ( { value : '' } ) ; expect ( validate < any > ( '1' , ty ) ) . toEqual ( { value : '1' } ) ; expect ( validate < any > ( false , ty ) ) . toEqual ( { value : false } ) ; expect ( validate < any > ( true , ty ) ) . toEqual ( { value : true } ) ; expect ( validate < any > ( null , ty ) ) . toEqual ( { value : null } ) ; expect ( validate < any > ( void 0 , ty ) ) . toEqual ( { value : void 0 } ) ; expect ( validate < any > ( { } , ty ) ) . toEqual ( { value : { } } ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( { value : [ ] } ) ; expect ( validate < any > ( 3 , ty ) ) . toEqual ( { value : 3 } ) ; expect ( validate < any > ( BigInt ( 7 ) , ty ) ) . toEqual ( { value : BigInt ( 7 ) } ) ; expect ( validate < any > ( 'XB' , ty ) ) . toEqual ( { value : 'XB' } ) ; expect ( validate < any > ( true , ty ) ) . toEqual ( { value : true } ) ; } { const rhs = { name : 'FooB' , typeName : 'FooB' , kind : 'unknown' , } ; const ty = getType ( schema , 'FooB' ) ; expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( 0 , ty ) ) . toEqual ( { value : 0 } ) ; expect ( validate < any > ( 1 , ty ) ) . toEqual ( { value : 1 } ) ; expect ( validate < any > ( BigInt ( 0 ) , ty ) ) . toEqual ( { value : BigInt ( 0 ) } ) ; expect ( validate < any > ( BigInt ( 1 ) , ty ) ) . toEqual ( { value : BigInt ( 1 ) } ) ; expect ( validate < any > ( '' , ty ) ) . toEqual ( { value : '' } ) ; expect ( validate < any > ( '1' , ty ) ) . toEqual ( { value : '1' } ) ; expect ( validate < any > ( false , ty ) ) . toEqual ( { value : false } ) ; expect ( validate < any > ( true , ty ) ) . toEqual ( { value : true } ) ; expect ( validate < any > ( null , ty ) ) . toEqual ( { value : null } ) ; expect ( validate < any > ( void 0 , ty ) ) . toEqual ( { value : void 0 } ) ; expect ( validate < any > ( { } , ty ) ) . toEqual ( { value : { } } ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( { value : [ ] } ) ; expect ( validate < any > ( 3 , ty ) ) . toEqual ( { value : 3 } ) ; expect ( validate < any > ( BigInt ( 7 ) , ty ) ) . toEqual ( { value : BigInt ( 7 ) } ) ; expect ( validate < any > ( 'XB' , ty ) ) . toEqual ( { value : 'XB' } ) ; expect ( validate < any > ( true , ty ) ) . toEqual ( { value : true } ) ; } { const rhs = { name : 'FooC' , typeName : 'FooC' , kind : 'never' , } ; const ty = getType ( schema , 'FooC' ) ; expect ( ty ) . toEqual ( rhs ) ; expect ( validate < string > ( 0 , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( 1 , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( BigInt ( 0 ) , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( BigInt ( 1 ) , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( '' , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( '1' , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( false , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( true , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( null , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( void 0 , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( { } , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( 3 , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( BigInt ( 7 ) , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( 'XB' , ty ) ) . toEqual ( null ) ; expect ( validate < string > ( true , ty ) ) . toEqual ( null ) ; } } ) ; it ( "compiler-deep-cherrypick-patch-1" , function ( ) { const schema = compile ( `
            interface A {
                a1: string;
                a2?: number;
                a3: string[];
            }
            interface B {
                b1: boolean;
                b2: A;
            }
            interface C {
                c1: string;
                c2: B;
                c3?: A;
            }
        ` ) ; const ty = getType ( schema , 'C' ) ; const original = { c1 : 'ccccc' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '1' , '2' ] , a4 : true , } , b3 : '33333' , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , a4 : false , } , c4 : '44444' , } ; const needle = pick ( original , ty ) ; expect ( needle ) . toEqual ( { c1 : 'ccccc' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '1' , '2' ] , } , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , } , } as any ) ; const patched = patch ( original , needle , ty ) ; expect ( patched ) . toEqual ( { c1 : 'ccccc' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '1' , '2' ] , a4 : true , } , b3 : '33333' , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , a4 : false , } , c4 : '44444' , } as any ) ; } ) ; it ( "compiler-deep-cherrypick-patch-2" , function ( ) { const schema = compile ( `
            interface A {
                a1: string;
                a2?: number;
                a3: string[];
            }
            interface B {
                b1: boolean;
                b2: A;
            }
            interface C {
                c1: string;
                c2: B;
                c3?: A;
            }
        ` ) ; const ty = getType ( schema , 'C' ) ; const original = { c1 : 'ccccc' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '1' , '2' ] , a4 : true , } , b3 : '33333' , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , a4 : false , } , c4 : '44444' , } ; const needle = pick ( original , ty ) ; expect ( needle ) . toEqual ( { c1 : 'ccccc' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '1' , '2' ] , } , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , } , } as any ) ; needle . c1 = '!ccccc!' ; needle . c4 = '!44444!' ; ( needle as any ) . c5 = true ; ( needle as any ) . c2 . b2 . a3 = [ '!1!' ] ; ( needle as any ) . c2 . b2 . a4 = false ; ( needle as any ) . c2 . b2 . a5 = 999 ; ( needle as any ) . c3 . a4 = true ; const patched = patch ( original , needle , ty ) ; expect ( patched ) . toEqual ( { c1 : '!ccccc!' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '!1!' ] , a4 : true , } , b3 : '33333' , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , a4 : false , } , c4 : '44444' , } as any ) ; } ) ; it ( "compiler-deep-cherrypick-patch-3" , function ( ) { const schema = compile ( `
            interface A {
                a1: string;
                a2?: number;
                a3: string[];
                [propNames: string]: any;
            }
            interface B {
                b1: boolean;
                b2: A;
            }
            interface C {
                c1: string;
                c2: B;
                c3?: A;
            }
        ` ) ; const ty = getType ( schema , 'C' ) ; const original = { c1 : 'ccccc' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '1' , '2' ] , a4 : true , } , b3 : '33333' , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , a4 : false , } , c4 : '44444' , } ; const needle = pick ( original , ty ) ; expect ( needle ) . toEqual ( { c1 : 'ccccc' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '1' , '2' ] , a4 : true , } , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , a4 : false , } , } as any ) ; needle . c1 = '!ccccc!' ; needle . c4 = '!44444!' ; ( needle as any ) . c5 = true ; ( needle as any ) . c2 . b2 . a3 = [ '!1!' ] ; ( needle as any ) . c2 . b2 . a4 = false ; ( needle as any ) . c2 . b2 . a5 = 999 ; ( needle as any ) . c3 . a4 = true ; const patched = patch ( original , needle , ty ) ; expect ( patched ) . toEqual ( { c1 : '!ccccc!' , c2 : { b1 : true , b2 : { a1 : 'bbbbb' , a2 : 22 , a3 : [ '!1!' ] , a4 : false , a5 : 999 , } , b3 : '33333' , } , c3 : { a1 : 'aaaaa' , a2 : 2 , a3 : [ '11' , '12' ] , a4 : true , } , c4 : '44444' , } as any ) ; } ) ; } ) ;