This PR changes the integration test to load language service the way it would be loaded in the editor. If the language service is specified in tsconfig, it'd only be loaded for Angular projects. Specifying it as `globalPlugins` loads it unconditionally whenever tsserver is brought up. PR Close #30153
174 lines
5.1 KiB
TypeScript
174 lines
5.1 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, [
|
|
'--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`,
|
|
});
|
|
// 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`,
|
|
});
|
|
|
|
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');
|
|
});
|
|
|
|
it('should perform quickinfo', async () => {
|
|
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');
|
|
|
|
client.sendRequest('open', {
|
|
file: `${PWD}/project/app/widget.component.html`,
|
|
});
|
|
|
|
const resp3 = await client.sendRequest('quickinfo', {
|
|
file: `${PWD}/project/app/widget.component.html`,
|
|
line: 1,
|
|
offset: 19,
|
|
});
|
|
expect(resp3).toMatchGolden('quickinfo_externalTemplate.json');
|
|
});
|
|
|
|
it('should perform definition', async () => {
|
|
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');
|
|
});
|
|
|
|
it('should perform definitionAndBoundSpan', async () => {
|
|
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('definitionAndBoundSpan', {
|
|
file: `${PWD}/project/app/app.component.ts`,
|
|
line: 5,
|
|
offset: 28,
|
|
});
|
|
expect(resp2).toMatchGolden('definitionAndBoundSpan.json');
|
|
});
|
|
|
|
});
|