Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: mocks can be deployed with libs #68

Merged
merged 1 commit into from
Sep 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/factories/smock-contract.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Message from '@nomiclabs/ethereumjs-vm/dist/evm/message';
import { FactoryOptions } from '@nomiclabs/hardhat-ethers/types';
import { BaseContract, ContractFactory, ethers } from 'ethers';
import { Interface } from 'ethers/lib/utils';
import { ethers as hardhatEthers } from 'hardhat';
Expand Down Expand Up @@ -33,9 +34,10 @@ export async function createFakeContract<Contract extends BaseContract>(

export async function createMockContractFactory<T extends ContractFactory>(
vm: ObservableVM,
contractName: string
contractName: string,
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<MockContractFactory<T>> {
const factory = (await hardhatEthers.getContractFactory(contractName)) as unknown as MockContractFactory<T>;
const factory = (await hardhatEthers.getContractFactory(contractName, signerOrOptions)) as unknown as MockContractFactory<T>;

const realDeploy = factory.deploy;
factory.deploy = async (...args: Parameters<T['deploy']>) => {
Expand Down
10 changes: 7 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseContract, ContractFactory } from 'ethers';
import { FactoryOptions } from '@nomiclabs/hardhat-ethers/types';
import { BaseContract, ContractFactory, ethers } from 'ethers';
import hre from 'hardhat';
import { matchers } from './chai-plugin/matchers';
import { Sandbox } from './sandbox';
Expand All @@ -12,10 +13,13 @@ async function fake<T extends BaseContract>(spec: FakeContractSpec, opts: FakeCo
return await sandbox.fake(spec, opts);
}

async function mock<T extends ContractFactory>(contractName: string): Promise<MockContractFactory<T>> {
async function mock<T extends ContractFactory>(
contractName: string,
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<MockContractFactory<T>> {
if (!sandbox) await init();

return await sandbox.mock(contractName);
return await sandbox.mock(contractName, signerOrOptions);
}

async function init() {
Expand Down
10 changes: 7 additions & 3 deletions src/sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import VM from '@nomiclabs/ethereumjs-vm';
import { BaseContract, ContractFactory } from 'ethers';
import { FactoryOptions } from '@nomiclabs/hardhat-ethers/types';
import { BaseContract, ContractFactory, ethers } from 'ethers';
import hre from 'hardhat';
import { ethersInterfaceFromSpec } from './factories/ethers-interface';
import { createFakeContract, createMockContractFactory } from './factories/smock-contract';
Expand Down Expand Up @@ -44,8 +45,11 @@ export class Sandbox {
);
}

async mock<T extends ContractFactory>(contractName: string): Promise<MockContractFactory<T>> {
return createMockContractFactory(this.vm, contractName);
async mock<T extends ContractFactory>(
contractName: string,
signerOrOptions?: ethers.Signer | FactoryOptions
): Promise<MockContractFactory<T>> {
return createMockContractFactory(this.vm, contractName, signerOrOptions);
}

static async create(): Promise<Sandbox> {
Expand Down
10 changes: 10 additions & 0 deletions test/contracts/mock/Librarian.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import './TestLibrary.sol';

contract Librarian {
function getLibValue() external pure returns (uint256) {
return TestLibrary.getSomeValue();
}
}
8 changes: 8 additions & 0 deletions test/contracts/mock/TestLibrary.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

library TestLibrary {
function getSomeValue() external pure returns (uint256) {
return 10;
}
}
39 changes: 39 additions & 0 deletions test/unit/mock/initialization.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { BigNumber } from '@ethersproject/bignumber';
import { smock } from '@src';
import { Librarian__factory, TestLibrary__factory } from '@typechained';
import chai, { expect } from 'chai';
import { ethers } from 'hardhat';

chai.use(smock.matchers);

describe('Mock: Initialization', () => {
it('should be able to use libraries', async () => {
const testLibrary = await (await ethers.getContractFactory('TestLibrary')).deploy();
const librarian = await (
await smock.mock<Librarian__factory>('Librarian', {
libraries: {
TestLibrary: testLibrary.address,
},
})
).deploy();
Comment on lines +10 to +18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀


expect(await librarian.getLibValue()).to.equal(10);
});

// TODO: make it work
it.skip('should be able to use mocked libraries', async () => {
const testLibrary = await (await smock.mock<TestLibrary__factory>('TestLibrary')).deploy();
const librarian = await (
await smock.mock<Librarian__factory>('Librarian', {
libraries: {
TestLibrary: testLibrary.address,
},
})
).deploy();

const mockValue = BigNumber.from(123);
testLibrary.getSomeValue.returns(mockValue);

expect(await librarian.getLibValue()).to.equal(mockValue);
});
});