diff --git a/v-next/example-project/contracts/Counter.t.sol b/v-next/example-project/contracts/Counter.t.sol index b4f50e64eea..a52d195a6db 100644 --- a/v-next/example-project/contracts/Counter.t.sol +++ b/v-next/example-project/contracts/Counter.t.sol @@ -14,6 +14,10 @@ contract CounterTest { require(counter.x() == 0, "Initial value should be 0"); } + function testFailInitialValue() public view { + require(counter.x() == 1, "Initial value should be 1"); + } + function testFuzzInc(uint8 x) public { for (uint8 i = 0; i < x; i++) { counter.inc(); @@ -21,6 +25,13 @@ contract CounterTest { require(counter.x() == x, "Value after calling inc x times should be x"); } + function testFailFuzzInc(uint8 x) public { + for (uint8 i = 0; i < x; i++) { + counter.inc(); + } + require(counter.x() == x + 1, "Value after calling inc x times should be x + 1"); + } + function invariant() public { assert(true); } diff --git a/v-next/example-project/hardhat.config.ts b/v-next/example-project/hardhat.config.ts index b0ef2213496..94f7f777365 100644 --- a/v-next/example-project/hardhat.config.ts +++ b/v-next/example-project/hardhat.config.ts @@ -153,6 +153,9 @@ const config: HardhatUserConfig = { version: "0.8.1", }, }, + test: { + testFail: true, + } }, test: { version: "0.8.2", diff --git a/v-next/hardhat/src/internal/builtin-plugins/solidity-test/task-action.ts b/v-next/hardhat/src/internal/builtin-plugins/solidity-test/task-action.ts index 017c3ff8412..848ac166afa 100644 --- a/v-next/hardhat/src/internal/builtin-plugins/solidity-test/task-action.ts +++ b/v-next/hardhat/src/internal/builtin-plugins/solidity-test/task-action.ts @@ -1,5 +1,6 @@ import type { RunOptions, TestEvent } from "./types.js"; import type { NewTaskActionFunction } from "../../../types/tasks.js"; +import type { SolidityTestRunnerConfigArgs } from "@ignored/edr"; import { finished } from "node:stream/promises"; @@ -23,10 +24,6 @@ const runSolidityTests: NewTaskActionFunction = async (_taskArguments, hre) => { ) ).filter((artifact) => artifact !== undefined); - const config = { - projectRoot: hre.config.paths.root, - }; - let includesFailures = false; let includesErrors = false; @@ -34,7 +31,12 @@ const runSolidityTests: NewTaskActionFunction = async (_taskArguments, hre) => { const profile = hre.config.solidity.profiles[profileName]; const testOptions = profile.test; - const options: RunOptions = { timeout: testOptions.timeout }; + const config: SolidityTestRunnerConfigArgs = { + projectRoot: hre.config.paths.root, + ...testOptions, + }; + + const options: RunOptions = testOptions; const runStream = run(artifacts, testSuiteIds, config, options); diff --git a/v-next/hardhat/src/internal/builtin-plugins/solidity/config.ts b/v-next/hardhat/src/internal/builtin-plugins/solidity/config.ts index 61f4991a48e..e1040a30cea 100644 --- a/v-next/hardhat/src/internal/builtin-plugins/solidity/config.ts +++ b/v-next/hardhat/src/internal/builtin-plugins/solidity/config.ts @@ -12,6 +12,7 @@ import { resolveFromRoot } from "@ignored/hardhat-vnext-utils/path"; import { conditionalUnionType, incompatibleFieldType, + unionType, validateUserConfigZodType, } from "@ignored/hardhat-vnext-zod-utils"; import { z } from "zod"; @@ -35,7 +36,67 @@ const solcUserConfigType = z.object({ }); const solidityTestUserConfigType = z.object({ + // RunOptions timeout: z.number().optional(), + // Omit + fsPermissions: z.array(z.object({ + access: z.enum(["ReadWrite", "Read", "Write"]), + path: z.string(), + })).optional(), + trace: z.boolean().optional(), + testFail: z.boolean().optional(), + labels: z.array(z.object({ + address: z.instanceof(Buffer), + label: z.string(), + })).optional(), + isolate: z.boolean().optional(), + ffi: z.boolean().optional(), + sender: z.instanceof(Buffer).optional(), + txOrigin: z.instanceof(Buffer).optional(), + initialBalance: z.bigint().optional(), + blockBaseFeePerGas: z.bigint().optional(), + blockCoinbase: z.instanceof(Buffer).optional(), + blockTimestamp: z.bigint().optional(), + blockDifficulty: z.bigint().optional(), + blockGasLimit: z.bigint().optional(), + disableBlockGasLimit: z.boolean().optional(), + memoryLimit: z.bigint().optional(), + ethRpcUrl: z.string().optional(), + forkBlockNumber: z.number().optional(), + rpcEndpoints: z.record(z.string()).optional(), + rpcCachePath: z.string().optional(), + rpcStorageCaching: z.object({ + chains: unionType([ + z.array(z.string()), + z.enum(["All", "None"]), + ], ""), + endpoints: unionType([ + z.string(), + z.enum(["All", "Remote"]), + ], ""), + }).optional(), + promptTimeout: z.number().optional(), + fuzz: z.object({ + failurePersistDir: z.string().optional(), + failurePersistFile: z.string().optional(), + runs: z.number().optional(), + maxTestRejects: z.number().optional(), + seed: z.string().optional(), + dictionaryWeight: z.number().optional(), + includeStorage: z.boolean().optional(), + includePushBytes: z.boolean().optional(), + }).optional(), + invariant: z.object({ + failurePersistDir: z.string().optional(), + runs: z.number().optional(), + depth: z.number().optional(), + failOnRevert: z.boolean().optional(), + callOverride: z.boolean().optional(), + dictionaryWeight: z.number().optional(), + includeStorage: z.boolean().optional(), + includePushBytes: z.boolean().optional(), + shrinkRunLimit: z.number().optional(), + }).optional(), }); const singleVersionSolcUserConfigType = solcUserConfigType.extend({ diff --git a/v-next/hardhat/src/internal/builtin-plugins/solidity/type-extensions.ts b/v-next/hardhat/src/internal/builtin-plugins/solidity/type-extensions.ts index 209501cad5c..84b7f07e7f6 100644 --- a/v-next/hardhat/src/internal/builtin-plugins/solidity/type-extensions.ts +++ b/v-next/hardhat/src/internal/builtin-plugins/solidity/type-extensions.ts @@ -13,7 +13,8 @@ declare module "../../../types/config.js" { settings?: any; } - export type SolidityTestUserConfig = RunOptions; + export type SolidityTestUserConfig = RunOptions & + Omit; export interface SingleVersionSolcUserConfig extends SolcUserConfig { test?: SolidityTestUserConfig; @@ -55,7 +56,8 @@ declare module "../../../types/config.js" { settings: any; } - export type SolidityTestConfig = RunOptions; + export type SolidityTestConfig = RunOptions & + Omit; export interface SolidityBuildProfileConfig { compilers: SolcConfig[]; @@ -85,6 +87,7 @@ declare module "../../../types/config.js" { import "../../../types/hre.js"; import type { SolidityBuildSystem } from "../../../types/solidity/build-system.js"; import type { RunOptions } from "../solidity-test/types.js"; +import type { SolidityTestRunnerConfigArgs } from "@ignored/edr"; declare module "../../../types/hre.js" { export interface HardhatRuntimeEnvironment {