diff --git a/tools/gulp/tasks/unit-test.ts b/tools/gulp/tasks/unit-test.ts index dda92efb825c..8ae722d180de 100644 --- a/tools/gulp/tasks/unit-test.ts +++ b/tools/gulp/tasks/unit-test.ts @@ -75,13 +75,16 @@ gulp.task('test', [':test:deps'], () => { }); // Refreshes Karma's file list and schedules a test run. - let runTests = () => { - server.refreshFiles().then(() => server._injector.get('executor').schedule()); + // Tests will only run if TypeScript compilation was successful. + let runTests = (err?: Error) => { + if (!err) { + server.refreshFiles().then(() => server._injector.get('executor').schedule()); + } }; // Boot up the test server and run the tests whenever a new browser connects. server.start(); - server.on('browser_register', runTests); + server.on('browser_register', () => runTests()); // Watch for file changes, rebuild and run the tests. gulp.watch(patternRoot + '.ts', () => runSequence(':build:components:ts:spec', runTests)); diff --git a/tools/gulp/util/task_helpers.ts b/tools/gulp/util/task_helpers.ts index 8913ef2a44be..377d5ff77781 100644 --- a/tools/gulp/util/task_helpers.ts +++ b/tools/gulp/util/task_helpers.ts @@ -35,9 +35,7 @@ function _globify(maybeGlob: string, suffix = '**/*') { /** Creates a task that runs the TypeScript compiler */ export function tsBuildTask(tsConfigPath: string, extraOptions?: CompilerOptions) { - return () => { - compileProject(tsConfigPath, extraOptions); - }; + return () => compileProject(tsConfigPath, extraOptions); } diff --git a/tools/gulp/util/ts-compiler.ts b/tools/gulp/util/ts-compiler.ts index 6045b7aee64b..ab1890066c32 100644 --- a/tools/gulp/util/ts-compiler.ts +++ b/tools/gulp/util/ts-compiler.ts @@ -6,13 +6,14 @@ import * as chalk from 'chalk'; export function compileProject(project: string, options: ts.CompilerOptions) { let parsed = parseProjectConfig(project, options); let program = ts.createProgram(parsed.fileNames, parsed.options); + let baseDir = program.getCurrentDirectory(); // Report any invalid TypeScript options for the project. - checkDiagnostics(program.getOptionsDiagnostics()); + reportDiagnostics(program.getOptionsDiagnostics(), baseDir); let emitResult = program.emit(); - checkDiagnostics(emitResult.diagnostics); + reportDiagnostics(emitResult.diagnostics, baseDir); } /** Parses a TypeScript project configuration. */ @@ -31,26 +32,26 @@ function parseProjectConfig(project: string, options: ts.CompilerOptions) { } /** Formats the TypeScript diagnostics into a error string. */ -export function formatDiagnostics(diagnostics: ts.Diagnostic[]): string { +export function formatDiagnostics(diagnostics: ts.Diagnostic[], baseDir: string): string { return diagnostics.map(diagnostic => { - let res = ts.DiagnosticCategory[diagnostic.category]; + let res = `• ${chalk.red(`TS${diagnostic.code}`)} - `; if (diagnostic.file) { let {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + let filePath = path.relative(baseDir, diagnostic.file.fileName); - res += ` at ${diagnostic.file.fileName}(${line + 1},${character + 1}):`; + res += `${filePath}(${line + 1},${character + 1}): `; } - res += ` ${ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`; + res += `${ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`; return res; }).join('\n'); } -/** Checks diagnostics and throws errors if present. */ -export function checkDiagnostics(diagnostics: ts.Diagnostic[]) { +/** Checks and reports diagnostics if present. */ +export function reportDiagnostics(diagnostics: ts.Diagnostic[], baseDir?: string) { if (diagnostics && diagnostics.length && diagnostics[0]) { - console.error(formatDiagnostics(diagnostics)); - console.error(chalk.red('TypeScript compilation failed. Exiting process.')); - process.exit(1); + console.error(formatDiagnostics(diagnostics, baseDir)); + throw new Error('TypeScript compilation failed.'); } }