Feedback from PR, lint fixes
This commit is contained in:
parent
8884f3b4f6
commit
5fb5b244fb
|
@ -1,24 +1,24 @@
|
|||
/// <reference path="..\..\..\src\harness\harness.ts" />
|
||||
|
||||
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(<protocol.Response>{
|
||||
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(<protocol.Response>{
|
||||
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(<protocol.ConfigureResponse>{
|
||||
command: CommandNames.Configure,
|
||||
type: 'response',
|
||||
success: true,
|
||||
request_seq: 0,
|
||||
seq: 0,
|
||||
body: undefined
|
||||
});
|
||||
});
|
||||
});
|
||||
expect(lastSent).to.deep.equal(<protocol.ConfigureResponse>{
|
||||
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 = <protocol.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 = <protocol.Event>msg;
|
||||
this.emit(event.event, event.body);
|
||||
}
|
||||
}
|
||||
handle(msg: protocol.Message): void {
|
||||
if (msg.type === "response") {
|
||||
const response = <protocol.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 = <protocol.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();
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue