| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  | import {ChildProcess, fork} from 'child_process'; | 
					
						
							|  |  |  | import {join} from 'path'; | 
					
						
							|  |  |  | import {goldenMatcher} from './matcher'; | 
					
						
							|  |  |  | import {Client} from './tsclient'; | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('Angular Language Service', () => { | 
					
						
							|  |  |  |   jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; /* 10 seconds */ | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  |   const PWD = process.env.PWD!; | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |   const SERVER_PATH = './node_modules/typescript/lib/tsserver.js'; | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |   let server: ChildProcess; | 
					
						
							|  |  |  |   let client: Client; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     jasmine.addMatchers(goldenMatcher); | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |     server = fork( | 
					
						
							|  |  |  |         SERVER_PATH, | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |           '--logVerbosity', | 
					
						
							|  |  |  |           'verbose', | 
					
						
							|  |  |  |           '--logFile', | 
					
						
							|  |  |  |           join(PWD, 'tsserver.log'), | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           stdio: ['pipe', 'pipe', 'inherit', 'ipc'], | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |     client = new Client(server); | 
					
						
							|  |  |  |     client.listen(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  |   afterEach(async () => { | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |     client.sendRequest('exit', {}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Give server process some time to flush all messages
 | 
					
						
							|  |  |  |     await new Promise((resolve) => setTimeout(resolve, 1000)); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  |   it('should be launched as tsserver plugin', async () => { | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |     let response = await client.sendRequest('configure', { | 
					
						
							|  |  |  |       hostInfo: 'vscode', | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     expect(response).toMatchGolden('configure.json'); | 
					
						
							|  |  |  |     response = await client.sendRequest('compilerOptionsForInferredProjects', { | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |       'options': { | 
					
						
							|  |  |  |         module: 'CommonJS', | 
					
						
							|  |  |  |         target: 'ES6', | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |         allowSyntheticDefaultImports: true, | 
					
						
							|  |  |  |         allowNonTsExtensions: true, | 
					
						
							|  |  |  |         allowJs: true, | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |         jsx: 'Preserve' | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     expect(response).toMatchGolden('compilerOptionsForInferredProjects.json'); | 
					
						
							|  |  |  |     // Server does not send response to open request
 | 
					
						
							|  |  |  |     // https://github.com/Microsoft/TypeScript/blob/master/lib/protocol.d.ts#L1055
 | 
					
						
							|  |  |  |     client.sendRequest('open', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.module.ts`, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     // Server does not send response to geterr request
 | 
					
						
							|  |  |  |     // https://github.com/Microsoft/TypeScript/blob/master/lib/protocol.d.ts#L1770
 | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |     client.sendRequest('geterr', {delay: 0, files: [`${PWD}/project/app/app.module.ts`]}); | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  |   it('should perform completions', async () => { | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |     await client.sendRequest('configure', { | 
					
						
							|  |  |  |       hostInfo: 'vscode', | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     await client.sendRequest('compilerOptionsForInferredProjects', { | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |       'options': { | 
					
						
							|  |  |  |         module: 'CommonJS', | 
					
						
							|  |  |  |         target: 'ES6', | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |         allowSyntheticDefaultImports: true, | 
					
						
							|  |  |  |         allowNonTsExtensions: true, | 
					
						
							|  |  |  |         allowJs: true, | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |         jsx: 'Preserve' | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.sendRequest('open', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |     client.sendRequest('geterr', {delay: 0, files: [`${PWD}/project/app/app.component.ts`]}); | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     client.sendRequest('change', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |       line: 5, | 
					
						
							|  |  |  |       offset: 30, | 
					
						
							|  |  |  |       endLine: 5, | 
					
						
							|  |  |  |       endOffset: 30, | 
					
						
							|  |  |  |       insertString: '.', | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const response = await client.sendRequest('completionInfo', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |       line: 5, | 
					
						
							|  |  |  |       offset: 31, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     expect(response).toMatchGolden('completionInfo.json'); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2019-04-19 08:53:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  |   it('should perform quickinfo', async () => { | 
					
						
							| 
									
										
										
										
											2019-04-19 08:53:19 -07:00
										 |  |  |     client.sendRequest('open', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const resp1 = await client.sendRequest('reload', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |       tmpFile: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |     }) as any; | 
					
						
							|  |  |  |     expect(resp1.command).toBe('reload'); | 
					
						
							|  |  |  |     expect(resp1.success).toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const resp2 = await client.sendRequest('quickinfo', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |       line: 5, | 
					
						
							|  |  |  |       offset: 28, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     expect(resp2).toMatchGolden('quickinfo.json'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  |   it('should perform definition', async () => { | 
					
						
							| 
									
										
										
										
											2019-04-19 08:53:19 -07:00
										 |  |  |     client.sendRequest('open', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const resp1 = await client.sendRequest('reload', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |       tmpFile: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |     }) as any; | 
					
						
							|  |  |  |     expect(resp1.command).toBe('reload'); | 
					
						
							|  |  |  |     expect(resp1.success).toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const resp2 = await client.sendRequest('definition', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |       line: 5, | 
					
						
							|  |  |  |       offset: 28, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     expect(resp2).toMatchGolden('definition.json'); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2019-04-25 11:11:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  |   it('should perform definitionAndBoundSpan', async () => { | 
					
						
							| 
									
										
										
										
											2019-04-25 11:11:33 -07:00
										 |  |  |     client.sendRequest('open', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |     const resp1 = await client.sendRequest('reload', { | 
					
						
							| 
									
										
										
										
											2019-04-25 11:11:33 -07:00
										 |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |       tmpFile: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |     }) as any; | 
					
						
							|  |  |  |     expect(resp1.command).toBe('reload'); | 
					
						
							|  |  |  |     expect(resp1.success).toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |     const resp2 = await client.sendRequest('definitionAndBoundSpan', { | 
					
						
							| 
									
										
										
										
											2019-04-25 11:11:33 -07:00
										 |  |  |       file: `${PWD}/project/app/app.component.ts`, | 
					
						
							|  |  |  |       line: 5, | 
					
						
							|  |  |  |       offset: 28, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     expect(resp2).toMatchGolden('definitionAndBoundSpan.json'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  |   it('should perform definitionAndBoundSpan for template URLs', async () => { | 
					
						
							| 
									
										
										
										
											2019-08-20 13:13:46 -05:00
										 |  |  |     client.sendRequest('open', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/widget.component.ts`, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const resp1 = await client.sendRequest('reload', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/widget.component.ts`, | 
					
						
							|  |  |  |       tmpFile: `${PWD}/project/app/widget.component.ts`, | 
					
						
							|  |  |  |     }) as any; | 
					
						
							|  |  |  |     expect(resp1.command).toBe('reload'); | 
					
						
							|  |  |  |     expect(resp1.success).toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const resp2 = await client.sendRequest('definitionAndBoundSpan', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/widget.component.ts`, | 
					
						
							|  |  |  |       line: 5, | 
					
						
							|  |  |  |       offset: 19, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     expect(resp2).toMatchGolden('templateUrlDefinition.json'); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2019-09-01 09:56:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should perform definitionAndBoundSpan for style URLs', async () => { | 
					
						
							|  |  |  |     client.sendRequest('open', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/widget.component.ts`, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     client.sendRequest('open', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/style.css`, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const resp1 = await client.sendRequest('reload', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/widget.component.ts`, | 
					
						
							|  |  |  |       tmpFile: `${PWD}/project/app/widget.component.ts`, | 
					
						
							|  |  |  |     }) as any; | 
					
						
							|  |  |  |     expect(resp1.command).toBe('reload'); | 
					
						
							|  |  |  |     expect(resp1.success).toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const resp2 = await client.sendRequest('definitionAndBoundSpan', { | 
					
						
							|  |  |  |       file: `${PWD}/project/app/widget.component.ts`, | 
					
						
							|  |  |  |       line: 6, | 
					
						
							|  |  |  |       offset: 18, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     expect(resp2).toMatchGolden('styleUrlsDefinition.json'); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-12-17 23:44:26 -08:00
										 |  |  | }); |