UNPKG

typescript-assistant

Version:

Combines and integrates professional Typescript tools into your project

109 lines (102 loc) 3.48 kB
import { Task, TaskRunner } from '../taskrunner'; import { Logger } from '../logger'; import { Bus, EventType } from '../bus'; import { absolutePath } from '../util'; import { Git } from '../git'; export interface NYC { start(triggers: EventType[]): void; stop(): void; run(): Promise<boolean>; } let delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms)); export let createNyc = (dependencies: { taskRunner: TaskRunner, logger: Logger, bus: Bus, git: Git }): NYC => { let { taskRunner, logger, bus, git } = dependencies; let runningTask: Task | undefined; let coolingDown: Promise<void> | undefined; let startNyc = async (): Promise<boolean> => { let hasFailingTest = false; let myCoolingDown = delay(100); coolingDown = myCoolingDown; await (myCoolingDown); if (coolingDown !== myCoolingDown) { return false; } if (runningTask) { logger.log('nyc', 'Aborting previous nyc run'); runningTask.kill(); runningTask = undefined; } else { bus.report({ tool: 'test', status: 'busy' }); bus.report({ tool: 'coverage', status: 'busy' }); } let errorLine = ''; let lastLineWasNotOk = false; let handleOutput = (line: string) => { if (task === runningTask) { if (lastLineWasNotOk) { errorLine = line; lastLineWasNotOk = false; } // For extra debug info: // if (!/^ok \d+ (.*)/.exec(line)) { logger.log('nyc', ' [ ' + line); } let notOk = /^not ok \d+ (.*)/.exec(line); let contextIt = /^(} )?at Context\.\S+ \(([^)]+)\)/.exec(line); if (notOk) { lastLineWasNotOk = true; logger.log('nyc', `FAILED: ${notOk[1]}`); hasFailingTest = true; } else if (contextIt) { logger.log('nyc', `${absolutePath(contextIt[2])} ${errorLine}`); errorLine = ''; } } return true; }; let handleError = (line: string) => { if (task === runningTask) { if (!line.startsWith('ERROR: Coverage for')) { logger.error('nyc', line); } } return true; }; let task = runningTask = taskRunner.runTask( './node_modules/.bin/nyc', ('--check-coverage -- ' + './node_modules/.bin/mocha --require ts-node/register/transpile-only --reporter tap test/**/*-tests.ts*').split(' '), { name: 'nyc', logger, handleOutput, handleError }); return runningTask.result.then(() => { if (task === runningTask) { runningTask = undefined; logger.log('nyc', 'code coverage OK'); bus.report({ tool: 'test', status: 'ready', errors: 0 }); bus.report({ tool: 'coverage', status: 'ready', errors: 0 }); } return true; }).catch(async () => { if (task === runningTask) { runningTask = undefined; logger.log('nyc', 'code coverage FAILED'); bus.report({ tool: 'test', status: 'ready', errors: hasFailingTest ? 1 : 0 }); bus.report({ tool: 'coverage', status: 'ready', errors: 1 }); } let isOnBranch = await git.isOnBranch(); return isOnBranch && !hasFailingTest; }); }; return { run: () => startNyc().catch(() => false), start: (triggers: EventType[]) => { bus.registerAll(triggers, startNyc); startNyc().catch(() => false); }, stop: () => { bus.unregister(startNyc); } }; };