From 6ea3ab7e14a14baec8327192c1698e269a0a4e04 Mon Sep 17 00:00:00 2001 From: Bowen Ni Date: Wed, 30 Nov 2016 16:37:28 -0800 Subject: [PATCH] Fix exit code. Give a specific type. Add test cases. --- modules/@angular/compiler-cli/src/main.ts | 6 +- .../@angular/compiler-cli/test/main_spec.ts | 74 ++++++++++++++++--- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/modules/@angular/compiler-cli/src/main.ts b/modules/@angular/compiler-cli/src/main.ts index ffaae93cc6..f8832997b2 100644 --- a/modules/@angular/compiler-cli/src/main.ts +++ b/modules/@angular/compiler-cli/src/main.ts @@ -22,14 +22,14 @@ function codegen( return CodeGenerator.create(ngOptions, cliOptions, program, host).codegen(); } -export function main(args: any, consoleError: any): Promise { +export function main(args: any, consoleError: (s: string) => void = console.error): Promise { const project = args.p || args.project || '.'; const cliOptions = new tsc.NgcCliOptions(args); return tsc.main(project, cliOptions, codegen).then(() => 0).catch(e => { if (e instanceof tsc.UserError) { consoleError(e.message); - return Promise.resolve(0); + return Promise.resolve(1); } else { consoleError(e.stack); consoleError('Compilation failed'); @@ -41,5 +41,5 @@ export function main(args: any, consoleError: any): Promise { // CLI entry point if (require.main === module) { const args = require('minimist')(process.argv.slice(2)); - main(args, console.error).then((exitCode: number) => process.exit(exitCode)); + main(args).then((exitCode: number) => process.exit(exitCode)); } \ No newline at end of file diff --git a/modules/@angular/compiler-cli/test/main_spec.ts b/modules/@angular/compiler-cli/test/main_spec.ts index 5f4d11a2f3..df0c0e4491 100644 --- a/modules/@angular/compiler-cli/test/main_spec.ts +++ b/modules/@angular/compiler-cli/test/main_spec.ts @@ -44,7 +44,7 @@ describe('compiler-cli', () => { it('should compile without errors', (done) => { write('test.ts', 'export const A = 1;'); - const mockConsole = {error: {}}; + const mockConsole = {error: (s: string) => {}}; spyOn(mockConsole, 'error'); @@ -58,32 +58,88 @@ describe('compiler-cli', () => { }); it('should not print the stack trace if user input file does not exist', (done) => { - const mockConsole = {error: {}}; + const mockConsole = {error: (s: string) => {}}; spyOn(mockConsole, 'error'); main({p: basePath}, mockConsole.error) .then((exitCode) => { - expect(mockConsole.error).toHaveBeenCalled(); + expect(mockConsole.error).toHaveBeenCalledWith(`Error File '` + path.join(basePath, 'test.ts') + `' not found.`); expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); - expect(exitCode).toEqual(0); + expect(exitCode).toEqual(1); done(); }) .catch(e => done.fail(e)); }); it('should not print the stack trace if user input file is malformed', (done) => { - write('test.ts', 'foo bar'); + write('test.ts', 'foo;'); - const mockConsole = {error: {}}; + const mockConsole = {error: (s: string) => {}}; spyOn(mockConsole, 'error'); main({p: basePath}, mockConsole.error) .then((exitCode) => { - expect(mockConsole.error).toHaveBeenCalled(); + expect(mockConsole.error).toHaveBeenCalledWith('Error at ' + path.join(basePath, 'test.ts') + `:1:1: Cannot find name 'foo'.`); expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); - expect(exitCode).toEqual(0); + expect(exitCode).toEqual(1); + done(); + }) + .catch(e => done.fail(e)); + }); + + it('should not print the stack trace if cannot find the imported module', (done) => { + write('test.ts', "import {MyClass} from './not-exist-deps';"); + + const mockConsole = {error: (s: string) => {}}; + + spyOn(mockConsole, 'error'); + + main({p: basePath}, mockConsole.error) + .then((exitCode) => { + expect(mockConsole.error).toHaveBeenCalledWith('Error at ' + path.join(basePath, 'test.ts') + `:1:23: Cannot find module './not-exist-deps'.`); + expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); + expect(exitCode).toEqual(1); + done(); + }) + .catch(e => done.fail(e)); + }); + + it('should not print the stack trace if cannot import', (done) => { + write('empty-deps.ts', 'export const A = 1;'); + write('test.ts', "import {MyClass} from './empty-deps';"); + + const mockConsole = {error: (s: string) => {}}; + + spyOn(mockConsole, 'error'); + + main({p: basePath}, mockConsole.error) + .then((exitCode) => { + expect(mockConsole.error).toHaveBeenCalledWith('Error at ' + path.join(basePath, 'test.ts') + `:1:9: Module '"` + path.join(basePath, 'empty-deps') + `"' has no exported member 'MyClass'.`); + expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); + expect(exitCode).toEqual(1); + done(); + }) + .catch(e => done.fail(e)); + }); + + it('should not print the stack trace if type mismatches', (done) => { + write('empty-deps.ts', 'export const A = "abc";'); + write('test.ts', ` + import {A} from './empty-deps'; + A(); + `); + + const mockConsole = {error: (s: string) => {}}; + + spyOn(mockConsole, 'error'); + + main({p: basePath}, mockConsole.error) + .then((exitCode) => { + expect(mockConsole.error).toHaveBeenCalledWith('Error at ' + path.join(basePath, 'test.ts') + ':3:7: Cannot invoke an expression whose type lacks a call signature.'); + expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); + expect(exitCode).toEqual(1); done(); }) .catch(e => done.fail(e)); @@ -92,7 +148,7 @@ describe('compiler-cli', () => { it('should print the stack trace on compiler internal errors', (done) => { write('test.ts', 'export const A = 1;'); - const mockConsole = {error: {}}; + const mockConsole = {error: (s: string) => {}}; spyOn(mockConsole, 'error');