Skip to content

Commit ccb1c9c

Browse files
committed
chore: add viem assertion to example project
To aid manual testing of assertions, add the viem assertion plugin to the example project.
1 parent 42c6592 commit ccb1c9c

File tree

8 files changed

+168
-57
lines changed

8 files changed

+168
-57
lines changed

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.0;
3+
pragma solidity *;
4+
5+
contract FailingContract {
6+
error CustomError();
7+
error CustomErrorWithUintAndString(uint, string);
8+
9+
function fail() public pure {
10+
innerRevert();
11+
}
12+
13+
function innerRevert() internal pure {
14+
revert("Revert Message");
15+
}
16+
17+
function failByRevertWithCustomError() external pure {
18+
revert CustomError();
19+
}
20+
21+
function failByRevertWithCustomErrorWithUintAndString(
22+
uint n,
23+
string memory s
24+
) external pure {
25+
revert CustomErrorWithUintAndString(n, s);
26+
}
27+
}

v-next/example-project/contracts/Rocket.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@ contract Rocket {
55
string public name;
66
string public status;
77

8+
event LaunchWithoutArgs();
9+
event LaunchWithTwoStringArgs(string u, string v);
10+
811
constructor(string memory _name) {
912
name = _name;
1013
status = "ignition";
1114
}
1215

1316
function launch() public {
1417
status = "lift-off";
18+
19+
emit LaunchWithoutArgs();
20+
emit LaunchWithTwoStringArgs(name, status);
1521
}
1622
}

