@ethereum-waffle/mock-contract
Advanced tools
Comparing version 4.0.3-dev.f3d5029 to 4.0.3-dev.f8ca718
@@ -1,8 +0,13 @@ | ||
import { Contract, Signer, utils } from 'ethers'; | ||
import { BaseContract, Contract, Signer, utils } from 'ethers'; | ||
import type { JsonFragment } from '@ethersproject/abi'; | ||
declare type ABI = string | Array<utils.Fragment | JsonFragment | string>; | ||
export declare type Stub = ReturnType<typeof stub>; | ||
export interface MockContract extends Contract { | ||
interface StubInterface { | ||
returns(...args: any): StubInterface; | ||
reverts(): StubInterface; | ||
revertsWithReason(reason: string): StubInterface; | ||
withArgs(...args: any[]): StubInterface; | ||
} | ||
export interface MockContract<T extends BaseContract = BaseContract> extends Contract { | ||
mock: { | ||
[key: string]: Stub; | ||
[key in ((keyof T['functions'] | 'receive'))]: StubInterface; | ||
}; | ||
@@ -12,10 +17,8 @@ call(contract: Contract, functionName: string, ...params: any[]): Promise<any>; | ||
} | ||
declare function stub(mockContract: Contract, encoder: utils.AbiCoder, func: utils.FunctionFragment, params?: any[]): { | ||
returns: (...args: any) => Promise<void>; | ||
reverts: () => Promise<any>; | ||
revertsWithReason: (reason: string) => Promise<any>; | ||
withArgs: (...args: any[]) => any; | ||
declare type DeployOptions = { | ||
address: string; | ||
override?: boolean; | ||
}; | ||
export declare function deployMockContract(signer: Signer, abi: ABI): Promise<MockContract>; | ||
export declare function deployMockContract<T extends BaseContract = BaseContract>(signer: Signer, abi: ABI, options?: DeployOptions): Promise<MockContract<T>>; | ||
export {}; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -9,22 +9,129 @@ "use strict"; | ||
const Doppelganger_json_1 = __importDefault(require("./Doppelganger.json")); | ||
async function deploy(signer) { | ||
class Stub { | ||
constructor(mockContract, encoder, func) { | ||
this.mockContract = mockContract; | ||
this.encoder = encoder; | ||
this.func = func; | ||
this.stubCalls = []; | ||
this.revertSet = false; | ||
this.argsSet = false; | ||
this.callData = mockContract.interface.getSighash(func); | ||
} | ||
err(reason) { | ||
this.stubCalls = []; | ||
this.revertSet = false; | ||
this.argsSet = false; | ||
throw new Error(reason); | ||
} | ||
returns(...args) { | ||
if (this.revertSet) | ||
this.err('Revert must be the last call'); | ||
if (!this.func.outputs) | ||
this.err('Cannot mock return values from a void function'); | ||
const encoded = this.encoder.encode(this.func.outputs, args); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReturns(this.callData, encoded); | ||
}); | ||
} | ||
else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueReturn(this.callData, encoded); | ||
}); | ||
} | ||
return this; | ||
} | ||
reverts() { | ||
if (this.revertSet) | ||
this.err('Revert must be the last call'); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReverts(this.callData, 'Mock revert'); | ||
}); | ||
} | ||
else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueRevert(this.callData, 'Mock revert'); | ||
}); | ||
} | ||
this.revertSet = true; | ||
return this; | ||
} | ||
revertsWithReason(reason) { | ||
if (this.revertSet) | ||
this.err('Revert must be the last call'); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReverts(this.callData, reason); | ||
}); | ||
} | ||
else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueRevert(this.callData, reason); | ||
}); | ||
} | ||
this.revertSet = true; | ||
return this; | ||
} | ||
withArgs(...params) { | ||
if (this.argsSet) | ||
this.err('withArgs can be called only once'); | ||
this.callData = this.mockContract.interface.encodeFunctionData(this.func, params); | ||
this.argsSet = true; | ||
return this; | ||
} | ||
async then(resolve, reject) { | ||
for (let i = 0; i < this.stubCalls.length; i++) { | ||
try { | ||
await this.stubCalls[i](); | ||
} | ||
catch (e) { | ||
this.stubCalls = []; | ||
this.argsSet = false; | ||
this.revertSet = false; | ||
reject(e); | ||
return; | ||
} | ||
} | ||
this.stubCalls = []; | ||
this.argsSet = false; | ||
this.revertSet = false; | ||
resolve(); | ||
} | ||
} | ||
async function deploy(signer, options) { | ||
if (options) { | ||
const { address, override } = options; | ||
const provider = signer.provider; | ||
if (!override && await provider.getCode(address) !== '0x') { | ||
throw new Error(`${address} already contains a contract. ` + | ||
'If you want to override it, set the override parameter.'); | ||
} | ||
if (provider._hardhatNetwork) { | ||
if (await provider.send('hardhat_setCode', [ | ||
address, | ||
'0x' + Doppelganger_json_1.default.evm.deployedBytecode.object | ||
])) { | ||
return new ethers_1.Contract(address, Doppelganger_json_1.default.abi, signer); | ||
} | ||
else | ||
throw new Error(`Couldn't deploy at ${address}`); | ||
} | ||
else { | ||
if (await provider.send('evm_setAccountCode', [ | ||
address, | ||
'0x' + Doppelganger_json_1.default.evm.deployedBytecode.object | ||
])) { | ||
return new ethers_1.Contract(address, Doppelganger_json_1.default.abi, signer); | ||
} | ||
else | ||
throw new Error(`Couldn't deploy at ${address}`); | ||
} | ||
} | ||
const factory = new ethers_1.ContractFactory(Doppelganger_json_1.default.abi, Doppelganger_json_1.default.bytecode, signer); | ||
return factory.deploy(); | ||
} | ||
function stub(mockContract, encoder, func, params) { | ||
const callData = params | ||
? mockContract.interface.encodeFunctionData(func, params) | ||
: mockContract.interface.getSighash(func); | ||
return { | ||
returns: async (...args) => { | ||
if (!func.outputs) | ||
return; | ||
const encoded = encoder.encode(func.outputs, args); | ||
await mockContract.__waffle__mockReturns(callData, encoded); | ||
}, | ||
reverts: async () => mockContract.__waffle__mockReverts(callData, 'Mock revert'), | ||
revertsWithReason: async (reason) => mockContract.__waffle__mockReverts(callData, reason), | ||
withArgs: (...args) => stub(mockContract, encoder, func, args) | ||
}; | ||
} | ||
function createMock(abi, mockContractInstance) { | ||
@@ -34,3 +141,3 @@ const { functions } = new ethers_1.utils.Interface(abi); | ||
const mockedAbi = Object.values(functions).reduce((acc, func) => { | ||
const stubbed = stub(mockContractInstance, encoder, func); | ||
const stubbed = new Stub(mockContractInstance, encoder, func); | ||
return { | ||
@@ -42,6 +149,12 @@ ...acc, | ||
}, {}); | ||
mockedAbi.receive = { | ||
returns: () => { throw new Error('Receive function return is not implemented.'); }, | ||
withArgs: () => { throw new Error('Receive function return is not implemented.'); }, | ||
reverts: () => mockContractInstance.__waffle__receiveReverts('Mock Revert'), | ||
revertsWithReason: (reason) => mockContractInstance.__waffle__receiveReverts(reason) | ||
}; | ||
return mockedAbi; | ||
} | ||
async function deployMockContract(signer, abi) { | ||
const mockContractInstance = await deploy(signer); | ||
async function deployMockContract(signer, abi, options) { | ||
const mockContractInstance = await deploy(signer, options); | ||
const mock = createMock(abi, mockContractInstance); | ||
@@ -48,0 +161,0 @@ const mockedContract = new ethers_1.Contract(mockContractInstance.address, abi, signer); |
@@ -1,8 +0,13 @@ | ||
import { Contract, Signer, utils } from 'ethers'; | ||
import { BaseContract, Contract, Signer, utils } from 'ethers'; | ||
import type { JsonFragment } from '@ethersproject/abi'; | ||
declare type ABI = string | Array<utils.Fragment | JsonFragment | string>; | ||
export declare type Stub = ReturnType<typeof stub>; | ||
export interface MockContract extends Contract { | ||
interface StubInterface { | ||
returns(...args: any): StubInterface; | ||
reverts(): StubInterface; | ||
revertsWithReason(reason: string): StubInterface; | ||
withArgs(...args: any[]): StubInterface; | ||
} | ||
export interface MockContract<T extends BaseContract = BaseContract> extends Contract { | ||
mock: { | ||
[key: string]: Stub; | ||
[key in ((keyof T['functions'] | 'receive'))]: StubInterface; | ||
}; | ||
@@ -12,10 +17,8 @@ call(contract: Contract, functionName: string, ...params: any[]): Promise<any>; | ||
} | ||
declare function stub(mockContract: Contract, encoder: utils.AbiCoder, func: utils.FunctionFragment, params?: any[]): { | ||
returns: (...args: any) => Promise<void>; | ||
reverts: () => Promise<any>; | ||
revertsWithReason: (reason: string) => Promise<any>; | ||
withArgs: (...args: any[]) => any; | ||
declare type DeployOptions = { | ||
address: string; | ||
override?: boolean; | ||
}; | ||
export declare function deployMockContract(signer: Signer, abi: ABI): Promise<MockContract>; | ||
export declare function deployMockContract<T extends BaseContract = BaseContract>(signer: Signer, abi: ABI, options?: DeployOptions): Promise<MockContract<T>>; | ||
export {}; | ||
//# sourceMappingURL=index.d.ts.map |
import { Contract, ContractFactory, utils } from 'ethers'; | ||
import DoppelgangerContract from './Doppelganger.json'; | ||
async function deploy(signer) { | ||
class Stub { | ||
constructor(mockContract, encoder, func) { | ||
this.mockContract = mockContract; | ||
this.encoder = encoder; | ||
this.func = func; | ||
this.stubCalls = []; | ||
this.revertSet = false; | ||
this.argsSet = false; | ||
this.callData = mockContract.interface.getSighash(func); | ||
} | ||
err(reason) { | ||
this.stubCalls = []; | ||
this.revertSet = false; | ||
this.argsSet = false; | ||
throw new Error(reason); | ||
} | ||
returns(...args) { | ||
if (this.revertSet) | ||
this.err('Revert must be the last call'); | ||
if (!this.func.outputs) | ||
this.err('Cannot mock return values from a void function'); | ||
const encoded = this.encoder.encode(this.func.outputs, args); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReturns(this.callData, encoded); | ||
}); | ||
} | ||
else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueReturn(this.callData, encoded); | ||
}); | ||
} | ||
return this; | ||
} | ||
reverts() { | ||
if (this.revertSet) | ||
this.err('Revert must be the last call'); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReverts(this.callData, 'Mock revert'); | ||
}); | ||
} | ||
else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueRevert(this.callData, 'Mock revert'); | ||
}); | ||
} | ||
this.revertSet = true; | ||
return this; | ||
} | ||
revertsWithReason(reason) { | ||
if (this.revertSet) | ||
this.err('Revert must be the last call'); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReverts(this.callData, reason); | ||
}); | ||
} | ||
else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueRevert(this.callData, reason); | ||
}); | ||
} | ||
this.revertSet = true; | ||
return this; | ||
} | ||
withArgs(...params) { | ||
if (this.argsSet) | ||
this.err('withArgs can be called only once'); | ||
this.callData = this.mockContract.interface.encodeFunctionData(this.func, params); | ||
this.argsSet = true; | ||
return this; | ||
} | ||
async then(resolve, reject) { | ||
for (let i = 0; i < this.stubCalls.length; i++) { | ||
try { | ||
await this.stubCalls[i](); | ||
} | ||
catch (e) { | ||
this.stubCalls = []; | ||
this.argsSet = false; | ||
this.revertSet = false; | ||
reject(e); | ||
return; | ||
} | ||
} | ||
this.stubCalls = []; | ||
this.argsSet = false; | ||
this.revertSet = false; | ||
resolve(); | ||
} | ||
} | ||
async function deploy(signer, options) { | ||
if (options) { | ||
const { address, override } = options; | ||
const provider = signer.provider; | ||
if (!override && await provider.getCode(address) !== '0x') { | ||
throw new Error(`${address} already contains a contract. ` + | ||
'If you want to override it, set the override parameter.'); | ||
} | ||
if (provider._hardhatNetwork) { | ||
if (await provider.send('hardhat_setCode', [ | ||
address, | ||
'0x' + DoppelgangerContract.evm.deployedBytecode.object | ||
])) { | ||
return new Contract(address, DoppelgangerContract.abi, signer); | ||
} | ||
else | ||
throw new Error(`Couldn't deploy at ${address}`); | ||
} | ||
else { | ||
if (await provider.send('evm_setAccountCode', [ | ||
address, | ||
'0x' + DoppelgangerContract.evm.deployedBytecode.object | ||
])) { | ||
return new Contract(address, DoppelgangerContract.abi, signer); | ||
} | ||
else | ||
throw new Error(`Couldn't deploy at ${address}`); | ||
} | ||
} | ||
const factory = new ContractFactory(DoppelgangerContract.abi, DoppelgangerContract.bytecode, signer); | ||
return factory.deploy(); | ||
} | ||
function stub(mockContract, encoder, func, params) { | ||
const callData = params | ||
? mockContract.interface.encodeFunctionData(func, params) | ||
: mockContract.interface.getSighash(func); | ||
return { | ||
returns: async (...args) => { | ||
if (!func.outputs) | ||
return; | ||
const encoded = encoder.encode(func.outputs, args); | ||
await mockContract.__waffle__mockReturns(callData, encoded); | ||
}, | ||
reverts: async () => mockContract.__waffle__mockReverts(callData, 'Mock revert'), | ||
revertsWithReason: async (reason) => mockContract.__waffle__mockReverts(callData, reason), | ||
withArgs: (...args) => stub(mockContract, encoder, func, args) | ||
}; | ||
} | ||
function createMock(abi, mockContractInstance) { | ||
@@ -27,3 +134,3 @@ const { functions } = new utils.Interface(abi); | ||
const mockedAbi = Object.values(functions).reduce((acc, func) => { | ||
const stubbed = stub(mockContractInstance, encoder, func); | ||
const stubbed = new Stub(mockContractInstance, encoder, func); | ||
return { | ||
@@ -35,6 +142,12 @@ ...acc, | ||
}, {}); | ||
mockedAbi.receive = { | ||
returns: () => { throw new Error('Receive function return is not implemented.'); }, | ||
withArgs: () => { throw new Error('Receive function return is not implemented.'); }, | ||
reverts: () => mockContractInstance.__waffle__receiveReverts('Mock Revert'), | ||
revertsWithReason: (reason) => mockContractInstance.__waffle__receiveReverts(reason) | ||
}; | ||
return mockedAbi; | ||
} | ||
export async function deployMockContract(signer, abi) { | ||
const mockContractInstance = await deploy(signer); | ||
export async function deployMockContract(signer, abi, options) { | ||
const mockContractInstance = await deploy(signer, options); | ||
const mock = createMock(abi, mockContractInstance); | ||
@@ -41,0 +154,0 @@ const mockedContract = new Contract(mockContractInstance.address, abi, signer); |
{ | ||
"name": "@ethereum-waffle/mock-contract", | ||
"description": "Mock smart contracts in a smart way.", | ||
"version": "4.0.3-dev.f3d5029", | ||
"version": "4.0.3-dev.f8ca718", | ||
"author": "Marek Kirejczyk <account@ethworks.io> (http://ethworks.io)", | ||
@@ -39,14 +39,15 @@ "repository": "git@github.com:EthWorks/Waffle.git", | ||
"devDependencies": { | ||
"@ethereum-waffle/chai": "4.0.9-dev.f8ca718", | ||
"@ethereum-waffle/compiler": "4.0.3-dev.f8ca718", | ||
"@ethereum-waffle/provider": "4.0.5-dev.f8ca718", | ||
"@ethersproject/abi": "^5.6.1", | ||
"@ethersproject/providers": "5.6.2", | ||
"eslint": "^7.14.0", | ||
"ethers": "5.6.2", | ||
"@ethersproject/abi": "^5.6.1", | ||
"@ethereum-waffle/chai": "4.0.8-dev.f3d5029", | ||
"@ethereum-waffle/compiler": "4.0.3-dev.f3d5029", | ||
"mocha": "^8.2.1", | ||
"rimraf": "^3.0.2", | ||
"solc": "0.8.15", | ||
"@ethereum-waffle/provider": "4.0.5-dev.f3d5029", | ||
"ts-node": "^9.0.0", | ||
"typechain": "^8.0.0", | ||
"mocha": "^8.2.1", | ||
"rimraf": "^3.0.2", | ||
"typescript": "^4.6.2", | ||
"eslint": "^7.14.0", | ||
"ts-node": "^9.0.0" | ||
"typescript": "^4.6.2" | ||
}, | ||
@@ -57,12 +58,11 @@ "peerDependencies": { | ||
"scripts": { | ||
"test": "export NODE_ENV=test && yarn test:build && mocha", | ||
"test": "ts-node ./test/helpers/buildTestContracts.ts && export NODE_ENV=test && mocha", | ||
"lint": "eslint '{src,test}/**/*.ts'", | ||
"lint:fix": "eslint --fix '{src,test}/**/*.ts'", | ||
"build": "rimraf ./dist && yarn build:sol && yarn build:esm && yarn build:cjs", | ||
"build": "rimraf ./dist && yarn build:sol && yarn build:esm && yarn build:cjs && ts-node ./test/helpers/buildTestContracts.ts", | ||
"build:sol": "ts-node compile.ts", | ||
"build:esm": "tsc -p tsconfig.build.json --outDir dist/esm --module ES6", | ||
"build:cjs": "tsc -p tsconfig.build.json --outDir dist/cjs", | ||
"test:build": "ts-node ./test/helpers/buildTestContracts.ts", | ||
"clean": "rimraf ./dist ./test/example/build" | ||
} | ||
} |
185
src/index.ts
@@ -1,13 +0,19 @@ | ||
import {Contract, ContractFactory, Signer, utils} from 'ethers'; | ||
import {BaseContract, Contract, ContractFactory, Signer, utils} from 'ethers'; | ||
import type {JsonFragment} from '@ethersproject/abi'; | ||
import DoppelgangerContract from './Doppelganger.json'; | ||
import type {JsonRpcProvider} from '@ethersproject/providers'; | ||
type ABI = string | Array<utils.Fragment | JsonFragment | string> | ||
export type Stub = ReturnType<typeof stub>; | ||
interface StubInterface { | ||
returns(...args: any): StubInterface; | ||
reverts(): StubInterface; | ||
revertsWithReason(reason: string): StubInterface; | ||
withArgs(...args: any[]): StubInterface; | ||
} | ||
export interface MockContract extends Contract { | ||
export interface MockContract<T extends BaseContract = BaseContract> extends Contract { | ||
mock: { | ||
[key: string]: Stub; | ||
[key in ((keyof T['functions'] | 'receive'))]: StubInterface; | ||
}; | ||
@@ -18,25 +24,137 @@ call (contract: Contract, functionName: string, ...params: any[]): Promise<any>; | ||
async function deploy(signer: Signer) { | ||
const factory = new ContractFactory(DoppelgangerContract.abi, DoppelgangerContract.bytecode, signer); | ||
return factory.deploy(); | ||
class Stub implements StubInterface { | ||
callData: string; | ||
stubCalls: Array<() => Promise<any>> = []; | ||
revertSet = false; | ||
argsSet = false; | ||
constructor( | ||
private mockContract: Contract, | ||
private encoder: utils.AbiCoder, | ||
private func: utils.FunctionFragment | ||
) { | ||
this.callData = mockContract.interface.getSighash(func); | ||
} | ||
private err(reason: string): never { | ||
this.stubCalls = []; | ||
this.revertSet = false; | ||
this.argsSet = false; | ||
throw new Error(reason); | ||
} | ||
returns(...args: any) { | ||
if (this.revertSet) this.err('Revert must be the last call'); | ||
if (!this.func.outputs) this.err('Cannot mock return values from a void function'); | ||
const encoded = this.encoder.encode(this.func.outputs, args); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReturns(this.callData, encoded); | ||
}); | ||
} else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueReturn(this.callData, encoded); | ||
}); | ||
} | ||
return this; | ||
} | ||
reverts() { | ||
if (this.revertSet) this.err('Revert must be the last call'); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReverts(this.callData, 'Mock revert'); | ||
}); | ||
} else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueRevert(this.callData, 'Mock revert'); | ||
}); | ||
} | ||
this.revertSet = true; | ||
return this; | ||
} | ||
revertsWithReason(reason: string) { | ||
if (this.revertSet) this.err('Revert must be the last call'); | ||
// if there no calls then this is the first call and we need to use mockReturns to override the queue | ||
if (this.stubCalls.length === 0) { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__mockReverts(this.callData, reason); | ||
}); | ||
} else { | ||
this.stubCalls.push(async () => { | ||
await this.mockContract.__waffle__queueRevert(this.callData, reason); | ||
}); | ||
} | ||
this.revertSet = true; | ||
return this; | ||
} | ||
withArgs(...params: any[]) { | ||
if (this.argsSet) this.err('withArgs can be called only once'); | ||
this.callData = this.mockContract.interface.encodeFunctionData(this.func, params); | ||
this.argsSet = true; | ||
return this; | ||
} | ||
async then(resolve: () => void, reject: (e: any) => void) { | ||
for (let i = 0; i < this.stubCalls.length; i++) { | ||
try { | ||
await this.stubCalls[i](); | ||
} catch (e) { | ||
this.stubCalls = []; | ||
this.argsSet = false; | ||
this.revertSet = false; | ||
reject(e); | ||
return; | ||
} | ||
} | ||
this.stubCalls = []; | ||
this.argsSet = false; | ||
this.revertSet = false; | ||
resolve(); | ||
} | ||
} | ||
function stub(mockContract: Contract, encoder: utils.AbiCoder, func: utils.FunctionFragment, params?: any[]) { | ||
const callData = params | ||
? mockContract.interface.encodeFunctionData(func, params) | ||
: mockContract.interface.getSighash(func); | ||
type DeployOptions = { | ||
address: string; | ||
override?: boolean; | ||
} | ||
return { | ||
returns: async (...args: any) => { | ||
if (!func.outputs) return; | ||
const encoded = encoder.encode(func.outputs, args); | ||
await mockContract.__waffle__mockReturns(callData, encoded); | ||
}, | ||
reverts: async () => mockContract.__waffle__mockReverts(callData, 'Mock revert'), | ||
revertsWithReason: async (reason: string) => mockContract.__waffle__mockReverts(callData, reason), | ||
withArgs: (...args: any[]) => stub(mockContract, encoder, func, args) | ||
}; | ||
async function deploy(signer: Signer, options?: DeployOptions) { | ||
if (options) { | ||
const {address, override} = options; | ||
const provider = signer.provider as JsonRpcProvider; | ||
if (!override && await provider.getCode(address) !== '0x') { | ||
throw new Error( | ||
`${address} already contains a contract. ` + | ||
'If you want to override it, set the override parameter.'); | ||
} | ||
if ((provider as any)._hardhatNetwork) { | ||
if (await provider.send('hardhat_setCode', [ | ||
address, | ||
'0x' + DoppelgangerContract.evm.deployedBytecode.object | ||
])) { | ||
return new Contract(address, DoppelgangerContract.abi, signer); | ||
} else throw new Error(`Couldn't deploy at ${address}`); | ||
} else { | ||
if (await provider.send('evm_setAccountCode', [ | ||
address, | ||
'0x' + DoppelgangerContract.evm.deployedBytecode.object | ||
])) { | ||
return new Contract(address, DoppelgangerContract.abi, signer); | ||
} else throw new Error(`Couldn't deploy at ${address}`); | ||
} | ||
} | ||
const factory = new ContractFactory(DoppelgangerContract.abi, DoppelgangerContract.bytecode, signer); | ||
return factory.deploy(); | ||
} | ||
function createMock(abi: ABI, mockContractInstance: Contract) { | ||
function createMock<T extends BaseContract>(abi: ABI, mockContractInstance: Contract): MockContract<T>['mock'] { | ||
const {functions} = new utils.Interface(abi); | ||
@@ -46,3 +164,3 @@ const encoder = new utils.AbiCoder(); | ||
const mockedAbi = Object.values(functions).reduce((acc, func) => { | ||
const stubbed = stub(mockContractInstance, encoder, func); | ||
const stubbed = new Stub(mockContractInstance as MockContract, encoder, func); | ||
return { | ||
@@ -53,12 +171,23 @@ ...acc, | ||
}; | ||
}, {} as MockContract['mock']); | ||
}, {} as MockContract<T>['mock']); | ||
(mockedAbi as any).receive = { | ||
returns: () => { throw new Error('Receive function return is not implemented.'); }, | ||
withArgs: () => { throw new Error('Receive function return is not implemented.'); }, | ||
reverts: () => mockContractInstance.__waffle__receiveReverts('Mock Revert'), | ||
revertsWithReason: (reason: string) => mockContractInstance.__waffle__receiveReverts(reason) | ||
}; | ||
return mockedAbi; | ||
} | ||
export async function deployMockContract(signer: Signer, abi: ABI): Promise<MockContract> { | ||
const mockContractInstance = await deploy(signer); | ||
export async function deployMockContract<T extends BaseContract = BaseContract>( | ||
signer: Signer, | ||
abi: ABI, | ||
options?: DeployOptions | ||
): Promise<MockContract<T>> { | ||
const mockContractInstance = await deploy(signer, options); | ||
const mock = createMock(abi, mockContractInstance); | ||
const mockedContract = new Contract(mockContractInstance.address, abi, signer) as MockContract; | ||
const mock = createMock<T>(abi, mockContractInstance); | ||
const mockedContract = new Contract(mockContractInstance.address, abi, signer) as MockContract<T>; | ||
mockedContract.mock = mock; | ||
@@ -65,0 +194,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
515951
2388
13