Waffle 4 is out 🧇🚀

Przemek Rzad
TrueFi Engineering
Published in
5 min readOct 31, 2022

In Waffle 4, we have focused mostly on improving existing matchers and introducing new ones.

We have also upgraded major dependencies to catch up with the swiftly moving world of web3 development.

If you’re not familiar with Waffle, check out this introductory post.

🪡 Improved and more precise matchers

Regular Expressions in revertedWith

You can now use regular expressions in reason strings in therevertWith matcher. This can be useful for asserting reverts with dynamic, parametrized reason strings, such as this one from Open Zeppelin:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/26dddee1c05ff91264ae24c5c172bd05827cf5d8/contracts/access/AccessControl.sol#L65

In Waffle 4, you can do the following:

Asserting revert reason strings with a regular expression.

Chaining “to.emit" matchers

Frequently, a single transaction can emit more than one blockchain event. In Waffle 4, you can assert many events on a single transaction.

Chaining “to.emit” matchers.

Other matchers can be chained as well. However, excessive chaining is not recommended, in order to make sure a potential issue can be pinpointed to a specific assert.

Events with (selected) arguments

Sometimes, your test is focused on a single argument of an emitted event. Previously, you had to list all of the events in to.emit.withArgs matcher, otherwise you ended up with a failing test.

To address this problem, there is a new to.emit.withNamedArgs matcher, to allow you to name the arguments that you want to assert.

Asserting only named arguments of an event.

Thanks Nick for implementing this feature and sending a PR. 👏

Structs in the “emit.withArgs” matcher

Solidity Structs can be emitted as one of the parameters of a blockchain Event. The updated to.emit.withArgs matcher now is able to assert those structs.

Asserting structs in parameters of an emitted event.

This applied to the aforementioned to.emit.withNamedArgs matcher as well.

Reverted with custom errors

Solidity introduced a concept of Custom Errors. Starting from version v0.8.4, you can use those errors to convey more information to the users when something goes wrong, in a gas-efficient way.

An example of a Custom error.

Here is how you assert that a particular Custom Error (with particular arguments) has been thrown by the Smart Contract:

Asserting a Custom Error.

This feature only works when using Waffle with Hardhat.

Matcher “to.changeTokenBalance” accepts address strings

Previously, you had to pass an ethers Wallet instance as parameters of to.changeTokenBalance matcher. This introduced the need of hacks if all you had was an address.

In Waffle 4, this is no longer a problem, and you can mix and match both Wallet instances and just address strings in the parameters of this matcher.

Mixing Wallet instances and address strings in the “changeTokenBalances” matcher.

Other improvements

  • The matchers have been updated to work with an Optimism L2 local node, while using an OptimismProvider from @ethereum-waffle/optimism package.

🌍 Catching up with the world

The JavaScript ecosystem is known for moving fast and inventing new tools and framework. There is a rolling joke about how there is a new trendy JavaScript framework every year.

The Ethereum ecosystem is moving fast as well — understandably so, considering the blockchain industry is the frontier of new paradigm of money and distributed systems.

Waffle, being in the midst of these two ecosystem, has to catch up with the changes and dependencies.

Upgraded Ganache

In Waffle 3, we depended on ganache-core to run local, in-memory blockchain for testing purposes, which has been deprecated. Waffle 4 has been upgraded to use the new Ganache — which allows us to test Smart Contracts against up-to-date Ethereum forks.

Upgraded TypeChain

TypeChain is indispensable both for testing and development of Ethereum applications, adding static type checking for Smart Contracts in the code. We upgraded to the recent version 8 of TypeChain, in order to help catch more bugs during compilation.

Deprecating Jest in favor of Mocha

We have found Mocha testing framework to be more lightweight, easier to setup, and faster than its alternative Jest.

We promote Mocha as the recommended framework for setting up tests with Waffle. @ethereum-waffle/jest package remains as a deprecated component of Waffle. We provide a migration guide for switching from Jest to Mocha.

Connecting with the community

We’ve been to Devcon 6 in Bogotá — it was an amazing and resourceful event! We’ve had a chance to connect with web3 developers in our Waffle (and useDApp) booth and learn about their experiences in testing Smart Contracts. Shout-out to anyone visiting us. 😉

Waffle (and useDApp) booth in Devcon 6 in Bogotá

🔧 Technical adjustments

We have fine-tuned some technical details in the package.

  • Every change is deployed to NPM under a dev tag — for those bleeding edge fans.
  • Internally, we use pnpm to manage our packages.
    We have found pnpm to be fast, reliable and generally better in monorepo setups with lots of packages. Aside from Waffle, we use pnpm in useDApp and TrueFi, and we’re happy with it. 👌
  • We added an internal package just for testing Waffle matcher in conjunction with Hardhat. Our test suite is executed both against a local Ganache node and a Hardhat node.
  • The test suite has been extended to run against latest versions of Solidity.
  • ethers is now a peerDependency of Waffle, in order to make it easier to integrate it.

Let us know on Discord or on GitHub if something is not working exactly right in your setup.

Happy coding 😉
Przemek

--

--

Przemek Rzad
TrueFi Engineering

Software Engineer at Truefi Engineering. Currently working on open source tools — useDApp and Waffle.