v-next/example-project/hardhat.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import HardhatNodeTestRunner from "@nomicfoundation/hardhat-node-test-runner";
88
import HardhatMochaTestRunner from "@nomicfoundation/hardhat-mocha";
99
import HardhatKeystore from "@nomicfoundation/hardhat-keystore";
1010
import HardhatViem from "@nomicfoundation/hardhat-viem";
11+
import HardhatViemMatchers from "@nomicfoundation/hardhat-viem-matchers";
1112
import hardhatNetworkHelpersPlugin from "@nomicfoundation/hardhat-network-helpers";
1213
import hardhatEthersPlugin from "@nomicfoundation/hardhat-ethers";
1314
import hardhatChaiMatchersPlugin from "@nomicfoundation/hardhat-ethers-chai-matchers";
@@ -156,6 +157,7 @@ const config: HardhatUserConfig = {
156157
hardhatNetworkHelpersPlugin,
157158
HardhatNodeTestRunner,
158159
HardhatViem,
160+
HardhatViemMatchers,
159161
hardhatChaiMatchersPlugin,
160162
hardhatTypechain,
161163
hardhatIgnitionViem,

v-next/example-project/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"@nomicfoundation/hardhat-node-test-runner": "workspace:^3.0.0-next.11",
3737
"@nomicfoundation/hardhat-typechain": "workspace:^3.0.0-next.11",
3838
"@nomicfoundation/hardhat-viem": "workspace:^3.0.0-next.11",
39+
"@nomicfoundation/hardhat-viem-matchers": "workspace:^3.0.0-next.11",
3940
"@openzeppelin/contracts": "5.1.0",
4041
"@types/chai": "^4.2.0",
4142
"@types/mocha": ">=10.0.10",
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { describe, it, before } from "node:test";
2+
import hre from "hardhat";
3+
import { ContractReturnType } from "@nomicfoundation/hardhat-viem/types";
4+
5+
const { viem } = await hre.network.connect();
6+
7+
describe("Example EDR based test", () => {
8+
describe("revert", () => {
9+
let failingContract: ContractReturnType<"FailingContract">;
10+
11+
before(async () => {
12+
failingContract = await viem.deployContract("FailingContract");
13+
});
14+
15+
it("should support checking that a transaction reverts", async () => {
16+
await viem.assertions.revert(failingContract.read.fail());
17+
});
18+
19+
it("should support checking that a transaction reverts with a specific message", async () => {
20+
await viem.assertions.revertWith(
21+
failingContract.read.fail(),
22+
"Revert Message",
23+
);
24+
});
25+
26+
it("should support checking that a transaction reverts with a custom error and specific arguments", async () => {
27+
await viem.assertions.revertWithCustomErrorWithArgs(
28+
failingContract.read.failByRevertWithCustomErrorWithUintAndString([
29+
10n,
30+
"example",
31+
]),
32+
failingContract,
33+
"CustomErrorWithUintAndString",
34+
[10n, "example"],
35+
);
36+
});
37+
});
38+
39+
describe("Events", () => {
40+
it("should support detecting an emitted event", async () => {
41+
const rocketContract = await viem.deployContract("Rocket", ["Apollo"]);
42+
43+
await viem.assertions.emit(
44+
rocketContract.write.launch(),
45+
rocketContract,
46+
"LaunchWithoutArgs",
47+
);
48+
});
49+
50+
it("should support detecting an emitted events arguments", async () => {
51+
const rocketContract = await viem.deployContract("Rocket", ["Apollo"]);
52+
53+
await viem.assertions.emitWithArgs(
54+
rocketContract.write.launch(),
55+
rocketContract,
56+
"LaunchWithTwoStringArgs",
57+
["Apollo", "lift-off"],
58+
);
59+
});
60+
});
61+
62+
it("should support detecting a change of balance", async () => {
63+
const [bobWalletClient, aliceWalletClient] = await viem.getWalletClients();
64+
65+
await viem.assertions.balancesHaveChanged(
66+
bobWalletClient.sendTransaction({
67+
to: aliceWalletClient.account.address,
68+
value: 3333333333333333n,
69+
}),
70+
[
71+
{
72+
address: aliceWalletClient.account.address,
73+
amount: 3333333333333333n,
74+
},
75+
{
76+
address: bobWalletClient.account.address,
77+
amount: -3333333333333333n,
78+
},
79+
],
80+
);
81+
});
82+
});

v-next/example-project/tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
{
2626
"path": "../hardhat-viem"
2727
},
28+
{
29+
"path": "../hardhat-viem-matchers"
30+
},
2831
{
2932
"path": "../hardhat-ethers-chai-matchers"
3033
},

v-next/hardhat-viem-matchers/README.md

Lines changed: 44 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -65,57 +65,45 @@ Several matchers are included to assert that a transaction reverted, and the rea
6565
Assert that a transaction reverted for any reason, without checking the cause of the revert:
6666

6767
```ts
68-
revert(
69-
contractFn: Promise<ReadContractReturnType | WriteContractReturnType>,
70-
): Promise<void>;
68+
await viem.assertions.revert(token.write.transfer([address, 0n]));
7169
```
7270

7371
#### `.revertWith`
7472

7573
Assert that a transaction reverted with a specific reason string:
7674

7775
```ts
78-
revertWith(
79-
contractFn: Promise<ReadContractReturnType | WriteContractReturnType>,
80-
expectedRevertReason: string,
81-
): Promise<void>;
82-
```
83-
84-
You can also use regular expressions:
85-
86-
```ts
87-
xxxx;
76+
await viem.assertions.revertWith(
77+
token.write.transfer([address, 0n]),
78+
"transfer value must be positive",
79+
);
8880
```
8981

9082
#### `.revertWithCustomError`
9183

9284
Assert that a transaction reverted with a specific custom error:
9385

9486
```ts
95-
revertWithCustomError<ContractName extends CompiledContractName>(
96-
contractFn: Promise<ReadContractReturnType | WriteContractReturnType>,
97-
contract: ContractReturnType<ContractName>,
98-
customErrorName: string,
99-
): Promise<void>;
87+
await viem.assertions.revertWithCustomError(
88+
token.write.transfer([address, 0n]),
89+
token,
90+
"InvalidTransferValue",
91+
);
10092
```
10193

102-
The first argument must be the contract that defines the error. The contract is used to determine the full signature of the expected error. The matcher does not check whether the error was emitted by the contract.
103-
104-
If the error has arguments, the .withArgs matcher can be added:
105-
106-
xxx
94+
The second argument must be the contract that defines the error. The contract is used to determine the full signature of the expected error. The matcher does not check whether the error was emitted by the contract.
10795

10896
#### `.revertWithCustomErrorWithArgs`
10997

11098
Assert that a transaction reverted with a custom error and specific arguments:
11199

112100
```ts
113-
revertWithCustomErrorWithArgs<ContractName extends CompiledContractName>(
114-
contractFn: Promise<ReadContractReturnType | WriteContractReturnType>,
115-
contract: ContractReturnType<ContractName>,
116-
customErrorName: string,
117-
args: any[],
118-
): Promise<void>;
101+
await viem.assertions.revertWithCustomErrorWithArgs(
102+
token.write.transfer([address, 0n]),
103+
token,
104+
"InvalidTransferValue",
105+
[0n],
106+
);
119107
```
120108

121109
### Events
@@ -125,34 +113,24 @@ revertWithCustomErrorWithArgs<ContractName extends CompiledContractName>(
125113
Assert that a transaction emits a specific event:
126114

127115
```ts
128-
emit<
129-
ContractName extends CompiledContractName,
130-
EventName extends ContractName extends keyof ContractAbis
131-
? ContractEventName<ContractAbis[ContractName]>
132-
: string,
133-
>(
134-
contractFn: Promise<ReadContractReturnType | WriteContractReturnType>,
135-
contract: ContractReturnType<ContractName>,
136-
eventName: EventName,
137-
): Promise<void>;
116+
await viem.assertions.emit(
117+
rocketContract.write.launch(),
118+
rocketContract,
119+
"LaunchEvent",
120+
);
138121
```
139122

140123
#### `.emitWithArgs`
141124

142125
Assert that a transaction emits an event with specific arguments:
143126

144127
```ts
145-
emitWithArgs<
146-
ContractName extends CompiledContractName,
147-
EventName extends ContractName extends keyof ContractAbis
148-
? ContractEventName<ContractAbis[ContractName]>
149-
: string,
150-
>(
151-
contractFn: Promise<ReadContractReturnType | WriteContractReturnType>,
152-
contract: ContractReturnType<ContractName>,
153-
eventName: EventName,
154-
args: any[],
155-
): Promise<void>;
128+
await viem.assertions.emitWithArgs(
129+
rocketContract.write.launch(),
130+
rocketContract,
131+
"LaunchEventWithArgs",
132+
["Apollo", "lift-off"],
133+
);
156134
```
157135

158136
### Balance change
@@ -164,11 +142,20 @@ These matchers can be used to assert how a given transaction affects the ether b
164142
Assert that a transaction changes the balance of specific addresses:
165143

166144
```ts
167-
balancesHaveChanged: (
168-
resolvedTxHash: Promise<Hash>,
169-
changes: Array<{
170-
address: Address;
171-
amount: bigint;
172-
}>,
173-
) => Promise<void>;
145+
await viem.assertions.balancesHaveChanged(
146+
bobWalletClient.sendTransaction({
147+
to: aliceWalletClient.account.address,
148+
value: 3333333333333333n,
149+
}),
150+
[
151+
{
152+
address: aliceWalletClient.account.address,
153+
amount: 3333333333333333n,
154+
},
155+
{
156+
address: bobWalletClient.account.address,
157+
amount: -3333333333333333n,
158+
},
159+
],
160+
);
174161
```

0 commit comments

Comments
 (0)