Skip to content

Commit

Permalink
🦷 Automatically inject call history into hardhat provider (#776)
Browse files Browse the repository at this point in the history
  • Loading branch information
rzadp authored Aug 19, 2022
1 parent b6fd45b commit 9940630
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 72 deletions.
7 changes: 7 additions & 0 deletions .changeset/modern-tools-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@ethereum-waffle/chai": patch
"@ethereum-waffle/hardhat": patch
"@ethereum-waffle/optimism": patch
---

🦷 (Experimental) Automatically inject call history into hardhat provider
3 changes: 2 additions & 1 deletion waffle-chai/.mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ process.env.NODE_ENV = 'test'
module.exports = {
require: 'ts-node/register/transpile-only',
timeout: 50000,
spec: 'test/**/*.{js,ts}'
spec: 'test/**/*.{js,ts}',
file: 'test/test-setup.ts'
}
1 change: 1 addition & 0 deletions waffle-chai/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {supportChangeTokenBalance} from './matchers/changeTokenBalance';
import {supportChangeTokenBalances} from './matchers/changeTokenBalances';
import {supportCalledOnContract} from './matchers/calledOnContract/calledOnContract';
import {supportCalledOnContractWith} from './matchers/calledOnContract/calledOnContractWith';
import './inject-call-history';

export function waffleChai(chai: Chai.ChaiStatic, utils: Chai.ChaiUtils) {
supportBigNumber(chai.Assertion, utils);
Expand Down
78 changes: 78 additions & 0 deletions waffle-chai/src/inject-call-history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import type {RecordedCall} from '@ethereum-waffle/provider';
import {utils} from 'ethers';

/**
* Injects call history into hardhat provider,
* making it possible to use matchers like calledOnContract
*/

class CallHistory {
recordedCalls: RecordedCall[] = [];

addUniqueCall(call: RecordedCall) {
if (!this.recordedCalls.find(c => c.address === call.address && c.data === call.data)) {
this.recordedCalls.push(call);
}
}

clearAll() {
this.recordedCalls = [];
}
}

function toRecordedCall(message: any): RecordedCall {
return {
address: message.to?.buf ? utils.getAddress(utils.hexlify(message.to.buf)) : undefined,
data: message.data ? utils.hexlify(message.data) : '0x'
};
}

const inject = () => {
let waffle: any;
try {
waffle = require('hardhat')?.waffle;
} catch { return; }
if (!waffle || !waffle.provider) return;
const callHistory = new CallHistory();
(waffle.provider as any).clearCallHistory = () => {
callHistory.clearAll();
};

let beforeMessageListener: (message: any) => void | undefined;
const init = waffle.provider?._hardhatNetwork?.provider?._wrapped?._wrapped?._wrapped?._init;
if (!init) return;
waffle.provider._hardhatNetwork.provider._wrapped._wrapped._wrapped._init = async function () {
await init.apply(this);
if (typeof beforeMessageListener === 'function') {
// has to be here because of weird behaviour of init function, which requires us to re-register the handler.
waffle.provider
?._hardhatNetwork
?.provider
?._wrapped
?._wrapped
?._wrapped
?._node
?._vmTracer
?._vm
?.off?.('beforeMessage', beforeMessageListener);
}
beforeMessageListener = (message: any) => {
callHistory.addUniqueCall(toRecordedCall(message));
};
waffle.provider.callHistory = callHistory.recordedCalls;
waffle.provider
?._hardhatNetwork.provider
?._wrapped._wrapped
?._wrapped
?._node
?._vmTracer
?._vm
?.on?.('beforeMessage', beforeMessageListener);
};
};

let injected = false;
if (!injected && !!process.env.WAFFLE_EXPERIMENTAL_HARDHAT_CALL_HISTORY) {
injected = true;
inject();
}
7 changes: 0 additions & 7 deletions waffle-chai/test/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import {waffleChai} from '../src';

chai.use(chaiAsPromised);
chai.use(waffleChai);

export {calledOnContractTest} from './matchers/calledOnContract/calledOnContractTest';
export {calledOnContractValidatorsTest} from './matchers/calledOnContract/calledOnContractValidatorsTest';
export {calledOnContractWithTest} from './matchers/calledOnContract/calledOnContractWithTest';
Expand Down
6 changes: 6 additions & 0 deletions waffle-chai/test/test-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import {waffleChai} from '../src';

chai.use(chaiAsPromised);
chai.use(waffleChai);
1 change: 1 addition & 0 deletions waffle-hardhat/.mocharc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
process.env.NODE_ENV = 'test'
process.env.WAFFLE_EXPERIMENTAL_HARDHAT_CALL_HISTORY = true
module.exports = {
require: 'ts-node/register/transpile-only',
timeout: 50000,
Expand Down
62 changes: 0 additions & 62 deletions waffle-hardhat/src/inject-call-history.ts

This file was deleted.

7 changes: 6 additions & 1 deletion waffle-hardhat/test/test-setup.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
import '../src/inject-call-history';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import {solidity} from 'ethereum-waffle';

chai.use(chaiAsPromised);
chai.use(solidity);
3 changes: 2 additions & 1 deletion waffle-optimism/.mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ process.env.NODE_ENV = 'test'
module.exports = {
require: 'ts-node/register/transpile-only',
timeout: 50000,
spec: 'test/**/*.test.{js,ts}'
spec: 'test/**/*.test.{js,ts}',
file: 'test/test-setup.ts'
}
6 changes: 6 additions & 0 deletions waffle-optimism/test/test-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import {solidity} from 'ethereum-waffle';

chai.use(chaiAsPromised);
chai.use(solidity);

0 comments on commit 9940630

Please sign in to comment.