test overriding Session.event

This commit is contained in:
Arthur Ozga 2017-11-17 19:48:57 -08:00
parent 890820b528
commit d2cc4f15be
3 changed files with 70 additions and 72 deletions

View file

@ -210,6 +210,8 @@ namespace ts.projectSystem {
class TestSession extends server.Session { class TestSession extends server.Session {
private seq = 0; private seq = 0;
public events: protocol.Event[] = [];
public host: TestServerHost;
getProjectService() { getProjectService() {
return this.projectService; return this.projectService;
@ -229,6 +231,16 @@ namespace ts.projectSystem {
request.type = "request"; request.type = "request";
return this.executeCommand(<T>request); return this.executeCommand(<T>request);
} }
public event<T>(body: T, eventName: string) {
this.events.push(server.toEvent(eventName, body));
super.event(body, eventName);
}
public clearMessages() {
clear(this.events);
this.host.clearOutput();
}
} }
export function createSession(host: server.ServerHost, opts: Partial<server.SessionOptions> = {}) { export function createSession(host: server.ServerHost, opts: Partial<server.SessionOptions> = {}) {
@ -436,48 +448,29 @@ namespace ts.projectSystem {
verifyDiagnostics(actual, []); verifyDiagnostics(actual, []);
} }
function assertEvent(actualOutput: string, expectedEvent: protocol.Event, host: TestServerHost) { function checkErrorMessage(session: TestSession, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) {
assert.equal(actualOutput, server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, host.newLine)); checkNthEvent(session, ts.server.toEvent(eventName, diagnostics), 0, /*isMostRecent*/ false);
} }
function checkErrorMessage(host: TestServerHost, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) { function checkCompleteEvent(session: TestSession, numberOfCurrentEvents: number, expectedSequenceId: number) {
const outputs = host.getOutput(); checkNthEvent(session, ts.server.toEvent("requestCompleted", { request_seq: expectedSequenceId }), numberOfCurrentEvents - 1, /*isMostRecent*/ true);
assert.isTrue(outputs.length >= 1, outputs.toString());
const event: protocol.Event = {
seq: 0,
type: "event",
event: eventName,
body: diagnostics
};
assertEvent(outputs[0], event, host);
} }
function checkCompleteEvent(host: TestServerHost, numberOfCurrentEvents: number, expectedSequenceId: number) { function checkProjectUpdatedInBackgroundEvent(session: TestSession, openFiles: string[]) {
const outputs = host.getOutput(); checkNthEvent(session, ts.server.toEvent("projectsUpdatedInBackground", { openFiles }), 0, /*isMostRecent*/ true);
assert.equal(outputs.length, numberOfCurrentEvents, outputs.toString());
const event: protocol.RequestCompletedEvent = {
seq: 0,
type: "event",
event: "requestCompleted",
body: {
request_seq: expectedSequenceId
}
};
assertEvent(outputs[numberOfCurrentEvents - 1], event, host);
} }
function checkProjectUpdatedInBackgroundEvent(host: TestServerHost, openFiles: string[]) { function checkNthEvent(session: TestSession, expectedEvent: protocol.Event, index: number, isMostRecent: boolean) {
const outputs = host.getOutput(); const events = session.events;
assert.equal(outputs.length, 1, outputs.toString()); assert.deepEqual(events[index], expectedEvent);
const event: protocol.ProjectsUpdatedInBackgroundEvent = {
seq: 0, const outputs = session.host.getOutput();
type: "event", assert.equal(outputs[index], server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, session.host.newLine));
event: "projectsUpdatedInBackground",
body: { if (isMostRecent) {
openFiles assert.strictEqual(events.length, index + 1, JSON.stringify(events));
} assert.strictEqual(outputs.length, index + 1, JSON.stringify(outputs));
}; }
assertEvent(outputs[0], event, host);
} }
describe("tsserverProjectSystem", () => { describe("tsserverProjectSystem", () => {
@ -2887,14 +2880,14 @@ namespace ts.projectSystem {
assert.isFalse(hasError); assert.isFalse(hasError);
host.checkTimeoutQueueLength(2); host.checkTimeoutQueueLength(2);
checkErrorMessage(host, "syntaxDiag", { file: untitledFile, diagnostics: [] }); checkErrorMessage(session, "syntaxDiag", { file: untitledFile, diagnostics: [] });
host.clearOutput(); session.clearMessages();
host.runQueuedImmediateCallbacks(); host.runQueuedImmediateCallbacks();
assert.isFalse(hasError); assert.isFalse(hasError);
checkErrorMessage(host, "semanticDiag", { file: untitledFile, diagnostics: [] }); checkErrorMessage(session, "semanticDiag", { file: untitledFile, diagnostics: [] });
checkCompleteEvent(host, 2, expectedSequenceId); checkCompleteEvent(session, 2, expectedSequenceId);
} }
it("has projectRoot", () => { it("has projectRoot", () => {
@ -2938,7 +2931,7 @@ namespace ts.projectSystem {
verifyErrorsInApp(); verifyErrorsInApp();
function verifyErrorsInApp() { function verifyErrorsInApp() {
host.clearOutput(); session.clearMessages();
const expectedSequenceId = session.getNextSeq(); const expectedSequenceId = session.getNextSeq();
session.executeCommandSeq<protocol.GeterrRequest>({ session.executeCommandSeq<protocol.GeterrRequest>({
command: server.CommandNames.Geterr, command: server.CommandNames.Geterr,
@ -2948,13 +2941,13 @@ namespace ts.projectSystem {
} }
}); });
host.checkTimeoutQueueLengthAndRun(1); host.checkTimeoutQueueLengthAndRun(1);
checkErrorMessage(host, "syntaxDiag", { file: app.path, diagnostics: [] }); checkErrorMessage(session, "syntaxDiag", { file: app.path, diagnostics: [] });
host.clearOutput(); session.clearMessages();
host.runQueuedImmediateCallbacks(); host.runQueuedImmediateCallbacks();
checkErrorMessage(host, "semanticDiag", { file: app.path, diagnostics: [] }); checkErrorMessage(session, "semanticDiag", { file: app.path, diagnostics: [] });
checkCompleteEvent(host, 2, expectedSequenceId); checkCompleteEvent(session, 2, expectedSequenceId);
host.clearOutput(); session.clearMessages();
} }
}); });
}); });
@ -3679,7 +3672,7 @@ namespace ts.projectSystem {
} }
}); });
checkNumberOfProjects(service, { inferredProjects: 1 }); checkNumberOfProjects(service, { inferredProjects: 1 });
host.clearOutput(); session.clearMessages();
const expectedSequenceId = session.getNextSeq(); const expectedSequenceId = session.getNextSeq();
session.executeCommandSeq<protocol.GeterrRequest>({ session.executeCommandSeq<protocol.GeterrRequest>({
command: server.CommandNames.Geterr, command: server.CommandNames.Geterr,
@ -3690,23 +3683,24 @@ namespace ts.projectSystem {
}); });
host.checkTimeoutQueueLengthAndRun(1); host.checkTimeoutQueueLengthAndRun(1);
checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] }); checkErrorMessage(session, "syntaxDiag", { file: file1.path, diagnostics: [] });
host.clearOutput(); session.clearMessages();
host.runQueuedImmediateCallbacks(); host.runQueuedImmediateCallbacks();
const moduleNotFound = Diagnostics.Cannot_find_module_0; const moduleNotFound = Diagnostics.Cannot_find_module_0;
const startOffset = file1.content.indexOf('"') + 1; const startOffset = file1.content.indexOf('"') + 1;
checkErrorMessage(host, "semanticDiag", { checkErrorMessage(session, "semanticDiag", {
file: file1.path, diagnostics: [{ file: file1.path, diagnostics: [{
start: { line: 1, offset: startOffset }, start: { line: 1, offset: startOffset },
end: { line: 1, offset: startOffset + '"pad"'.length }, end: { line: 1, offset: startOffset + '"pad"'.length },
text: formatStringFromArgs(moduleNotFound.message, ["pad"]), text: formatStringFromArgs(moduleNotFound.message, ["pad"]),
code: moduleNotFound.code, code: moduleNotFound.code,
category: DiagnosticCategory[moduleNotFound.category].toLowerCase() category: DiagnosticCategory[moduleNotFound.category].toLowerCase(),
source: undefined
}] }]
}); });
checkCompleteEvent(host, 2, expectedSequenceId); checkCompleteEvent(session, 2, expectedSequenceId);
host.clearOutput(); session.clearMessages();
const padIndex: FileOrFolder = { const padIndex: FileOrFolder = {
path: `${folderPath}/node_modules/@types/pad/index.d.ts`, path: `${folderPath}/node_modules/@types/pad/index.d.ts`,
@ -3715,15 +3709,15 @@ namespace ts.projectSystem {
files.push(padIndex); files.push(padIndex);
host.reloadFS(files, { ignoreWatchInvokedWithTriggerAsFileCreate: true }); host.reloadFS(files, { ignoreWatchInvokedWithTriggerAsFileCreate: true });
host.runQueuedTimeoutCallbacks(); host.runQueuedTimeoutCallbacks();
checkProjectUpdatedInBackgroundEvent(host, [file1.path]); checkProjectUpdatedInBackgroundEvent(session, [file1.path]);
host.clearOutput(); session.clearMessages();
host.runQueuedTimeoutCallbacks(); host.runQueuedTimeoutCallbacks();
checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] }); checkErrorMessage(session, "syntaxDiag", { file: file1.path, diagnostics: [] });
host.clearOutput(); session.clearMessages();
host.runQueuedImmediateCallbacks(); host.runQueuedImmediateCallbacks();
checkErrorMessage(host, "semanticDiag", { file: file1.path, diagnostics: [] }); checkErrorMessage(session, "semanticDiag", { file: file1.path, diagnostics: [] });
}); });
}); });
@ -4837,7 +4831,7 @@ namespace ts.projectSystem {
command: "projectInfo", command: "projectInfo",
arguments: { file: f1.path } arguments: { file: f1.path }
}); });
host.clearOutput(); session.clearMessages();
// cancel previously issued Geterr // cancel previously issued Geterr
cancellationToken.setRequestToCancel(getErrId); cancellationToken.setRequestToCancel(getErrId);
@ -4861,7 +4855,7 @@ namespace ts.projectSystem {
assert.equal(host.getOutput().length, 1, "expect 1 message"); assert.equal(host.getOutput().length, 1, "expect 1 message");
const e1 = <protocol.Event>getMessage(0); const e1 = <protocol.Event>getMessage(0);
assert.equal(e1.event, "syntaxDiag"); assert.equal(e1.event, "syntaxDiag");
host.clearOutput(); session.clearMessages();
cancellationToken.setRequestToCancel(getErrId); cancellationToken.setRequestToCancel(getErrId);
host.runQueuedImmediateCallbacks(); host.runQueuedImmediateCallbacks();
@ -4883,7 +4877,7 @@ namespace ts.projectSystem {
assert.equal(host.getOutput().length, 1, "expect 1 message"); assert.equal(host.getOutput().length, 1, "expect 1 message");
const e1 = <protocol.Event>getMessage(0); const e1 = <protocol.Event>getMessage(0);
assert.equal(e1.event, "syntaxDiag"); assert.equal(e1.event, "syntaxDiag");
host.clearOutput(); session.clearMessages();
// the semanticDiag message // the semanticDiag message
host.runQueuedImmediateCallbacks(); host.runQueuedImmediateCallbacks();
@ -4906,7 +4900,7 @@ namespace ts.projectSystem {
assert.equal(host.getOutput().length, 1, "expect 1 message"); assert.equal(host.getOutput().length, 1, "expect 1 message");
const e1 = <protocol.Event>getMessage(0); const e1 = <protocol.Event>getMessage(0);
assert.equal(e1.event, "syntaxDiag"); assert.equal(e1.event, "syntaxDiag");
host.clearOutput(); session.clearMessages();
session.executeCommandSeq(<protocol.GeterrRequest>{ session.executeCommandSeq(<protocol.GeterrRequest>{
command: "geterr", command: "geterr",
@ -4920,7 +4914,7 @@ namespace ts.projectSystem {
const event = <protocol.RequestCompletedEvent>getMessage(n); const event = <protocol.RequestCompletedEvent>getMessage(n);
assert.equal(event.event, "requestCompleted"); assert.equal(event.event, "requestCompleted");
assert.equal(event.body.request_seq, expectedSeq, "expectedSeq"); assert.equal(event.body.request_seq, expectedSeq, "expectedSeq");
host.clearOutput(); session.clearMessages();
} }
function getMessage(n: number) { function getMessage(n: number) {
@ -6423,7 +6417,7 @@ namespace ts.projectSystem {
}); });
// Verified the events, reset them // Verified the events, reset them
host.clearOutput(); session.clearMessages();
} }
} }
}); });

