test(language-service): Add tests for quickinfo and definition (#29990)

`quickinfo` is used for hover tooltip.
`definition` is used for "Go to definition".

PR Close #29990
This commit is contained in:
Keen Yee Liau
2019-04-19 08:53:19 -07:00
committed by Ben Lesh
parent f348deae92
commit 017bf0b794
7 changed files with 127 additions and 40 deletions

View File

@ -15,51 +15,56 @@ export class Client {
listen() {
this.server.stdout.on('data', (data: Buffer) => {
this.data = this.data ? Buffer.concat([this.data, data]) : data;
// tsserver could batch multiple responses together so we have to go
// through the entire buffer to keep looking for messages.
const CONTENT_LENGTH = 'Content-Length: '
const index = this.data.indexOf(CONTENT_LENGTH);
if (index < 0) {
return;
}
let start = index + CONTENT_LENGTH.length;
let end = this.data.indexOf('\r\n', start);
if (end < start) {
return;
}
const contentLengthStr = this.data.slice(start, end).toString();
const contentLength = Number(contentLengthStr);
if (isNaN(contentLength) || contentLength < 0) {
return;
}
start = end + 4;
end = start + contentLength;
if (end > this.data.length) {
return;
}
const content = this.data.slice(start, end).toString();
this.data = this.data.slice(end);
try {
const payload = JSON.parse(content);
if (payload.type === "event") {
do {
const index = this.data.indexOf(CONTENT_LENGTH);
if (index < 0) {
return;
}
this.responseEmitter.emit('response', payload);
}
catch (error) {
this.responseEmitter.emit('error', error);
}
let start = index + CONTENT_LENGTH.length;
let end = this.data.indexOf('\r\n', start);
if (end < start) {
return;
}
const contentLengthStr = this.data.slice(start, end).toString();
const contentLength = Number(contentLengthStr);
if (isNaN(contentLength) || contentLength < 0) {
return;
}
start = end + 4;
end = start + contentLength;
if (end > this.data.length) {
return;
}
const content = this.data.slice(start, end).toString();
this.data = this.data.slice(end);
try {
const payload = JSON.parse(content);
if (payload.type === "response") {
const seq = `${payload.request_seq}`;
this.responseEmitter.emit(seq, payload);
}
}
catch (error) {
this.responseEmitter.emit('error', error);
}
} while (this.data.length > 0)
});
}
async send(type: string, command: string, params: {}) {
const seq = this.id++;
const request = {
seq: this.id++,
seq,
type,
command,
arguments: params
};
this.server.stdin.write(JSON.stringify(request) + '\r\n');
return new Promise((resolve, reject) => {
this.responseEmitter.once('response', resolve);
this.responseEmitter.once(`${seq}`, resolve);
this.responseEmitter.once('error', reject);
});
}