F. Eugene Aumson ead8099109
Auto-gen Python Exchange wrapper (#1919)
* Rename existing wrapper, to match contract name

* base contract: make member var public

* json_schemas.py: stop storing copies of schemas!

* .gitignore generated erc20_token.py wrapper

* json schemas: allow uppercase digits in address

* existing exchange wrapper: re-order methods

to match method order in Solidity contract, to reduce noise in upcoming
diffs of newly generated code vs. old manually-written code.

* existing exchange wrapper: rename method params

To match contract method param names

* existing exchange wrapper: remove redundant member

* existing exchange wrapper: make signatures bytes

Not strings.

* abi-gen/test-cli: show context on diff failure

* abi-gen-templates/Py: fix broken event interface

Previous changes had removed the `token_address` parameter from all
generated methods, but this instance was missed because there weren't
tests/examples using events for the first contract for which wrappers
were generated (ERC20Token).

* abi-gen: remove unused method parameters

* abi-gen: convert Py method params to snake case

* abi-gen: rewrite Python tuple handling

* python-generated-wrappers: include Exchange

* abi-gen-templates/Py: easy linter fixes

* abi-gen-templates/Py: satisfy docstring linters

* abi-gen-templates/Py: normalize bytes before use

* contract_wrappers.py: replace Exchange w/generated

* contract_wrappers.py: rm manually written Exchange

* contract_wrappers.py/doctest: rename variables

* abi-gen: fix misspelling in docstring

Co-Authored-By: Fabio B <me@fabioberger.com>

* Py docs: error on warning, and test build in CI

* abi-gen: doc Py bytes params as requiring UTF-8

* abi-gen: git mv diff.sh test-cli/

* abi-gen: put Py wrapper in module folder, not file

This leaves space for user-defined additions to the same module, such as
for custom types, as shown herein.

* abi-gen: customizable param validation for Python

* contract_wrappers.py: JSON schema Order validation

* CircleCI Build Artifacts

For abi-gen command-line test output, for generated Python contract
wrappers as output by abi-gen, for generated Python contract wrappers as
reformatted and included in the Python package area, and for the "build"
output folder in each Python package, which includes the generated
documentation.

* CHANGELOG updates for all components

* abi-gen: grammar in comments

Co-Authored-By: Fabio B <me@fabioberger.com>

* abi-gen: CHANGELOG spelling correction

Co-Authored-By: Fabio B <me@fabioberger.com>

* order_utils.py: reverse (chronological) CHANGELOG

* abi-gen-templates: reset CHANGELOG patch version

* CHANGELOGs: use multiple entries where appropriate

* abi-gen: enable devdoc solc output in test-cli

* abi-gen-templates/Py: consolidate return type

* abi-gen/test-cli: non-pure fixture contract method

Added a method to the "dummy" test fixture contract that isn't pure.
All of the other prior method cases were pure.

* abi-gen/Py: fix const methods missing return type

* abi-gen/Py: fix wrong return types on some methods

Specifically, wrapper methods wrapping contract methods that modify
contract state and return no return value.  There was no test case for
this.  Now there is.

* contract_wrappers.py: rm generated code in `clean`

* Parallelize Py monorepo scripts (test, lint, etc)
2019-07-23 12:58:18 -04:00

867 lines
38 KiB
TypeScript

import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as dirtyChai from 'dirty-chai';
import forEach = require('lodash.foreach');
import 'mocha';
import { schemas, SchemaValidator } from '../src/index';
chai.config.includeStack = true;
chai.use(dirtyChai);
const expect = chai.expect;
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
const {
numberSchema,
addressSchema,
hexSchema,
orderCancellationRequestsSchema,
orderFillOrKillRequestsSchema,
orderFillRequestsSchema,
orderHashSchema,
orderSchema,
signedOrderSchema,
signedOrdersSchema,
blockParamSchema,
blockRangeSchema,
tokenSchema,
jsNumber,
txDataSchema,
paginatedCollectionSchema,
relayerApiErrorResponseSchema,
relayerApiOrderbookResponseSchema,
relayerApiAssetDataPairsResponseSchema,
relayerApiOrderConfigPayloadSchema,
relayerApiOrderConfigResponseSchema,
relayerApiOrdersChannelSubscribeSchema,
relayerApiOrdersChannelUpdateSchema,
relayerApiOrdersResponseSchema,
relayerApiOrderSchema,
wholeNumberSchema,
} = schemas;
describe('Schema', () => {
const validator = new SchemaValidator();
const validateAgainstSchema = (testCases: any[], schema: any, shouldFail = false) => {
forEach(testCases, (testCase: any) => {
const validationResult = validator.validate(testCase, schema);
const hasErrors = validationResult.errors.length !== 0;
if (shouldFail) {
if (!hasErrors) {
throw new Error(
`Expected testCase: ${JSON.stringify(testCase, null, '\t')} to fail and it didn't.`,
);
}
} else {
if (hasErrors) {
throw new Error(JSON.stringify(validationResult.errors, null, '\t'));
}
}
});
};
const paginatedResponse = {
total: 100,
perPage: 10,
page: 3,
};
describe('#numberSchema', () => {
it('should validate valid numbers', () => {
const testCases = ['42', '0', '1.3', '0.2', '00.00'];
validateAgainstSchema(testCases, numberSchema);
});
it('should fail for invalid numbers', () => {
const testCases = ['.3', '1.', 'abacaba', 'и', '1..0'];
const shouldFail = true;
validateAgainstSchema(testCases, numberSchema, shouldFail);
});
});
describe('#wholeNumberSchema', () => {
it('should validate valid numbers', () => {
const testCases = ['5', '42', '0'];
validateAgainstSchema(testCases, wholeNumberSchema);
});
it('should fail for invalid numbers', () => {
const testCases = ['1.3', '0.2', '00.00', '.3', '1.', 'abacaba', 'и', '1..0'];
const shouldFail = true;
validateAgainstSchema(testCases, wholeNumberSchema, shouldFail);
});
});
describe('#addressSchema', () => {
it('should validate valid addresses', () => {
const testCases = ['0x8b0292b11a196601ed2ce54b665cafeca0347d42', NULL_ADDRESS];
validateAgainstSchema(testCases, addressSchema);
});
it('should fail for invalid addresses', () => {
const testCases = ['0x', '0', '0x00', '0xzzzzzzB11a196601eD2ce54B665CaFEca0347D42'];
const shouldFail = true;
validateAgainstSchema(testCases, addressSchema, shouldFail);
});
});
describe('#hexSchema', () => {
it('should validate valid hex string', () => {
const testCases = ['0x8b0292b11a196601ed2ce54b665cafeca0347d42', NULL_ADDRESS];
validateAgainstSchema(testCases, hexSchema);
});
it('should fail for invalid hex string', () => {
const testCases = ['0', '0xzzzzzzB11a196601eD2ce54B665CaFEca0347D42'];
const shouldFail = true;
validateAgainstSchema(testCases, hexSchema, shouldFail);
});
});
describe('#orderHashSchema', () => {
it('should validate valid order hash', () => {
const testCases = [
'0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
'0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
];
validateAgainstSchema(testCases, orderHashSchema);
});
it('should fail for invalid order hash', () => {
const testCases = [
{},
'0x',
'0x8b0292B11a196601eD2ce54B665CaFEca0347D42',
'61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33',
];
const shouldFail = true;
validateAgainstSchema(testCases, orderHashSchema, shouldFail);
});
});
describe('#blockParamSchema', () => {
it('should validate valid block param', () => {
const blockNumber = 42;
const testCases = [blockNumber, 'latest', 'pending', 'earliest'];
validateAgainstSchema(testCases, blockParamSchema);
});
it('should fail for invalid block param', () => {
const testCases = [{}, '42', 'pemding'];
const shouldFail = true;
validateAgainstSchema(testCases, blockParamSchema, shouldFail);
});
});
describe('#blockRangeSchema', () => {
it('should validate valid subscription opts', () => {
const testCases = [{ fromBlock: 42, toBlock: 'latest' }, { fromBlock: 42 }, {}];
validateAgainstSchema(testCases, blockRangeSchema);
});
it('should fail for invalid subscription opts', () => {
const testCases = [{ fromBlock: '42' }];
const shouldFail = true;
validateAgainstSchema(testCases, blockRangeSchema, shouldFail);
});
});
describe('#tokenSchema', () => {
const token = {
name: 'Zero Ex',
symbol: 'ZRX',
decimals: 100500,
address: '0x8b0292b11a196601ed2ce54b665cafeca0347d42',
url: 'https://0xproject.com',
};
it('should validate valid token', () => {
const testCases = [token];
validateAgainstSchema(testCases, tokenSchema);
});
it('should fail for invalid token', () => {
const num = 4;
const testCases = [
{
...token,
address: null,
},
{
...token,
decimals: undefined,
},
[],
num,
];
const shouldFail = true;
validateAgainstSchema(testCases, tokenSchema, shouldFail);
});
});
describe('#paginatedCollectionSchema', () => {
it('should validate valid paginated collections', () => {
const testCases = [paginatedResponse];
validateAgainstSchema(testCases, paginatedCollectionSchema);
});
it('should fail for invalid paginated collections', () => {
const paginatedCollectionNoTotal = {
page: 10,
perPage: 2,
};
const paginatedCollectionNoPerPage = {
page: 10,
total: 100,
};
const paginatedCollectionNoPage = {
total: 10,
perPage: 20,
};
const testCases = [{}, paginatedCollectionNoPage, paginatedCollectionNoPerPage, paginatedCollectionNoTotal];
const shouldFail = true;
validateAgainstSchema(testCases, paginatedCollectionSchema, shouldFail);
});
});
describe('order including schemas', () => {
const order = {
makerAddress: NULL_ADDRESS,
takerAddress: NULL_ADDRESS,
senderAddress: NULL_ADDRESS,
makerFee: '1',
takerFee: '2',
makerAssetAmount: '1',
takerAssetAmount: '2',
makerAssetData: NULL_ADDRESS,
takerAssetData: NULL_ADDRESS,
salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
feeRecipientAddress: NULL_ADDRESS,
exchangeAddress: NULL_ADDRESS,
expirationTimeSeconds: '42',
};
const relayerApiOrder = {
order,
metaData: {
someMetaData: 5,
},
};
const relayerApiOrdersResponse = {
...paginatedResponse,
records: [relayerApiOrder, relayerApiOrder],
};
describe('#orderSchema', () => {
it('should validate valid order', () => {
const testCases = [order];
validateAgainstSchema(testCases, orderSchema);
});
it('should fail for invalid order', () => {
const testCases = [
{
...order,
salt: undefined,
},
{
...order,
salt: 'salt',
},
'order',
];
const shouldFail = true;
validateAgainstSchema(testCases, orderSchema, shouldFail);
});
});
describe('signed order including schemas', () => {
const signedOrder = {
...order,
signature:
'0x031b61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
};
describe('#signedOrdersSchema', () => {
it('should validate valid signed orders', () => {
const testCases = [[signedOrder], []];
validateAgainstSchema(testCases, signedOrdersSchema);
});
it('should fail for invalid signed orders', () => {
const testCases = [[signedOrder, 1]];
const shouldFail = true;
validateAgainstSchema(testCases, signedOrdersSchema, shouldFail);
});
});
describe('#signedOrderSchema', () => {
it('should validate valid signed order', () => {
const testCases = [signedOrder];
validateAgainstSchema(testCases, signedOrderSchema);
});
it('should fail for invalid signed order', () => {
const testCases = [
{
...signedOrder,
signature: undefined,
},
];
const shouldFail = true;
validateAgainstSchema(testCases, signedOrderSchema, shouldFail);
});
});
describe('#orderFillOrKillRequestsSchema', () => {
const orderFillOrKillRequests = [
{
signedOrder,
fillTakerAmount: '5',
},
];
it('should validate valid order fill or kill requests', () => {
const testCases = [orderFillOrKillRequests];
validateAgainstSchema(testCases, orderFillOrKillRequestsSchema);
});
it('should fail for invalid order fill or kill requests', () => {
const testCases = [
[
{
...orderFillOrKillRequests[0],
fillTakerAmount: undefined,
},
],
];
const shouldFail = true;
validateAgainstSchema(testCases, orderFillOrKillRequestsSchema, shouldFail);
});
});
describe('#orderCancellationRequestsSchema', () => {
const orderCancellationRequests = [
{
order,
takerTokenCancelAmount: '5',
},
];
it('should validate valid order cancellation requests', () => {
const testCases = [orderCancellationRequests];
validateAgainstSchema(testCases, orderCancellationRequestsSchema);
});
it('should fail for invalid order cancellation requests', () => {
const testCases = [
[
{
...orderCancellationRequests[0],
takerTokenCancelAmount: undefined,
},
],
];
const shouldFail = true;
validateAgainstSchema(testCases, orderCancellationRequestsSchema, shouldFail);
});
});
describe('#orderFillRequestsSchema', () => {
const orderFillRequests = [
{
signedOrder,
takerTokenFillAmount: '5',
},
];
it('should validate valid order fill requests', () => {
const testCases = [orderFillRequests];
validateAgainstSchema(testCases, orderFillRequestsSchema);
});
it('should fail for invalid order fill requests', () => {
const testCases = [
[
{
...orderFillRequests[0],
takerTokenFillAmount: undefined,
},
],
];
const shouldFail = true;
validateAgainstSchema(testCases, orderFillRequestsSchema, shouldFail);
});
});
describe('standard relayer api schemas', () => {
describe('#relayerApiOrderSchema', () => {
it('should validate valid relayer api order', () => {
const testCases = [relayerApiOrder];
validateAgainstSchema(testCases, relayerApiOrderSchema);
});
it('should fail for invalid relayer api orders', () => {
const testCases = [{}, order, { order }, { order, metaData: 5 }];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiOrderSchema, shouldFail);
});
});
describe('#relayerApiErrorResponseSchema', () => {
it('should validate valid errorResponse', () => {
const testCases = [
{
code: 102,
reason: 'Order submission disabled',
},
{
code: 101,
reason: 'Validation failed',
validationErrors: [
{
field: 'maker',
code: 1002,
reason: 'Invalid address',
},
],
},
];
validateAgainstSchema(testCases, relayerApiErrorResponseSchema);
});
it('should fail for invalid error responses', () => {
const testCases = [
{},
{
code: 102,
},
{
code: '102',
reason: 'Order submission disabled',
},
{
reason: 'Order submission disabled',
},
{
code: 101,
reason: 'Validation failed',
validationErrors: [
{
field: 'maker',
reason: 'Invalid address',
},
],
},
{
code: 101,
reason: 'Validation failed',
validationErrors: [
{
field: 'maker',
code: '1002',
reason: 'Invalid address',
},
],
},
];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiErrorResponseSchema, shouldFail);
});
});
describe('#relayerApiOrderConfigPayloadSchema', () => {
it('should validate valid fees payloads', () => {
const testCases = [
{
exchangeAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
makerAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
takerAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
makerAssetData: NULL_ADDRESS,
takerAssetData: NULL_ADDRESS,
makerAssetAmount: '10000000000000000000',
takerAssetAmount: '30000000000000000000',
expirationTimeSeconds: '42',
},
];
validateAgainstSchema(testCases, relayerApiOrderConfigPayloadSchema);
});
it('should fail for invalid fees payloads', () => {
const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
const testCases = [
{},
{
makerAssetAmount: '10000000000000000000',
takerAssetAmount: '30000000000000000000',
makerAssetData: NULL_ADDRESS,
takerAssetData: NULL_ADDRESS,
},
{
takerAddress: checksummedAddress,
makerAssetAmount: '10000000000000000000',
takerAssetAmount: '30000000000000000000',
},
{
makerAssetAmount: 10000000000000000000,
takerAssetAmount: 30000000000000000000,
},
];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiOrderConfigPayloadSchema, shouldFail);
});
});
describe('#relayerApiOrderConfigResponseSchema', () => {
it('should validate valid fees responses', () => {
const testCases = [
{
makerFee: '10000000000000000',
takerFee: '30000000000000000',
feeRecipientAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
senderAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
},
];
validateAgainstSchema(testCases, relayerApiOrderConfigResponseSchema);
});
it('should fail for invalid fees responses', () => {
const checksummedAddress = '0xA2b31daCf30a9C50ca473337c01d8A201ae33e32';
const testCases = [
{},
{
makerFee: 10000000000000000,
takerFee: 30000000000000000,
},
{
feeRecipient: checksummedAddress,
takerToSpecify: checksummedAddress,
makerFee: '10000000000000000',
takerFee: '30000000000000000',
},
];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiOrderConfigResponseSchema, shouldFail);
});
});
describe('#relayerAssetDataPairsResponseSchema', () => {
it('should validate valid assetPairs response', () => {
const testCases = [
{
...paginatedResponse,
records: [],
},
{
...paginatedResponse,
records: [
{
assetDataA: {
assetData: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
minAmount: '0',
maxAmount: '10000000000000000000',
precision: 5,
},
assetDataB: {
assetData: '0xef7fff64389b814a946f3e92105513705ca6b990',
minAmount: '0',
maxAmount: '50000000000000000000',
precision: 5,
},
},
],
},
{
...paginatedResponse,
records: [
{
assetDataA: {
assetData: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
},
assetDataB: {
assetData: '0xef7fff64389b814a946f3e92105513705ca6b990',
},
},
],
},
];
validateAgainstSchema(testCases, relayerApiAssetDataPairsResponseSchema);
});
it('should fail for invalid assetPairs responses', () => {
const testCases = [
{
...paginatedResponse,
records: [
{
assetDataA: {
assetData: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
minAmount: '0',
maxAmount: '10000000000000000000',
precision: 5,
},
assetDataC: {
assetData: '0xef7fff64389b814a946f3e92105513705ca6b990',
minAmount: '0',
maxAmount: '50000000000000000000',
precision: 5,
},
},
],
},
{
records: [
{
assetDataA: {
assetData: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
minAmount: '0',
maxAmount: '10000000000000000000',
precision: 5,
},
assetDataB: {
assetData: '0xef7fff64389b814a946f3e92105513705ca6b990',
minAmount: '0',
maxAmount: '50000000000000000000',
precision: 5,
},
},
],
},
{
...paginatedResponse,
records: [
{
assetDataA: {
minAmount: '0',
maxAmount: '10000000000000000000',
precision: 5,
},
assetDataB: {
minAmount: '0',
maxAmount: '50000000000000000000',
precision: 5,
},
},
],
},
];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiAssetDataPairsResponseSchema, shouldFail);
});
});
describe('#relayerApiOrdersResponseSchema', () => {
it('should validate valid orders responses', () => {
const testCases = [
relayerApiOrdersResponse,
{
...paginatedResponse,
records: [],
},
];
validateAgainstSchema(testCases, relayerApiOrdersResponseSchema);
});
it('should fail for invalid orders responses', () => {
const testCases = [
{
records: [relayerApiOrder, relayerApiOrder],
},
{
...paginatedResponse,
},
{
...paginatedResponse,
records: [{}, relayerApiOrder],
},
];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiOrdersResponseSchema, shouldFail);
});
});
describe('#relayerApiOrderbookResponseSchema', () => {
it('should validate valid order book responses', () => {
const testCases = [
{
bids: {
...paginatedResponse,
records: [relayerApiOrder],
},
asks: {
...paginatedResponse,
records: [],
},
},
{
bids: {
...paginatedResponse,
records: [relayerApiOrder, relayerApiOrder],
},
asks: {
...paginatedResponse,
records: [relayerApiOrder, relayerApiOrder],
},
},
{
bids: {
...paginatedResponse,
records: [],
},
asks: {
...paginatedResponse,
records: [relayerApiOrder, relayerApiOrder],
},
},
];
validateAgainstSchema(testCases, relayerApiOrderbookResponseSchema);
});
it('should fail for invalid order fill requests', () => {
const testCases = [
{},
{
bids: {
records: [relayerApiOrder],
},
asks: {
...paginatedResponse,
records: [],
},
},
{
bids: {
...paginatedResponse,
records: [relayerApiOrder, relayerApiOrder],
},
asks: {},
},
{
bids: {
...paginatedResponse,
},
asks: {
...paginatedResponse,
records: [relayerApiOrder, relayerApiOrder],
},
},
];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiOrdersResponseSchema, shouldFail);
});
});
describe('#relayerApiOrdersChannelSubscribeSchema', () => {
it('should validate valid orders channel websocket subscribe message', () => {
const testCases = [
{
type: 'subscribe',
channel: 'orders',
requestId: 'randomId',
},
{
type: 'subscribe',
channel: 'orders',
requestId: 'randomId',
payload: {
makerAssetProxyId: '0x02571792',
takerAssetProxyId: '0xf47261b0',
},
},
{
type: 'subscribe',
channel: 'orders',
requestId: 'randomId',
payload: {},
},
];
validateAgainstSchema(testCases, relayerApiOrdersChannelSubscribeSchema);
});
it('should fail for invalid orders channel websocket subscribe message', () => {
const bogusAddress = '0xz2b31daCf30a9C50ca473337c01d8A201ae33e32';
const testCases = [
{
type: 'subscribe',
channel: 'orders',
},
{
type: 'subscribe',
channel: 'orders',
requestId: 'randomId',
payload: {
makerAssetProxyId: '0x02571792',
takerAssetProxyId: '0xf47261b0',
makerAssetAddress: bogusAddress,
},
},
{
type: 'subscribe',
channel: 'orders',
requestId: 'randomId',
payload: {
makerAssetProxyId: 'invalidId',
},
},
];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiOrdersChannelSubscribeSchema, shouldFail);
});
});
describe('#relayerApiOrdersChannelUpdateSchema', () => {
it('should validate valid orders channel websocket update message', () => {
const testCases = [
{
type: 'update',
channel: 'orders',
requestId: 'randomId',
payload: [relayerApiOrder],
},
{
type: 'update',
channel: 'orders',
requestId: 'randomId',
payload: [],
},
];
validateAgainstSchema(testCases, relayerApiOrdersChannelUpdateSchema);
});
it('should fail for invalid orders channel websocket update message', () => {
const testCases = [
{
type: 'foo',
channel: 'orders',
requestId: 'randomId',
},
{
type: 'update',
channel: 'bar',
requestId: 2,
payload: [relayerApiOrder],
},
{
type: 'update',
channel: 'orders',
requestId: 'randomId',
payload: {},
},
{
type: 'update',
channel: 'orders',
requestId: 'randomId',
payload: relayerApiErrorResponseSchema,
},
];
const shouldFail = true;
validateAgainstSchema(testCases, relayerApiOrdersChannelUpdateSchema, shouldFail);
});
});
});
});
});
describe('BigNumber serialization', () => {
it('should correctly serialize BigNumbers', () => {
const testCases = {
'42': '42',
'0': '0',
'1.3': '1.3',
'0.2': '0.2',
'00.00': '0',
'.3': '0.3',
};
forEach(testCases, (serialized: string, input: string) => {
expect(JSON.parse(JSON.stringify(new BigNumber(input)))).to.be.equal(serialized);
});
});
});
describe('#jsNumberSchema', () => {
it('should validate valid js number', () => {
// tslint:disable-next-line:custom-no-magic-numbers
const testCases = [1, 42];
validateAgainstSchema(testCases, jsNumber);
});
it('should fail for invalid js number', () => {
// tslint:disable-next-line:custom-no-magic-numbers
const testCases = [NaN, -1, new BigNumber(1)];
const shouldFail = true;
validateAgainstSchema(testCases, jsNumber, shouldFail);
});
});
describe('#txDataSchema', () => {
it('should validate valid txData', () => {
const bigNumGasAmount = new BigNumber(42);
const testCases = [
{
from: NULL_ADDRESS,
},
{
from: NULL_ADDRESS,
gas: bigNumGasAmount,
},
{
from: NULL_ADDRESS,
gas: 42,
},
];
validateAgainstSchema(testCases, txDataSchema);
});
it('should fail for invalid txData', () => {
const testCases = [
{
gas: new BigNumber(42),
},
{},
[],
new BigNumber(1),
];
const shouldFail = true;
validateAgainstSchema(testCases, txDataSchema, shouldFail);
});
});
}); // tslint:disable:max-file-line-count