Skip to content

Commit

Permalink
Merge pull request #2976 from NomicFoundation/francovictorio/hh-937/i…
Browse files Browse the repository at this point in the history
…mprove-waffle-warning

Improve waffle warning and migration guides
  • Loading branch information
alcuadrado committed Feb 9, 2023
2 parents 95328cc + 8fa00c9 commit 0edcf75
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 98 deletions.
6 changes: 6 additions & 0 deletions .changeset/seven-panthers-wonder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@nomicfoundation/hardhat-chai-matchers": patch
"@nomiclabs/hardhat-waffle": patch
---

Improved the warning shown when both `@nomicfoundation/hardhat-chai-matchers` and `@nomiclabs/hardhat-waffle` are used.
2 changes: 1 addition & 1 deletion docs/redirects.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const customRedirects = [
},
{
source: "/migrate-from-waffle",
destination: "/hardhat-chai-matchers/docs/migrate-from-waffle",
destination: "/hardhat-runner/docs/guides/migrating-from-hardhat-waffle",
permanent: false
},
{
Expand Down
34 changes: 2 additions & 32 deletions docs/src/content/hardhat-chai-matchers/docs/migrate-from-waffle.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Migrating from Waffle

This page explains how to migrate from Waffle to Hardhat Chai Matchers, and the advantages of doing it. Migrating should only take a few minutes.
If you want to replace Waffle with Hardhat Chai Matchers, we recommend you [migrate to the Hardhat Toolbox](/hardhat-runner/docs/guides/migrating-from-hardhat-waffle). If for some reason you want to migrate without using the Toolbox, read on.

## How to migrate

Expand Down Expand Up @@ -90,38 +90,8 @@ The `@nomicfoundation/hardhat-chai-matchers` plugin is meant to be a drop-in rep

::::

4. If you were not importing the `@nomiclabs/hardhat-ethers` plugin explicitly (because the Hardhat Waffle plugin already imported it), then add it to your config:

::::tabsgroup{options=TypeScript,JavaScript}

:::tab{value=TypeScript}

```ts
import "@nomiclabs/hardhat-ethers";
```

:::

:::tab{value=JavaScript}

```js
require("@nomiclabs/hardhat-ethers");
```

:::

::::

:::tip

Looking for a replacement of Waffle's `loadFixture`? You can find our version of it in [Hardhat Network Helpers](/hardhat-network-helpers/docs/reference#fixtures).
Looking for a replacement for Waffle's `loadFixture`? You can find our version of it in [Hardhat Network Helpers](/hardhat-network-helpers/docs/reference#fixtures).

:::

## Why migrate?

The Hardhat Chai Matchers are compatible with Waffle's API and offer several advantages:

- **More features**: the Hardhat Chai Matchers include new matchers, like [`.revertedWithCustomError`](./reference#.revertedwithcustomerror) and [`.revertedWithPanic`](/chai-matchers/reference.md#.revertedwithpanic), which let you perform better assertions of a transaction's revert reason.
- **Support for native BigInts**: Besides numbers and ethers’s BigNumbers, you can also use JavaScript's native BigInts in your assertions, which means being able to do things like `expect(await token.totalSupply()).to.equal(10n**18n)` instead of `expect(await token.totalSupply()).to.equal(ethers.BigNumber.from("1000000000000000000"))`.
- **More reliable**: Several problems and minor bugs in Waffle's matchers are fixed in the Hardhat Chai Matchers.
Original file line number Diff line number Diff line change
@@ -1,29 +1,111 @@
# Migrating away from hardhat-waffle

Our recommended setup used to include [Waffle] using our [`hardhat-waffle`] plugin.
In the past, our recommended setup included [Waffle], by using the [`hardhat-waffle`] plugin.

We now recommend using our [Hardhat Chai Matchers] and [Hardhat Network Helpers] instead.
However, we now recommend using [Hardhat Toolbox], a plugin that bundles a curated set of useful packages. This set includes [Hardhat Chai Matchers] and [Hardhat Network Helpers], which work as an improved replacement for `hardhat-waffle`.

Migrating to these packages only takes a few minutes, as they were designed as a drop-in replacement. If you do so, you'll get more functionality, like support for Solidity custom errors and native `bigint` support, and a more reliable testing experience.
Migrating to the Toolbox only takes a few minutes. If you do so, you'll get more functionality, like support for Solidity custom errors and native `bigint` support, and a more reliable testing experience. It will also make it easier for you to keep up to date with our recommended setup.

To learn how to start using them, read [this guide](../../../hardhat-chai-matchers/docs/migrate-from-waffle.md).
## Migrating to Hardhat Toolbox

## Using the Hardhat Toolbox
Follow these steps to migrate your project to Hardhat Toolbox.

You can get our recommended setup by installing [`@nomicfoundation/hardhat-toolbox`], a single plugin that has everything you need.
1. First you'll need to remove some packages from your project.

When you use it, you'll be able to:
::::tabsgroup{options="npm 7+,npm 6,yarn"}

- Deploy and interact with your contracts using [ethers.js](https://docs.ethers.io/v5/) and the [`hardhat-ethers`](/hardhat-runner/plugins/nomiclabs-hardhat-ethers) plugin.
- Test your contracts with [Mocha](https://mochajs.org/), [Chai](https://chaijs.com/) and our own [Hardhat Chai Matchers](/hardhat-chai-matchers) plugin.
- Interact with Hardhat Network with our [Hardhat Network Helpers](/hardhat-network-helpers).
- Verify the source code of your contracts with the [hardhat-etherscan](/hardhat-runner/plugins/nomiclabs-hardhat-etherscan) plugin.
- Get metrics on the gas used by your contracts with the [hardhat-gas-reporter](https://github.com/cgewecke/hardhat-gas-reporter) plugin.
- Measure your tests coverage with [solidity-coverage](https://github.com/sc-forks/solidity-coverage).
- And, if you are using TypeScript, get type bindings for your contracts with [Typechain](https://github.com/dethcrypto/TypeChain/).
:::tab{value="npm 7+"}

```
npm uninstall @nomiclabs/hardhat-waffle ethereum-waffle @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers
```

:::

:::tab{value="npm 6"}

```
npm uninstall @nomiclabs/hardhat-waffle ethereum-waffle @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers
```

:::

:::tab{value=yarn}

```
yarn remove @nomiclabs/hardhat-waffle ethereum-waffle
```

:::

::::

2. Then you need to install the Toolbox. If you are using yarn or an old version of npm, you'll also have to install some other packages (the peer dependencies of the Toolbox).

::::tabsgroup{options="npm 7+,npm 6,yarn"}

:::tab{value="npm 7+"}

```
npm install --save-dev @nomicfoundation/hardhat-toolbox
```

:::

:::tab{value="npm 6"}

```
npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers
```

:::

:::tab{value="yarn"}

```
yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers
```

:::

::::

3. Finally, remove `hardhat-waffle` from your imported plugins and import the Toolbox instead:

::::tabsgroup{options=TypeScript,JavaScript}

:::tab{value=TypeScript}

```diff
- import "@nomiclabs/hardhat-waffle";
+ import "@nomicfoundation/hardhat-toolbox";
```

:::

:::tab{value=JavaScript}

```diff
- require("@nomiclabs/hardhat-waffle");
+ require("@nomicfoundation/hardhat-toolbox");
```

:::

::::

Adding the Toolbox will make many other imports redundant, so you can remove any of these if you want:

- `@nomiclabs/hardhat-ethers`
- `@nomiclabs/hardhat-etherscan`
- `hardhat-gas-reporter`
- `solidity-coverage`
- `@typechain/hardhat`

Check the [Hardhat Chai Matchers] and [Hardhat Network Helpers] docs to learn more about the functionality included in the Toolbox.

[waffle]: https://getwaffle.io
[`hardhat-waffle`]: ../../plugins/nomiclabs-hardhat-waffle
[`@nomicfoundation/hardhat-toolbox`]: ../../plugins/nomicfoundation-hardhat-toolbox
[hardhat chai matchers]: /hardhat-chai-matchers
[hardhat network helpers]: /hardhat-network-helpers
[hardhat toolbox]: /hardhat-runner/plugins/nomicfoundation-hardhat-toolbox
1 change: 0 additions & 1 deletion packages/hardhat-chai-matchers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
"@ethersproject/abi": "^5.1.2",
"@types/chai-as-promised": "^7.1.3",
"chai-as-promised": "^7.1.1",
"chalk": "^2.4.2",
"deep-eql": "^4.0.1",
"ordinal": "^1.0.3"
}
Expand Down
4 changes: 2 additions & 2 deletions packages/hardhat-chai-matchers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import "@nomiclabs/hardhat-ethers";

import "./types";

import { checkIfWaffleIsInstalled } from "./internal/checkIfWaffleIsInstalled";
import { hardhatWaffleIncompatibilityCheck } from "./internal/hardhatWaffleIncompatibilityCheck";
import "./internal/add-chai-matchers";

checkIfWaffleIsInstalled();
hardhatWaffleIncompatibilityCheck();

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function hardhatWaffleIncompatibilityCheck() {
if ((global as any).__HARDHAT_WAFFLE_IS_LOADED === true) {
throw new Error(
`You are using both @nomicfoundation/hardhat-chai-matchers and @nomiclabs/hardhat-waffle. They don't work correctly together, so please make sure you only use one.
We recommend you migrate to @nomicfoundation/hardhat-chai-matchers. Learn how to do it here: https://hardhat.org/migrate-from-waffle`
);
}

(global as any).__HARDHAT_CHAI_MATCHERS_IS_LOADED = true;
}
35 changes: 3 additions & 32 deletions packages/hardhat-toolbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,8 @@ When you use this plugin, you'll be able to:
- Measure your tests coverage with [solidity-coverage](https://github.com/sc-forks/solidity-coverage).
- And, if you are using TypeScript, get type bindings for your contracts with [Typechain](https://github.com/dethcrypto/TypeChain/).

### Installation
### Usage

We recommend using npm 7 or later. If you do that, then you just need to install the plugin itself:
To create a new project that uses the Toolbox, check our [Setting up a project guide](https://hardhat.org/hardhat-runner/docs/guides/project-setup).

```bash
npm install --save-dev @nomicfoundation/hardhat-toolbox
```

If you are using an older version of npm, you'll also need to install all the packages used by the toolbox.

```bash
npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers
```

That's also the case if you are using yarn:

```
yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers
```

### Migrating to Hardhat Toolbox

Migrating an existing project to the Toolbox is easy:

1. First, if you are using `hardhat-waffle`, we recommend you migrate to our [Hardhat Chai Matchers](https://hardhat.org/hardhat-chai-matchers). They are a drop-in replacement, so this should only take a few minutes. Learn how to do that [here](https://hardhat.org/hardhat-chai-matchers/docs/migrate-from-waffle).
2. Install the toolbox and its dependencies. If you are using npm 7 or later, you just need to do `npm install --save-dev @nomicfoundation/hardhat-toolbox`. If not, check the [Installation section](#installation) above.
3. Uninstall `@nomiclabs/hardhat-waffle` and `ethereum-waffle`, and remove the `@nomiclabs/hardhat-waffle` import from your Hardhat config.
4. Import the Toolbox in your Hardhat config. This will make many other imports redundant, so you can remove any of these if you want:

- `@nomiclabs/hardhat-ethers`
- `@nomiclabs/hardhat-etherscan`
- `hardhat-gas-reporter`
- `solidity-coverage`
- `@typechain/hardhat`
If you want to migrate an existing Hardhat project to use the Toolbox, read [our migration guide](https://hardhat.org/hardhat-runner/docs/guides/migrating-from-hardhat-waffle).
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function hardhatChaiMatchersIncompatibilityCheck() {
if ((global as any).__HARDHAT_CHAI_MATCHERS_IS_LOADED === true) {
throw new Error(
`You are using both @nomiclabs/hardhat-waffle and @nomicfoundation/hardhat-chai-matchers. They don't work correctly together, so please make sure you only use one.
We recommend you migrate to @nomicfoundation/hardhat-chai-matchers. Learn how to do it here: https://hardhat.org/migrate-from-waffle`
);
}

(global as any).__HARDHAT_WAFFLE_IS_LOADED = true;
}
3 changes: 3 additions & 0 deletions packages/hardhat-waffle/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { extendEnvironment } from "hardhat/config";
import { lazyObject } from "hardhat/plugins";

import { getDeployMockContract, hardhatDeployContract } from "./deploy";
import { hardhatChaiMatchersIncompatibilityCheck } from "./hardhatChaiMatchersIncompatibilityCheck";
import { getLinkFunction } from "./link";
import { initializeWaffleMatchers } from "./matchers";
import "./type-extensions";

hardhatChaiMatchersIncompatibilityCheck();

extendEnvironment((hre) => {
// We can't actually implement a MockProvider because of its private
// properties, so we cast it here 😢
Expand Down

0 comments on commit 0edcf75

Please sign in to comment.