Skip to content

Commit

Permalink
fix: event emitter transport
Browse files Browse the repository at this point in the history
  • Loading branch information
shanejonas committed Jul 29, 2019
1 parent 8bcf352 commit ba1e23b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 63 deletions.
114 changes: 63 additions & 51 deletions src/RequestManager.test.ts
@@ -1,75 +1,65 @@
import RequestManager from "./RequestManager";
import EventEmitterTransport from "./transports/EventEmitterTransport";
import { EventEmitter } from "events";

describe("client-js", () => {
it("can be constructed", () => {
const transport = new EventEmitterTransport("foo://unique-uri");
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const c = new RequestManager([transport]);
expect(!!c).toEqual(true);
});

it("has a request method that returns a promise", () => {
const transport = new EventEmitterTransport("foo://unique-uri");
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const c = new RequestManager([transport]);
expect(typeof c.request).toEqual("function");
expect(typeof c.request("my_method", null).then).toEqual("function");
});

it("can connect", () => {
const transport = new EventEmitterTransport("foo://unique-uri");
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const c = new RequestManager([transport]);
return c.connect();
});

it("can close", () => {
const transport = new EventEmitterTransport("foo://unique-uri");
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const c = new RequestManager([transport]);
c.close();
});

it("can send a request", (done) => {
const transport = new EventEmitterTransport("foo://unique-uri");
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const serverTransport = new EventEmitterTransport(emitter, "to1", "from1");
const c = new RequestManager([transport]);
c.connect();
transport.onData((data: any) => {
const d = JSON.parse(data);
expect(d.method).toEqual("foo");
expect(d.foo).toEqual("bar");
done();
});
c.request("foo", []);
serverTransport.sendData(JSON.stringify({ foo: "bar" }));
});

it("can error on batchng a request", async () => {
const transport = new EventEmitterTransport("foo://unique-uri");
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const c = new RequestManager([transport]);
return c.connect().then(() => {
expect(() => c.stopBatch()).toThrow();
});
});

it("can return errors on batch requests", async () => {
const transport = new EventEmitterTransport("foo://unique-uri");
transport.sendData = (data) => {
const result = JSON.stringify([
{
jsonrpc: "2.0",
id: "0",
error: {
code: 509,
message: "too much 509",
data: {
test: "data",
},
},
},
{
jsonrpc: "2.0",
id: "1",
result: "bar",
},
]);
transport.connection.emit("message", result);
};
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const serverTransport = new EventEmitterTransport(emitter, "to1", "from1");

const c = new RequestManager([transport]);
await c.connect();
Expand All @@ -85,15 +75,49 @@ describe("client-js", () => {
test: "data",
},
});
serverTransport.sendData(JSON.stringify([
{
jsonrpc: "2.0",
id: "0",
error: {
code: 509,
message: "too much 509",
data: {
test: "data",
},
},
},
{
jsonrpc: "2.0",
id: "1",
result: "bar",
},
]));
expect(requests[1]).resolves.toEqual("bar");
c.stopBatch();
c.close();
});

it("can batch a request", async () => {
const transport = new EventEmitterTransport("foo://unique-uri");
transport.sendData = (data) => {
const result = JSON.stringify([
it("can batch a request", (done) => {
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const serverTransport = new EventEmitterTransport(emitter, "to1", "from1");

const c = new RequestManager([transport]);
c.connect().then(() => {
c.startBatch();
const requests = [
c.request("foo", []),
c.request("foo", []),
];
c.stopBatch();
Promise.all(requests).then(([a, b]) => {
expect(a).toEqual("foo");
expect(b).toEqual("bar");
c.close();
done();
});
serverTransport.sendData(JSON.stringify([
{
jsonrpc: "2.0",
id: 0,
Expand All @@ -104,26 +128,13 @@ describe("client-js", () => {
id: 1,
result: "bar",
},
]);
transport.connection.emit("message", result);
};

const c = new RequestManager([transport]);
await c.connect();
c.startBatch();
const requests = [
c.request("foo", []),
c.request("foo", []),
];
c.stopBatch();
const [a, b] = await Promise.all(requests);
expect(a).toEqual("foo");
expect(b).toEqual("bar");
c.close();
]));
});
});

it("can send a request and error", async () => {
const transport = new EventEmitterTransport("foo://unique-uri");
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const c = new RequestManager([transport]);
transport.onData = (fn) => {
transport.connection.on("message", () => {
Expand Down Expand Up @@ -152,7 +163,8 @@ describe("client-js", () => {

describe("stopBatch", () => {
it("does nothing if the batch is empty", () => {
const transport = new EventEmitterTransport("foo://unique-uri");
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
transport.sendData = jest.fn();
const c = new RequestManager([transport]);
c.startBatch();
Expand Down
13 changes: 9 additions & 4 deletions src/index.test.ts
@@ -1,33 +1,38 @@
import Client from ".";
import RequestManager from "./RequestManager";
import EventEmitterTransport from "./transports/EventEmitterTransport";
import { EventEmitter } from "events";

jest.mock("./RequestManager");

const mockedRequestManager = RequestManager as jest.Mock<RequestManager>;
describe("client-js", () => {
it("can be constructed", () => {
const c = new Client(new RequestManager([new EventEmitterTransport("foo://unique")]));
const emitter = new EventEmitter();
const c = new Client(new RequestManager([new EventEmitterTransport(emitter, "from1", "to1")]));
expect(!!c).toEqual(true);
});

it("has a request method that returns a promise", () => {
const c = new Client(new RequestManager([new EventEmitterTransport("foo://unique")]));
const emitter = new EventEmitter();
const c = new Client(new RequestManager([new EventEmitterTransport(emitter, "from1", "to1")]));
expect(typeof c.request).toEqual("function");
expect(typeof c.request("my_method", null).then).toEqual("function");
});

describe("startBatch", () => {
it("calls the requestManager.startBatch", () => {
const rm = new mockedRequestManager([new EventEmitterTransport("foo://unique")]);
const emitter = new EventEmitter();
const rm = new mockedRequestManager([new EventEmitterTransport(emitter, "from1", "to1")]);
const c = new Client(rm);
c.startBatch();
expect(mockedRequestManager.mock.instances[0].startBatch).toHaveBeenCalled();
});
});

describe("stopBatch", () => {
const rm = new RequestManager([new EventEmitterTransport("foo://unique")]);
const emitter = new EventEmitter();
const rm = new mockedRequestManager([new EventEmitterTransport(emitter, "from1", "to1")]);
const c = new Client(rm);
c.startBatch();
c.stopBatch();
Expand Down
16 changes: 12 additions & 4 deletions src/transports/EventEmitterTransport.test.ts
@@ -1,21 +1,29 @@
import EventEmitterTransport from "./EventEmitterTransport";
import { EventEmitter } from "events";

describe("EventEmitterTransport", () => {
it("can connect", () => {
const eventEmitterTransport = new EventEmitterTransport("foo://bar");
const emitter = new EventEmitter();
const eventEmitterTransport = new EventEmitterTransport(emitter, "foo://in", "foo://out");
eventEmitterTransport.connect();
});
it("can close", () => {
const eventEmitterTransport = new EventEmitterTransport("foo://bar");
const emitter = new EventEmitter();
const reqUri = "from";
const resUri = "to";
const eventEmitterTransport = new EventEmitterTransport(emitter, reqUri, resUri);
eventEmitterTransport.close();
});
it("can send and receive data", (done) => {
const eventEmitterTransport = new EventEmitterTransport("foo://bar");
const emitter = new EventEmitter();
const eventEmitterTransport = new EventEmitterTransport(emitter, "from1", "to1");
eventEmitterTransport.onData((data: any) => {
const d = JSON.parse(data);
expect(d.foo).toEqual("bar");
done();
});
eventEmitterTransport.sendData(JSON.stringify({foo: "bar"}));

const eventEmitterServerTransport = new EventEmitterTransport(emitter, "to1", "from1");
eventEmitterServerTransport.sendData(JSON.stringify({foo: "bar"}));
});
});
12 changes: 8 additions & 4 deletions src/transports/EventEmitterTransport.ts
Expand Up @@ -3,19 +3,23 @@ import ITransport from "./Transport";

class EventEmitterTransport implements ITransport {
public connection: EventEmitter;
constructor(uri: string) {
this.connection = new EventEmitter();
private reqUri: string;
private resUri: string;
constructor(emitter: EventEmitter, reqUri: string, resUri: string) {
this.connection = emitter;
this.reqUri = reqUri;
this.resUri = resUri;
}
public connect(): Promise<any> {
return Promise.resolve();
}
public onData(callback: (data: string) => any) {
this.connection.addListener("message", (data: any) => {
this.connection.on(this.reqUri, (data: any) => {
callback(data);
});
}
public sendData(data: string) {
this.connection.emit("message", data);
this.connection.emit(this.resUri, data);
}
public close() {
this.connection.removeAllListeners();
Expand Down

0 comments on commit ba1e23b

Please sign in to comment.