View file

@ -573,7 +573,7 @@ namespace ts.server {
} }
private writeToEventSocket(body: any, eventName: string): void { private writeToEventSocket(body: any, eventName: string): void {
this.eventSocket.write(formatMessage({ seq: 0, type: "event", event: eventName, body }, this.logger, this.byteLength, this.host.newLine), "utf8"); this.eventSocket.write(formatMessage(toEvent(body, eventName), this.logger, this.byteLength, this.host.newLine), "utf8");
} }
exit() { exit() {

View file

@ -245,6 +245,16 @@ namespace ts.server {
event: Event; event: Event;
} }
/** @internal */
export function toEvent(eventName: string, body: {}): protocol.Event {
return {
seq: 0,
type: "event",
event: eventName,
body
};
}
export interface SessionOptions { export interface SessionOptions {
host: ServerHost; host: ServerHost;
cancellationToken: ServerCancellationToken; cancellationToken: ServerCancellationToken;
@ -400,13 +410,7 @@ namespace ts.server {
} }
public event<T>(body: T, eventName: string): void { public event<T>(body: T, eventName: string): void {
const ev: protocol.Event = { this.send(toEvent(eventName, body));
seq: 0,
type: "event",
event: eventName,
body
};
this.send(ev);
} }
// For backwards-compatibility only. // For backwards-compatibility only.