Skip to content

Commit

Permalink
Cleanup assertions
Browse files Browse the repository at this point in the history
  • Loading branch information
jacogr committed Dec 14, 2017
1 parent 01df043 commit f89f00d
Show file tree
Hide file tree
Showing 32 changed files with 79 additions and 83 deletions.
13 changes: 5 additions & 8 deletions packages/client-chains/src/validate/genesis.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,13 @@ const validateObject = require('./object');
const KNOWN_KEYS = ['author', 'hash', 'parentHash', 'stateRoot'];
const PREFIX = 'Chain.genesis';

module.exports = function validateParams (genesis: ChainConfigType$Genesis, strict: boolean = false): boolean {
module.exports = function validateGenesis (genesis: ChainConfigType$Genesis, strict: boolean = false): boolean {
validateObject(PREFIX, genesis, KNOWN_KEYS, strict);

assert(isHex(genesis.author, 160), `${PREFIX}.author should be a valid network accountId`);

assert(isHex(genesis.hash, 256), `${PREFIX}.hash should be a valid header hash`);

assert(isHex(genesis.parentHash, 256), `${PREFIX}.parentHash should be a valid header hash`);

assert(isHex(genesis.stateRoot, 256), `${PREFIX}.stateRoot should be a valid hash`);
assert(isHex(genesis.author, 160), `${PREFIX}.author should be AccountId`);
assert(isHex(genesis.hash, 256), `${PREFIX}.hash should be a HeaderHash`);
assert(isHex(genesis.parentHash, 256), `${PREFIX}.parentHash should be HeaderHash`);
assert(isHex(genesis.stateRoot, 256), `${PREFIX}.stateRoot should be Hash`);

return true;
};
Expand Down
8 changes: 4 additions & 4 deletions packages/client-chains/src/validate/genesis.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,30 +42,30 @@ describe('validateGenesis', () => {
() => validateGenesis(
Object.assign({}, test, { author: 'notHex' })
)
).toThrow(/valid network accountId/);
).toThrow(/AccountId/);
});

it('validates the hash', () => {
expect(
() => validateGenesis(
Object.assign({}, test, { hash: 'notHex' })
)
).toThrow(/valid header hash/);
).toThrow(/HeaderHash/);
});

it('validates the parentHash', () => {
expect(
() => validateGenesis(
Object.assign({}, test, { parentHash: 'notHex' })
)
).toThrow(/valid header hash/);
).toThrow(/HeaderHash/);
});

it('validates the stateRoot', () => {
expect(
() => validateGenesis(
Object.assign({}, test, { stateRoot: 'notHex' })
)
).toThrow(/valid hash/);
).toThrow(/Hash/);
});
});
1 change: 0 additions & 1 deletion packages/client-chains/src/validate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const KNOWN_KEYS = ['description', 'genesis', 'name', 'nodes', 'params'];

module.exports = function validateChain (chain: ChainConfigType, strict: boolean = false): ChainConfigType {
validateObject('Chain', chain, KNOWN_KEYS, strict);

validateGenesis(chain.genesis, strict);
validateParams(chain.params, strict);

Expand Down
2 changes: 1 addition & 1 deletion packages/client-chains/src/validate/params.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const PREFIX = 'Chain.params';
module.exports = function validateParams (params: ChainConfigType$Params, strict: boolean = false): boolean {
validateObject(PREFIX, params, KNOWN_KEYS, strict);

assert(isHex(params.networkID), `${PREFIX}.networkID should be a hex number`);
assert(isHex(params.networkID), `${PREFIX}.networkID should be a Hex`);

return true;
};
Expand Down
2 changes: 1 addition & 1 deletion packages/client-chains/src/validate/params.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ describe('validateParams', () => {
() => validateParams(
Object.assign({}, test, { networkID: 123 })
)
).toThrow(/networkID should be a hex/);
).toThrow(/networkID should be a Hex/);
});
});
5 changes: 2 additions & 3 deletions packages/client-p2p/src/create/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ const DEFAULT_TRANSPORTS = [
];

