From 0b00cc1c896c76e9f1a8b16b870f3458d7577f1b Mon Sep 17 00:00:00 2001
From: galargh <piotr.galar@gmail.com>
Date: Tue, 15 Oct 2024 20:10:33 +0200
Subject: [PATCH 1/2] feat: enhance the solidity test artifacts discovery

---
 pnpm-lock.yaml                                | 15 +++
 v-next/hardhat/package.json                   |  1 +
 .../builtin-plugins/solidity-test/helpers.ts  | 91 +++++++++++++++--
 .../solidity-test/task-action.ts              | 25 +++--
 .../builtin-plugins/solidity-test/helpers.ts  | 98 +++++++++++++++++++
 .../solidity-test/test-fixtures/Test.t.sol    | 43 ++++++++
 6 files changed, 251 insertions(+), 22 deletions(-)
 create mode 100644 v-next/hardhat/test/internal/builtin-plugins/solidity-test/helpers.ts
 create mode 100644 v-next/hardhat/test/internal/builtin-plugins/solidity-test/test-fixtures/Test.t.sol

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a06dd0527f..35cf8bca49 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1479,6 +1479,9 @@ importers:
       '@ignored/hardhat-vnext-zod-utils':
         specifier: workspace:^3.0.0-next.3
         version: link:../hardhat-zod-utils
+      '@nomicfoundation/slang':
+        specifier: ^0.18.2
+        version: 0.18.2
       '@nomicfoundation/solidity-analyzer':
         specifier: ^0.1.0
         version: 0.1.2
@@ -2578,6 +2581,9 @@ packages:
   '@bcoe/v8-coverage@0.2.3':
     resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
 
+  '@bytecodealliance/preview2-shim@0.17.0':
+    resolution: {integrity: sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ==}
+
   '@changesets/apply-release-plan@7.0.5':
     resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==}
 
@@ -3184,6 +3190,9 @@ packages:
   '@nomicfoundation/ignition-ui@0.15.5':
     resolution: {integrity: sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==}
 
+  '@nomicfoundation/slang@0.18.2':
+    resolution: {integrity: sha512-xcas+KrKP5O2YM/Stn+ifco2ztZ/ZUu5fMMbyH/0miEyT+1wQVGVgfy/Y7u++JSJCQM7ZGqbGcajjAOCs9gALQ==}
+
   '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2':
     resolution: {integrity: sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==}
     engines: {node: '>= 12'}
@@ -6991,6 +7000,8 @@ snapshots:
 
   '@bcoe/v8-coverage@0.2.3': {}
 
+  '@bytecodealliance/preview2-shim@0.17.0': {}
+
   '@changesets/apply-release-plan@7.0.5':
     dependencies:
       '@changesets/config': 3.0.3
@@ -7868,6 +7879,10 @@ snapshots:
 
   '@nomicfoundation/ignition-ui@0.15.5': {}
 
+  '@nomicfoundation/slang@0.18.2':
+    dependencies:
+      '@bytecodealliance/preview2-shim': 0.17.0
+
   '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2':
     optional: true
 
diff --git a/v-next/hardhat/package.json b/v-next/hardhat/package.json
index 0f92917e58..00835a77fa 100644
--- a/v-next/hardhat/package.json
+++ b/v-next/hardhat/package.json
@@ -85,6 +85,7 @@
     "@ignored/hardhat-vnext-errors": "workspace:^3.0.0-next.3",
     "@ignored/hardhat-vnext-utils": "workspace:^3.0.0-next.3",
     "@ignored/hardhat-vnext-zod-utils": "workspace:^3.0.0-next.3",
+    "@nomicfoundation/slang": "^0.18.2",
     "@nomicfoundation/solidity-analyzer": "^0.1.0",
     "@sentry/node": "^5.18.1",
     "adm-zip": "^0.4.16",
diff --git a/v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts b/v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts
index 391d321417..da610a670c 100644
--- a/v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts
+++ b/v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts
@@ -1,15 +1,17 @@
 import type { ArtifactsManager } from "../../../types/artifacts.js";
-import type { ArtifactId, Artifact } from "@ignored/edr";
+import type { Artifact } from "@ignored/edr";
 
 import { HardhatError } from "@ignored/hardhat-vnext-errors";
