Unit tests for token & contract JSON (#768)
This commit is contained in:
parent
af2e0b69e1
commit
7d2c3e1990
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
};
|
|
@ -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) => ({
|
||||||
|
|
|
@ -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;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -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;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue