import { DebugProtocol } from 'vscode-debugprotocol' ; import { ExtendedDebugClient } from './debugClient' ; const LoggingReporter = require ( './loggingReporter' ) ; let unhandledAdapterErrors ; const origTest = test ; const checkLogTest = ( title , testCallback ? , testFn = origTest ) : Mocha . ITest => { if ( ! testCallback ) { return origTest ( title , testCallback ) ; } function runTest ( ) { return new Promise ( ( resolve , reject ) => { const optionalCallback = e => { if ( e ) reject ( e ) ; else resolve ( ) ; } ; const maybeP = testCallback ( optionalCallback ) ; if ( maybeP && maybeP . then ) { maybeP . then ( resolve , reject ) ; } } ) ; } return testFn ( title , ( ) => { return runTest ( ) . then ( ( ) => { if ( unhandledAdapterErrors . length ) { const errStr = unhandledAdapterErrors . length === 1 ? unhandledAdapterErrors [ 0 ] : JSON . stringify ( unhandledAdapterErrors ) ; throw new Error ( errStr ) ; } } ) ; } ) ; } ; ( < Mocha . ITestDefinition > checkLogTest ) . only = ( expectation , assertion ) => checkLogTest ( expectation , assertion , origTest . only ) ; ( < Mocha . ITestDefinition > checkLogTest ) . skip = test . skip ; test = ( < any > checkLogTest ) ; function log ( e ) { if ( e . body . category === 'telemetry' ) return ; const timestamp = new Date ( ) . toISOString ( ) . split ( /[TZ]/ ) [ 1 ] ; const outputBody = e . body . output ? e . body . output . trim ( ) : 'variablesReference: ' + e . body . variablesReference ; const msg = ` ${ timestamp } ${ outputBody }` ; LoggingReporter . logEE . emit ( 'log' , msg ) ; if ( msg . indexOf ( '********' ) >= 0 ) unhandledAdapterErrors . push ( msg ) ; } export type PatchLaunchArgsCb = ( launchArgs : any ) => Promise < void > | void ; let dc ; function patchLaunchFn ( patchLaunchArgsCb ) { function patchLaunchArgs ( launchArgs ) { launchArgs . trace = 'verbose' ; const patchReturnVal = patchLaunchArgsCb ( launchArgs ) ; return patchReturnVal || Promise . resolve ( ) ; } const origLaunch = dc . launch ; dc . launch = ( launchArgs ) => { return patchLaunchArgs ( launchArgs ) . then ( ( ) => origLaunch . call ( dc , launchArgs ) ) ; } ; const origAttachRequest = dc . attachRequest ; dc . attachRequest = ( attachArgs ) => { return patchLaunchArgs ( attachArgs ) . then ( ( ) => origAttachRequest . call ( dc , attachArgs ) ) ; } ; } export interface ISetupOpts { entryPoint : string ; type : string ; patchLaunchArgs ? : PatchLaunchArgsCb ; port ? : number ; alwaysDumpLogs ? : boolean ; } export function setup ( opts ) { unhandledAdapterErrors = [ ] ; dc = new ExtendedDebugClient ( 'node' , opts . entryPoint , opts . type ) ; if ( opts . patchLaunchArgs ) { patchLaunchFn ( opts . patchLaunchArgs ) ; } LoggingReporter . alwaysDumpLogs = opts . alwaysDumpLogs ; dc . addListener ( 'output' , log ) ; return dc . start ( opts . port ) . then ( ( ) => dc ) ; } export function teardown ( ) { dc . removeListener ( 'output' , log ) ; return dc . stop ( ) ; }