From db90e562a3ca29f8bf2b5bce041a6aa3462fcf8e Mon Sep 17 00:00:00 2001 From: John Kane Date: Tue, 27 Aug 2024 10:46:41 +0100 Subject: [PATCH] test: add example test of mocking hre artifacts We add a `createMockHardhatRuntimeEnvironment` that overrides the standard artifacts built-in plugin and substitutes in a mock version that can be leveraged in tests and development. --- ...create-mock-hardhat-runtime-environment.ts | 173 ++++++++++++++++++ .../example-mock-plugin-using-test.ts | 61 ++++++ 2 files changed, 234 insertions(+) create mode 100644 v-next/hardhat-test-utils/src/create-mock-hardhat-runtime-environment.ts create mode 100644 v-next/hardhat/test/internal/example-mock-plugin-using-test.ts diff --git a/v-next/hardhat-test-utils/src/create-mock-hardhat-runtime-environment.ts b/v-next/hardhat-test-utils/src/create-mock-hardhat-runtime-environment.ts new file mode 100644 index 0000000000..f3f8127db2 --- /dev/null +++ b/v-next/hardhat-test-utils/src/create-mock-hardhat-runtime-environment.ts @@ -0,0 +1,173 @@ +// import { HardhatError } from "@ignored/hardhat-vnext-errors"; + +// import { BUILTIN_GLOBAL_OPTIONS_DEFINITIONS } from "../../src/internal/builtin-global-options.js"; +// import { builtinPlugins as originalBuiltinPlugins } from "../../src/internal/builtin-plugins/index.js"; + +// import "../../src/internal/builtin-plugins/artifacts/type-extensions.js"; + +// class MockArtifactsManager implements ArtifactsManager { +// readonly #artifacts: Map; + +// constructor() { +// this.#artifacts = new Map(); +// } + +// public async readArtifact( +// contractNameOrFullyQualifiedName: string, +// ): Promise { +// const artifact = this.#artifacts.get(contractNameOrFullyQualifiedName); + +// if (artifact === undefined) { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: +// "Unable to find the artifact during mock readArtifact " + +// contractNameOrFullyQualifiedName, +// }); +// } + +// return artifact; +// } + +// public artifactExists( +// _contractNameOrFullyQualifiedName: string, +// ): Promise { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } + +// public getAllFullyQualifiedNames(): Promise { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } + +// public getBuildInfo( +// _fullyQualifiedName: string, +// ): Promise { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } + +// public getArtifactPaths(): Promise { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } + +// public getDebugFilePaths(): Promise { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } + +// public getBuildInfoPaths(): Promise { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } + +// public async saveArtifactAndDebugFile( +// artifact: Artifact, +// _pathToBuildInfo?: string, +// ): Promise { +// this.#artifacts.set(artifact.contractName, artifact); +// } + +// public saveBuildInfo( +// _solcVersion: string, +// _solcLongVersion: string, +// _input: CompilerInput, +// _output: CompilerOutput, +// ): Promise { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } + +// public formArtifactPathFromFullyQualifiedName( +// _fullyQualifiedName: string, +// ): string { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } + +// public clearCache(): void { +// throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { +// message: "Not implemented yet", +// }); +// } +// } + +// const mockArtifactsPlugin: HardhatPlugin = { +// id: "artifacts", +// hookHandlers: { +// hre: async () => { +// return { +// extend: async ( +// _context: HookContext, +// hre: HardhatRuntimeEnvironment, +// _next: ( +// nextContext: HookContext, +// nextHre: HardhatRuntimeEnvironment, +// ) => Promise, +// ): Promise => { +// hre.artifacts = new MockArtifactsManager(); + +// const returnedFromNext = await _next(_context, hre); + +// return returnedFromNext; +// }, +// }; +// }, +// }, +// }; + +// const mockedBuiltinPlugins: HardhatPlugin[] = [mockArtifactsPlugin]; + +// const builtinPlugins = originalBuiltinPlugins.map((plugin) => { +// const mockedPlugin = mockedBuiltinPlugins.find((mp) => mp.id === plugin.id); + +// return mockedPlugin ?? plugin; +// }); + +// export async function createMockHardhatRuntimeEnvironment( +// config: HardhatUserConfig, +// userProvidedGlobalOptions: Partial = {}, +// projectRoot?: string, +// unsafeOptions: UnsafeHardhatRuntimeEnvironmentOptions = {}, +// ): Promise { +// const resolvedProjectRoot = await resolveProjectRoot(projectRoot); + +// if (unsafeOptions.resolvedPlugins === undefined) { +// const plugins = [...builtinPlugins, ...(config.plugins ?? [])]; + +// const resolvedPlugins = await resolvePluginList( +// resolvedProjectRoot, +// plugins, +// ); + +// unsafeOptions.resolvedPlugins = resolvedPlugins; +// } + +// if (unsafeOptions.globalOptionDefinitions === undefined) { +// const pluginGlobalOptionDefinitions = buildGlobalOptionDefinitions( +// unsafeOptions.resolvedPlugins, +// ); +// const globalOptionDefinitions = new Map([ +// ...BUILTIN_GLOBAL_OPTIONS_DEFINITIONS, +// ...pluginGlobalOptionDefinitions, +// ]); + +// unsafeOptions.globalOptionDefinitions = globalOptionDefinitions; +// } + +// return createBaseHardhatRuntimeEnvironment( +// config, +// userProvidedGlobalOptions, +// resolvedProjectRoot, +// unsafeOptions, +// ); +// } diff --git a/v-next/hardhat/test/internal/example-mock-plugin-using-test.ts b/v-next/hardhat/test/internal/example-mock-plugin-using-test.ts new file mode 100644 index 0000000000..9788949784 --- /dev/null +++ b/v-next/hardhat/test/internal/example-mock-plugin-using-test.ts @@ -0,0 +1,61 @@ +import type { Artifact } from "../../src/types/artifacts.js"; +import type { HardhatRuntimeEnvironment } from "../../src/types/hre.js"; +import type { HardhatPlugin } from "../../src/types/plugins.js"; + +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { task } from "../../src/config.js"; +import { createHardhatRuntimeEnvironment } from "../../src/hre.js"; + +// import { createMockHardhatRuntimeEnvironment } from "../helpers/create-mock-hardhat-runtime-environment.js"; + +describe("createMockHardhatRuntimeEnvironment", () => { + it.skip("should allow plugins that leverage the artifact hre object", async () => { + // arrange + + const myPlugin: HardhatPlugin = { + id: "my-plugin", + tasks: [ + task("hello-artifact-using-world", "Tests artifact loading") + .setAction(async ({}, hre: HardhatRuntimeEnvironment) => { + return hre.artifacts.readArtifact("MyContract"); + }) + .build(), + ], + }; + + // TODO: bring back the mock version + const mockHre = await createHardhatRuntimeEnvironment( + { + plugins: [myPlugin], + }, + {}, + undefined, + {}, + ); + + const exampleArtifact: Artifact = { + _format: "hh-sol-artifact-1", + contractName: "MyContract", + sourceName: "source.sol", + abi: [], + bytecode: "0x", + linkReferences: {}, + deployedBytecode: "0x", + deployedLinkReferences: {}, + }; + + await mockHre.artifacts.saveArtifactAndDebugFile(exampleArtifact); + + // act + const helloArtifactUsingWorld = mockHre.tasks.getTask( + "hello-artifact-using-world", + ); + + const result = await helloArtifactUsingWorld.run({}); + + // Assert + assert.equal(result, exampleArtifact); + }); +});