Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/unified-test-workflow' into feat…
Browse files Browse the repository at this point in the history
…/solidity-test-configuration
  • Loading branch information
galargh committed Oct 28, 2024
2 parents 1c5f1a1 + 02a82df commit 58fa591
Show file tree
Hide file tree
Showing 48 changed files with 416 additions and 184 deletions.
15 changes: 14 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions v-next/example-project/contracts/WithForge.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import "forge-std/Test.sol";

contract TestContract is Test {
ErrorsTest test;

function setUp() public {
test = new ErrorsTest();
}

function testExpectArithmetic() public {
vm.expectRevert(stdError.arithmeticError);
test.arithmeticError(10);
}
}

contract ErrorsTest {
function arithmeticError(uint256 a) public {
uint256 a = a - 100;
}
}
16 changes: 6 additions & 10 deletions v-next/example-project/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ const exampleTaskOverride = task("example2")
})
.build();

const testSolidityTask = task(["test", "solidity"], "Runs Solidity tests")
.setAction(async () => {
console.log("Running Solidity tests");
})
.build();

const greeting = task("hello", "Prints a greeting")
.addOption({
name: "greeting",
Expand Down Expand Up @@ -114,7 +108,6 @@ const pluginExample = {
const config: HardhatUserConfig = {
tasks: [
exampleTaskOverride,
testSolidityTask,
exampleEmptyTask,
exampleEmptySubtask,
greeting,
Expand All @@ -125,8 +118,7 @@ const config: HardhatUserConfig = {
pluginExample,
hardhatEthersPlugin,
HardhatKeystore,
// HardhatMochaTestRunner,
// if testing node plugin, use the following line instead
HardhatMochaTestRunner,
hardhatNetworkHelpersPlugin,
HardhatNodeTestRunner,
HardhatViem,
Expand Down Expand Up @@ -165,7 +157,11 @@ const config: HardhatUserConfig = {
},
},
dependenciesToCompile: ["@openzeppelin/contracts/token/ERC20/ERC20.sol"],
remappings: ["remapped/=npm/@openzeppelin/[email protected]/access/"],
remappings: [
"remapped/=npm/@openzeppelin/[email protected]/access/",
// This is necessary because most people import forge-std/Test.sol, and not forge-std/src/Test.sol
"forge-std/=npm/[email protected]/src/",
],
},
};

Expand Down
14 changes: 8 additions & 6 deletions v-next/example-project/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@
},
"devDependencies": {
"@ignored/hardhat-vnext": "workspace:^3.0.0-next.4",
"@ignored/hardhat-vnext-node-test-runner": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-network-helpers": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-mocha-test-runner": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-keystore": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-ethers": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-keystore": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-mocha-test-runner": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-network-helpers": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-node-test-runner": "workspace:^3.0.0-next.0",
"@ignored/hardhat-vnext-viem": "workspace:^3.0.0-next.0",
"@openzeppelin/contracts": "^5.1.0",
"@openzeppelin/contracts": "5.1.0",
"@types/mocha": ">=9.1.0",
"@types/node": "^20.14.9",
"mocha": "^10.0.0",
"prettier": "3.2.5",
"rimraf": "^5.0.5",
"typescript": "~5.5.0",
"viem": "^2.21.17"
"viem": "^2.21.17",
"forge-std": "foundry-rs/forge-std#v1.9.4"
}
}
4 changes: 2 additions & 2 deletions v-next/example-project/scripts/viem-plugin-example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ async function testContracts() {

// this does not work, as dec is not part of the abi
try {
// @ts-error
// @ts-ignore
await counter.write.dec();
} catch (e) {
console.error(e);
}

// this does not work, as rocket expects a string instead
// of a number as the first constructor argument
// @ts-error
// @ts-ignore
const rocket1 = await networkConnection.viem.deployContract("Rocket", [1n]);
console.log("Rocket launched at", rocket1.address);
const rocket1name = await rocket1.read.name();
Expand Down
Empty file.
8 changes: 6 additions & 2 deletions v-next/hardhat-mocha-test-runner/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { task } from "@ignored/hardhat-vnext/config";
import "./type-extensions.js";

const hardhatPlugin: HardhatPlugin = {
id: "test",
id: "hardhat-mocha",
tasks: [
task("test", "Runs tests using the Mocha test runner")
task(["test", "mocha"], "Runs tests using the Mocha test runner")
.addVariadicArgument({
name: "testFiles",
description: "An optional list of files to test",
Expand All @@ -22,6 +22,10 @@ const hardhatPlugin: HardhatPlugin = {
description: "Only run tests matching the given string or regexp",
defaultValue: "",
})
.addFlag({
name: "noCompile",
description: "Don't compile the project before running the test",
})
.setAction(import.meta.resolve("./task-action.js"))
.build(),
],
Expand Down
7 changes: 6 additions & 1 deletion v-next/hardhat-mocha-test-runner/src/task-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface TestActionArguments {
testFiles: string[];
bail: boolean;
grep: string;
noCompile: boolean;
}

function isTypescriptFile(path: string): boolean {
Expand Down Expand Up @@ -42,9 +43,13 @@ async function getTestFiles(

let testsAlreadyRun = false;
const testWithHardhat: NewTaskActionFunction<TestActionArguments> = async (
{ testFiles, bail, grep },
{ testFiles, bail, grep, noCompile },
hre,
) => {
if (!noCompile) {
await hre.tasks.getTask("compile").run({ quiet: true });
}

const files = await getTestFiles(testFiles, hre.config);

const tsx = fileURLToPath(import.meta.resolve("tsx/esm"));
Expand Down
2 changes: 1 addition & 1 deletion v-next/hardhat-mocha-test-runner/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe("Hardhat Mocha plugin", () => {

const hre = await createHardhatRuntimeEnvironment(hardhatConfig.default);

const result = await hre.tasks.getTask("test").run({});
const result = await hre.tasks.getTask(["test", "mocha"]).run({});

assert.equal(result, 0);
});
Expand Down
8 changes: 6 additions & 2 deletions v-next/hardhat-node-test-runner/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { task } from "@ignored/hardhat-vnext/config";
import "./type-extensions.js";

const hardhatPlugin: HardhatPlugin = {
id: "test",
id: "hardhat-node-test-runner",
tasks: [
task("test", "Runs tests using the NodeJS test runner")
task(["test", "node"], "Runs tests using the NodeJS test runner")
.addVariadicArgument({
name: "testFiles",
description: "An optional list of files to test",
Expand All @@ -22,6 +22,10 @@ const hardhatPlugin: HardhatPlugin = {
description: "Only run tests matching the given string or regexp",
defaultValue: "",
})
.addFlag({
name: "noCompile",
description: "Don't compile the project before running the test",
})
.setAction(import.meta.resolve("./task-action.js"))
.build(),
],
Expand Down
7 changes: 6 additions & 1 deletion v-next/hardhat-node-test-runner/src/task-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface TestActionArguments {
testFiles: string[];
only: boolean;
grep: string;
noCompile: boolean;
}

function isTypescriptFile(path: string): boolean {
Expand Down Expand Up @@ -50,9 +51,13 @@ async function getTestFiles(
* Note that we are testing this manually for now as you can't run a node:test within a node:test
*/
const testWithHardhat: NewTaskActionFunction<TestActionArguments> = async (
{ testFiles, only, grep },
{ testFiles, only, grep, noCompile },
hre,
) => {
if (!noCompile) {
await hre.tasks.getTask("compile").run({ quiet: true });
}

const files = await getTestFiles(testFiles, hre.config);

const tsx = fileURLToPath(import.meta.resolve("tsx/esm"));
Expand Down
7 changes: 5 additions & 2 deletions v-next/hardhat-viem/test/hook-handlers/network.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { NetworkConnection } from "@ignored/hardhat-vnext/types/network";
import type {
GenericChainType,
NetworkConnection,
} from "@ignored/hardhat-vnext/types/network";

import assert from "node:assert/strict";
import { before, describe, it } from "node:test";
Expand All @@ -10,7 +13,7 @@ import HardhatViem from "../../src/index.js";

describe("hook-handlers/network", () => {
describe("newConnection", () => {
let connection: NetworkConnection<"unknown">;
let connection: NetworkConnection<GenericChainType>;

before(async () => {
const hre = await createHardhatRuntimeEnvironment({
Expand Down
2 changes: 1 addition & 1 deletion v-next/hardhat/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ process.setSourceMapsEnabled(true);
// eslint-disable-next-line no-restricted-syntax -- Allow top-level await here
const { main } = await import("./internal/cli/main.js");

main(process.argv.slice(2), undefined, true).catch(() => {
main(process.argv.slice(2), { registerTsx: true }).catch(() => {
process.exitCode = 1;
});
Original file line number Diff line number Diff line change
@@ -1,15 +1,81 @@
import type {
ArtifactsManager,
BuildInfo,
GetAtifactByName,
} from "../../../../types/artifacts.js";
import type { HardhatRuntimeEnvironmentHooks } from "../../../../types/hooks.js";

export default async (): Promise<Partial<HardhatRuntimeEnvironmentHooks>> => {
const handlers: Partial<HardhatRuntimeEnvironmentHooks> = {
created: async (_context, hre): Promise<void> => {
class LazyArtifactsManager implements ArtifactsManager {
readonly #artifactsPath: string;
#artifactsManager: ArtifactsManager | undefined;

constructor(artifactsPath: string) {
this.#artifactsManager = undefined;
this.#artifactsPath = artifactsPath;
}

public async readArtifact<ContractNameT extends string>(
contractNameOrFullyQualifiedName: ContractNameT,
): Promise<GetAtifactByName<ContractNameT>> {
const artifactsManager = await this.#getArtifactsManager();
return artifactsManager.readArtifact(contractNameOrFullyQualifiedName);
}

public async artifactExists(
contractNameOrFullyQualifiedName: string,
): Promise<boolean> {
const artifactsManager = await this.#getArtifactsManager();
return artifactsManager.artifactExists(contractNameOrFullyQualifiedName);
}

public async getAllFullyQualifiedNames(): Promise<string[]> {
const artifactsManager = await this.#getArtifactsManager();
return artifactsManager.getAllFullyQualifiedNames();
}

public async getBuildInfo(
fullyQualifiedName: string,
): Promise<BuildInfo | undefined> {
const artifactsManager = await this.#getArtifactsManager();
return artifactsManager.getBuildInfo(fullyQualifiedName);
}

public async getArtifactPaths(): Promise<string[]> {
const artifactsManager = await this.#getArtifactsManager();
return artifactsManager.getArtifactPaths();
}

public async getBuildInfoPaths(): Promise<string[]> {
const artifactsManager = await this.#getArtifactsManager();
return artifactsManager.getBuildInfoPaths();
}

public async getArtifactPath(
contractNameOrFullyQualifiedName: string,
): Promise<string> {
const artifactsManager = await this.#getArtifactsManager();
return artifactsManager.getArtifactPath(contractNameOrFullyQualifiedName);
}

async #getArtifactsManager(): Promise<ArtifactsManager> {
if (this.#artifactsManager === undefined) {
const { ArtifactsManagerImplementation } = await import(
"../artifacts-manager.js"
);

hre.artifacts = new ArtifactsManagerImplementation(
hre.config.paths.artifacts,
this.#artifactsManager = new ArtifactsManagerImplementation(
this.#artifactsPath,
);
}

return this.#artifactsManager;
}
}

export default async (): Promise<Partial<HardhatRuntimeEnvironmentHooks>> => {
const handlers: Partial<HardhatRuntimeEnvironmentHooks> = {
created: async (_context, hre): Promise<void> => {
hre.artifacts = new LazyArtifactsManager(hre.config.paths.artifacts);
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HardhatPlugin } from "../../../types/plugins.js";
import "./type-extensions.js";

const hardhatPlugin: HardhatPlugin = {
id: "artifacts",
id: "builtin:artifacts",
hookHandlers: {
hre: import.meta.resolve("./hook-handlers/hre.js"),
},
Expand Down
2 changes: 1 addition & 1 deletion v-next/hardhat/src/internal/builtin-plugins/clean/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { HardhatPlugin } from "../../../types/plugins.js";
import { task } from "../../core/config.js";

const hardhatPlugin: HardhatPlugin = {
id: "clean",
id: "builtin:clean",
tasks: [
task("clean", "Clears the cache and deletes all artifacts")
.addFlag({
Expand Down
Loading

0 comments on commit 58fa591

Please sign in to comment.