123456789101112131415161718192021222324252627282930313233343536373839404142 |
- const { config } = require('hardhat');
- const { expect } = require('chai');
- const optimizationsEnabled = config.solidity.compilers.some(c => c.settings.optimizer.enabled);
- /** Revert handler that supports custom errors. */
- async function expectRevertCustomError(promise, expectedErrorName, args) {
- try {
- await promise;
- expect.fail("Expected promise to throw but it didn't");
- } catch (revert) {
- if (!Array.isArray(args)) {
- expect.fail('Expected 3rd array parameter for error arguments');
- }
- if (expectedErrorName) {
- if (optimizationsEnabled) {
- // Optimizations currently mess with Hardhat's decoding of custom errors
- expect(revert.message).to.include.oneOf([expectedErrorName, 'unrecognized return data or custom error']);
- } else {
- const [, error] = revert.message.match(/'(.*)'/);
- if (!/([A-Z])\w+\(.*\)/g.test(error)) {
- expect.fail(`Couldn't parse "${error}" as a custom error`);
- }
- const [, errorName] = error.match(/(\w+)\(.*\)/);
- const argMatches = [...error.replace(errorName, '').matchAll(/(0x[0-9A-Fa-f]+|-?\d+|\w+)/g)];
- expect(errorName).to.be.equal(
- expectedErrorName,
- `Unexpected custom error name (with found args: [${argMatches.map(([a]) => a)}])`,
- );
- // Coerce to string for comparison since `arg` can be either a number or hex.
- const sanitizedExpected = args.map(arg => arg.toString().toLowerCase());
- const sanitizedActual = argMatches.map(([arg]) => arg.toString().toLowerCase());
- expect(sanitizedActual).to.have.members(sanitizedExpected, `Unexpected ${errorName} arguments`);
- }
- }
- }
- }
- module.exports = {
- expectRevertCustomError,
- };
|