import { TypeAssertion , ValidationContext } from '../types' ; import { validate , getType } from '../validator' ; import { compile } from '../compiler' ; import { serialize , deserialize } from '../serializer' ; describe ( "compiler-4" , function ( ) { it ( "compiler-exported-types-1" , function ( ) { const schema = compile ( `
            export type Foo = string | number;
            type Bar = string | number;
        ` ) ; { expect ( Array . from ( schema . keys ( ) ) ) . toEqual ( [ 'Foo' , 'Bar' , ] ) ; } { const rhs = { name : 'Foo' , typeName : 'Foo' , kind : 'one-of' , oneOf : [ { kind : 'primitive' , primitiveName : 'string' , } , { kind : 'primitive' , primitiveName : 'number' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Foo' ) , getType ( schema , 'Foo' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Foo' ) ?. exported ) . toEqual ( true ) ; } } { const rhs = { name : 'Bar' , typeName : 'Bar' , kind : 'one-of' , oneOf : [ { kind : 'primitive' , primitiveName : 'string' , } , { kind : 'primitive' , primitiveName : 'number' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Bar' ) , getType ( schema , 'Bar' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Bar' ) ?. exported ) . toEqual ( false ) ; } } } ) ; it ( "compiler-exported-types-2" , function ( ) { const schema = compile ( `
            export interface Foo {}
            interface Bar {}
        ` ) ; { expect ( Array . from ( schema . keys ( ) ) ) . toEqual ( [ 'Foo' , 'Bar' , ] ) ; } { const rhs = { name : 'Foo' , typeName : 'Foo' , kind : 'object' , members : [ ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Foo' ) , getType ( schema , 'Foo' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Foo' ) ?. exported ) . toEqual ( true ) ; } } { const rhs = { name : 'Bar' , typeName : 'Bar' , kind : 'object' , members : [ ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Bar' ) , getType ( schema , 'Bar' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Bar' ) ?. exported ) . toEqual ( false ) ; } } } ) ; it ( "compiler-exported-types-3" , function ( ) { const schema = compile ( `
            export enum Foo {}
            enum Bar {}
        ` ) ; { expect ( Array . from ( schema . keys ( ) ) ) . toEqual ( [ 'Foo' , 'Bar' , ] ) ; } { const rhs = { name : 'Foo' , typeName : 'Foo' , kind : 'enum' , values : [ ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Foo' ) , getType ( schema , 'Foo' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Foo' ) ?. exported ) . toEqual ( true ) ; } } { const rhs = { name : 'Bar' , typeName : 'Bar' , kind : 'enum' , values : [ ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Bar' ) , getType ( schema , 'Bar' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Bar' ) ?. exported ) . toEqual ( false ) ; } } } ) ; it ( "compiler-doc-comments-1" , function ( ) { const schema = compile ( `
            /* comment1 */
            export type Foo = string | number;
            /*
             * comment2
             */
            type Bar = string | number;
        ` ) ; { expect ( Array . from ( schema . keys ( ) ) ) . toEqual ( [ 'Foo' , 'Bar' , ] ) ; } { const rhs = { name : 'Foo' , typeName : 'Foo' , kind : 'one-of' , oneOf : [ { kind : 'primitive' , primitiveName : 'string' , } , { kind : 'primitive' , primitiveName : 'number' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Foo' ) , getType ( schema , 'Foo' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Foo' ) ?. exported ) . toEqual ( true ) ; } } { const rhs = { name : 'Bar' , typeName : 'Bar' , kind : 'one-of' , oneOf : [ { kind : 'primitive' , primitiveName : 'string' , } , { kind : 'primitive' , primitiveName : 'number' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Bar' ) , getType ( schema , 'Bar' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Bar' ) ?. exported ) . toEqual ( false ) ; } } } ) ; it ( "compiler-doc-comments-2" , function ( ) { const schema = compile ( `
            /** comment1 */
            export type Foo = string | number;
            /**
             * comment2
             */
            type Bar = string | number;
        ` ) ; { expect ( Array . from ( schema . keys ( ) ) ) . toEqual ( [ 'Foo' , 'Bar' , ] ) ; } { const rhs = { name : 'Foo' , typeName : 'Foo' , kind : 'one-of' , oneOf : [ { kind : 'primitive' , primitiveName : 'string' , } , { kind : 'primitive' , primitiveName : 'number' , } ] , docComment : 'comment1' , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Foo' ) , getType ( schema , 'Foo' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Foo' ) ?. exported ) . toEqual ( true ) ; } } { const rhs = { name : 'Bar' , typeName : 'Bar' , kind : 'one-of' , oneOf : [ { kind : 'primitive' , primitiveName : 'string' , } , { kind : 'primitive' , primitiveName : 'number' , } ] , docComment : '* comment2' , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Bar' ) , getType ( schema , 'Bar' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Bar' ) ?. exported ) . toEqual ( false ) ; } } } ) ; it ( "compiler-doc-comments-3" , function ( ) { const schema = compile ( `
            /** comment X */
            type X = string;
            /** comment Foo */
            export interface Foo {
                /** comment Foo.a */
                a: number;
                /** comment Foo.b */
                b: X;
                c: X;
                /** comment Foo.d */
                d: string;
                /** comment Foo.propNames */
                [propNames: string]: string;
            }
            /** comment Bar */
            interface Bar extends Foo {
                /** comment Bar.e */
                e: number;
                /** comment Bar.propNames */
                [propNames: number]: number;
            }
        ` ) ; { expect ( Array . from ( schema . keys ( ) ) ) . toEqual ( [ 'X' , 'Foo' , 'Bar' , ] ) ; } { const rhs = { name : 'X' , typeName : 'X' , kind : 'primitive' , primitiveName : 'string' , docComment : 'comment X' , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'X' ) ?. exported ) . toEqual ( false ) ; } } { const rhs = { name : 'Foo' , typeName : 'Foo' , kind : 'object' , members : [ [ 'a' , { name : 'a' , kind : 'primitive' , primitiveName : 'number' } , false , 'comment Foo.a' , ] , [ 'b' , { name : 'b' , typeName : 'X' , kind : 'primitive' , primitiveName : 'string' , docComment : 'comment X' } , false , 'comment Foo.b' , ] , [ 'c' , { name : 'c' , typeName : 'X' , kind : 'primitive' , primitiveName : 'string' , docComment : 'comment X' } , ] , [ 'd' , { name : 'd' , kind : 'primitive' , primitiveName : 'string' } , false , 'comment Foo.d' , ] , ] , additionalProps : [ [ [ 'string' ] , { kind : 'primitive' , primitiveName : 'string' } , false , 'comment Foo.propNames' ] , ] , docComment : 'comment Foo' , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Foo' ) , getType ( schema , 'Foo' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Foo' ) ?. exported ) . toEqual ( true ) ; } } { const rhs = { name : 'Bar' , typeName : 'Bar' , kind : 'object' , members : [ [ 'e' , { name : 'e' , kind : 'primitive' , primitiveName : 'number' } , false , 'comment Bar.e' , ] , [ 'a' , { name : 'a' , kind : 'primitive' , primitiveName : 'number' } , true , 'comment Foo.a' , ] , [ 'b' , { name : 'b' , typeName : 'X' , kind : 'primitive' , primitiveName : 'string' , docComment : 'comment X' } , true , 'comment Foo.b' , ] , [ 'c' , { name : 'c' , typeName : 'X' , kind : 'primitive' , primitiveName : 'string' , docComment : 'comment X' } , true , ] , [ 'd' , { name : 'd' , kind : 'primitive' , primitiveName : 'string' } , true , 'comment Foo.d' , ] , ] , additionalProps : [ [ [ 'string' ] , { kind : 'primitive' , primitiveName : 'string' } , true , 'comment Foo.propNames' ] , [ [ 'number' ] , { kind : 'primitive' , primitiveName : 'number' } , false , 'comment Bar.propNames' ] , ] , baseTypes : [ getType ( schema , 'Foo' ) as any ] , docComment : 'comment Bar' , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Bar' ) , getType ( schema , 'Bar' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Bar' ) ?. exported ) . toEqual ( false ) ; } } } ) ; it ( "compiler-doc-comments-4" , function ( ) { const schema = compile ( `
            /** comment Foo */
            export enum Foo {
                /** comment Foo.A */
                A,
                /** comment Foo.B */
                B = 'bbb',
            }
        ` ) ; { expect ( Array . from ( schema . keys ( ) ) ) . toEqual ( [ 'Foo' , ] ) ; } { const rhs = { name : 'Foo' , typeName : 'Foo' , kind : 'enum' , values : [ [ 'A' , 0 , 'comment Foo.A' ] , [ 'B' , 'bbb' , 'comment Foo.B' ] , ] , docComment : 'comment Foo' , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'Foo' ) , getType ( schema , 'Foo' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( schema . get ( 'Foo' ) ?. exported ) . toEqual ( true ) ; } } } ) ; it ( "compiler-array-length-1" , function ( ) { const schemas = [ compile ( `
            type X = string[3..5];
        ` ) , compile ( `
            type X = Array<string, 3..5>;
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; expect ( Array . from ( schemas [ 1 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'repeated' , min : 3 , max : 5 , repeated : { kind : 'primitive' , primitiveName : 'string' , } , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' , '2' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' , '5' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( null ) ; } } } } ) ; it ( "compiler-array-length-2" , function ( ) { const schemas = [ compile ( `
            type X = string[..5];
        ` ) , compile ( `
            type X = Array<string, ..5>;
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; expect ( Array . from ( schemas [ 1 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'repeated' , min : null , max : 5 , repeated : { kind : 'primitive' , primitiveName : 'string' , } , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( { value : [ ] } ) ; expect ( validate < any > ( [ '1' ] , ty ) ) . toEqual ( { value : [ '1' ] } ) ; expect ( validate < any > ( [ '1' , '2' ] , ty ) ) . toEqual ( { value : [ '1' , '2' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' , '5' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( null ) ; } } } } ) ; it ( "compiler-array-length-3" , function ( ) { const schemas = [ compile ( `
            type X = string[3..];
        ` ) , compile ( `
            type X = Array<string, 3..>;
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; expect ( Array . from ( schemas [ 1 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'repeated' , min : 3 , max : null , repeated : { kind : 'primitive' , primitiveName : 'string' , } , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' , '2' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' , '5' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' , '5' , '6' ] } ) ; } } } } ) ; it ( "compiler-array-length-4a" , function ( ) { const schemas = [ compile ( `
            type X = string[3];
        ` ) , compile ( `
            type X = Array<string, 3>;
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; expect ( Array . from ( schemas [ 1 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'repeated' , min : 3 , max : 3 , repeated : { kind : 'primitive' , primitiveName : 'string' , } , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' , '2' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( null ) ; } } } } ) ; it ( "compiler-array-length-4b" , function ( ) { const schemas = [ compile ( `
            type X = string[];
        ` ) , compile ( `
            type X = Array<string>;
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; expect ( Array . from ( schemas [ 1 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'repeated' , min : null , max : null , repeated : { kind : 'primitive' , primitiveName : 'string' , } , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( { value : [ ] } ) ; expect ( validate < any > ( [ '1' ] , ty ) ) . toEqual ( { value : [ '1' ] } ) ; expect ( validate < any > ( [ '1' , '2' ] , ty ) ) . toEqual ( { value : [ '1' , '2' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' , '5' ] } ) ; expect ( validate < any > ( [ '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( { value : [ '1' , '2' , '3' , '4' , '5' , '6' ] } ) ; } } } } ) ; it ( "compiler-spread-length-1" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string, 3..5>, boolean];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : 3 , max : 5 , spread : { kind : 'primitive' , primitiveName : 'string' , } , } , { kind : 'primitive' , primitiveName : 'boolean' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' , false ] , ty ) ) . toEqual ( null ) ; } } } } ) ; it ( "compiler-spread-length-2" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string, ..5>, boolean];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : null , max : 5 , spread : { kind : 'primitive' , primitiveName : 'string' , } , } , { kind : 'primitive' , primitiveName : 'boolean' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , false ] , ty ) ) . toEqual ( { value : [ 0 , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' , false ] , ty ) ) . toEqual ( null ) ; } } } } ) ; it ( "compiler-spread-length-3" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string, 3..>, boolean];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : 3 , max : null , spread : { kind : 'primitive' , primitiveName : 'string' , } , } , { kind : 'primitive' , primitiveName : 'boolean' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' , '6' , false ] } ) ; } } } } ) ; it ( "compiler-spread-length-4a" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string, 3>, boolean];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : 3 , max : 3 , spread : { kind : 'primitive' , primitiveName : 'string' , } , } , { kind : 'primitive' , primitiveName : 'boolean' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' , false ] , ty ) ) . toEqual ( null ) ; } } } } ) ; it ( "compiler-spread-length-4b" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string>, boolean];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : null , max : null , spread : { kind : 'primitive' , primitiveName : 'string' , } , } , { kind : 'primitive' , primitiveName : 'boolean' , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , false ] , ty ) ) . toEqual ( { value : [ 0 , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' , '6' , false ] } ) ; } } } } ) ; it ( "compiler-spread-length-5" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string, 3..5>];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : 3 , max : 5 , spread : { kind : 'primitive' , primitiveName : 'string' , } , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( null ) ; } } } } ) ; it ( "compiler-spread-length-6" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string, ..5>];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : null , max : 5 , spread : { kind : 'primitive' , primitiveName : 'string' , } , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 ] , ty ) ) . toEqual ( { value : [ 0 ] } ) ; expect ( validate < any > ( [ 0 , '1' ] , ty ) ) . toEqual ( { value : [ 0 , '1' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( null ) ; } } } } ) ; it ( "compiler-spread-length-7" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string, 3..>];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : 3 , max : null , spread : { kind : 'primitive' , primitiveName : 'string' , } , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' , '6' ] } ) ; } } } } ) ; it ( "compiler-spread-length-8" , function ( ) { const schemas = [ compile ( `
            type X = [number, ...<string>];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'spread' , min : null , max : null , spread : { kind : 'primitive' , primitiveName : 'string' , } , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 ] , ty ) ) . toEqual ( { value : [ 0 ] } ) ; expect ( validate < any > ( [ 0 , '1' ] , ty ) ) . toEqual ( { value : [ 0 , '1' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , '3' , '4' , '5' , '6' ] , ty ) ) . toEqual ( { value : [ 0 , '1' , '2' , '3' , '4' , '5' , '6' ] } ) ; } } } } ) ; it ( "compiler-spread-optional-length-1" , function ( ) { const schemas = [ compile ( `
            type X = [number, string?, boolean?];
        ` ) ] ; { expect ( Array . from ( schemas [ 0 ] . keys ( ) ) ) . toEqual ( [ 'X' , ] ) ; } for ( const schema of schemas ) { { const rhs = { name : 'X' , typeName : 'X' , kind : 'sequence' , sequence : [ { kind : 'primitive' , primitiveName : 'number' , } , { kind : 'optional' , optional : { kind : 'primitive' , primitiveName : 'string' , } , } , { kind : 'optional' , optional : { kind : 'primitive' , primitiveName : 'boolean' , } , } ] , } ; for ( const ty of [ getType ( deserialize ( serialize ( schema ) ) , 'X' ) , getType ( schema , 'X' ) ] ) { expect ( ty ) . toEqual ( rhs ) ; expect ( validate < any > ( [ ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 ] , ty ) ) . toEqual ( { value : [ 0 ] } ) ; expect ( validate < any > ( [ 0 , '1' ] , ty ) ) . toEqual ( { value : [ 0 , '1' ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , false ] , ty ) ) . toEqual ( { value : [ 0 , '1' , false ] } ) ; expect ( validate < any > ( [ 0 , '1' , '2' , false ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , false , true ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , false , true ] , ty ) ) . toEqual ( null ) ; expect ( validate < any > ( [ 0 , '1' , '2' , false , true ] , ty ) ) . toEqual ( null ) ; } } } } ) ; } ) ;