Unit tests for token & contract JSON (#768)

This commit is contained in:
William O'Beirne 2018-01-11 01:47:48 -05:00 committed by Daniel Ternyak
parent af2e0b69e1
commit 7d2c3e1990
9 changed files with 117 additions and 19 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,17 @@
import ETC from './ETC.json'; import ETC from './etc.json';
import ETH from './ETH.json'; import ETH from './eth.json';
import Rinkeby from './Rinkeby.json'; import EXP from './exp.json';
import Ropsten from './Ropsten.json'; import Rinkeby from './rinkeby.json';
import Ropsten from './ropsten.json';
import RSK from './rsk.json';
import UBQ from './ubq.json';
export default { export default {
ETC, ETC,
ETH, ETH,
EXP,
Rinkeby, Rinkeby,
Ropsten Ropsten,
RSK,
UBQ
}; };

File diff suppressed because one or more lines are too long

View File

@ -67,7 +67,7 @@ export interface Token {
export interface NetworkContract { export interface NetworkContract {
name: string; name: string;
address: string; address?: string;
abi: string; abi: string;
} }

View File

@ -0,0 +1,19 @@
import ETC from './etc.json';
import ETH from './eth.json';
import EXP from './exp.json';
import Kovan from './kovan.json';
import Rinkeby from './rinkeby.json';
import Ropsten from './ropsten.json';
import RSK from './rsk.json';
import UBQ from './ubq.json';
export default {
ETC,
ETH,
EXP,
Kovan,
Rinkeby,
Ropsten,
RSK,
UBQ
};

View File

@ -46,9 +46,10 @@ e":"a", "type":"uint256"}], "name":"foo", "outputs": [] }]';
contractOptions = contractOptions.concat( contractOptions = contractOptions.concat(
contracts.map(contract => { contracts.map(contract => {
const addr = contract.address ? `(${contract.address.substr(0, 10)}...)` : '';
return { return {
name: `${contract.name} (${contract.address.substr(0, 10)}...)`, name: `${contract.name} ${addr}`,
value: contract.address value: this.makeContractValue(contract)
}; };
}) })
); );
@ -122,23 +123,26 @@ e":"a", "type":"uint256"}], "name":"foo", "outputs": [] }]';
); );
} }
private handleInput = name => (ev: any) => { private handleInput = name => (ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>) => {
this.props.resetState(); this.props.resetState();
this.setState({ [name]: ev.target.value }); this.setState({ [name]: ev.currentTarget.value });
}; };
private handleSelectContract = (ev: any) => { private handleSelectContract = (ev: React.FormEvent<HTMLSelectElement>) => {
this.props.resetState(); this.props.resetState();
const addr = ev.target.value; const contract = this.props.contracts.find(currContract => {
const contract = this.props.contracts.reduce((prev, currContract) => { return this.makeContractValue(currContract) === ev.currentTarget.value;
return currContract.address === addr ? currContract : prev;
}); });
this.setState({ this.setState({
address: contract.address, address: contract && contract.address ? contract.address : '',
abiJson: contract.abi abiJson: contract && contract.abi ? contract.abi : ''
}); });
}; };
private makeContractValue(contract: NetworkContract) {
return `${contract.name}:${contract.address}`;
}
} }
const mapStateToProps = (state: AppState) => ({ const mapStateToProps = (state: AppState) => ({

View File

@ -0,0 +1,32 @@
import CONTRACTS from 'config/contracts';
import { isValidETHAddress } from 'libs/validators';
describe('Contracts JSON', () => {
Object.keys(CONTRACTS).forEach(network => {
it(`${network} contracts array properly formatted`, () => {
const contracts = CONTRACTS[network];
const addressCollisionMap = {};
contracts.forEach(contract => {
if (contract.address && !isValidETHAddress(contract.address)) {
throw Error(`Contract '${contract.name}' has invalid address '${contract.address}'`);
}
if (addressCollisionMap[contract.address]) {
throw Error(
`Contract '${contract.name}' has the same address as ${
addressCollisionMap[contract.address]
}`
);
}
try {
JSON.stringify(contract.abi);
} catch (err) {
throw Error(`Contract '${contract.name}' has invalid JSON ABI`);
}
addressCollisionMap[contract.address] = contract.name;
});
});
});
});

View File

@ -0,0 +1,40 @@
import TOKENS from 'config/tokens';
import { isValidETHAddress } from 'libs/validators';
describe('Tokens JSON', () => {
Object.keys(TOKENS).forEach(network => {
it(`${network} tokens array properly formatted`, () => {
const tokens = TOKENS[network];
const addressCollisionMap = {};
const symbolCollisionMap = {};
tokens.forEach(token => {
if (!isValidETHAddress(token.address)) {
throw Error(`Token ${token.symbol} has invalid contract address '${token.address}'`);
}
if (addressCollisionMap[token.address]) {
throw Error(
`Token ${token.symbol} has the same address as ${addressCollisionMap[token.address]}`
);
}
if (symbolCollisionMap[token.symbol]) {
throw Error(
`Symbol ${token.symbol} is repeated between tokens at ${token.address} and ${
symbolCollisionMap[token.symbol]
}`
);
}
if (
token.decimal < 0 ||
token.decimal > 18 ||
token.decimal === null ||
token.decimal === undefined
) {
throw Error(`Token ${token.symbol} has invalid decimal '${token.decimal}'`);
}
addressCollisionMap[token.address] = token.symbol;
symbolCollisionMap[token.symbol] = token.address;
});
});
});
});