-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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. There is a supporting test to show the usage of the mocked artifacts manager.
- Loading branch information
Showing
3 changed files
with
209 additions
and
0 deletions.
There are no files selected for viewing
54 changes: 54 additions & 0 deletions
54
v-next/hardhat/test/internal/example-mock-artifacts-plugin-using-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
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 { createMockHardhatRuntimeEnvironment } from "../test-helpers/create-mock-hardhat-runtime-environment.js"; | ||
|
||
// TODO: This test is an example and should be removed with the completion of | ||
// the build system and the artifacts plugin. | ||
describe("createMockHardhatRuntimeEnvironment", () => { | ||
it("should allow plugins that leverage the artifact hre object", async () => { | ||
// arrange | ||
const exampleArtifact: Artifact = { | ||
_format: "hh-sol-artifact-1", | ||
contractName: "MyContract", | ||
sourceName: "source.sol", | ||
abi: [], | ||
bytecode: "0x", | ||
linkReferences: {}, | ||
deployedBytecode: "0x", | ||
deployedLinkReferences: {}, | ||
}; | ||
|
||
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(), | ||
], | ||
}; | ||
|
||
const mockHre = await createMockHardhatRuntimeEnvironment({ | ||
plugins: [myPlugin], | ||
}); | ||
|
||
await mockHre.artifacts.saveArtifact(exampleArtifact); | ||
|
||
// act | ||
const helloArtifactUsingWorld = mockHre.tasks.getTask( | ||
"hello-artifact-using-world", | ||
); | ||
|
||
const result = await helloArtifactUsingWorld.run({}); | ||
|
||
// Assert | ||
assert.equal(result, exampleArtifact); | ||
}); | ||
}); |
51 changes: 51 additions & 0 deletions
51
v-next/hardhat/test/test-helpers/create-mock-hardhat-runtime-environment.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import type { HardhatUserConfig } from "../../src/config.js"; | ||
import type { UnsafeHardhatRuntimeEnvironmentOptions } from "../../src/internal/core/types.js"; | ||
import type { GlobalOptions } from "../../src/types/global-options.js"; | ||
import type { HardhatRuntimeEnvironment } from "../../src/types/hre.js"; | ||
import type { HardhatPlugin } from "../../src/types/plugins.js"; | ||
|
||
import "../../src/internal/builtin-plugins/artifacts/type-extensions.js"; | ||
|
||
import { createHardhatRuntimeEnvironment } from "../../src/hre.js"; | ||
import artifacts from "../../src/internal/builtin-plugins/artifacts/index.js"; | ||
import { resolveProjectRoot } from "../../src/internal/core/hre.js"; | ||
|
||
import { MockArtifactsManager } from "./mock-artifacts-manager.js"; | ||
|
||
export async function createMockHardhatRuntimeEnvironment( | ||
config: HardhatUserConfig, | ||
userProvidedGlobalOptions: Partial<GlobalOptions> = {}, | ||
projectRoot?: string, | ||
unsafeOptions: UnsafeHardhatRuntimeEnvironmentOptions = {}, | ||
): Promise<HardhatRuntimeEnvironment> { | ||
const resolvedProjectRoot = await resolveProjectRoot(projectRoot); | ||
|
||
return createHardhatRuntimeEnvironment( | ||
{ ...config, plugins: [mockArtifactsPlugin, ...(config.plugins ?? [])] }, | ||
userProvidedGlobalOptions, | ||
resolvedProjectRoot, | ||
unsafeOptions, | ||
); | ||
} | ||
|
||
const mockArtifactsPlugin: HardhatPlugin = { | ||
id: "mock-artifacts", | ||
dependencies: [async () => artifacts], | ||
hookHandlers: { | ||
hre: async () => { | ||
return { | ||
created: async ( | ||
context, | ||
hre, | ||
next, | ||
): Promise<HardhatRuntimeEnvironment> => { | ||
const updatedHre = await next(context, hre); | ||
|
||
updatedHre.artifacts = new MockArtifactsManager(); | ||
|
||
return updatedHre; | ||
}, | ||
}; | ||
}, | ||
}, | ||
}; |
104 changes: 104 additions & 0 deletions
104
v-next/hardhat/test/test-helpers/mock-artifacts-manager.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import type { | ||
ArtifactsManager, | ||
Artifact, | ||
BuildInfo, | ||
CompilerInput, | ||
CompilerOutput, | ||
} from "../../src/types/artifacts.js"; | ||
|
||
import { HardhatError } from "@ignored/hardhat-vnext-errors"; | ||
|
||
export class MockArtifactsManager implements ArtifactsManager { | ||
readonly #artifacts: Map<string, Artifact>; | ||
|
||
constructor() { | ||
this.#artifacts = new Map(); | ||
} | ||
|
||
public async readArtifact( | ||
contractNameOrFullyQualifiedName: string, | ||
): Promise<Artifact> { | ||
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<boolean> { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
|
||
public getAllFullyQualifiedNames(): Promise<string[]> { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
|
||
public getBuildInfo( | ||
_fullyQualifiedName: string, | ||
): Promise<BuildInfo | undefined> { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
|
||
public getArtifactPaths(): Promise<string[]> { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
|
||
public getDebugFilePaths(): Promise<string[]> { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
|
||
public getBuildInfoPaths(): Promise<string[]> { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
|
||
public async saveArtifact(artifact: Artifact): Promise<void> { | ||
this.#artifacts.set(artifact.contractName, artifact); | ||
} | ||
|
||
public saveBuildInfo( | ||
_solcVersion: string, | ||
_solcLongVersion: string, | ||
_input: CompilerInput, | ||
_output: CompilerOutput, | ||
): Promise<string> { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
|
||
public formArtifactPathFromFullyQualifiedName( | ||
_fullyQualifiedName: string, | ||
): string { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
|
||
public getArtifactPath( | ||
_contractNameOrFullyQualifiedName: string, | ||
): Promise<string> { | ||
throw new HardhatError(HardhatError.ERRORS.INTERNAL.ASSERTION_ERROR, { | ||
message: "Not implemented in MockArtifactsManager", | ||
}); | ||
} | ||
} |