1
- import { Contract , ContractFactory , Signer , utils } from 'ethers' ;
1
+ import { BaseContract , Contract , ContractFactory , Signer , utils } from 'ethers' ;
2
2
import type { JsonFragment } from '@ethersproject/abi' ;
3
3
4
4
import DoppelgangerContract from './Doppelganger.json' ;
@@ -13,9 +13,9 @@ interface StubInterface {
13
13
withArgs ( ...args : any [ ] ) : StubInterface ;
14
14
}
15
15
16
- export interface MockContract extends Contract {
16
+ export interface MockContract < T extends BaseContract = BaseContract > extends Contract {
17
17
mock : {
18
- [ key : string ] : StubInterface ;
18
+ [ key in ( ( keyof T [ 'functions' ] | 'receive' ) ) ] : StubInterface ;
19
19
} ;
20
20
call ( contract : Contract , functionName : string , ...params : any [ ] ) : Promise < any > ;
21
21
staticcall ( contract : Contract , functionName : string , ...params : any [ ] ) : Promise < any > ;
@@ -155,7 +155,7 @@ async function deploy(signer: Signer, options?: DeployOptions) {
155
155
return factory . deploy ( ) ;
156
156
}
157
157
158
- function createMock ( abi : ABI , mockContractInstance : Contract ) {
158
+ function createMock < T extends BaseContract > ( abi : ABI , mockContractInstance : Contract ) : MockContract < T > [ 'mock' ] {
159
159
const { functions} = new utils . Interface ( abi ) ;
160
160
const encoder = new utils . AbiCoder ( ) ;
161
161
@@ -166,9 +166,9 @@ function createMock(abi: ABI, mockContractInstance: Contract) {
166
166
[ func . name ] : stubbed ,
167
167
[ func . format ( ) ] : stubbed
168
168
} ;
169
- } , { } as MockContract [ 'mock' ] ) ;
169
+ } , { } as MockContract < T > [ 'mock' ] ) ;
170
170
171
- mockedAbi . receive = {
171
+ ( mockedAbi as any ) . receive = {
172
172
returns : ( ) => { throw new Error ( 'Receive function return is not implemented.' ) ; } ,
173
173
withArgs : ( ) => { throw new Error ( 'Receive function return is not implemented.' ) ; } ,
174
174
reverts : ( ) => mockContractInstance . __waffle__receiveReverts ( 'Mock Revert' ) ,
@@ -178,11 +178,15 @@ function createMock(abi: ABI, mockContractInstance: Contract) {
178
178
return mockedAbi ;
179
179
}
180
180
181
- export async function deployMockContract ( signer : Signer , abi : ABI , options ?: DeployOptions ) : Promise < MockContract > {
181
+ export async function deployMockContract < T extends BaseContract = BaseContract > (
182
+ signer : Signer ,
183
+ abi : ABI ,
184
+ options ?: DeployOptions
185
+ ) : Promise < MockContract < T > > {
182
186
const mockContractInstance = await deploy ( signer , options ) ;
183
187
184
- const mock = createMock ( abi , mockContractInstance ) ;
185
- const mockedContract = new Contract ( mockContractInstance . address , abi , signer ) as MockContract ;
188
+ const mock = createMock < T > ( abi , mockContractInstance ) ;
189
+ const mockedContract = new Contract ( mockContractInstance . address , abi , signer ) as MockContract < T > ;
186
190
mockedContract . mock = mock ;
187
191
188
192
const encoder = new utils . AbiCoder ( ) ;
0 commit comments