| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {makeTempDir} from '@angular/tsc-wrapped/test/test_support'; | 
					
						
							|  |  |  | import * as fs from 'fs'; | 
					
						
							|  |  |  | import * as path from 'path'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {main} from '../src/main'; | 
					
						
							|  |  |  | import {ReflectionCapabilities, reflector} from './private_import_core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('compiler-cli', () => { | 
					
						
							|  |  |  |   let basePath: string; | 
					
						
							|  |  |  |   let write: (fileName: string, content: string) => void; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     basePath = makeTempDir(); | 
					
						
							|  |  |  |     write = (fileName: string, content: string) => { | 
					
						
							|  |  |  |       fs.writeFileSync(path.join(basePath, fileName), content, {encoding: 'utf-8'}); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     write('tsconfig.json', `{
 | 
					
						
							|  |  |  |       "compilerOptions": { | 
					
						
							|  |  |  |         "experimentalDecorators": true, | 
					
						
							|  |  |  |         "types": [], | 
					
						
							|  |  |  |         "outDir": "built", | 
					
						
							|  |  |  |         "declaration": true, | 
					
						
							| 
									
										
										
										
											2016-12-15 09:12:40 -08:00
										 |  |  |         "module": "es2015", | 
					
						
							|  |  |  |         "moduleResolution": "node" | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  |       }, | 
					
						
							|  |  |  |       "angularCompilerOptions": { | 
					
						
							|  |  |  |         "annotateForClosureCompiler": true | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       "files": ["test.ts"] | 
					
						
							|  |  |  |     }`);
 | 
					
						
							| 
									
										
										
										
											2016-12-15 09:12:40 -08:00
										 |  |  |     const nodeModulesPath = path.resolve(basePath, 'node_modules'); | 
					
						
							|  |  |  |     fs.mkdirSync(nodeModulesPath); | 
					
						
							|  |  |  |     fs.symlinkSync(path.resolve(__dirname, '..', '..'), path.resolve(nodeModulesPath, '@angular')); | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Restore reflector since AoT compiler will update it with a new static reflector
 | 
					
						
							|  |  |  |   afterEach(() => { reflector.updateCapabilities(new ReflectionCapabilities()); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should compile without errors', (done) => { | 
					
						
							|  |  |  |     write('test.ts', 'export const A = 1;'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |     const mockConsole = {error: (s: string) => {}}; | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     spyOn(mockConsole, 'error'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     main({p: basePath}, mockConsole.error) | 
					
						
							|  |  |  |         .then((exitCode) => { | 
					
						
							|  |  |  |           expect(mockConsole.error).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |           expect(exitCode).toEqual(0); | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .catch(e => done.fail(e)); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should not print the stack trace if user input file does not exist', (done) => { | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |     const mockConsole = {error: (s: string) => {}}; | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     spyOn(mockConsole, 'error'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     main({p: basePath}, mockConsole.error) | 
					
						
							|  |  |  |         .then((exitCode) => { | 
					
						
							| 
									
										
										
										
											2016-11-30 16:45:40 -08:00
										 |  |  |           expect(mockConsole.error) | 
					
						
							|  |  |  |               .toHaveBeenCalledWith( | 
					
						
							|  |  |  |                   `Error File '` + path.join(basePath, 'test.ts') + `' not found.`); | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  |           expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |           expect(exitCode).toEqual(1); | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  |           done(); | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .catch(e => done.fail(e)); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should not print the stack trace if user input file is malformed', (done) => { | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |     write('test.ts', 'foo;'); | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |     const mockConsole = {error: (s: string) => {}}; | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     spyOn(mockConsole, 'error'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     main({p: basePath}, mockConsole.error) | 
					
						
							|  |  |  |         .then((exitCode) => { | 
					
						
							| 
									
										
										
										
											2016-11-30 16:45:40 -08:00
										 |  |  |           expect(mockConsole.error) | 
					
						
							|  |  |  |               .toHaveBeenCalledWith( | 
					
						
							|  |  |  |                   'Error at ' + path.join(basePath, 'test.ts') + `:1:1: Cannot find name 'foo'.`); | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  |           expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |           expect(exitCode).toEqual(1); | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .catch(e => done.fail(e)); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should not print the stack trace if cannot find the imported module', (done) => { | 
					
						
							| 
									
										
										
										
											2016-11-30 16:45:40 -08:00
										 |  |  |     write('test.ts', `import {MyClass} from './not-exist-deps';`); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const mockConsole = {error: (s: string) => {}}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     spyOn(mockConsole, 'error'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     main({p: basePath}, mockConsole.error) | 
					
						
							|  |  |  |         .then((exitCode) => { | 
					
						
							| 
									
										
										
										
											2016-11-30 16:45:40 -08:00
										 |  |  |           expect(mockConsole.error) | 
					
						
							|  |  |  |               .toHaveBeenCalledWith( | 
					
						
							|  |  |  |                   'Error at ' + path.join(basePath, 'test.ts') + | 
					
						
							|  |  |  |                   `:1:23: Cannot find module './not-exist-deps'.`); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |           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;'); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:45:40 -08:00
										 |  |  |     write('test.ts', `import {MyClass} from './empty-deps';`); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const mockConsole = {error: (s: string) => {}}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     spyOn(mockConsole, 'error'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     main({p: basePath}, mockConsole.error) | 
					
						
							|  |  |  |         .then((exitCode) => { | 
					
						
							| 
									
										
										
										
											2016-11-30 16:45:40 -08:00
										 |  |  |           expect(mockConsole.error) | 
					
						
							|  |  |  |               .toHaveBeenCalledWith( | 
					
						
							|  |  |  |                   'Error at ' + path.join(basePath, 'test.ts') + `:1:9: Module '"` + | 
					
						
							|  |  |  |                   path.join(basePath, 'empty-deps') + `"' has no exported member 'MyClass'.`); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |           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) => { | 
					
						
							| 
									
										
										
										
											2016-11-30 16:45:40 -08:00
										 |  |  |           expect(mockConsole.error) | 
					
						
							|  |  |  |               .toHaveBeenCalledWith( | 
					
						
							|  |  |  |                   'Error at ' + path.join(basePath, 'test.ts') + | 
					
						
							|  |  |  |                   ':3:7: Cannot invoke an expression whose type lacks a call signature.'); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |           expect(mockConsole.error).not.toHaveBeenCalledWith('Compilation failed'); | 
					
						
							|  |  |  |           expect(exitCode).toEqual(1); | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  |           done(); | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .catch(e => done.fail(e)); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should print the stack trace on compiler internal errors', (done) => { | 
					
						
							|  |  |  |     write('test.ts', 'export const A = 1;'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-30 16:37:28 -08:00
										 |  |  |     const mockConsole = {error: (s: string) => {}}; | 
					
						
							| 
									
										
										
										
											2016-11-30 13:59:53 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     spyOn(mockConsole, 'error'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     main({p: 'not-exist'}, mockConsole.error) | 
					
						
							|  |  |  |         .then((exitCode) => { | 
					
						
							|  |  |  |           expect(mockConsole.error).toHaveBeenCalled(); | 
					
						
							|  |  |  |           expect(mockConsole.error).toHaveBeenCalledWith('Compilation failed'); | 
					
						
							|  |  |  |           expect(exitCode).toEqual(1); | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .catch(e => done.fail(e)); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2016-11-30 16:45:40 -08:00
										 |  |  | }); |