From 5fb5b244fbd9c1360b539798dd36ec9ab868badf Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 11:14:19 -0700 Subject: [PATCH] Feedback from PR, lint fixes --- tests/cases/unittests/session.ts | 819 +++++++++++++++---------------- 1 file changed, 407 insertions(+), 412 deletions(-) diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts index 1d7b9572bbb..1d2efbb498c 100644 --- a/tests/cases/unittests/session.ts +++ b/tests/cases/unittests/session.ts @@ -1,24 +1,24 @@ /// module ts.server { - let lastWrittenToHost: string, - mockHost: ServerHost = { - args: [], - newLine: '\n', - useCaseSensitiveFileNames: true, - write: (s) => lastWrittenToHost = s, - readFile: () => void 0, - writeFile: () => void 0, - resolvePath: () => void 0, - fileExists: () => false, - directoryExists: () => false, - createDirectory: () => void 0, - getExecutingFilePath: () => void 0, - getCurrentDirectory: () => void 0, - readDirectory: () => void 0, - exit: () => void 0 - }, - mockLogger: Logger = { + let lastWrittenToHost: string; + const mockHost: ServerHost = { + args: [], + newLine: "\n", + useCaseSensitiveFileNames: true, + write(s): void { lastWrittenToHost = s; }, + readFile(): string { return void 0; }, + writeFile(): void {}, + resolvePath(): string { return void 0; }, + fileExists: () => false, + directoryExists: () => false, + createDirectory(): void {}, + getExecutingFilePath(): string { return void 0; }, + getCurrentDirectory(): string { return void 0; }, + readDirectory(): string[] { return []; }, + exit(): void {} + }; + const mockLogger: Logger = { close(): void {}, isVerbose(): boolean { return false; }, loggingEnabled(): boolean { return false; }, @@ -27,433 +27,428 @@ module ts.server { startGroup(): void {}, endGroup(): void {}, msg(s: string, type?: string): void {}, - }; - - describe('the Session class', () => { - let session: Session, - lastSent: protocol.Message; + }; + + describe("the Session class", () => { + let session: Session; + let lastSent: protocol.Message; - beforeEach(() => { - session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger); - session.send = (msg: protocol.Message) => { - lastSent = msg; - }; - }); + beforeEach(() => { + session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + session.send = (msg: protocol.Message) => { + lastSent = msg; + }; + }); - describe('executeCommand', () => { - it('should throw when commands are executed with invalid arguments', () => { - let req : protocol.FileRequest = { - command: CommandNames.Open, - seq: 0, - type: 'command', - arguments: { - file: undefined - } - }; + describe("executeCommand", () => { + it("should throw when commands are executed with invalid arguments", () => { + const req: protocol.FileRequest = { + command: CommandNames.Open, + seq: 0, + type: "command", + arguments: { + file: undefined + } + }; - expect(() => session.executeCommand(req)).to.throw(); - }); - it('should output an error response when a command does not exist', () => { - let req : protocol.Request = { - command: 'foobar', - seq: 0, - type: 'command' - }; + expect(() => session.executeCommand(req)).to.throw(); + }); + it("should output an error response when a command does not exist", () => { + const req: protocol.Request = { + command: "foobar", + seq: 0, + type: "command" + }; - session.executeCommand(req); + session.executeCommand(req); - expect(lastSent).to.deep.equal({ - command: CommandNames.Unknown, - type: 'response', - seq: 0, - message: 'Unrecognized JSON command: foobar', - request_seq: 0, - success: false - }); - }); - it('should return a tuple containing the response and if a response is required on success', () => { - let req : protocol.ConfigureRequest = { - command: CommandNames.Configure, - seq: 0, - type: 'command', - arguments: { - hostInfo: 'unit test', - formatOptions: { - newLineCharacter: '`n' - } - } - }; + expect(lastSent).to.deep.equal({ + command: CommandNames.Unknown, + type: "response", + seq: 0, + message: "Unrecognized JSON command: foobar", + request_seq: 0, + success: false + }); + }); + it("should return a tuple containing the response and if a response is required on success", () => { + const req: protocol.ConfigureRequest = { + command: CommandNames.Configure, + seq: 0, + type: "command", + arguments: { + hostInfo: "unit test", + formatOptions: { + newLineCharacter: "`n" + } + } + }; - expect(session.executeCommand(req)).to.deep.equal({ - responseRequired: false - }); - expect(lastSent).to.deep.equal({ - command: CommandNames.Configure, - type: 'response', - success: true, - request_seq: 0, - seq: 0, - body: undefined - }); - }); - }); + expect(session.executeCommand(req)).to.deep.equal({ + responseRequired: false + }); + expect(lastSent).to.deep.equal({ + command: CommandNames.Configure, + type: "response", + success: true, + request_seq: 0, + seq: 0, + body: undefined + }); + }); + }); - describe('onMessage', () => { - it('should not throw when commands are executed with invalid arguments', () => { - let i = 0; - for (name in CommandNames) { - if (!Object.prototype.hasOwnProperty.call(CommandNames, name)) { - continue; - } - let req : protocol.Request = { - command: name, - seq: i++, - type: 'command' - }; - session.onMessage(JSON.stringify(req)); - req.seq += 2; - req.arguments = {}; - session.onMessage(JSON.stringify(req)); - req.seq += 2; - req.arguments = null; - session.onMessage(JSON.stringify(req)); - } - }); - it('should output the response for a correctly handled message', () => { - let req : protocol.ConfigureRequest = { - command: CommandNames.Configure, - seq: 0, - type: 'command', - arguments: { - hostInfo: 'unit test', - formatOptions: { - newLineCharacter: '`n' - } - } - }; + describe("onMessage", () => { + it("should not throw when commands are executed with invalid arguments", () => { + let i = 0; + for (name in CommandNames) { + if (!Object.prototype.hasOwnProperty.call(CommandNames, name)) { + continue; + } + const req: protocol.Request = { + command: name, + seq: i++, + type: "command" + }; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = {}; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = null; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = ""; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = 0; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = []; + session.onMessage(JSON.stringify(req)); + } + session.onMessage("GARBAGE NON_JSON DATA"); + }); + it("should output the response for a correctly handled message", () => { + const req: protocol.ConfigureRequest = { + command: CommandNames.Configure, + seq: 0, + type: "command", + arguments: { + hostInfo: "unit test", + formatOptions: { + newLineCharacter: "`n" + } + } + }; - session.onMessage(JSON.stringify(req)); + session.onMessage(JSON.stringify(req)); - expect(lastSent).to.deep.equal({ - command: CommandNames.Configure, - type: 'response', - success: true, - request_seq: 0, - seq: 0, - body: undefined - }); - }); - }); + expect(lastSent).to.deep.equal({ + command: CommandNames.Configure, + type: "response", + success: true, + request_seq: 0, + seq: 0, + body: undefined + }); + }); + }); - describe('exit', () => { - it('is a noop which can be handled by subclasses', () => { - session.exit(); // Does nothing, should keep running tests - expect(session).to.exist; - }); - }); + describe("exit", () => { + it("is a noop which can be handled by subclasses", () => { + session.exit(); // Does nothing, should keep running tests + expect(session).to.exist; + }); + }); - describe('send', () => { - it('is an overrideable handle which sends protocol messages over the wire', () => { - let msg = {seq: 0, type: 'none'}, - strmsg = JSON.stringify(msg), - len = 1 + Buffer.byteLength(strmsg, 'utf8'), - resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; + describe("send", () => { + it("is an overrideable handle which sends protocol messages over the wire", () => { + const msg = {seq: 0, type: "none"}; + const strmsg = JSON.stringify(msg); + const len = 1 + Buffer.byteLength(strmsg, "utf8"); + const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; - session.send = Session.prototype.send; - assert(session.send); - expect(session.send(msg)).to.not.exist; - expect(lastWrittenToHost).to.equal(resultMsg); - }); - }); + session.send = Session.prototype.send; + assert(session.send); + expect(session.send(msg)).to.not.exist; + expect(lastWrittenToHost).to.equal(resultMsg); + }); + }); - describe('addProtocolHandler', () => { - it('can add protocol handlers', () => { - let respBody = { - item: false - }, - command = 'newhandle', - result = { - response: respBody, - responseRequired: true - }; + describe("addProtocolHandler", () => { + it("can add protocol handlers", () => { + const respBody = { + item: false + }; + const command = "newhandle"; + const result = { + response: respBody, + responseRequired: true + }; - session.addProtocolHandler(command, (req) => result); + session.addProtocolHandler(command, (req) => result); - expect(session.executeCommand({ - command, - seq: 0, - type: 'command' - })).to.deep.equal(result); - }); - it('throws when a duplicate handler is passed', () => { - let respBody = { - item: false - }, - resp = { - response: respBody, - responseRequired: true - }, - command = 'newhandle'; + expect(session.executeCommand({ + command, + seq: 0, + type: "command" + })).to.deep.equal(result); + }); + it("throws when a duplicate handler is passed", () => { + const respBody = { + item: false + }; + const resp = { + response: respBody, + responseRequired: true + }; + const command = "newhandle"; - session.addProtocolHandler(command, (req) => resp); + session.addProtocolHandler(command, (req) => resp); - expect(() => session.addProtocolHandler(command, (req) => resp)) - .to.throw(`Protocol handler already exists for command "${command}"`); - }); - }); - - describe('event', () => { - it('can format event responses and send them', () => { - let evt = 'notify-test', - info = { - test: true - }; + expect(() => session.addProtocolHandler(command, (req) => resp)) + .to.throw(`Protocol handler already exists for command "${command}"`); + }); + }); + + describe("event", () => { + it("can format event responses and send them", () => { + const evt = "notify-test"; + const info = { + test: true + }; - session.event(info, evt); + session.event(info, evt); - expect(lastSent).to.deep.equal({ - type: 'event', - seq: 0, - event: evt, - body: info - }); - }); - }); + expect(lastSent).to.deep.equal({ + type: "event", + seq: 0, + event: evt, + body: info + }); + }); + }); - describe('output', () => { - it('can format command responses and send them', () => { - let body = { - block: { - key: 'value' - } - }, - command = 'test'; + describe("output", () => { + it("can format command responses and send them", () => { + const body = { + block: { + key: "value" + } + }; + const command = "test"; - session.output(body, command); + session.output(body, command); - expect(lastSent).to.deep.equal({ - seq: 0, - request_seq: 0, - type: 'response', - command, - body: body, - success: true - }); - }); - }); - }); + expect(lastSent).to.deep.equal({ + seq: 0, + request_seq: 0, + type: "response", + command, + body: body, + success: true + }); + }); + }); + }); - describe('how Session is extendable via subclassing', () => { - let TestSession = class extends Session { - lastSent: protocol.Message; - customHandler: string = 'testhandler'; - constructor(){ - super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); - this.addProtocolHandler(this.customHandler, () => { - return {response: undefined, responseRequired: true}; - }); - } - send(msg: protocol.Message) { - this.lastSent = msg; - } - }; + describe("how Session is extendable via subclassing", () => { + class TestSession extends Session { + lastSent: protocol.Message; + customHandler: string = "testhandler"; + constructor(){ + super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + this.addProtocolHandler(this.customHandler, () => { + return {response: undefined, responseRequired: true}; + }); + } + send(msg: protocol.Message) { + this.lastSent = msg; + } + }; - it('can override methods such as send', () => { - let session = new TestSession(), - body = { - block: { - key: 'value' - } - }, - command = 'test'; + it("can override methods such as send", () => { + const session = new TestSession(); + const body = { + block: { + key: "value" + } + }; + const command = "test"; - session.output(body, command); + session.output(body, command); - expect(session.lastSent).to.deep.equal({ - seq: 0, - request_seq: 0, - type: 'response', - command, - body: body, - success: true - }); - }); - it('can add and respond to new protocol handlers', () => { - let session = new TestSession(); + expect(session.lastSent).to.deep.equal({ + seq: 0, + request_seq: 0, + type: "response", + command, + body: body, + success: true + }); + }); + it("can add and respond to new protocol handlers", () => { + const session = new TestSession(); - expect(session.executeCommand({ - seq: 0, - type: 'command', - command: session.customHandler - })).to.deep.equal({ - response: undefined, - responseRequired: true - }); - }); - it('has access to the project service', () => { - let ServiceSession = class extends TestSession { - constructor() { - super(); - assert(this.projectService); - expect(this.projectService).to.be.instanceOf(ProjectService); - } - }; - new ServiceSession(); - }); - }); + expect(session.executeCommand({ + seq: 0, + type: "command", + command: session.customHandler + })).to.deep.equal({ + response: undefined, + responseRequired: true + }); + }); + it("has access to the project service", () => { + class ServiceSession extends TestSession { + constructor() { + super(); + assert(this.projectService); + expect(this.projectService).to.be.instanceOf(ProjectService); + } + }; + new ServiceSession(); + }); + }); - describe('an example of using the Session API to create an in-process server', () => { - let inProcHost: ServerHost = { - args: [], - newLine: '\n', - useCaseSensitiveFileNames: true, - write: (s) => lastWrittenToHost = s, - readFile: () => void 0, - writeFile: () => void 0, - resolvePath: () => void 0, - fileExists: () => false, - directoryExists: () => false, - createDirectory: () => void 0, - getExecutingFilePath: () => void 0, - getCurrentDirectory: () => void 0, - readDirectory: () => void 0, - exit: () => void 0 - }, - InProcSession = class extends Session { - private queue: protocol.Request[] = []; - constructor(private client: {handle: (msg: protocol.Message) => void}) { - super(inProcHost, Buffer.byteLength, process.hrtime, mockLogger); - this.addProtocolHandler('echo', (req: protocol.Request) => ({ - response: req.arguments, - responseRequired: true - })); - } - - send(msg: protocol.Message) { - this.client.handle(msg); - } + describe("an example of using the Session API to create an in-process server", () => { + class InProcSession extends Session { + private queue: protocol.Request[] = []; + constructor(private client: {handle: (msg: protocol.Message) => void}) { + super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + this.addProtocolHandler("echo", (req: protocol.Request) => ({ + response: req.arguments, + responseRequired: true + })); + } + + send(msg: protocol.Message) { + this.client.handle(msg); + } - enqueue(msg: protocol.Request) { - this.queue = [msg].concat(this.queue); - } - - handleRequest(msg: protocol.Request) { - let response: protocol.Response; - try { - response = this.executeCommand(msg).response; - } catch (e) { - this.output(undefined, msg.command, msg.seq, e.toString()); - return; - } - if (response) { - this.output(response, msg.command, msg.seq); - } - } + enqueue(msg: protocol.Request) { + this.queue.unshift(msg); + } + + handleRequest(msg: protocol.Request) { + let response: protocol.Response; + try { + ({response} = this.executeCommand(msg)); + } + catch (e) { + this.output(undefined, msg.command, msg.seq, e.toString()); + return; + } + if (response) { + this.output(response, msg.command, msg.seq); + } + } - consumeQueue() { - while (this.queue.length > 0) { - let elem = this.queue[this.queue.length - 1]; - this.queue = this.queue.slice(0, this.queue.length - 1); - this.handleRequest(elem); - } - } - }, - InProcClient = class { - private server: Session & {enqueue: (msg: protocol.Request) => void}; - private seq: number = 0; - private callbacks: ts.Map<(resp: protocol.Response) => void> = {}; - private eventHandlers: ts.Map<(args: any) => void> = {}; + consumeQueue() { + while (this.queue.length > 0) { + const elem = this.queue.pop(); + this.handleRequest(elem); + } + } + } + + class InProcClient { + private server: InProcSession; + private seq: number = 0; + private callbacks: ts.Map<(resp: protocol.Response) => void> = {}; + private eventHandlers: ts.Map<(args: any) => void> = {}; - handle(msg: protocol.Message): void { - if (msg.type === 'response') { - let response = msg; - if (this.callbacks[response.request_seq]) { - this.callbacks[response.request_seq](response); - delete this.callbacks[response.request_seq]; - } - } else if (msg.type === 'event') { - let event = msg; - this.emit(event.event, event.body); - } - } + handle(msg: protocol.Message): void { + if (msg.type === "response") { + const response = msg; + if (this.callbacks[response.request_seq]) { + this.callbacks[response.request_seq](response); + delete this.callbacks[response.request_seq]; + } + } + else if (msg.type === "event") { + const event = msg; + this.emit(event.event, event.body); + } + } - emit(name: string, args: any): void { - if (!this.eventHandlers[name]) { - return; - } - this.eventHandlers[name](args); - } + emit(name: string, args: any): void { + if (this.eventHandlers[name]) { + this.eventHandlers[name](args); + } + } - on(name: string, handler: (args: any) => void): void { - this.eventHandlers[name] = handler; - } + on(name: string, handler: (args: any) => void): void { + this.eventHandlers[name] = handler; + } - connect(session: Session & {enqueue: (msg: protocol.Request) => void}): void { - this.server = session; - } - - execute(command: string, args: any, callback: (resp: protocol.Response) => void): void { - if (!this.server) { - return; - } - this.seq++; - this.server.enqueue({ - seq: this.seq, - type: 'command', - command, - arguments: args - }); - this.callbacks[this.seq] = callback; - } - }; - - it('can be constructed and respond to commands', (done) => { - let cli = new InProcClient(), - session = new InProcSession(cli), - toEcho = { - data: true - }, - toEvent = { - data: false - }, - responses = 0; + connect(session: InProcSession): void { + this.server = session; + } + + execute(command: string, args: any, callback: (resp: protocol.Response) => void): void { + if (!this.server) { + return; + } + this.seq++; + this.server.enqueue({ + seq: this.seq, + type: "command", + command, + arguments: args + }); + this.callbacks[this.seq] = callback; + } + }; + + it("can be constructed and respond to commands", (done) => { + const cli = new InProcClient(); + const session = new InProcSession(cli); + const toEcho = { + data: true + }; + const toEvent = { + data: false + }; + let responses = 0; - // Connect the client - cli.connect(session); - - // Add an event handler - cli.on('testevent', (eventinfo) => { - expect(eventinfo).to.equal(toEvent); - responses++; - expect(responses).to.equal(1); - }); - - // Trigger said event from the server - session.event(toEvent, 'testevent'); - - // Queue an echo command - cli.execute('echo', toEcho, (resp) => { - assert(resp.success, resp.message); - responses++; - expect(responses).to.equal(2); - expect(resp.body).to.deep.equal(toEcho); - }); - - // Queue a configure command - cli.execute('configure', { - hostInfo: 'unit test', - formatOptions: { - newLineCharacter: '`n' - } - }, (resp) => { - assert(resp.success, resp.message); - responses++; - expect(responses).to.equal(3); - done(); - }); - - // Consume the queue and trigger the callbacks - session.consumeQueue(); - }); - }); + // Connect the client + cli.connect(session); + + // Add an event handler + cli.on("testevent", (eventinfo) => { + expect(eventinfo).to.equal(toEvent); + responses++; + expect(responses).to.equal(1); + }); + + // Trigger said event from the server + session.event(toEvent, "testevent"); + + // Queue an echo command + cli.execute("echo", toEcho, (resp) => { + assert(resp.success, resp.message); + responses++; + expect(responses).to.equal(2); + expect(resp.body).to.deep.equal(toEcho); + }); + + // Queue a configure command + cli.execute("configure", { + hostInfo: "unit test", + formatOptions: { + newLineCharacter: "`n" + } + }, (resp) => { + assert(resp.success, resp.message); + responses++; + expect(responses).to.equal(3); + done(); + }); + + // Consume the queue and trigger the callbacks + session.consumeQueue(); + }); + }); } \ No newline at end of file