3

I know that we can use closeTo chai matcher like this:

expect(BigNumber.from(100)).to.be.closeTo(BigNumber.from(101), 10);

And we can test whether a transaction emits an event with specific arguments like this:

await expect(contract.addAddress("street", "city")).to.emit(contract, 'AddAddress').withArgs("street", "city");

But how can we use closeTo matcher with to.emit. so that we can check whether transaction emits an event with specific arguments that are close to some value?


Reference: https://ethereum-waffle.readthedocs.io/en/latest/matchers.html

1 Answer 1

1

I don't think there's an easy way to do this, at least right now. As an alternative you can do something like this:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract Test {
  event MyEvent(uint x);

  function emitEvent(uint n) public {
    emit MyEvent(n);
  }
}
const { expect } = require("chai");
const { ethers } = require("hardhat");
const { BigNumber } = ethers;

describe("Test", function () {
  it("Emit event close to", async function () {
    const Test = await ethers.getContractFactory("Test");
    const test = await Test.deploy();
    await test.deployed();

    const txPromise = test.emitEvent(100);

    await expect(txPromise).to.emit(test, 'MyEvent')

    const receipt = await (await txPromise).wait();

    const myEvent = receipt.events[0];
    const value = myEvent.args[0];

    expect(value).to.be.closeTo(BigNumber.from(100), 1)
  });
});

It's not pretty, and it assumes that the tx only emits that single event. But you could create a helper function that abstracts this away and gets the proper event by filtering all the events, for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.