TrueFiEng/Waffle

New matcher: expect to change balance

marekkirejczyk opened this issue ยท 8 comments

Example usage:

expect(() => wallet.transfer('0xab..cd.', 200)).to.changeBalance('0xb', 200)

chained:

expect(() => wallet.transfer('0xab...cd', 200))
  .to.changeBalance('0xab...cd', -200)  
  .to.changeBalance('0xab...cd', 200);

token:

expect(() => token.transfer('0xb', 200))
  .to.changeTokenBalance(someToken, '0xb', 200);

Partially implemented in #24

The matcher works nice for wallets, could you also support passing a bare address to the function? Would be useful e.g. to track balance changes on a contract address. Currently, if I try to do that, I get a runtime error: TypeError: wallet.getBalance is not a function.

Side note: could you also make the typings concrete here? Currently the arguments are wallet: any, balance: any -- I have to find out what I'm expected to pass there through trial and error or looking into the docs (which, in fact, also don't specify these types), while with proper typings it would be obvious from the start :)

Hi @quezak

The problem with passing bare address is that matcher don't have access to the provider. So it is either wallet or (we could implement) bare address + provider

Typing definitely can be improved. Would you create a separate issue for that?

Thanks for the reply! Another idea: it looks much easier (and satisfies my use case) to accept Wallet | Contract -- ethers.js contracts have an address and provider field, same as wallets, so it could even use the same code.

I'll add the typings issue some time later.

@quezak I second that:

Would be useful e.g. to track balance changes on a contract address

@marekkirejczyk @sz-piotr Any ETAs for new features like this ?

Thanks for the amazing tool btw!

Proposed variation of syntax for different ways to provide provider:

expect(() => wallet.transfer('0xab..cd.', 200)).to.changeBalance('0xab...cd', 200, provider)
expect(() => wallet.transfer('0xab..cd.', 200)).to.changeBalance(wallet, 200)
expect(() => wallet.transfer('0xab..cd.', 200)).to.changeBalance(contract, 200)

Can we skip promise and have sth like below?

expect(await wallet.transfer('0xab..cd.', 200).to.changeBalance('0xab...cd', 200, provider)

Idea 1:

Take the block number from receipt and check the balance in previous block
Pros:

  • no need for Promise

Cons:

  • what if we have more than one thing happening in the block

Idea 2:

  • explore what else is there in receipt, can we use it to explore VM state diff?

@quezak Contract type to change balance added in #363
To be released in 3.1.1

โœ… Expectation for token balance
โœ… Suport for Contracts