Skip to content

Commit

Permalink
chore: restore the semantics of paths.tests.solidity
Browse files Browse the repository at this point in the history
  • Loading branch information
galargh committed Jan 3, 2025
1 parent 67daa57 commit 18dca31
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 64 deletions.
6 changes: 1 addition & 5 deletions v-next/example-project/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,7 @@ const config: HardhatUserConfig = {
tests: {
mocha: "test/mocha",
nodeTest: "test/node",
solidity: [
"contracts/Counter.sol",
"contracts/Counter.t.sol",
"contracts/WithForge.t.sol",
],
solidity: "test/contracts",
},
},
solidity: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,12 @@ export async function getArtifacts(
*/
export async function getTestSuiteIds(
artifacts: EdrArtifact[],
rootFilePaths: string[],
rootTestFilePaths: string[],
projectRoot: string,
): Promise<EdrArtifactId[]> {
const testSources = rootFilePaths
.filter((p) => {
return p.endsWith(".t.sol");
})
.map((p) => path.relative(projectRoot, p));
const testSources = rootTestFilePaths.map((p) =>
path.relative(projectRoot, p),
);

return artifacts
.map(({ id }) => id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,20 @@ export default async (): Promise<Partial<ConfigHooks>> => {
resolveConfigurationVariable,
);

let testsPaths: string[];
let testsPath = userConfig.paths?.tests;

// TODO: use isObject when the type narrowing issue is fixed
if (
typeof userConfig.paths?.tests === "object" &&
userConfig.paths.tests.solidity !== undefined
) {
if (Array.isArray(userConfig.paths.tests.solidity)) {
testsPaths = userConfig.paths.tests.solidity;
} else {
testsPaths = [userConfig.paths.tests.solidity];
}
} else {
testsPaths = resolvedConfig.paths.sources.solidity;
}

const resolvedPaths = testsPaths.map((p) =>
resolveFromRoot(resolvedConfig.paths.root, p),
);
testsPath =
typeof testsPath === "object" ? testsPath.solidity : testsPath;
testsPath ??= "test";

return {
...resolvedConfig,
paths: {
...resolvedConfig.paths,
tests: {
...resolvedConfig.paths.tests,
solidity: resolvedPaths,
solidity: resolveFromRoot(resolvedConfig.paths.root, testsPath),
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import type { NewTaskActionFunction } from "../../../types/tasks.js";

import { finished } from "node:stream/promises";

import {
getAllFilesMatching,
isDirectory,
} from "@ignored/hardhat-vnext-utils/fs";
import { resolveFromRoot } from "@ignored/hardhat-vnext-utils/path";
import { getAllFilesMatching } from "@ignored/hardhat-vnext-utils/fs";
import { createNonClosingWriter } from "@ignored/hardhat-vnext-utils/stream";

import { shouldMergeCompilationJobs } from "../solidity/build-profiles.js";
Expand All @@ -28,47 +24,42 @@ interface TestActionArguments {
}

const runSolidityTests: NewTaskActionFunction<TestActionArguments> = async (
{ timeout, noCompile },
{ timeout },
hre,
) => {
const rootFilePaths = (
await Promise.all(
hre.config.paths.tests.solidity
.map((p) => resolveFromRoot(hre.config.paths.root, p))
.map(async (p) => {
// NOTE: The paths specified in the `paths.tests.solidity` array
// can be either directories or files.
if (await isDirectory(p)) {
return getAllFilesMatching(p, (f) => f.endsWith(".sol"));
} else if (p.endsWith(".sol") === true) {
return [p];
} else {
return [];
}
}),
)
const rootSourceFilePaths = await hre.solidity.getRootFilePaths();
// NOTE: A test file is either a file with a `.sol` extension in the `tests.solidity`
// directory or a file with a `.t.sol` extension in the `sources.solidity` directory
const rootTestFilePaths = (
await Promise.all([
getAllFilesMatching(hre.config.paths.tests.solidity, (f) =>
f.endsWith(".sol"),
),
...hre.config.paths.sources.solidity.map(async (dir) => {
return getAllFilesMatching(dir, (f) => f.endsWith(".t.sol"));
}),
])
).flat(1);

const buildOptions: BuildOptions = {
// NOTE: The uncached sources will still be compiled event if `noCompile`
// is true. We could consider adding a `cacheOnly` option to support true
// `noCompile` behavior.
force: !noCompile,
force: false,
buildProfile: hre.globalOptions.buildProfile,
mergeCompilationJobs: shouldMergeCompilationJobs(
hre.globalOptions.buildProfile,
),
quiet: false,
};

// NOTE: We compile all the sources together with the tests
const rootFilePaths = [...rootSourceFilePaths, ...rootTestFilePaths];
const results = await hre.solidity.build(rootFilePaths, buildOptions);

throwIfSolidityBuildFailed(results);

const artifacts = await getArtifacts(results, hre.config.paths.artifacts);
const testSuiteIds = await getTestSuiteIds(
artifacts,
rootFilePaths,
rootTestFilePaths,
hre.config.paths.root,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import "@ignored/hardhat-vnext/types/config";

declare module "@ignored/hardhat-vnext/types/config" {
export interface TestPathsUserConfig {
solidity?: string | string[];
solidity?: string;
}

export interface TestPathsConfig {
solidity: string[];
solidity: string;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ export class SolidityBuildSystemImplementation implements SolidityBuildSystem {
const localFilesToCompile = (
await Promise.all(
this.#options.soliditySourcesPaths.map((dir) =>
getAllFilesMatching(dir, (f) => f.endsWith(".sol")),
getAllFilesMatching(
dir,
(f) => f.endsWith(".sol") && !f.endsWith(".t.sol"),
),
),
)
).flat(1);
Expand Down
8 changes: 6 additions & 2 deletions v-next/hardhat/test/internal/core/config-validation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { HardhatUserConfig } from "../../../src/config.js";
import type { ProjectPathsUserConfig } from "../../../src/types/config.js";
import type {
ProjectPathsUserConfig,
TestPathsUserConfig,
} from "../../../src/types/config.js";
import type { HardhatPlugin } from "../../../src/types/plugins.js";
import type {
EmptyTaskDefinition,
Expand Down Expand Up @@ -1247,7 +1250,8 @@ describe("config validation", function () {
it("should work when the tests and sources properties are both objects", async function () {
// Objects are not validated because they are customizable by the user
const paths: ProjectPathsUserConfig = {
tests: { randomProperty: "randomValue" },
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- testing validations for js users who can bypass type checks */
tests: { randomProperty: "randomValue" } as TestPathsUserConfig,
sources: {},
};

Expand Down
6 changes: 3 additions & 3 deletions v-next/hardhat/test/internal/core/hook-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ describe("HookManager", () => {
givenHre: HardhatRuntimeEnvironment,
): Promise<void> => {
givenHre.config.paths.tests = {
solidity: ["./test-folder-from-plugin1"],
solidity: "./test-folder-from-plugin1",
};
},
} as Partial<HardhatRuntimeEnvironmentHooks>;
Expand All @@ -279,7 +279,7 @@ describe("HookManager", () => {
givenHre: HardhatRuntimeEnvironment,
): Promise<void> => {
givenHre.config.paths.tests = {
solidity: ["./test-folder-from-overriding-plugin2"],
solidity: "./test-folder-from-overriding-plugin2",
};
},
} as Partial<HardhatRuntimeEnvironmentHooks>;
Expand All @@ -304,7 +304,7 @@ describe("HookManager", () => {

assert.equal(result.length, 2);
assert.equal(
hre.config.paths.tests.solidity[0],
hre.config.paths.tests.solidity,
"./test-folder-from-overriding-plugin2",
);
});
Expand Down

0 comments on commit 18dca31

Please sign in to comment.