Update orderbook channel and factory tests
This commit is contained in:
parent
c403dcdabf
commit
af395eccda
@ -59,6 +59,7 @@
|
|||||||
"isomorphic-fetch": "^2.2.1",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"query-string": "^5.0.1",
|
"query-string": "^5.0.1",
|
||||||
|
"sinon": "^4.0.0",
|
||||||
"websocket": "^1.0.25"
|
"websocket": "^1.0.25"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -68,6 +69,7 @@
|
|||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
"@types/query-string": "^5.0.1",
|
"@types/query-string": "^5.0.1",
|
||||||
|
"@types/sinon": "^2.2.2",
|
||||||
"@types/websocket": "^0.0.39",
|
"@types/websocket": "^0.0.39",
|
||||||
"async-child-process": "^1.1.1",
|
"async-child-process": "^1.1.1",
|
||||||
"chai": "^4.0.1",
|
"chai": "^4.0.1",
|
||||||
|
@ -1,21 +1,27 @@
|
|||||||
import * as WebSocket from 'websocket';
|
import * as WebSocket from 'websocket';
|
||||||
|
|
||||||
import { OrderbookChannel } from './types';
|
import { OrderbookChannel, OrderbookChannelHandler } from './types';
|
||||||
import { assert } from './utils/assert';
|
import { assert } from './utils/assert';
|
||||||
import { WebSocketOrderbookChannel } from './ws_orderbook_channel';
|
import { WebSocketOrderbookChannel } from './ws_orderbook_channel';
|
||||||
|
|
||||||
export const orderbookChannelFactory = {
|
export const orderbookChannelFactory = {
|
||||||
/**
|
/**
|
||||||
* Instantiates a new WebSocketOrderbookChannel instance
|
* Instantiates a new WebSocketOrderbookChannel instance
|
||||||
* @param url The relayer API base WS url you would like to interact with
|
* @param url The relayer API base WS url you would like to interact with
|
||||||
|
* @param handler An OrderbookChannelHandler instance that responds to various
|
||||||
|
* channel updates
|
||||||
* @return An OrderbookChannel Promise
|
* @return An OrderbookChannel Promise
|
||||||
*/
|
*/
|
||||||
async createWebSocketOrderbookChannelAsync(url: string): Promise<OrderbookChannel> {
|
async createWebSocketOrderbookChannelAsync(
|
||||||
|
url: string,
|
||||||
|
handler: OrderbookChannelHandler,
|
||||||
|
): Promise<OrderbookChannel> {
|
||||||
assert.isUri('url', url);
|
assert.isUri('url', url);
|
||||||
|
assert.isOrderbookChannelHandler('handler', handler);
|
||||||
return new Promise<OrderbookChannel>((resolve, reject) => {
|
return new Promise<OrderbookChannel>((resolve, reject) => {
|
||||||
const client = new WebSocket.w3cwebsocket(url);
|
const client = new WebSocket.w3cwebsocket(url);
|
||||||
client.onopen = () => {
|
client.onopen = () => {
|
||||||
const orderbookChannel = new WebSocketOrderbookChannel(client);
|
const orderbookChannel = new WebSocketOrderbookChannel(client, handler);
|
||||||
resolve(orderbookChannel);
|
resolve(orderbookChannel);
|
||||||
};
|
};
|
||||||
client.onerror = err => {
|
client.onerror = err => {
|
||||||
|
@ -11,7 +11,7 @@ export interface Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderbookChannel {
|
export interface OrderbookChannel {
|
||||||
subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler) => void;
|
subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
|
||||||
close: () => void;
|
close: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,18 +9,38 @@ import { orderbookChannelFactory } from '../src/orderbook_channel_factory';
|
|||||||
chai.config.includeStack = true;
|
chai.config.includeStack = true;
|
||||||
chai.use(dirtyChai);
|
chai.use(dirtyChai);
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
|
const emptyOrderbookChannelHandler = {
|
||||||
|
onSnapshot: () => {
|
||||||
|
_.noop();
|
||||||
|
},
|
||||||
|
onUpdate: () => {
|
||||||
|
_.noop();
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
_.noop();
|
||||||
|
},
|
||||||
|
onClose: () => {
|
||||||
|
_.noop();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
describe('orderbookChannelFactory', () => {
|
describe('orderbookChannelFactory', () => {
|
||||||
const websocketUrl = 'ws://localhost:8080';
|
const websocketUrl = 'ws://localhost:8080';
|
||||||
|
|
||||||
describe('#createWebSocketOrderbookChannelAsync', () => {
|
describe('#createWebSocketOrderbookChannelAsync', () => {
|
||||||
it('throws when input is not a url', () => {
|
it('throws when input is not a url', () => {
|
||||||
const badInput = 54;
|
const badUrlInput = 54;
|
||||||
const badSubscribeCall = orderbookChannelFactory.createWebSocketOrderbookChannelAsync.bind(
|
expect(
|
||||||
orderbookChannelFactory,
|
orderbookChannelFactory.createWebSocketOrderbookChannelAsync(
|
||||||
badInput,
|
badUrlInput as any,
|
||||||
);
|
emptyOrderbookChannelHandler,
|
||||||
expect(orderbookChannelFactory.createWebSocketOrderbookChannelAsync(badInput as any)).to.be.rejected();
|
),
|
||||||
|
).to.be.rejected();
|
||||||
|
});
|
||||||
|
it('throws when handler has the incorrect members', () => {
|
||||||
|
const badHandlerInput = {};
|
||||||
|
expect(
|
||||||
|
orderbookChannelFactory.createWebSocketOrderbookChannelAsync(websocketUrl, badHandlerInput as any),
|
||||||
|
).to.be.rejected();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@ import * as chai from 'chai';
|
|||||||
import * as dirtyChai from 'dirty-chai';
|
import * as dirtyChai from 'dirty-chai';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
|
import * as Sinon from 'sinon';
|
||||||
import * as WebSocket from 'websocket';
|
import * as WebSocket from 'websocket';
|
||||||
|
|
||||||
import { WebSocketOrderbookChannel } from '../src/ws_orderbook_channel';
|
import { WebSocketOrderbookChannel } from '../src/ws_orderbook_channel';
|
||||||
@ -26,8 +27,10 @@ const emptyOrderbookChannelHandler = {
|
|||||||
|
|
||||||
describe('WebSocketOrderbookChannel', () => {
|
describe('WebSocketOrderbookChannel', () => {
|
||||||
const websocketUrl = 'ws://localhost:8080';
|
const websocketUrl = 'ws://localhost:8080';
|
||||||
const client = new WebSocket.w3cwebsocket(websocketUrl);
|
const openClient = new WebSocket.w3cwebsocket(websocketUrl);
|
||||||
const orderbookChannel = new WebSocketOrderbookChannel(client, emptyOrderbookChannelHandler);
|
Sinon.stub(openClient, 'readyState').get(() => WebSocket.w3cwebsocket.OPEN);
|
||||||
|
Sinon.stub(openClient, 'send').callsFake(_.noop);
|
||||||
|
const openOrderbookChannel = new WebSocketOrderbookChannel(openClient, emptyOrderbookChannelHandler);
|
||||||
const subscriptionOpts = {
|
const subscriptionOpts = {
|
||||||
baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
|
baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
|
||||||
quoteTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
|
quoteTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
|
||||||
@ -36,22 +39,21 @@ describe('WebSocketOrderbookChannel', () => {
|
|||||||
};
|
};
|
||||||
describe('#subscribe', () => {
|
describe('#subscribe', () => {
|
||||||
it('throws when subscriptionOpts does not conform to schema', () => {
|
it('throws when subscriptionOpts does not conform to schema', () => {
|
||||||
const badSubscribeCall = orderbookChannel.subscribe.bind(
|
const badSubscribeCall = openOrderbookChannel.subscribe.bind(openOrderbookChannel, {});
|
||||||
orderbookChannel,
|
|
||||||
{},
|
|
||||||
emptyOrderbookChannelHandler,
|
|
||||||
);
|
|
||||||
expect(badSubscribeCall).throws(
|
expect(badSubscribeCall).throws(
|
||||||
'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
|
'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('does not throw when inputs are of correct types', () => {
|
it('does not throw when inputs are of correct types', () => {
|
||||||
const goodSubscribeCall = orderbookChannel.subscribe.bind(
|
const goodSubscribeCall = openOrderbookChannel.subscribe.bind(openOrderbookChannel, subscriptionOpts);
|
||||||
orderbookChannel,
|
|
||||||
subscriptionOpts,
|
|
||||||
emptyOrderbookChannelHandler,
|
|
||||||
);
|
|
||||||
expect(goodSubscribeCall).to.not.throw();
|
expect(goodSubscribeCall).to.not.throw();
|
||||||
});
|
});
|
||||||
|
it('throws when client is closed', () => {
|
||||||
|
const closedClient = new WebSocket.w3cwebsocket(websocketUrl);
|
||||||
|
Sinon.stub(closedClient, 'readyState').get(() => WebSocket.w3cwebsocket.CLOSED);
|
||||||
|
const closedOrderbookChannel = new WebSocketOrderbookChannel(closedClient, emptyOrderbookChannelHandler);
|
||||||
|
const badSubscribeCall = closedOrderbookChannel.subscribe.bind(closedOrderbookChannel, subscriptionOpts);
|
||||||
|
expect(badSubscribeCall).throws('WebSocket connection is closed');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user