import * as pathNode from 'path' ; import * as fs from 'fs' ; import * as resolve from 'resolve' ; import { ipcRenderer , remote } from 'electron' ; import * as querystring from 'querystring' ; import * as glob from 'glob' ; import { FlossEvent } from './common' ; let nycInst ; if ( process . env . NYC_CONFIG ) { try { const NYC = require ( 'nyc' ) ; let config = { } ; if ( process . env . NYC_CONFIG ) config = JSON . parse ( process . env . NYC_CONFIG ) ; config . isChildProcess = true ; config . _processInfo = { pid : process . pid , ppid : process . ppid , parent : process . env . NYC_PROCESS_ID || null , root : process . env . NYC_ROOT_ID } ; if ( process . env . NYC_PROCESSINFO_EXTERNAL_ID ) { config . _processInfo . externalId = process . env . NYC_PROCESSINFO_EXTERNAL_ID ; delete process . env . NYC_PROCESSINFO_EXTERNAL_ID ; } nycInst = new NYC ( config ) ; nycInst . wrap ( ) ; } catch ( e ) { console . log ( e ) ; } } class Renderer { options : any ; constructor ( linkId ) { ipcRenderer . on ( FlossEvent . Start , ( _ev , data ) => { this . options = ( global as any ) . options = JSON . parse ( data ) ; const { path , debug , quiet , require : additionalRequire , } = this . options ; this . setupConsoleOutput ( quiet , ! debug ) ; require ( 'mocha/mocha' ) ; if ( additionalRequire ) { require ( additionalRequire ) ; } const files = glob . sync ( path ) ; if ( debug ) { this . headful ( files ) ; } else { this . headless ( files ) ; } } ) ; const mochaPath = pathNode . dirname ( resolve . sync ( 'mocha' , { basedir : __dirname } ) ) ; const link = document . getElementById ( linkId ) as HTMLLinkElement ; link . href = pathNode . join ( mochaPath , 'mocha.css' ) ; } /**
     * Run tests using devtools and Electron window.
     */ private headful ( files ) { mocha . setup ( { ui : 'bdd' , timeout : 0 } ) ; files . map ( ( file ) => this . addFile ( file ) ) . filter ( ( file ) => file !== null ) . forEach ( ( file ) => require ( file as string ) ) ; mocha . run ( ( ) => { if ( nycInst ) { nycInst . writeCoverageFile ( ) ; } } ) ; } private headless ( files ) { try { mocha . setup ( { ui : 'bdd' , } ) ; let reporterOptions ; if ( typeof this . options . reporterOptions === 'string' ) { reporterOptions = querystring . parse ( this . options . reporterOptions ) ; } const Mocha = require ( 'mocha' ) ; const mochaInst = new Mocha ( { reporter : this . options . reporter , reporterOptions , color : true , } ) ; files . map ( ( file ) => this . addFile ( file ) ) . filter ( ( file ) => file !== null ) . forEach ( ( file ) => mochaInst . addFile ( file as string ) ) ; mochaInst . run ( ( errorCount ) => { if ( nycInst ) { try { nycInst . writeCoverageFile ( ) ; } catch ( e ) { this . failed ( 'Unable to write coverage file.' ) ; return ; } } if ( errorCount > 0 ) { this . failed ( ) ; } else { this . success ( ) ; } } ) ; } catch ( e ) { if ( nycInst ) { nycInst . writeCoverageFile ( ) ; } this . failed ( e . message ) ; } } /**
     * Report when we're done, this will close floss.
     */ private success ( ) { ipcRenderer . send ( FlossEvent . Done ) ; } /**
     * Report if we failed, this will close floss with non-zero errorCode.
     */ private failed ( message ? ) { ipcRenderer . send ( FlossEvent . Error , message ) ; } /**
     * Create new bindings for `console` functions
     * Use default console[name] and also send IPC
     * log so we can log to stdout
     */ private setupConsoleOutput ( isQuiet , isHeadless ) { const remoteConsole = remote . getGlobal ( 'console' ) ; if ( ! isQuiet && isHeadless ) { for ( const name in console ) { const n = name as keyof Console ; if ( typeof console [ n ] === 'function' ) { console [ n ] = remoteConsole [ n ] ; } } } Object . defineProperty ( process , 'stdout' , { value : { write : ( str ) => remote . process . stdout . write ( str ) , } } ) ; } param testPath private addFile ( testPath ) { testPath = pathNode . resolve ( testPath ) ; if ( ! fs . existsSync ( testPath ) ) { return null ; } if ( fs . statSync ( testPath ) . isDirectory ( ) ) { const indexFile = pathNode . join ( testPath , 'index.js' ) ; const indexTs = pathNode . join ( testPath , 'index.ts' ) ; if ( fs . existsSync ( indexFile ) ) { return indexFile ; } else if ( fs . existsSync ( indexTs ) ) { return indexTs ; } console . error ( `No index.js file found in directory: ${ testPath }` ) ; return null ; } return testPath ; } } module . exports = Renderer ;