| 
									
										
										
										
											2018-01-26 14:12:46 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2018-01-26 14:12:46 -08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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 * as path from 'path'; | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  | import * as ts from 'typescript'; | 
					
						
							| 
									
										
										
										
											2018-01-26 14:12:46 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {ReflectorHost} from '../src/reflector_host'; | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  | import {TypeScriptServiceHost} from '../src/typescript_host'; | 
					
						
							| 
									
										
										
										
											2018-01-26 14:12:46 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {MockTypescriptHost} from './test_utils'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('reflector_host_spec', () => { | 
					
						
							|  |  |  |   // Regression #21811
 | 
					
						
							|  |  |  |   it('should be able to find angular under windows', () => { | 
					
						
							|  |  |  |     const originalJoin = path.join; | 
					
						
							| 
									
										
										
										
											2019-05-22 08:26:05 +02:00
										 |  |  |     const originalPosixJoin = path.posix.join; | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  |     const mockHost = | 
					
						
							| 
									
										
										
										
											2019-09-17 14:33:41 -07:00
										 |  |  |         new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts'], 'node_modules', { | 
					
						
							| 
									
										
										
										
											2019-05-22 08:26:05 +02:00
										 |  |  |           ...path, | 
					
						
							|  |  |  |           join: (...args: string[]) => originalJoin.apply(path, args), | 
					
						
							| 
									
										
										
										
											2020-04-03 20:57:39 -07:00
										 |  |  |           posix: {...path.posix, join: (...args: string[]) => originalPosixJoin.apply(path, args)} | 
					
						
							| 
									
										
										
										
											2019-05-22 08:26:05 +02:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2019-08-05 17:13:20 -07:00
										 |  |  |     const reflectorHost = new ReflectorHost(() => undefined as any, mockHost); | 
					
						
							| 
									
										
										
										
											2018-01-26 14:12:46 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 15:07:39 +02:00
										 |  |  |     if (process.platform !== 'win32') { | 
					
						
							|  |  |  |       // If we call this in Windows it will cause a 'Maximum call stack size exceeded error'
 | 
					
						
							|  |  |  |       // Because we are spying on the same function that we are call faking
 | 
					
						
							| 
									
										
										
										
											2020-04-03 20:57:39 -07:00
										 |  |  |       spyOn(path, 'join').and.callFake((...args: string[]) => { | 
					
						
							|  |  |  |         return path.win32.join(...args); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-04-25 15:07:39 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-26 14:12:46 -08:00
										 |  |  |     const result = reflectorHost.moduleNameToFileName('@angular/core'); | 
					
						
							|  |  |  |     expect(result).not.toBeNull('could not find @angular/core using path.win32'); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should use module resolution cache', () => { | 
					
						
							| 
									
										
										
										
											2019-09-17 14:33:41 -07:00
										 |  |  |     const mockHost = new MockTypescriptHost(['/app/main.ts']); | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  |     // TypeScript relies on `ModuleResolutionHost.fileExists()` to perform
 | 
					
						
							| 
									
										
										
										
											2019-09-12 09:29:41 -07:00
										 |  |  |     // module resolution, so spy on this method to determine how many times
 | 
					
						
							|  |  |  |     // it's called.
 | 
					
						
							|  |  |  |     const spy = spyOn(mockHost, 'fileExists').and.callThrough(); | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const tsLS = ts.createLanguageService(mockHost); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-11 23:12:58 -07:00
										 |  |  |     // First count is zero due to lazy instantiation of the StaticReflector
 | 
					
						
							|  |  |  |     // and MetadataResolver.
 | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  |     const ngLSHost = new TypeScriptServiceHost(mockHost, tsLS); | 
					
						
							|  |  |  |     const firstCount = spy.calls.count(); | 
					
						
							| 
									
										
										
										
											2019-09-11 23:12:58 -07:00
										 |  |  |     expect(firstCount).toBe(0); | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  |     spy.calls.reset(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Second count is due to resolution of the Tour of Heroes (toh) project.
 | 
					
						
							|  |  |  |     // This resolves all Angular directives in the project.
 | 
					
						
							|  |  |  |     ngLSHost.getAnalyzedModules(); | 
					
						
							|  |  |  |     const secondCount = spy.calls.count(); | 
					
						
							| 
									
										
										
										
											2020-05-13 11:27:22 +02:00
										 |  |  |     expect(secondCount).toBeGreaterThan(500); | 
					
						
							|  |  |  |     expect(secondCount).toBeLessThan(600); | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  |     spy.calls.reset(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Third count is due to recompution after the program changes.
 | 
					
						
							|  |  |  |     mockHost.addCode('');  // this will mark project as dirty
 | 
					
						
							|  |  |  |     ngLSHost.getAnalyzedModules(); | 
					
						
							|  |  |  |     const thirdCount = spy.calls.count(); | 
					
						
							| 
									
										
										
										
											2019-09-12 09:29:41 -07:00
										 |  |  |     expect(thirdCount).toBeGreaterThan(0); | 
					
						
							|  |  |  |     expect(thirdCount).toBeLessThan(10); | 
					
						
							| 
									
										
										
										
											2019-09-04 12:45:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Summary
 | 
					
						
							|  |  |  |     // |               | First Count | Second Count | Third Count |
 | 
					
						
							|  |  |  |     // |---------------|-------------|--------------|-------------|
 | 
					
						
							|  |  |  |     // | Without Cache | 2581        | 6291         | 257         |
 | 
					
						
							|  |  |  |     // | With Cache    | 26          | 550          | 84          |
 | 
					
						
							|  |  |  |     // | Improvement   | ~100x       | ~10x         | ~3x         |
 | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2019-08-05 17:13:20 -07:00
										 |  |  | }); |