-
Notifications
You must be signed in to change notification settings - Fork 11.8k
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
Migrate Ownable tests #4657
Migrate Ownable tests #4657
Conversation
|
New dependencies detected. Learn more about Socket for GitHub ↗︎
|
test/access/Ownable.test.js
Outdated
const { deploy, getFactory } = require('../helpers/deploy'); | ||
|
||
async function fixture() { | ||
const accounts = await ethers.getSigners(); // this is slow :/ |
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.
We could cache it in a global helper. But it should run only once per contract test suite anyway.
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.
This is easily cacheable in env.contract.js
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.
Do you know how this will behave with ethers?
Would it work if in the tests we do this.accounts.shift()
?
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 was thinking in something like:
extendEnvironment(env => {
const { contract } = env;
env.contract = function (name, body) {
const { takeSnapshot } = require('@nomicfoundation/hardhat-network-helpers');
contract(name, accounts => {
// reset the state of the chain in between contract test suites
let snapshot;
let signers;
before(async function () {
signers = signers ?? await ethers.getSigners();
snapshot = await takeSnapshot();
});
after(async function () {
await snapshot.restore();
});
// remove the default account from the accounts list used in tests, in order
// to protect tests against accidentally passing due to the contract
// deployer being used subsequently as function caller
// The signers array is also cloned using the spread operator to avoid changes
// to the original array.
body([...signers].slice(1));
});
};
});
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.
And we would get the signers as an argument of contract("...", accounts => { ... });
?
That makes sens, but it will also break the existing truffle tests, which we don't want.
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.
what do you think of keeping a registry of already migrated contract suites?
Too maintenance heavy (and error prone) IMO.
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.
We couldn't confirm such theory, but if that's the case, we should keep loadFixtures per contract suite and also this snapshot.
If loadFixture does a "per contract suite" snapshot, I don't see why we would have to also do a "cross contract suite" snapshot. That is making everything slower, and I really don't see what it brings in exchange. The only usecase I see for that, is if we wanted our test to all start with blockNumber = 0
... and I don't think that is an assumption we should make. IMO our tests (each test.js file) should work regardless of the initial state of the chain.
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.
we could do
body(accounts.slice(1), signers.slice(1));
And then do
// truffle, no change needed
contract("...", accounts => { ... });
and
// ethers
contract("...", (_, signers) => { ... });
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.
Keeping the high-level snapshot makes sense if not all the contract suites implement a fixture. Let's try removing the high-level snapshot once we finish with the migration as well.
we could do
body(accounts.slice(1), signers.slice(1));
I like this, let's implement it that way 😄
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.
Side note, I also added a comment in #4658 to keep track of things we should do to consolidate the migration once done
|
||
expect(await this.ownable.owner()).to.equal(other); | ||
expect(await this.ownable.owner()).to.equal(this.other.address); |
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.
Using .address
everywhere will be a pain. There is an issue about it:
Are there any workarounds? Is it worth it to contribute to Hardhat to improve this?
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 once wrote an helper that is
const getAddress = (account : string | { address: string }) : string => account.address ?? account;
but calling it everywhere is even worst.
Maybe it could be integrated by default ...
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.
ethers.resolveAddress
already does it even better ...
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: I'd love to simplify the code by removing .address
when its better supported, but I don't think we should wait for that. We should migrate with .address
and then remove them when possible.
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.
Agree with migrating using .address
without waiting for Hardhat support.
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.
For anyone curious, this PR NomicFoundation/hardhat#4449 resolves the issue in hardhat-chai-matchers
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.
Looking good. It's very weird that the CI is failing for an ERC721 test. Any idea?
|
||
expect(await this.ownable.owner()).to.equal(other); | ||
expect(await this.ownable.owner()).to.equal(this.other.address); |
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.
Agree with migrating using .address
without waiting for Hardhat support.
Co-authored-by: Ernesto García <[email protected]>
Upgradeable tests are failing because we need to override Taking a look |
In
I'm starting to think that |
Tests are failing because custom errors can't be decoded. Not sure what may be causing it but perhaps it's related to #4349 |
After reviewing, I have the suspicion the decoding errors were caused by overriding the LGTM if they pass. |
Ok it didn't work. An ugly workaround for now would be to run |
Checklist:
Note: Edit: this might ba the |
Adding |
- name: Compile contracts # TODO: Remove after migrating tests to ethers | ||
run: npm run compile |
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 needed because the solcover.js
config specifies that compileCommand: 'npm run compile'
. Are you sure this actually did something?
Just curious, we can leave if it'll be removed at the end of the migration
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'm not sure it actually does somthing. I just added that to all workflows
Lets see if we can remove them after the migration.
// - the return of hre.ethers.getSigners() | ||
extendEnvironment(hre => { | ||
// TODO: replace with a mocha root hook. | ||
// (see https://github.com/sc-forks/solidity-coverage/issues/819#issuecomment-1762963679) |
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.
Honestly I don't see how to use these hooks because they require using a --require
flag that I don't see exposed through Hardhat's test CLI (based on mocha).
I hope it's ok to ask two questions here:
|
Co-authored-by: ernestognw <[email protected]>
This is the first PR of a long series that will migrate from truffle + web3js to hardhat-toolbox + ethers v6.
The goal of this PR is to
Obviously, this being a small test file, not all issues will appear from the start. This is intended. Here we resolve the most obvious things. As we progress in the migration, we will identify and resolve more subtle challenges. Homefully, we don't have to reconsider on past decision when we get there.
Guidelines
Deprecations:
@nomiclabs/hardhat-truffle5
@nomiclabs/hardhat-web3
@openzeppelin/test-helpers
web3
./helpers/customError
Possible deprecations (to evaluate in upcomming PR:
merkletreejs
→@openzeppelin/merkle-tree
keccak256
→ethers
?eth-sig-util
→ethers
?ethereumjs-util
→ethers
?ethereumjs-wallet
→ethers
?Question
./hardhat/env-contracts.js
body(accounts.slice(1))
has no effect over on ethers.getSigners()PR Checklist
npx changeset add
)