import { BrokerKernel } from '@deepkit/broker' ; import { ClassType } from '@deepkit/core' ; import { ConsoleTransport , Logger , MemoryLoggerTransport } from '@deepkit/logger' ; import { Database , DatabaseRegistry , MemoryDatabaseAdapter } from '@deepkit/orm' ; import { ClassSchema } from '@deepkit/type' ; import { ApplicationServer } from './application-server' ; import { Broker , BrokerServer , DirectBroker } from './broker/broker' ; import { injectorReference } from '@deepkit/injector' ; import { App , AppModule , RootAppModule , RootModuleDefinition } from '@deepkit/app' ; import { WebMemoryWorkerFactory , WebWorkerFactory } from './worker' ; import { HttpKernel , HttpResponse , RequestBuilder } from '@deepkit/http' ; import { RpcClient } from '@deepkit/rpc' ; import { FrameworkModule } from './module' ; export class TestHttpResponse extends HttpResponse { public body : Buffer = Buffer . alloc ( 0 ) ; write ( chunk , encoding , callback ? ) { if ( typeof encoding === 'function' ) { callback = encoding ; encoding = null ; } if ( chunk ) { if ( 'string' === typeof chunk ) { chunk = Buffer . from ( chunk , encoding || 'utf8' ) ; } this . body = Buffer . concat ( [ this . body , chunk ] ) ; } if ( callback ) callback ( ) ; return true ; } end ( chunk , encoding ? , callback ? ) { if ( typeof chunk === 'function' ) { callback = chunk ; chunk = null ; encoding = null ; } else if ( typeof encoding === 'function' ) { callback = encoding ; encoding = null ; } if ( chunk ) { if ( 'string' === typeof chunk ) { chunk = Buffer . from ( chunk , encoding || 'utf8' ) ; } this . body = Buffer . concat ( [ this . body , chunk ] ) ; } if ( callback ) callback ( ) ; } } export class TestingFacade < A extends App < any > > { constructor ( public app ) { } public async startServer ( ) { await this . app . get ( ApplicationServer ) . start ( ) ; } public async stopServer ( ) { await this . app . get ( ApplicationServer ) . close ( ) ; } public async request ( requestBuilder ) { const request = requestBuilder . build ( ) ; const response = new TestHttpResponse ( request ) ; await this . app . get ( HttpKernel ) . handleRequest ( request , response ) ; return response ; } public createRpcClient ( ) { return this . app . get ( ApplicationServer ) . createClient ( ) ; } } export class BrokerMemoryServer extends BrokerServer { public kernel = new BrokerKernel ( ) ; async start ( ) { } async stop ( ) { } } /**
 * Creates a new App instance, but with kernel services in place that work in memory.
 * For example RPC/Broker/HTTP communication without TCP stack. Logger uses MemoryLogger.
 */ export function createTestingApp < O extends RootModuleDefinition > ( options , entities = [ ] , setup ? ) { const module = new RootAppModule ( options ) ; module . setupProvider ( Logger ) . removeTransport ( injectorReference ( ConsoleTransport ) ) ; module . setupProvider ( Logger ) . addTransport ( injectorReference ( MemoryLoggerTransport ) ) ; module . addProvider ( { provide : WebWorkerFactory , useClass : WebMemoryWorkerFactory } ) ; module . addProvider ( { provide : BrokerServer , useClass : BrokerMemoryServer } ) ; module . addProvider ( MemoryLoggerTransport ) ; module . addProvider ( { provide : Broker , deps : [ BrokerServer ] , useFactory : ( server ) => { return new DirectBroker ( server . kernel ) ; } } ) ; if ( ! module . hasImport ( FrameworkModule ) ) module . addImportAtBeginning ( new FrameworkModule ) ; if ( entities . length ) { module . addProvider ( { provide : Database , useValue : new Database ( new MemoryDatabaseAdapter , entities ) } ) ; module . setupGlobalProvider ( DatabaseRegistry ) . addDatabase ( Database , { } , module ) ; } if ( setup ) module . setup ( setup as any ) ; return new TestingFacade ( App . fromModule ( module ) ) ; }