import chalk from 'chalk' ; import { createServer , Server } from 'http' ; import express , { Express , Router } from 'express' ; import listen from 'async-listen' ; import Client from '../../src/util/client' ; import { Output } from '../../src/util/output' ; chalk . level = 0 ; export type Scenario = Router ; export class MockClient extends Client { mockServer ? : Server ; mockOutput : jest . Mock < void , Parameters < Output [ 'print' ] > > ; private app : Express ; scenario : Scenario ; constructor ( ) { super ( { argv : [ ] , apiUrl : '' , authConfig : { } , output : new Output ( ) , config : { } , localConfig : { } , } ) ; this . mockOutput = jest . fn ( ) ; this . app = express ( ) ; this . app . use ( express . json ( ) ) ; this . app . use ( ( req , res , next ) => { this . scenario ( req , res , next ) ; } ) ; this . app . use ( ( req , res ) => { const message = `[Vercel API Mock] \`${ req . method } ${ req . path }\` was not handled.` ; console . warn ( message ) ; res . status ( 404 ) . json ( { error : { code : 'not_found' , message , } , } ) ; } ) ; this . scenario = Router ( ) ; } reset ( ) { this . output = new Output ( ) ; this . mockOutput = jest . fn ( ) ; this . output . print = s => { return this . mockOutput ( s ) ; } ; this . argv = [ ] ; this . authConfig = { } ; this . config = { } ; this . localConfig = { } ; this . output . spinner = ( ) => { } ; this . scenario = Router ( ) ; this . output . isTTY = true ; } get outputBuffer ( ) { return this . mockOutput . mock . calls . map ( c => c [ 0 ] ) . join ( '' ) ; } async startMockServer ( ) { this . mockServer = createServer ( this . app ) ; await listen ( this . mockServer , 0 ) ; const address = this . mockServer . address ( ) ; if ( ! address || typeof address === 'string' ) { throw new Error ( 'Unexpected http server address' ) ; } this . apiUrl = `http://127.0.0.1:${ address . port }` ; } stopMockServer ( ) { this . mockServer ?. close ( ) ; } setArgv ( ... argv ) { this . argv = [ process . execPath , 'cli.js' , ... argv ] ; } useScenario ( scenario ) { this . scenario = scenario ; } } export const client = new MockClient ( ) ; beforeAll ( async ( ) => { await client . startMockServer ( ) ; } ) ; beforeEach ( ( ) => { client . reset ( ) ; } ) ; afterAll ( ( ) => { client . stopMockServer ( ) ; } ) ;