Skip to content

Commit

Permalink
Merge pull request #51 from open-rpc/fix/refactor-testing
Browse files Browse the repository at this point in the history
fix: mocking
  • Loading branch information
BelfordZ authored Jul 29, 2019
2 parents fd457a9 + 374beb3 commit cc53cf9
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 26 deletions.
46 changes: 36 additions & 10 deletions src/RequestManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import EventEmitterTransport from "./transports/EventEmitterTransport";
import { EventEmitter } from "events";

describe("client-js", () => {

it("can be constructed", () => {
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
Expand Down Expand Up @@ -32,17 +33,15 @@ describe("client-js", () => {
c.close();
});

it("can send a request", (done) => {
it("can send a request", async () => {
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.request("foo", []).then(() => {
done();
});
serverTransport.sendData(JSON.stringify({ id: 0, result: { foo: "foofoo" } }));
});
await c.connect();
const reqPromise = c.request("foo", []);
serverTransport.sendData(JSON.stringify({ id: 0, result: { foo: "foofoo" } }));
await expect(reqPromise).resolves.toEqual({ foo: "foofoo" });
});

it("can error on malformed response", (done) => {
Expand All @@ -63,9 +62,8 @@ describe("client-js", () => {
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const c = new RequestManager([transport]);
return c.connect().then(() => {
expect(() => c.stopBatch()).toThrow();
});
await c.connect();
expect(() => c.stopBatch()).toThrow();
});

it("can return errors on batch requests", (done) => {
Expand Down Expand Up @@ -173,6 +171,19 @@ describe("client-js", () => {
});
});

it("onData throws if the ID is not found", async () => {
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();
expect(() => serverTransport.sendData(JSON.stringify({
jsonrpc: "2.0",
id: 10,
result: 123,
}))).toThrow("Received an unrecognized response id: 10. Valid ids are: ");
});

describe("stopBatch", () => {
it("does nothing if the batch is empty", () => {
const emitter = new EventEmitter();
Expand All @@ -184,4 +195,19 @@ describe("client-js", () => {
expect(transport.sendData).not.toHaveBeenCalled();
});
});

describe("startBatch", () => {
it("it does nothing if a batch is already started", async () => {
const emitter = new EventEmitter();
const transport = new EventEmitterTransport(emitter, "from1", "to1");
const c = new RequestManager([transport]);
await c.connect();
c.startBatch();
c.request("foo", []);
expect(c.batch.length).toBe(1);
c.startBatch();
c.request("foo", []);
expect(c.batch.length).toBe(2);
});
});
});
32 changes: 16 additions & 16 deletions src/RequestManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ interface IJSONRPCNotification {
class RequestManager {
public transports: ITransport[];
public connectPromise: Promise<any>;
public batch: IJSONRPCRequest[] = [];
private requests: any;
private batchStarted: boolean = false;
private batch: IJSONRPCRequest[] = [];
private lastId: number = -1;

constructor(transports: ITransport[]) {
Expand All @@ -46,27 +46,27 @@ class RequestManager {

public connect(): Promise<any> {
return Promise.all(this.transports.map(async (transport) => {
await transport.connect();
transport.onData(this.onData.bind(this));
await transport.connect();
}));
}

public async request(method: string, params: any): Promise<any> {
const i = (++this.lastId).toString();

// naively grab first transport and use it
const transport = this.transports[0];

const payload: IJSONRPCRequest = {
jsonrpc: "2.0",
id: i,
method,
params,
};

return new Promise((resolve, reject) => {
// naively grab first transport and use it
const transport = this.transports[0];
this.requests[i] = {
resolve,
reject,
};

const payload: IJSONRPCRequest = {
jsonrpc: "2.0",
id: i,
method,
params,
};
this.requests[i] = { resolve, reject };

if (this.batchStarted) {
this.batch.push(payload);
} else {
Expand Down Expand Up @@ -124,7 +124,7 @@ class RequestManager {
} else if (response.result) {
promiseForResult.resolve(response.result);
} else {
promiseForResult.reject(new Error(`Malformed JSON-RPC response object: ${response}`));
promiseForResult.reject(new Error(`Malformed JSON-RPC response object: ${JSON.stringify(response)}`));
}
});
}
Expand Down
4 changes: 4 additions & 0 deletions src/transports/EventEmitterTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ class EventEmitterTransport implements ITransport {
this.reqUri = reqUri;
this.resUri = resUri;
}

public connect(): Promise<any> {
return Promise.resolve();
}

public onData(callback: (data: string) => any) {
this.connection.on(this.reqUri, (data: any) => {
callback(data);
});
}

public sendData(data: string) {
this.connection.emit(this.resUri, data);
}

public close() {
this.connection.removeAllListeners();
}
Expand Down

0 comments on commit cc53cf9

Please sign in to comment.