hardhat
Version:
Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.
131 lines (117 loc) • 3.77 kB
text/typescript
import type { RunOptions } from "./runner.js";
import type { Abi } from "../../../types/artifacts.js";
import type { ChainType } from "../../../types/network.js";
import type { SolidityTestConfig } from "../../../types/test.js";
import type {
SolidityTestRunnerConfigArgs,
PathPermission,
Artifact,
ObservabilityConfig,
} from "@nomicfoundation/edr";
import {
opGenesisState,
opLatestHardfork,
l1GenesisState,
l1HardforkLatest,
IncludeTraces,
FsAccessPermission,
} from "@nomicfoundation/edr";
import { hexStringToBytes } from "@nomicfoundation/hardhat-utils/hex";
import { OPTIMISM_CHAIN_TYPE } from "../../constants.js";
function hexStringToBuffer(hexString: string): Buffer {
return Buffer.from(hexStringToBytes(hexString));
}
export function solidityTestConfigToRunOptions(
config: SolidityTestConfig,
): RunOptions {
return config;
}
export function solidityTestConfigToSolidityTestRunnerConfigArgs(
chainType: ChainType,
projectRoot: string,
config: SolidityTestConfig,
verbosity: number,
observability?: ObservabilityConfig,
testPattern?: string,
): SolidityTestRunnerConfigArgs {
const fsPermissions: PathPermission[] | undefined = [
config.fsPermissions?.readWriteFile?.map((p) => ({
access: FsAccessPermission.ReadWriteFile,
path: p,
})) ?? [],
config.fsPermissions?.readFile?.map((p) => ({
access: FsAccessPermission.ReadFile,
path: p,
})) ?? [],
config.fsPermissions?.writeFile?.map((p) => ({
access: FsAccessPermission.WriteFile,
path: p,
})) ?? [],
config.fsPermissions?.dangerouslyReadWriteDirectory?.map((p) => ({
access: FsAccessPermission.DangerouslyReadWriteDirectory,
path: p,
})) ?? [],
config.fsPermissions?.readDirectory?.map((p) => ({
access: FsAccessPermission.ReadDirectory,
path: p,
})) ?? [],
config.fsPermissions?.dangerouslyWriteDirectory?.map((p) => ({
access: FsAccessPermission.DangerouslyWriteDirectory,
path: p,
})) ?? [],
].flat(1);
const sender: Buffer | undefined =
config.from === undefined ? undefined : hexStringToBuffer(config.from);
const txOrigin: Buffer | undefined =
config.txOrigin === undefined
? undefined
: hexStringToBuffer(config.txOrigin);
const blockCoinbase: Buffer | undefined =
config.coinbase === undefined
? undefined
: hexStringToBuffer(config.coinbase);
const localPredeploys =
chainType === OPTIMISM_CHAIN_TYPE
? opGenesisState(opLatestHardfork())
: l1GenesisState(l1HardforkLatest());
let includeTraces: IncludeTraces = IncludeTraces.None;
if (verbosity >= 5) {
includeTraces = IncludeTraces.All;
} else if (verbosity >= 3) {
includeTraces = IncludeTraces.Failing;
}
const blockGasLimit =
config.blockGasLimit === false ? undefined : config.blockGasLimit;
const disableBlockGasLimit = config.blockGasLimit === false;
const blockDifficulty = config.prevRandao;
const ethRpcUrl = config.forking?.url;
const forkBlockNumber = config.forking?.blockNumber;
const rpcEndpoints = config.forking?.rpcEndpoints;
return {
projectRoot,
...config,
fsPermissions,
localPredeploys,
sender,
txOrigin,
blockCoinbase,
observability,
testPattern,
includeTraces,
blockGasLimit,
disableBlockGasLimit,
blockDifficulty,
ethRpcUrl,
forkBlockNumber,
rpcEndpoints,
};
}
export function isTestSuiteArtifact(artifact: Artifact): boolean {
const abi: Abi = JSON.parse(artifact.contract.abi);
return abi.some(({ type, name }) => {
if (type === "function" && typeof name === "string") {
return name.startsWith("test") || name.startsWith("invariant");
}
return false;
});
}