openzeppelin-test-helpers
openzeppelin-test-helpers copied to clipboard
Provide TypeScript type definitions
Requested in https://github.com/OpenZeppelin/openzeppelin-test-environment/issues/73#issuecomment-629425128.
Some prior conversation in https://github.com/OpenZeppelin/openzeppelin-test-helpers/pull/116#issuecomment-611281410.
@bruce-plutusds is there a chance we could see your port of this library to TypeScript?
I tried running TypeScript to generate type declarations from our current JavaScript files, but it's triggering a compiler bug, and it doesn't seem feasible to fix it. So we will have to migrate everything to TypeScript. We can do this in two steps:
- Migrate all source files to TypeScript, with generous use of
any
. Keep the tests in JavaScript for now, since the priority is getting type definitions for the public API. - Progressively remove uses of
any
. Remember that the priority is typing the public API, and internal functions are not as important (for now).
Things to watch out for:
- Truffle and Web3 receipts, which we use in
expectEvent
. I'm not sure if those packages provide their own types. However, since our library receives the receipt objects from the user, and we use very few properties anyway, I'd suggest we define our own interfaces with the properties we need. - Numbers. Functions that receive numbers may work with
BN
,number
, or evenstring
. We have to check and type appropriately.
Are there any plans to tackle this soon? :grin:
@nventuro Sorry we don't have the time to tackle this right now, but would welcome and review any PRs. :slightly_smiling_face:
Big fan of this library. I started a PR to add type definitions: https://github.com/OpenZeppelin/openzeppelin-test-helpers/pull/141.
Hey! Any news on this one?
No news, sorry.
+1. Haven't had much time to continue this. Happy to pass the torch to someone else if they want to run with it.
Hope that base configuration can be integrated, then other people can convert partially
I think I can spare the bandwidth to finish this off, provided the scope is set in advance.
OS dev is frustrating, and so is submitting PR's that immediately fall by the way because they don't check box (X) :-)
Are there any plans on tackling this? Anybody doing the port? Thanks!
I also ran into this trying to test events so I added:
// types/openzeppelin-test-helpers.d.ts
declare module '@openzeppelin/test-helpers' {
import { ContractReceipt } from 'ethers'
export function expectEvent(receipt: ContractReceipt, eventName: string, eventArgs: Record<string, any>): void
}
which gets picked up by default via tsc
(typeRoots
setting in tsconfig
) and allowed me to use
import { expectEvent } from '@openzeppelin/test-helpers'
in my .test.ts
TypeScript test files.
But strangely it was throwing errors that it couldn't find events which were clearly there due to my hand-written test code that validated it.
So ultimately I decided to remove the dependency on @openzeppelin/test-helpers
and write my own helper function for testing events:
import { ContractReceipt } from "@ethersproject/contracts";
import { EventFilter } from "@ethersproject/abstract-provider";
import { expect } from "chai";
// Asserts that the logs in receipt contain an event with name eventName and arguments
// that match those specified in eventArgs.
function expectEvent(
receipt: ContractReceipt,
eventName: string,
eventArgs: Record<string, any>
) {
expect(receipt.events).to.not.be.undefined;
const event = receipt.events?.find((e) => e.event === eventName);
expect(event, `Event '${eventName}' not found`).to.not.be.undefined;
for (const [key, value] of Object.entries(eventArgs)) {
expect(event?.args?.[key], `Event argument '${key}' not found`).to.equal(value);
}
}
// Asserts that the logs in receipt contain a single event with name eventName and arguments
// that match those specified in eventArgs.
function expectOneEvent(receipt: ContractReceipt, eventName: string, eventArgs: Record<string, any>) {
expect(receipt.events).to.not.be.undefined
expect(receipt.events?.length, `Expected exactly 1 event`).to.equal(1)
expectEvent(receipt, eventName, eventArgs)
}
which readers are welcome to use or adapt to their use case.