@0x/contracts-test-utils
: Add number_utils.ts
and hexSize()
.
This commit is contained in:
@@ -93,6 +93,10 @@
|
||||
{
|
||||
"note": "Add `shortZip()` to `lang_utils.ts`",
|
||||
"pr": 2155
|
||||
},
|
||||
{
|
||||
"note": "Add `number_utils.ts` and `hexSize()`",
|
||||
"pr": "TODO"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@@ -65,6 +65,13 @@ export function hexHash(n: Numberish): string {
|
||||
return ethUtil.bufferToHex(ethUtil.sha3(ethUtil.toBuffer(toHex(n))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length, in bytes, of a hex string.
|
||||
*/
|
||||
export function hexSize(hex: string): number {
|
||||
return Math.ceil((hex.length - 2) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string, a number, or a BigNumber into a hex string.
|
||||
* Works with negative numbers, as well.
|
||||
|
@@ -28,7 +28,17 @@ export { bytes32Values, testCombinatoriallyWithReferenceFunc, uint256Values } fr
|
||||
export { TransactionFactory } from './transaction_factory';
|
||||
export { MutatorContractFunction, TransactionHelper } from './transaction_helper';
|
||||
export { testWithReferenceFuncAsync } from './test_with_reference';
|
||||
export { hexConcat, hexHash, hexLeftPad, hexInvert, hexSlice, hexRandom, hexRightPad, toHex } from './hex_utils';
|
||||
export {
|
||||
hexConcat,
|
||||
hexHash,
|
||||
hexLeftPad,
|
||||
hexInvert,
|
||||
hexSlice,
|
||||
hexRandom,
|
||||
hexRightPad,
|
||||
hexSize,
|
||||
toHex,
|
||||
} from './hex_utils';
|
||||
export {
|
||||
BatchMatchOrder,
|
||||
ContractName,
|
||||
@@ -51,3 +61,12 @@ export { blockchainTests, BlockchainTestsEnvironment, describe } from './mocha_b
|
||||
export { chaiSetup, expect } from './chai_setup';
|
||||
export { getCodesizeFromArtifact } from './codesize';
|
||||
export { shortZip } from './lang_utils';
|
||||
export {
|
||||
assertIntegerRoughlyEquals,
|
||||
assertRoughlyEquals,
|
||||
getRandomFloat,
|
||||
getRandomInteger,
|
||||
getRandomPortion,
|
||||
getNumericalDivergence,
|
||||
toBaseUnitAmount,
|
||||
} from './number_utils';
|
||||
|
88
contracts/test-utils/src/number_utils.ts
Normal file
88
contracts/test-utils/src/number_utils.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
import { expect } from './chai_setup';
|
||||
import { Numberish } from './types';
|
||||
|
||||
/**
|
||||
* Generate a random integer between `min` and `max`, inclusive.
|
||||
*/
|
||||
export function getRandomInteger(min: Numberish, max: Numberish): BigNumber {
|
||||
const range = new BigNumber(max).minus(min);
|
||||
return getRandomPortion(range).plus(min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random integer between `0` and `total`, inclusive.
|
||||
*/
|
||||
export function getRandomPortion(total: Numberish): BigNumber {
|
||||
return new BigNumber(total).times(getRandomFloat(0, 1)).integerValue(BigNumber.ROUND_HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random, high-precision decimal between `min` and `max`, inclusive.
|
||||
*/
|
||||
export function getRandomFloat(min: Numberish, max: Numberish): BigNumber {
|
||||
// Generate a really high precision number between [0, 1]
|
||||
const r = new BigNumber(crypto.randomBytes(32).toString('hex'), 16).dividedBy(new BigNumber(2).pow(256).minus(1));
|
||||
return new BigNumber(max)
|
||||
.minus(min)
|
||||
.times(r)
|
||||
.plus(min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts two decimal numbers to integers with `precision` digits, then returns
|
||||
* the absolute difference.
|
||||
*/
|
||||
export function getNumericalDivergence(a: Numberish, b: Numberish, precision: number = 18): number {
|
||||
const _a = new BigNumber(a);
|
||||
const _b = new BigNumber(b);
|
||||
const maxIntegerDigits = Math.max(
|
||||
_a.integerValue(BigNumber.ROUND_DOWN).sd(true),
|
||||
_b.integerValue(BigNumber.ROUND_DOWN).sd(true),
|
||||
);
|
||||
const _toInteger = (n: BigNumber) => {
|
||||
const base = 10 ** (precision - maxIntegerDigits);
|
||||
return n.times(base).integerValue(BigNumber.ROUND_DOWN);
|
||||
};
|
||||
return _toInteger(_a)
|
||||
.minus(_toInteger(_b))
|
||||
.abs()
|
||||
.toNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that two numbers are equal up to `precision` digits.
|
||||
*/
|
||||
export function assertRoughlyEquals(actual: Numberish, expected: Numberish, precision: number = 18): void {
|
||||
if (getNumericalDivergence(actual, expected, precision) <= 1) {
|
||||
return;
|
||||
}
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that two numbers are equal with up to `maxError` difference between them.
|
||||
*/
|
||||
export function assertIntegerRoughlyEquals(actual: Numberish, expected: Numberish, maxError: number = 1): void {
|
||||
const diff = new BigNumber(actual)
|
||||
.minus(expected)
|
||||
.abs()
|
||||
.toNumber();
|
||||
if (diff <= maxError) {
|
||||
return;
|
||||
}
|
||||
expect(actual).to.bignumber.eq(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts `amount` into a base unit amount with 18 digits.
|
||||
*/
|
||||
export function toBaseUnitAmount(amount: Numberish): BigNumber {
|
||||
const decimals = 18;
|
||||
const amountAsBigNumber = new BigNumber(amount);
|
||||
const baseUnitAmount = Web3Wrapper.toBaseUnitAmount(amountAsBigNumber, decimals);
|
||||
return baseUnitAmount;
|
||||
}
|
Reference in New Issue
Block a user