Skip to content

Commit

Permalink
Within and closeTo matchers for BigNumber (TrueFiEng#416)
Browse files Browse the repository at this point in the history
* Within and closeTo matchers for BigNumber

* Add missing failing test cases

* Add examples of new matchers to documentation

Co-authored-by: Tetiana Platonova <[email protected]>
  • Loading branch information
p-sad and malyfko authored Feb 26, 2021
1 parent e4ff46a commit 9fd9661
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
7 changes: 6 additions & 1 deletion docs/source/matchers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ Testing equality of big numbers:
expect(await token.balanceOf(wallet.address)).to.equal(993);
Available matchers for BigNumbers are: `equal`, `eq`, `above`, `gt`, `gte`, `below`, `lt`, `lte`, `least`, `most`.
Available matchers for BigNumbers are: `equal`, `eq`, `above`, `gt`, `gte`, `below`, `lt`, `lte`, `least`, `most`, `within`, `closeTo`.

.. code-block:: ts
expect(BigNumber.from(100)).to.be.within(BigNumber.from(99), BigNumber.from(101));
expect(BigNumber.from(100)).to.be.closeTo(BigNumber.from(101), 10);
Emitting events
---------------
Expand Down
49 changes: 49 additions & 0 deletions waffle-chai/src/matchers/bigNumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export function supportBigNumber(
'lte',
override('lte', 'less than or equal', utils)
);

Assertion.overwriteMethod('within', overrideWithin(utils));

Assertion.overwriteMethod('closeTo', overrideCloseTo(utils));
}

type Methods = 'eq' | 'gt' | 'lt' | 'gte' | 'lte';
Expand Down Expand Up @@ -59,3 +63,48 @@ function overwriteBigNumberFunction(
}
};
}

function overrideWithin(utils: Chai.ChaiUtils) {
return (_super: (...args: any[]) => any) => overwriteBigNumberWithin(_super, utils);
}

function overwriteBigNumberWithin(_super: (...args: any[]) => any, chaiUtils: Chai.ChaiUtils) {
return function (this: Chai.AssertionStatic, ...args: any[]) {
const [start, finish] = args;
const expected = chaiUtils.flag(this, 'object');
if (BigNumber.isBigNumber(expected) || BigNumber.isBigNumber(start) || BigNumber.isBigNumber(finish)) {
this.assert(
BigNumber.from(start).lte(expected) && BigNumber.from(finish).gte(expected),
`Expected "${expected}" to be within [${[start, finish]}]`,
`Expected "${expected}" NOT to be within [${[start, finish]}]`,
[start, finish],
expected
);
} else {
_super.apply(this, args);
}
};
}

function overrideCloseTo(utils: Chai.ChaiUtils) {
return (_super: (...args: any[]) => any) =>
overwriteBigNumberCloseTo(_super, utils);
}

function overwriteBigNumberCloseTo(_super: (...args: any[]) => any, chaiUtils: Chai.ChaiUtils) {
return function (this: Chai.AssertionStatic, ...args: any[]) {
const [actual, delta] = args;
const expected = chaiUtils.flag(this, 'object');
if (BigNumber.isBigNumber(expected) || BigNumber.isBigNumber(actual) || BigNumber.isBigNumber(delta)) {
this.assert(
BigNumber.from(expected).sub(actual).abs().lte(delta),
`Expected "${expected}" to be within ${delta} of ${actual}`,
`Expected "${expected}" NOT to be within ${delta} of ${actual}`,
`A number between ${actual.sub(delta)} and ${actual.sub(delta)}`,
expected
);
} else {
_super.apply(this, args);
}
};
}
39 changes: 39 additions & 0 deletions waffle-chai/test/matchers/bigNumber.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,43 @@ describe('UNIT: BigNumber matchers', () => {
checkAll(10, 9, (a, b) => expect(a).not.to.be.lte(b));
});
});

describe('within', () => {
it('.to.be.within', () => {
expect(BigNumber.from(100)).to.be.within(BigNumber.from(99), BigNumber.from(101));
});

it('.not.to.be.within', () => {
expect(BigNumber.from(100)).not.to.be.within(BigNumber.from(101), BigNumber.from(102));
expect(BigNumber.from(100)).not.to.be.within(BigNumber.from(98), BigNumber.from(99));
});

it('expect to throw on error', () => {
expect(
() => expect(BigNumber.from(100)).to.be.within(BigNumber.from(80), BigNumber.from(90))
).to.throw(AssertionError, 'Expected "100" to be within [80,90]');
expect(
() => expect(BigNumber.from(100)).not.to.be.within(BigNumber.from(99), BigNumber.from(101))
).to.throw(AssertionError, 'Expected "100" NOT to be within [99,101]');
});
});

describe('closeTo', () => {
it('.to.be.closeTo', () => {
expect(BigNumber.from(100)).to.be.closeTo(BigNumber.from(101), 10);
});

it('.not.to.be.closeTo', () => {
expect(BigNumber.from(100)).not.to.be.closeTo(BigNumber.from(111), 10);
});

it('expect to throw on error', () => {
expect(
() => expect(BigNumber.from(100)).to.be.closeTo(BigNumber.from(111), 10)
).to.throw(AssertionError, 'Expected "100" to be within 10 of 111');
expect(
() => expect(BigNumber.from(100)).not.to.be.closeTo(BigNumber.from(101), 10)
).to.throw(AssertionError, 'Expected "100" NOT to be within 10 of 101');
});
});
});

0 comments on commit 9fd9661

Please sign in to comment.