module.exports = function createConfig (peerInfo: PeerInfo, bootNodes: ChainConfigType$Nodes = []): LibP2P$Config {
assert(isInstanceOf(peerInfo, PeerInfo), 'Expected peerInfo as a PeerInfo instance');

assert(Array.isArray(bootNodes), 'Expected bootNodes as an array of nodes');
assert(isInstanceOf(peerInfo, PeerInfo), 'Expected PeerInfo instance');
assert(Array.isArray(bootNodes), 'Expected array of bootNodes');

return {
connection: {
Expand Down
4 changes: 2 additions & 2 deletions packages/client-p2p/src/create/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ describe('createConfig', () => {
it('expects a peerInfo object', () => {
expect(
() => createConfig()
).toThrow(/peerInfo as a PeerInfo/);
).toThrow(/PeerInfo instance/);
});

it('expects a valid bootNodes array', () => {
expect(
() => createConfig(peerInfo, 'notanArray')
).toThrow(/array of nodes/);
).toThrow(/array of bootNodes/);
});

it('returns a valid configuration object', () => {
Expand Down
5 changes: 2 additions & 3 deletions packages/client-p2p/src/create/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ const createPeerInfo = require('./peerInfo');
const defaults = require('../defaults');

module.exports = async function createListener (ip: string = defaults.ADDRESS, port: number = defaults.PORT): Promise<PeerInfo> {
assert(isIp(ip), `Expected a valid IP address, received '${ip}'`);

assert(isNumber(port), `Expected a valid numeric port, received '${port}'`);
assert(isIp(ip), `Expected an IP address, received '${ip}'`);
assert(isNumber(port), `Expected a numeric port, received '${port}'`);

const type = isIp(ip, 'v4') ? 'ip4' : 'ip6';

Expand Down
4 changes: 2 additions & 2 deletions packages/client-p2p/src/create/listener.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ describe('createListener', () => {

it('validates the IP address', () => {
return createListener('no.ip.is.here').catch((error) => {
expect(error.message).toMatch(/valid IP address/);
expect(error.message).toMatch(/IP address/);
});
});

it('validates the port', () => {
return createListener('127.0.0.1', 'notAPort').catch((error) => {
expect(error.message).toMatch(/valid numeric port/);
expect(error.message).toMatch(/numeric port/);
});
});

Expand Down
5 changes: 2 additions & 3 deletions packages/client-p2p/src/create/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ const createListener = require('./listener');
const createPeerBook = require('./peerBook');

module.exports = async function createNode (config: P2pConfigType, chain: ChainConfigType): Promise<Libp2p> {
assert(isObject(config), 'Expected a valid p2p config object');

assert(isObject(chain), 'Expected a valid chain defintion');
assert(isObject(config), 'Expected P2P configuration');
assert(isObject(chain), 'Expected chain definition');

const listener = await createListener(config.address, config.port);
const peerBook = await createPeerBook(config.peers);
Expand Down
4 changes: 2 additions & 2 deletions packages/client-p2p/src/create/node.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ describe('createNode', () => {

it('requires a valid config object', () => {
return createNode().catch((error) => {
expect(error.message).toMatch(/valid p2p config/);
expect(error.message).toMatch(/P2P configuration/);
});
});

it('requires a valid chain definition object', () => {
return createNode({}).catch((error) => {
expect(error.message).toMatch(/valid chain/);
expect(error.message).toMatch(/chain definition/);
});
});

Expand Down
3 changes: 3 additions & 0 deletions packages/client-p2p/src/create/peerBook.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

import type { ChainConfigType$Nodes } from '@polkadot/client-chains/types';

const assert = require('@polkadot/util/assert');
const PeerBook = require('peer-book');

const createPeerInfo = require('./peerInfo');

module.exports = async function createPeerBook (peers: ChainConfigType$Nodes = []): Promise<PeerBook> {
assert(Array.isArray(peers), 'Expected an array of addresses');

const peerBook = new PeerBook();
const peerInfos = await Promise.all(
peers.map((peer) => createPeerInfo([peer]))
Expand Down
2 changes: 1 addition & 1 deletion packages/client-p2p/src/peers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = class Peers extends EventEmitter implements PeersInterface {
constructor (emitter: Libp2p) {
super();

assert(emitter, 'Expected to receive a Libp2p event emitter');
assert(emitter, 'Expected to receive a Libp2p emitter');

this._peers = {};

Expand Down
2 changes: 1 addition & 1 deletion packages/client-p2p/src/protocol/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const assert = require('@polkadot/util/assert');
const defaults = require('../defaults');

module.exports = function protocolHandler (protocol: string, conn: any): void {
assert(protocol === defaults.PROTOCOL, `Expected matching protocol, '${protocol}' received instead`);
assert(protocol === defaults.PROTOCOL, `Expected matching protocol, '${protocol}' received`);

console.log('Connection received', conn);
// pull(conn, conn)
Expand Down
5 changes: 2 additions & 3 deletions packages/client-p2p/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ module.exports = class Server extends EventEmitter implements P2pInterface {
constructor (config: P2pConfigType, chain: ChainConfigType, autoStart: boolean = true) {
super();

assert(isObject(config), 'Expected a P2P configuration object');

assert(isObject(chain), 'Expected a chain definition object');
assert(isObject(config), 'Expected P2P configuration');
assert(isObject(chain), 'Expected chain definition');

this._config = config;
this._chain = chain;
Expand Down
2 changes: 2 additions & 0 deletions packages/client-rpc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
},
"dependencies": {
"@polkadot/util": "^0.9.1",
"babel-runtime": "^6.26.0",
"co-body": "^5.1.1",
"eventemitter3": "^2.0.3",
"koa": "^2.4.1",
"koa-route": "^3.2.0",
"koa-websocket": "^4.1.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/client-rpc/src/jsonrpc/response.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const { createResponse } = require('./index');

describe('createResponse', () => {
it('creates a valid JSONRPC structure', () => {
it('creates a valid JsonRpc structure', () => {
expect(
createResponse(123, 'test result')
).toEqual({
Expand Down
9 changes: 7 additions & 2 deletions packages/client-rpc/src/server.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// ISC, Copyright 2017 Jaco Greeff
// @flow

import type { HandlersType, JsonRpcError, JsonRpcRequest, JsonRpcResponse, RpcConfigType, RpcType } from './types';
import type { HandlersType, JsonRpcError, JsonRpcRequest, JsonRpcResponse, RpcConfigType, RpcInterface, RpcType } from './types';

type PostContextType = {
body: string,
Expand All @@ -26,19 +26,22 @@ const ExtError = require('@polkadot/util/ext/error');
const l = require('@polkadot/util/logger')('rpc');
const isError = require('@polkadot/util/is/error');
const isFunction = require('@polkadot/util/is/function');
const EventEmitter = require('eventemitter3');

const defaults = require('./defaults');
const { createError, createResponse } = require('./jsonrpc');
const { validateConfig, validateRequest, validateHandlers } = require('./validate');

module.exports = class RPCServer {
module.exports = class RPCServer extends EventEmitter implements RpcInterface {
_handlers: HandlersType;
_path: string;
_port: number;
_server: ?net$Server;
_type: Array<RpcType>;

constructor ({ path = defaults.PATH, port = defaults.PORT, type = defaults.TYPE }: RpcConfigType, handlers: HandlersType, autoStart: boolean = true) {
super();

validateConfig({ path, port, type });
validateHandlers(handlers);

Expand Down Expand Up @@ -77,6 +80,7 @@ module.exports = class RPCServer {
this._server = app.listen(this._port);

l.log(`Server started on port=${this._port} for type=${this._type.join(',')}`);
this.emit('started');
}

async stop (): Promise<void> {
Expand All @@ -90,6 +94,7 @@ module.exports = class RPCServer {
server.close();

l.log('Server stopped');
this.emit('stopped');
}

_handlePost = async (ctx: PostContextType): Promise<void> => {
Expand Down
2 changes: 1 addition & 1 deletion packages/client-rpc/src/server.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('Server', () => {
expect(result).toMatchObject({
error: {
code: ExtError.CODES.INVALID_JSONRPC,
message: "Expected a numeric id, received 'notNumber'"
message: 'Expected a numeric id'
}
});
});
Expand Down
6 changes: 6 additions & 0 deletions packages/client-rpc/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ export type RpcConfigType = {
port: number,
type: Array<RpcType>
};

export type RpcInterface$Events = 'started' | 'stopped';

export interface RpcInterface {
on (type: RpcInterface$Events, () => any): any;
}
10 changes: 3 additions & 7 deletions packages/client-rpc/src/validate/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@ const isNumber = require('@polkadot/util/is/number');

const { TYPE } = require('../defaults');

const TYPE_OR: string = TYPE.map((type) => `'${type}'`).join(' or ');

module.exports = function validateConfig ({ path, port, type }: RpcConfigType): void {
assert(isNumber(port), `Cannot instantiate with non-numeric port='${port}'`);

assert(Array.isArray(type), `Type should be specified as an Array containing ${TYPE_OR}`);

assert(type.length !== 0, `Type should have at least one of ${TYPE_OR}`);
assert(isNumber(port), 'Expected a numeric port');
assert(Array.isArray(type), 'Expected type as an Array');
assert(type.length !== 0, 'Expected non-empty type Array');

const invalid = type
.filter((_type) => !TYPE.includes(_type))
Expand Down
6 changes: 3 additions & 3 deletions packages/client-rpc/src/validate/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ describe('validateConfig', () => {
it('throws when non-numeric port is specified', () => {
expect(
() => validateConfig({ port: 'abc' })
).toThrow(/non-numeric port='abc'/);
).toThrow(/numeric port/);
});

it('throws when type is not an array', () => {
expect(
() => validateConfig({ port: 123, type: 'notArray' })
).toThrow(/Type should be specified as an Array/);
).toThrow(/as an Array/);
});

it('throws when type is an empty array', () => {
expect(
() => validateConfig({ port: 123, type: [] })
).toThrow(/Type should have at least one/);
).toThrow(/non-empty type/);
});

it('throws when unknown type is found', () => {
Expand Down
5 changes: 4 additions & 1 deletion packages/client-rpc/src/validate/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import type { HandlersType } from '../types';

const assert = require('@polkadot/util/assert');
const isFunction = require('@polkadot/util/is/function');
const isObject = require('@polkadot/util/is/object');

module.exports = function validateHandlers (handlers: HandlersType = {}): void {
assert(isObject(handlers), 'Expected handler mapping object');

const handlerKeys = Object.keys(handlers);

assert(handlerKeys.length !== 0, 'Cannot instantiate without handlers');
assert(handlerKeys.length !== 0, 'Expected non-empty handler mapping');

const invalid = handlerKeys
.filter((key) => !isFunction(handlers[key]))
Expand Down
8 changes: 4 additions & 4 deletions packages/client-rpc/src/validate/handlers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
const { validateHandlers } = require('./index');

describe('validateHandlers', () => {
it('throws when handlers are undefined', () => {
it('throws when handlers is non-object', () => {
expect(
() => validateHandlers()
).toThrow(/without handlers/);
() => validateHandlers('notAnObject')
).toThrow(/handler mapping object/);
});

it('throws when handlers are empty', () => {
expect(
() => validateHandlers({})
).toThrow(/without handlers/);
).toThrow(/non-empty handler/);
});

it('throws when non-function handlers are found', () => {
Expand Down
8 changes: 2 additions & 6 deletions packages/client-rpc/src/validate/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@
const assert = require('@polkadot/util/assert');
const ExtError = require('@polkadot/util/ext/error');
const isNumber = require('@polkadot/util/is/number');
const isUndefined = require('@polkadot/util/is/undefined');

module.exports = function validateRequest (id: number, jsonrpc: string): void {
assert(jsonrpc === '2.0', `Invalid jsonrpc field, expected '2.0', got '${jsonrpc}'`, ExtError.CODES.INVALID_JSONRPC);

assert(!isUndefined(id), `Expected a defined id, received '${id}'`, ExtError.CODES.INVALID_JSONRPC);

assert(isNumber(id), `Expected a numeric id, received '${id}'`, ExtError.CODES.INVALID_JSONRPC);
assert(jsonrpc === '2.0', `Invalid jsonrpc field, expected '2.0'`, ExtError.CODES.INVALID_JSONRPC);
assert(isNumber(id), `Expected a numeric id`, ExtError.CODES.INVALID_JSONRPC);
};

0 comments on commit f89f00d

Please sign in to comment.