-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Viem matchers first iteration #6574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v-next
Are you sure you want to change the base?
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
hardhatTotal size of the bundle: List of dependencies (sorted by size)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a first iteration of viem matchers that provide custom assertions for balances, event emissions, and function reverts. It also adds utility functions for validating addresses and comparing big numbers, and integrates these matchers via Hardhat network hook handlers.
- Introduces main matcher functions: balancesHaveChanged, revert, revertWith, emit, and emitWithArgs.
- Implements utility methods (properAddress, properChecksumAddress, areApproximatelyEqual) to support matcher operations.
- Adds hook handlers for initializing viem matchers during network connection setup.
Reviewed Changes
Copilot reviewed 32 out of 37 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
v-next/hardhat-viem-matchers/src/internal/viem-matchers-initialization.ts | Initializes viem matchers by instantiating the HardhatViemMatchersImpl. |
v-next/hardhat-viem-matchers/src/internal/matchers/utils/proper-checksum-address.ts | Validates checksum addresses using helper functions from hardhat-utils. |
v-next/hardhat-viem-matchers/src/internal/matchers/utils/proper-address.ts | Uses assert to check for valid address formats. |
v-next/hardhat-viem-matchers/src/internal/matchers/utils/big-number/are-approximately-equal.ts | Provides a utility to check whether two bigints are approximately equal. |
v-next/hardhat-viem-matchers/src/internal/matchers/revert/utils.ts | Implements the core logic for testing function reverts and extracting reasons. |
v-next/hardhat-viem-matchers/src/internal/matchers/revert/revert.ts | Exposes a simple revert matcher wrapping around the core revert logic. |
v-next/hardhat-viem-matchers/src/internal/matchers/revert/revert-with.ts | Provides functionality to assert that a function reverts with a specific reason. |
v-next/hardhat-viem-matchers/src/internal/matchers/emit/utils.ts | Implements event emission detection by parsing logs from the viem client. |
v-next/hardhat-viem-matchers/src/internal/matchers/emit/emit.ts | Defines a matcher for asserting that an event is emitted. |
v-next/hardhat-viem-matchers/src/internal/matchers/emit/emit-with-args.ts | Enhances event emission assertions by comparing expected event arguments. |
v-next/hardhat-viem-matchers/src/internal/matchers/balances-have-changed.ts | Implements balance change verification based on pre/post balance snapshots. |
v-next/hardhat-viem-matchers/src/internal/hook-handlers/network.ts | Integrates matcher initialization into Hardhat's network connection workflow |
v-next/hardhat-viem-matchers/src/index.ts | Exports the Hardhat plugin and sets up dependency and hook handler configuration. |
v-next/hardhat-viem-matchers/README.md | Contains a placeholder for plugin documentation. |
v-next/hardhat-viem-matchers/.eslintrc.cjs | Configures ESLint settings based on a shared configuration. |
Files not reviewed (5)
- pnpm-lock.yaml: Language not supported
- v-next/hardhat-viem-matchers/.gitignore: Language not supported
- v-next/hardhat-viem-matchers/.prettierignore: Language not supported
- v-next/hardhat-viem-matchers/LICENSE: Language not supported
- v-next/hardhat-viem-matchers/package.json: Language not supported
); | ||
|
||
// Convert to bigint because the values in the logs are always bigInt | ||
argsToCheck[param.name] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: If the user passes an int as the expected argument, but the assertion fails because the actual value differs, the error message will display the received value as a bigint. This can be confusing.
Example: The user passes [1] as an argument, but the emitted value is 2. The error will be:
Expected: { i: 1n }
Got: { i: 2n }
This happens because, in the Viem logs, all values are apparently shown as bigint.
); | ||
|
||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TODO | ||
return parsedLogs as unknown as Array<{ args?: Record<string, any> }>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Viem typing is very complex, here I only need the args
object that in the case of the events it should be populated
@@ -0,0 +1,130 @@ | |||
// SPDX-License-Identifier: MIT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These methods were copied from chai-matchers
. Most are currently unused but will be utilized once more extensive testing is added.
}, [ | ||
{ | ||
address: bobWalletClient.account.address, | ||
amount: -1000000023255859375000n, // TODO: gas fees that change the value? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that the balance variation in the sender is bigger than the amount sent. I assume it's because of gas fee?
…-matchers-first-iteration
async newConnection<ChainTypeT extends ChainType | string>( | ||
context: HookContext, | ||
next: ( | ||
nextContext: HookContext, | ||
) => Promise<NetworkConnection<ChainTypeT>>, | ||
) { | ||
const connection: NetworkConnection<ChainTypeT> = await next(context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why all the explicit types here? If I remove them, the code continues to compile and the inferred types are correct. Is this a new convention you guys are following in HH3?
async newConnection(
context,
next,
) {
const connection = await next(context);
reason = error.details | ||
.split("reverted with reason string ")[1] | ||
.replaceAll("'", ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is very future-proof. Ideally we want an API-stable way of getting the return data, and then we decode it ourselves. I think this will be tricky, for fun JSON-RPC reasons, but it's important.
…-matchers-first-iteration
…-matchers-first-iteration
assert.fail("The function was expected to revert, but it did not."); | ||
} | ||
|
||
function extractRevertData( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function to extract the revert reason from a Viem error
Parent issue
POC for the
viem matchers
.Note:
chai-matchers
plugin. This is intentional, we first need to finalize the implementation approach we want to take with these matchers.I've included test scenarios that cover basic cases, mainly to provide a rough idea of how the matchers are intended to be used.
Method implemented:
Main methods:
Utils:
How the matchers object is implemented (pseudocode):