The current integration test for language service involves piping the results of one process to another using Unix pipes. This makes the test hard to debug, and hard to configure. This commit refactors the integration test to use regular Jasmine scaffolding. More importantly, it tests the way the language service will actually be installed by end users. Users would not have to add `@angular/language-service` to the plugins section in tsconfig.json Instead, all they need to do is install the *extension* from the VS Code Marketplace and Angular Language Service will be loaded as a global plugin. PR Close #28168
105 lines
3.2 KiB
TypeScript
105 lines
3.2 KiB
TypeScript
import { fork, ChildProcess } from 'child_process';
|
|
import { join } from 'path';
|
|
import { Client } from './tsclient';
|
|
import { goldenMatcher } from './matcher';
|
|
|
|
describe('Angular Language Service', () => {
|
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; /* 10 seconds */
|
|
const PWD = process.env.PWD!;
|
|
const SERVER_PATH = "./node_modules/typescript/lib/tsserver.js";
|
|
let server: ChildProcess;
|
|
let client: Client;
|
|
|
|
beforeEach(() => {
|
|
jasmine.addMatchers(goldenMatcher);
|
|
server = fork(SERVER_PATH, [
|
|
'--globalPlugins', '@angular/language-service',
|
|
'--logVerbosity', 'verbose',
|
|
'--logFile', join(PWD, 'tsserver.log'),
|
|
], {
|
|
stdio: ['pipe', 'pipe', 'inherit', 'ipc'],
|
|
});
|
|
client = new Client(server);
|
|
client.listen();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
client.sendRequest('exit', {});
|
|
|
|
// Give server process some time to flush all messages
|
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
});
|
|
|
|
it('should be launched as tsserver plugin', async () => {
|
|
let response = await client.sendRequest('configure', {
|
|
hostInfo: 'vscode',
|
|
});
|
|
expect(response).toMatchGolden('configure.json');
|
|
response = await client.sendRequest('compilerOptionsForInferredProjects', {
|
|
"options": {
|
|
module: "CommonJS",
|
|
target: "ES6",
|
|
allowSyntheticDefaultImports: true,
|
|
allowNonTsExtensions: true,
|
|
allowJs: true,
|
|
jsx: "Preserve"
|
|
}
|
|
});
|
|
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`,
|
|
fileContent: ""
|
|
});
|
|
// Server does not send response to geterr request
|
|
// https://github.com/Microsoft/TypeScript/blob/master/lib/protocol.d.ts#L1770
|
|
client.sendRequest('geterr', {
|
|
delay: 0,
|
|
files: [`${PWD}/project/app/app.module.ts`]
|
|
});
|
|
});
|
|
|
|
it('should perform completions', async () => {
|
|
await client.sendRequest('configure', {
|
|
hostInfo: 'vscode',
|
|
});
|
|
await client.sendRequest('compilerOptionsForInferredProjects', {
|
|
"options": {
|
|
module: "CommonJS",
|
|
target: "ES6",
|
|
allowSyntheticDefaultImports: true,
|
|
allowNonTsExtensions: true,
|
|
allowJs: true,
|
|
jsx: "Preserve"
|
|
}
|
|
});
|
|
|
|
client.sendRequest('open', {
|
|
file: `${PWD}/project/app/app.component.ts`,
|
|
fileContent: "import { Component } from '@angular/core';\n\n@Component({\n selector: 'my-app',\n template: `<h1>Hello {{name}}</h1>`,\n})\nexport class AppComponent { name = 'Angular'; }\n"
|
|
});
|
|
|
|
client.sendRequest('geterr', {
|
|
delay: 0,
|
|
files: [`${PWD}/project/app/app.component.ts`]
|
|
});
|
|
|
|
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');
|
|
});
|
|
});
|