import { InternalError } from "@adpt/utils" ; import express , { Express } from "express" ; import http from "http" ; import { Done } from "mocha" ; export { Request , Response } from "express" ; type FixtureFunc = ( callback : ( done : Done ) => PromiseLike < any > | void ) => void ; export interface MochaExpressOptions { } export interface ExpressFixture { app : Express ; url : string ; } class ExpressFixtureImpl implements ExpressFixture { app_ ? : Express ; server_ ? : http . Server ; url_ ? : string ; constructor ( public options = { } ) { } get app ( ) { if ( ! this . app_ ) throw new Error ( `Must call start before accessing app` ) ; return this . app_ ; } get server ( ) { if ( ! this . server_ ) throw new Error ( `Must call start before accessing server` ) ; return this . server_ ; } get url ( ) { if ( ! this . url_ ) throw new Error ( `Must call start before accessing url` ) ; return this . url_ ; } async start ( ) { const app = express ( ) ; this . app_ = app ; this . server_ = http . createServer ( app ) ; await new Promise ( ( res , rej ) => this . server . listen ( ( err ) => err ? rej ( err ) : res ( ) ) ) ; const addr = this . server . address ( ) ; if ( typeof addr === "string" ) throw new InternalError ( `Expected an object` ) ; this . url_ = `http://localhost:${ addr . port }` ; } async stop ( ) { const server = this . server_ ; if ( ! server ) return ; this . server_ = undefined ; await new Promise ( ( res , rej ) => server . close ( ( err ) => err ? rej ( err ) : res ( ) ) ) ; } } function setup ( beforeFn , afterFn , fixture ) { beforeFn ( async function startExpress ( this ) { this . timeout ( 20 * 1000 ) ; await fixture . start ( ) ; } ) ; afterFn ( async function stopExpress ( this ) { this . timeout ( 20 * 1000 ) ; await fixture . stop ( ) ; } ) ; } export function all ( options = { } ) { const fixture = new ExpressFixtureImpl ( options ) ; setup ( before , after , fixture ) ; return fixture ; } export function each ( options = { } ) { const fixture = new ExpressFixtureImpl ( options ) ; setup ( beforeEach , afterEach , fixture ) ; return fixture ; }