import { createMock } from 'ts-auto-mock' ; import * as STAR_DEFAULT from '../utils/interfaces/exportDefaultDeclaration' ; import { ImportInterface } from '../utils/interfaces/importInterface' ; import * as STAR from '../utils/typeQuery/typeQueryUtils' ; import { ExportedClass , ExportedDeclaredClass , exportedDeclaredFunction , ExportedEnum , exportedFunction , WrapExportedClass , WrapExportedEnum , } from '../utils/typeQuery/typeQueryUtils' ; import REQUIRE_DEFAULT = require ( '../utils/interfaces/exportDefaultDeclaration' ) ; import REQUIRE_EQUAL = require ( '../utils/interfaces/exportEqualObject' ) ; import REQUIRE = require ( '../utils/typeQuery/typeQueryUtils' ) ; declare function functionDeclaration ( ) ; describe ( 'typeQuery' , ( ) => { describe ( 'for function' , ( ) => { it ( 'should assign the function mock for a function declaration' , ( ) => { const functionMock = createMock < typeof functionDeclaration > ( ) ; expect ( functionMock ( ) ) . toEqual ( 0 ) ; } ) ; it ( 'should assign the function mock for an function declaration with body' , ( ) => { function func ( ) { return 'ok' ; } const functionMock = createMock < typeof func > ( ) ; expect ( functionMock ( ) ) . toEqual ( '' ) ; } ) ; it ( 'should assign the function mock for an imported function declaration' , ( ) => { const functionMock = createMock < typeof exportedDeclaredFunction > ( ) ; expect ( functionMock ( ) ) . toEqual ( '' ) ; } ) ; it ( 'should assign the function mock for an imported function declaration with body' , ( ) => { const functionMock = createMock < typeof exportedFunction > ( ) ; expect ( functionMock ( ) ) . toEqual ( 0 ) ; } ) ; it ( 'should return undefined for an intersection' , ( ) => { function func ( ) { return 'ok' ; } type Intersection = { } & typeof func ; const functionMock = createMock < Intersection > ( ) ; expect ( functionMock ) . toBeUndefined ( ) ; } ) ; it ( 'should return correct properties with multiple declarations' , ( ) => { function MultipleDeclaration ( ) { return { a : 's' } ; } interface MultipleDeclaration { b : string ; } const functionMock = createMock < typeof MultipleDeclaration > ( ) ; expect ( functionMock ( ) ) . toEqual ( { b : '' , } ) ; } ) ; } ) ; describe ( 'for class' , ( ) => { it ( 'should create a newable class for a class declaration in file' , ( ) => { class MyClass { public prop : string ; } const classMock = createMock < typeof MyClass > ( ) ; expect ( new classMock ( ) . prop ) . toEqual ( '' ) ; } ) ; it ( 'should create a newable class for an imported class declaration' , ( ) => { const classMock = createMock < typeof ExportedDeclaredClass > ( ) ; expect ( new classMock ( ) . prop ) . toEqual ( '' ) ; } ) ; it ( 'should create a newable class for an imported class' , ( ) => { const classMock = createMock < typeof ExportedClass > ( ) ; expect ( new classMock ( ) . prop ) . toEqual ( 0 ) ; } ) ; it ( 'should create a newable class for an wrapped imported typeof class' , ( ) => { const classMock = createMock < WrapExportedClass > ( ) ; expect ( new classMock ( ) . prop ) . toEqual ( 0 ) ; } ) ; it ( 'should return undefined for an intersection' , ( ) => { type Intersection = { } & WrapExportedClass ; const functionMock = createMock < Intersection > ( ) ; expect ( functionMock ) . toBeUndefined ( ) ; } ) ; } ) ; describe ( 'for enum' , ( ) => { it ( 'should assign the enum to the mock' , ( ) => { enum Enum { A , B = 'some' } const enumMock = createMock < typeof Enum > ( ) ; expect ( enumMock . A ) . toEqual ( Enum . A ) ; expect ( enumMock . B ) . toEqual ( Enum . B ) ; } ) ; it ( 'should assign the imported enum to the mock' , ( ) => { const enumMock = createMock < typeof ExportedEnum > ( ) ; expect ( enumMock . A ) . toEqual ( 0 ) ; expect ( enumMock . B ) . toEqual ( 'B' ) ; expect ( enumMock . C ) . toEqual ( 'MaybeC' ) ; } ) ; it ( 'should assign the imported enum to the mock when typeof wrapped in a type' , ( ) => { type WrapEnum = typeof ExportedEnum ; const enumMock = createMock < WrapEnum > ( ) ; expect ( enumMock . A ) . toEqual ( 0 ) ; expect ( enumMock . B ) . toEqual ( 'B' ) ; expect ( enumMock . C ) . toEqual ( 'MaybeC' ) ; } ) ; it ( 'should assign the enum to the mock when importing enum wrapper' , ( ) => { const enumMock = createMock < WrapExportedEnum > ( ) ; expect ( enumMock . A ) . toEqual ( 0 ) ; expect ( enumMock . B ) . toEqual ( 'B' ) ; expect ( enumMock . C ) . toEqual ( 'MaybeC' ) ; } ) ; it ( 'should return undefined for an intersection' , ( ) => { type Intersection = { } & WrapExportedEnum ; const functionMock = createMock < Intersection > ( ) ; expect ( functionMock ) . toBeUndefined ( ) ; } ) ; } ) ; describe ( 'for variable' , ( ) => { it ( 'should create the imported interface mock from the type of a variable' , ( ) => { let aVariable ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . a . b ) . toEqual ( '' ) ; } ) ; it ( 'should create the imported typeof enum mock from the type of a variable' , ( ) => { let aVariable ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . A ) . toEqual ( 0 ) ; } ) ; it ( 'should work for a method in an object' , ( ) => { const aVariable = { a ( ) { return 'wow' ; } , } ; const mock = createMock < typeof aVariable . a > ( ) ; expect ( mock ( ) ) . toEqual ( '' ) ; } ) ; it ( 'should return undefined for an intersection' , ( ) => { let aVariable ; type Intersection = { } & typeof aVariable ; const functionMock = createMock < Intersection > ( ) ; expect ( functionMock ) . toBeUndefined ( ) ; } ) ; describe ( 'import star' , ( ) => { it ( 'should mock every materialisable export (no types or interfaces)' , ( ) => { const mock = createMock < typeof STAR > ( ) ; expect ( mock . ExportedEnum . A ) . toBe ( ExportedEnum . A ) ; expect ( new mock . ExportedClass ( ) . prop ) . toEqual ( 0 ) ; expect ( new mock . ExportedDeclaredClass ( ) . prop ) . toEqual ( '' ) ; expect ( mock . exportedDeclaredFunction ( ) ) . toEqual ( '' ) ; } ) ; it ( 'should mock the default' , ( ) => { const mock = createMock < typeof STAR_DEFAULT > ( ) ; expect ( mock . functionDefault ( 'input' ) ) . toBe ( false ) ; expect ( mock . default ( 'input' ) ) . toBe ( false ) ; expect ( mock . functionNotDefault ( 'input' ) ) . toBe ( false ) ; } ) ; } ) ; describe ( 'import require' , ( ) => { it ( 'should mock every materialisable export (no types or interfaces)' , ( ) => { const mock = createMock < typeof REQUIRE > ( ) ; expect ( mock . ExportedEnum . A ) . toBe ( ExportedEnum . A ) ; expect ( new mock . ExportedClass ( ) . prop ) . toEqual ( 0 ) ; expect ( new mock . ExportedDeclaredClass ( ) . prop ) . toEqual ( '' ) ; expect ( mock . exportedDeclaredFunction ( ) ) . toEqual ( '' ) ; } ) ; it ( 'should mock the default' , ( ) => { const mock = createMock < typeof REQUIRE_DEFAULT > ( ) ; expect ( mock . functionDefault ( 'input' ) ) . toBe ( false ) ; expect ( mock . default ( 'input' ) ) . toBe ( false ) ; expect ( mock . functionNotDefault ( 'input' ) ) . toBe ( false ) ; } ) ; it ( 'should mock the `export =`' , ( ) => { const mock = createMock < typeof REQUIRE_EQUAL > ( ) ; expect ( new mock ( ) . prop ) . toBe ( 0 ) ; } ) ; } ) ; describe ( 'inferred type' , ( ) => { it ( 'should work for inferred object' , ( ) => { const aVariable = { prop : 'asd' } ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . prop ) . toEqual ( 'asd' ) ; } ) ; it ( 'should work for enum' , ( ) => { const aVariable = ExportedEnum ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . A ) . toEqual ( 0 ) ; } ) ; it ( 'should work for function call of a variable with no explicit return type of function' , ( ) => { const testExplicitType = ( value ) => { if ( value ) { return { prop : 'asd' } ; } return { prop : 'wooo' } ; } ; const aVariable = testExplicitType ( true ) ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . prop ) . toEqual ( '' ) ; } ) ; it ( 'should work for function call of a variable with no explicit type' , ( ) => { const test = ( value ) : { prop : string ; } => { if ( value ) { return { prop : 'asd' } ; } return { prop : 'wooo' } ; } ; const aVariable = test ( true ) ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . prop ) . toEqual ( '' ) ; } ) ; it ( 'should work for function call of a variable with no explicit type and no explicit return type of function' , ( ) => { const test = ( value ) => { if ( value ) { return { prop : 'asd' } ; } return { prop : 'wooo' } ; } ; const aVariable = test ( true ) ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . prop ) . toEqual ( 'wooo' ) ; } ) ; it ( 'should work for function call' , ( ) => { function test ( value ) { if ( value ) { return { prop : 'asd' } ; } return { prop : 'wooo' } ; } const aVariable = test ( true ) ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . prop ) . toEqual ( '' ) ; } ) ; it ( 'should work for function call of a function with no explicit return type' , ( ) => { function test ( value ) { if ( value ) { return { prop : 'asd' } ; } return { second : 7 } ; } const aVariable = test ( true ) ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . second ) . toEqual ( 7 ) ; } ) ; it ( 'should not call the real function to get the type for function call' , ( ) => { let count = 0 ; function test ( value ) { count ++ ; if ( value ) { return { prop : 'asd' } ; } return { second : 7 } ; } const aVariable = test ( true ) ; const mock = createMock < typeof aVariable > ( ) ; expect ( count ) . toEqual ( 1 ) ; } ) ; it ( 'should work for module' , ( ) => { const aVariable = STAR ; const mock = createMock < typeof aVariable > ( ) ; expect ( mock . ExportedEnum . A ) . toEqual ( ExportedEnum . A ) ; } ) ; } ) ; } ) ; } ) ;