UNPKG

@tevm/test-matchers

Version:

Vite test matchers for Tevm or EVM-related testing in TypeScript.

56 lines (50 loc) 2.12 kB
import type { AbiError, AbiParameter, ExtractAbiError } from 'abitype' import { type Abi, type ContractErrorName, decodeErrorResult } from 'viem' import { assert } from 'vitest' import type { ChainState, MatcherResult } from '../../chainable/types.js' import type { AbiInputsToNamedArgs } from '../../common/types.js' import type { ToBeRevertedWithState } from './types.js' export const withErrorNamedArgs = < TAbi extends Abi | undefined = Abi | undefined, TErrorName extends TAbi extends Abi ? ContractErrorName<TAbi> : never = TAbi extends Abi ? ContractErrorName<TAbi> : never, TInputs extends readonly AbiParameter[] = TAbi extends Abi ? ExtractAbiError<TAbi, TErrorName> extends { inputs: infer U extends readonly AbiParameter[] } ? U : readonly AbiParameter[] : never, >( _received: unknown, expectedArgs: Partial<AbiInputsToNamedArgs<TInputs>>, chainState?: ChainState<unknown, ToBeRevertedWithState>, ): MatcherResult => { assert(chainState, 'Internal error: no chain state found') const { previousState } = chainState if (!previousState || !('contract' in previousState)) throw new Error('withErrorNamedArgs() requires a contract with abi and error name') const { contract, decodedRevertData, rawRevertData } = previousState const decodedRevert = decodedRevertData ?? (rawRevertData ? decodeErrorResult({ abi: contract?.abi, data: rawRevertData }) : undefined) const decodedArgs = decodedRevert?.args if (!decodedArgs) throw new Error('Could not decode revert data') const namedArgs = (decodedRevert.abiItem as AbiError).inputs.reduce( (acc, input, index) => { acc[input.name ?? ''] = decodedArgs[index] return acc }, {} as Record<string, unknown>, ) const argsMatched = Object.keys(expectedArgs).every( (key) => key in namedArgs && namedArgs[key] === expectedArgs[key as keyof typeof expectedArgs], ) return { pass: argsMatched, actual: namedArgs, expected: expectedArgs, message: () => argsMatched ? 'Expected transaction not to revert with the specified arguments' : 'Expected transaction to revert with the specified arguments', } }