+import { exists, readUtf8File } from "@ignored/hardhat-vnext-utils/fs";
+import { resolveFromRoot } from "@ignored/hardhat-vnext-utils/path";
+import { NonterminalKind, TerminalKind } from "@nomicfoundation/slang/cst";
+import { Parser } from "@nomicfoundation/slang/parser";
 
-export async function buildSolidityTestsInput(
+export async function getArtifacts(
   hardhatArtifacts: ArtifactsManager,
-  isTestArtifact: (artifact: Artifact) => boolean = () => true,
-): Promise<{ artifacts: Artifact[]; testSuiteIds: ArtifactId[] }> {
+): Promise<Artifact[]> {
   const fqns = await hardhatArtifacts.getAllFullyQualifiedNames();
   const artifacts: Artifact[] = [];
-  const testSuiteIds: ArtifactId[] = [];
 
   for (const fqn of fqns) {
     const hardhatArtifact = await hardhatArtifacts.readArtifact(fqn);
@@ -38,10 +40,83 @@ export async function buildSolidityTestsInput(
 
     const artifact = { id, contract };
     artifacts.push(artifact);
-    if (isTestArtifact(artifact)) {
-      testSuiteIds.push(artifact.id);
+  }
+
+  return artifacts;
+}
+
+export async function isTestArtifact(
+  root: string,
+  artifact: Artifact,
+): Promise<boolean> {
+  const { name, source, solcVersion } = artifact.id;
+
+  if (!source.endsWith(".t.sol")) {
+    return false;
+  }
+
+  const sourcePath = resolveFromRoot(root, source);
+  const sourceExists = await exists(sourcePath);
+
+  if (!sourceExists) {
+    return false;
+  }
+
+  const content = await readUtf8File(sourcePath);
+  const parser = Parser.create(solcVersion);
+  const cursor = parser
+    .parse(NonterminalKind.SourceUnit, content)
+    .createTreeCursor();
+
+  while (
+    cursor.goToNextNonterminalWithKind(NonterminalKind.ContractDefinition)
+  ) {
+    const nameCursor = cursor.spawn();
+    if (!nameCursor.goToNextTerminalWithKind(TerminalKind.Identifier)) {
+      continue;
+    }
+    if (nameCursor.node.unparse() !== name) {
+      continue;
+    }
+
+    const abstractCursor = cursor.spawn();
+    if (abstractCursor.goToNextTerminalWithKind(TerminalKind.AbstractKeyword)) {
+      return false;
+    }
+
+    const functionCursor = cursor.spawn();
+
+    while (
+      functionCursor.goToNextNonterminalWithKind(
+        NonterminalKind.FunctionDefinition,
+      )
+    ) {
+      const functionNameCursor = functionCursor.spawn();
+      if (
+        !functionNameCursor.goToNextTerminalWithKind(TerminalKind.Identifier)
+      ) {
+        continue;
+      }
+
+      const functionName = functionNameCursor.node.unparse();
+      if (
+        functionName.startsWith("test") ||
+        functionName.startsWith("invariant")
+      ) {
+        const publicCursor = functionCursor.spawn();
+        if (publicCursor.goToNextTerminalWithKind(TerminalKind.PublicKeyword)) {
+          return true;
+        }
+
+        const externalCursor = functionCursor.spawn();
+        if (
+          externalCursor.goToNextTerminalWithKind(TerminalKind.ExternalKeyword)
+        ) {
+          return true;
+        }
+      }
     }
   }
 
-  return { artifacts, testSuiteIds };
+  return false;
 }
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 6e46418401..8265d9fa89 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
@@ -4,7 +4,7 @@ import type { NewTaskActionFunction } from "../../../types/tasks.js";
 
 import { finished } from "node:stream/promises";
 
-import { buildSolidityTestsInput } from "./helpers.js";
+import { getArtifacts, isTestArtifact } from "./helpers.js";
 import { testReporter } from "./reporter.js";
 import { run } from "./runner.js";
 
@@ -13,19 +13,16 @@ const runSolidityTests: NewTaskActionFunction = async ({ timeout }, hre) => {
 
   console.log("\nRunning Solidity tests...\n");
 
-  const { artifacts, testSuiteIds } = await buildSolidityTestsInput(
-    hre.artifacts,
-    (artifact) => {
-      const sourceName = artifact.id.source;
-      const isTestArtifact =
-        sourceName.endsWith(".t.sol") &&
-        sourceName.startsWith("contracts/") &&
-        !sourceName.startsWith("contracts/forge-std/") &&
-        !sourceName.startsWith("contracts/ds-test/");
-
-      return isTestArtifact;
-    },
-  );
+  const artifacts = await getArtifacts(hre.artifacts);
+  const testSuiteIds = (
+    await Promise.all(
+      artifacts.map(async (artifact) => {
+        if (await isTestArtifact(hre.config.paths.root, artifact)) {
+          return artifact.id;
+        }
+      }),
+    )
+  ).filter((artifact) => artifact !== undefined);
 
   const config = {
     projectRoot: hre.config.paths.root,
diff --git a/v-next/hardhat/test/internal/builtin-plugins/solidity-test/helpers.ts b/v-next/hardhat/test/internal/builtin-plugins/solidity-test/helpers.ts
new file mode 100644
index 0000000000..72431ee912
--- /dev/null
+++ b/v-next/hardhat/test/internal/builtin-plugins/solidity-test/helpers.ts
@@ -0,0 +1,98 @@
+import type { Artifact } from "@ignored/edr";
+
+import assert from "node:assert/strict";
+import { describe, it } from "node:test";
+
+import { isTestArtifact } from "../../../../src/internal/builtin-plugins/solidity-test/helpers.js";
+
+const testCases = [
+  {
+    contract: "Abstract",
+    expected: false,
+  },
+  {
+    contract: "NoTest",
+    expected: false,
+  },
+  {
+    contract: "PublicTest",
+    expected: true,
+  },
+  {
+    contract: "ExternalTest",
+    expected: true,
+  },
+  {
+    contract: "PrivateTest",
+    expected: false,
+  },
+  {
+    contract: "InternalTest",
+    expected: false,
+  },
+  {
+    contract: "PublicInvariant",
+    expected: true,
+  },
+  {
+    contract: "ExternalInvariant",
+    expected: true,
+  },
+  {
+    contract: "PrivateInvariant",
+    expected: false,
+  },
+  {
+    contract: "InternalInvariant",
+    expected: false,
+  },
+];
+
+describe("isTestArtifact", () => {
+  for (const { contract, expected } of testCases) {
+    it(`should return ${expected} for the ${contract} contract`, async () => {
+      const artifact: Artifact = {
+        id: {
+          name: contract,
+          source: `test-fixtures/Test.t.sol`,
+          solcVersion: "0.8.20",
+        },
+        contract: {
+          abi: "",
+        },
+      };
+      const actual = await isTestArtifact(import.meta.dirname, artifact);
+      assert.equal(actual, expected);
+    });
+  }
+
+  it("should return false if a file does not exist", async () => {
+    const artifact: Artifact = {
+      id: {
+        name: "Contract",
+        source: `test-fixtures/NonExistent.t.sol`,
+        solcVersion: "0.8.20",
+      },
+      contract: {
+        abi: "",
+      },
+    };
+    const actual = await isTestArtifact(import.meta.dirname, artifact);
+    assert.equal(actual, false);
+  });
+
+  it("should return false if the file has the wrong extension", async () => {
+    const artifact: Artifact = {
+      id: {
+        name: "Contract",
+        source: `test-fixtures/WrongExtension.sol`,
+        solcVersion: "0.8.20",
+      },
+      contract: {
+        abi: "",
+      },
+    };
+    const actual = await isTestArtifact(import.meta.dirname, artifact);
+    assert.equal(actual, false);
+  });
+});
diff --git a/v-next/hardhat/test/internal/builtin-plugins/solidity-test/test-fixtures/Test.t.sol b/v-next/hardhat/test/internal/builtin-plugins/solidity-test/test-fixtures/Test.t.sol
new file mode 100644
index 0000000000..025f6a7e35
--- /dev/null
+++ b/v-next/hardhat/test/internal/builtin-plugins/solidity-test/test-fixtures/Test.t.sol
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.20;
+
+abstract contract Abstract {
+  function testPublic() public {}
+  function testExternal() external {}
+  function invariantPublic() public {}
+  function invariantExternal() external {}
+}
+
+contract NoTest {}
+
+contract PublicTest {
+  function test() public {}
+}
+
+contract ExternalTest {
+  function test() external {}
+}
+
+contract PrivateTest {
+  function test() private {}
+}
+
+contract InternalTest {
+  function test() internal {}
+}
+
+contract PublicInvariant {
+  function invariant() public {}
+}
+
+contract ExternalInvariant {
+  function invariant() external {}
+}
+
+contract PrivateInvariant {
+  function invariant() private {}
+}
+
+contract InternalInvariant {
+  function invariant() internal {}
+}

From 9dd05afc73f37c5ff02b3af81d01261166119d02 Mon Sep 17 00:00:00 2001
From: galargh <piotr.galar@gmail.com>
Date: Wed, 23 Oct 2024 12:16:52 +0100
Subject: [PATCH 2/2] chore: simplify the test artifact discovery filter

---
 pnpm-lock.yaml                                | 49 ++++++--------
 v-next/hardhat/package.json                   |  1 -
 .../builtin-plugins/solidity-test/helpers.ts  | 66 ++-----------------
 .../builtin-plugins/solidity-test/helpers.ts  | 12 ++--
 4 files changed, 30 insertions(+), 98 deletions(-)

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 35cf8bca49..cef55a5aa7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1479,9 +1479,6 @@ importers:
       '@ignored/hardhat-vnext-zod-utils':
         specifier: workspace:^3.0.0-next.3
         version: link:../hardhat-zod-utils
-      '@nomicfoundation/slang':
-        specifier: ^0.18.2
-        version: 0.18.2
       '@nomicfoundation/solidity-analyzer':
         specifier: ^0.1.0
         version: 0.1.2
@@ -1496,7 +1493,7 @@ importers:
         version: 5.3.0
       debug:
         specifier: ^4.1.1
-        version: 4.3.7(supports-color@8.1.1)
+        version: 4.3.7
       enquirer:
         specifier: ^2.3.0
         version: 2.4.1
@@ -2581,9 +2578,6 @@ packages:
   '@bcoe/v8-coverage@0.2.3':
     resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
 
-  '@bytecodealliance/preview2-shim@0.17.0':
-    resolution: {integrity: sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ==}
-
   '@changesets/apply-release-plan@7.0.5':
     resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==}
 
@@ -3190,9 +3184,6 @@ packages:
   '@nomicfoundation/ignition-ui@0.15.5':
     resolution: {integrity: sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==}
 
-  '@nomicfoundation/slang@0.18.2':
-    resolution: {integrity: sha512-xcas+KrKP5O2YM/Stn+ifco2ztZ/ZUu5fMMbyH/0miEyT+1wQVGVgfy/Y7u++JSJCQM7ZGqbGcajjAOCs9gALQ==}
-
   '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2':
     resolution: {integrity: sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==}
     engines: {node: '>= 12'}
@@ -7000,8 +6991,6 @@ snapshots:
 
   '@bcoe/v8-coverage@0.2.3': {}
 
-  '@bytecodealliance/preview2-shim@0.17.0': {}
-
   '@changesets/apply-release-plan@7.0.5':
     dependencies:
       '@changesets/config': 3.0.3
@@ -7238,7 +7227,7 @@ snapshots:
   '@eslint/eslintrc@2.1.4':
     dependencies:
       ajv: 6.12.6
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       espree: 9.6.1
       globals: 13.24.0
       ignore: 5.3.2
@@ -7539,7 +7528,7 @@ snapshots:
   '@humanwhocodes/config-array@0.11.14':
     dependencies:
       '@humanwhocodes/object-schema': 2.0.3
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       minimatch: 3.1.2
     transitivePeerDependencies:
       - supports-color
@@ -7879,10 +7868,6 @@ snapshots:
 
   '@nomicfoundation/ignition-ui@0.15.5': {}
 
-  '@nomicfoundation/slang@0.18.2':
-    dependencies:
-      '@bytecodealliance/preview2-shim': 0.17.0
-
   '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2':
     optional: true
 
@@ -8237,7 +8222,7 @@ snapshots:
       '@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.5.4)
       '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.5.4)
       '@typescript-eslint/visitor-keys': 7.7.1
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       eslint: 8.57.0
       graphemer: 1.4.0
       ignore: 5.3.2
@@ -8267,7 +8252,7 @@ snapshots:
       '@typescript-eslint/types': 7.18.0
       '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
       '@typescript-eslint/visitor-keys': 7.18.0
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       eslint: 8.57.0
     optionalDependencies:
       typescript: 5.5.4
@@ -8280,7 +8265,7 @@ snapshots:
       '@typescript-eslint/types': 7.7.1
       '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.4)
       '@typescript-eslint/visitor-keys': 7.7.1
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       eslint: 8.57.0
     optionalDependencies:
       typescript: 5.5.4
@@ -8323,7 +8308,7 @@ snapshots:
     dependencies:
       '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
       '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4)
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       eslint: 8.57.0
       ts-api-utils: 1.3.0(typescript@5.5.4)
     optionalDependencies:
@@ -8335,7 +8320,7 @@ snapshots:
     dependencies:
       '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.4)
       '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.5.4)
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       eslint: 8.57.0
       ts-api-utils: 1.3.0(typescript@5.5.4)
     optionalDependencies:
@@ -8383,7 +8368,7 @@ snapshots:
     dependencies:
       '@typescript-eslint/types': 7.18.0
       '@typescript-eslint/visitor-keys': 7.18.0
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       globby: 11.1.0
       is-glob: 4.0.3
       minimatch: 9.0.5
@@ -8398,7 +8383,7 @@ snapshots:
     dependencies:
       '@typescript-eslint/types': 7.7.1
       '@typescript-eslint/visitor-keys': 7.7.1
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       globby: 11.1.0
       is-glob: 4.0.3
       minimatch: 9.0.5
@@ -8529,7 +8514,7 @@ snapshots:
 
   agent-base@6.0.2:
     dependencies:
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
     transitivePeerDependencies:
       - supports-color
 
@@ -9079,6 +9064,10 @@ snapshots:
     dependencies:
       ms: 2.1.3
 
+  debug@4.3.7:
+    dependencies:
+      ms: 2.1.3
+
   debug@4.3.7(supports-color@8.1.1):
     dependencies:
       ms: 2.1.3
@@ -9378,7 +9367,7 @@ snapshots:
   eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0):
     dependencies:
       '@nolyfill/is-core-module': 1.0.39
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       enhanced-resolve: 5.17.1
       eslint: 8.57.0
       eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
@@ -9544,7 +9533,7 @@ snapshots:
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.3
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
       doctrine: 3.0.0
       escape-string-regexp: 4.0.0
       eslint-scope: 7.2.2
@@ -9829,7 +9818,7 @@ snapshots:
 
   follow-redirects@1.15.9(debug@4.3.7):
     optionalDependencies:
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
 
   for-each@0.3.3:
     dependencies:
@@ -10142,7 +10131,7 @@ snapshots:
   https-proxy-agent@5.0.1:
     dependencies:
       agent-base: 6.0.2
-      debug: 4.3.7(supports-color@8.1.1)
+      debug: 4.3.7
     transitivePeerDependencies:
       - supports-color
 
diff --git a/v-next/hardhat/package.json b/v-next/hardhat/package.json
index 00835a77fa..0f92917e58 100644
--- a/v-next/hardhat/package.json
+++ b/v-next/hardhat/package.json
@@ -85,7 +85,6 @@
     "@ignored/hardhat-vnext-errors": "workspace:^3.0.0-next.3",
     "@ignored/hardhat-vnext-utils": "workspace:^3.0.0-next.3",
     "@ignored/hardhat-vnext-zod-utils": "workspace:^3.0.0-next.3",
-    "@nomicfoundation/slang": "^0.18.2",
     "@nomicfoundation/solidity-analyzer": "^0.1.0",
     "@sentry/node": "^5.18.1",
     "adm-zip": "^0.4.16",
diff --git a/v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts b/v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts
index da610a670c..a5f71e45ce 100644
--- a/v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts
+++ b/v-next/hardhat/src/internal/builtin-plugins/solidity-test/helpers.ts
@@ -2,10 +2,8 @@ import type { ArtifactsManager } from "../../../types/artifacts.js";
 import type { Artifact } from "@ignored/edr";
 
 import { HardhatError } from "@ignored/hardhat-vnext-errors";
-import { exists, readUtf8File } from "@ignored/hardhat-vnext-utils/fs";
+import { exists } from "@ignored/hardhat-vnext-utils/fs";
 import { resolveFromRoot } from "@ignored/hardhat-vnext-utils/path";
-import { NonterminalKind, TerminalKind } from "@nomicfoundation/slang/cst";
-import { Parser } from "@nomicfoundation/slang/parser";
 
 export async function getArtifacts(
   hardhatArtifacts: ArtifactsManager,
@@ -49,12 +47,14 @@ export async function isTestArtifact(
   root: string,
   artifact: Artifact,
 ): Promise<boolean> {
-  const { name, source, solcVersion } = artifact.id;
+  const { source } = artifact.id;
 
   if (!source.endsWith(".t.sol")) {
     return false;
   }
 
+  // NOTE: We also check whether the file exists in the workspace to filter out
+  // the artifacts from node modules.
   const sourcePath = resolveFromRoot(root, source);
   const sourceExists = await exists(sourcePath);
 
@@ -62,61 +62,5 @@ export async function isTestArtifact(
     return false;
   }
 
-  const content = await readUtf8File(sourcePath);
-  const parser = Parser.create(solcVersion);
-  const cursor = parser
-    .parse(NonterminalKind.SourceUnit, content)
-    .createTreeCursor();
-
-  while (
-    cursor.goToNextNonterminalWithKind(NonterminalKind.ContractDefinition)
-  ) {
-    const nameCursor = cursor.spawn();
-    if (!nameCursor.goToNextTerminalWithKind(TerminalKind.Identifier)) {
-      continue;
-    }
-    if (nameCursor.node.unparse() !== name) {
-      continue;
-    }
-
-    const abstractCursor = cursor.spawn();
-    if (abstractCursor.goToNextTerminalWithKind(TerminalKind.AbstractKeyword)) {
-      return false;
-    }
-
-    const functionCursor = cursor.spawn();
-
-    while (
-      functionCursor.goToNextNonterminalWithKind(
-        NonterminalKind.FunctionDefinition,
-      )
-    ) {
-      const functionNameCursor = functionCursor.spawn();
-      if (
-        !functionNameCursor.goToNextTerminalWithKind(TerminalKind.Identifier)
-      ) {
-        continue;
-      }
-
-      const functionName = functionNameCursor.node.unparse();
-      if (
-        functionName.startsWith("test") ||
-        functionName.startsWith("invariant")
-      ) {
-        const publicCursor = functionCursor.spawn();
-        if (publicCursor.goToNextTerminalWithKind(TerminalKind.PublicKeyword)) {
-          return true;
-        }
-
-        const externalCursor = functionCursor.spawn();
-        if (
-          externalCursor.goToNextTerminalWithKind(TerminalKind.ExternalKeyword)
-        ) {
-          return true;
-        }
-      }
-    }
-  }
-
-  return false;
+  return true;
 }
diff --git a/v-next/hardhat/test/internal/builtin-plugins/solidity-test/helpers.ts b/v-next/hardhat/test/internal/builtin-plugins/solidity-test/helpers.ts
index 72431ee912..245bf895ec 100644
--- a/v-next/hardhat/test/internal/builtin-plugins/solidity-test/helpers.ts
+++ b/v-next/hardhat/test/internal/builtin-plugins/solidity-test/helpers.ts
@@ -8,11 +8,11 @@ import { isTestArtifact } from "../../../../src/internal/builtin-plugins/solidit
 const testCases = [
   {
     contract: "Abstract",
-    expected: false,
+    expected: true,
   },
   {
     contract: "NoTest",
-    expected: false,
+    expected: true,
   },
   {
     contract: "PublicTest",
@@ -24,11 +24,11 @@ const testCases = [
   },
   {
     contract: "PrivateTest",
-    expected: false,
+    expected: true,
   },
   {
     contract: "InternalTest",
-    expected: false,
+    expected: true,
   },
   {
     contract: "PublicInvariant",
@@ -40,11 +40,11 @@ const testCases = [
   },
   {
     contract: "PrivateInvariant",
-    expected: false,
+    expected: true,
   },
   {
     contract: "InternalInvariant",
-    expected: false,
+    expected: true,
   },
 ];