test: lock V8 coverage counter semantics

This commit is contained in:
DongHyeonka
2026-08-02 10:12:34 +09:00
parent 5cc6b8a51c
commit 76bf9f1aa3
18 changed files with 826 additions and 4 deletions
+83
View File
@@ -1,3 +1,4 @@
import { execFile } from "node:child_process";
import { constants } from "node:fs";
import {
mkdir,
@@ -10,6 +11,7 @@ import {
} from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { promisify } from "node:util";
import { afterEach, describe, expect, it } from "vitest";
@@ -24,6 +26,7 @@ import {
const roots: string[] = [];
const now = Date.parse("2026-08-02T00:00:00.000Z");
const execFileAsync = promisify(execFile);
function counter(total = 1, covered = total, skipped = 0) {
return {
@@ -174,6 +177,86 @@ describe("repository-aware risk coverage", () => {
});
});
it("publishes artifact schema version 3 with exact counter-bearing fields", async () => {
const repositoryRoot = await mkdtemp(path.join(tmpdir(), "risk-coverage-cli-"));
roots.push(repositoryRoot);
const rawPolicy = JSON.parse(
await readFile("config/testing/risk-coverage.json", "utf8"),
) as Record<string, unknown>;
const modulePaths = rawPolicy.highRiskPaths as string[];
const cliPolicy = {
...rawPolicy,
repositoryBaseline: modulePaths.length,
};
await Promise.all([
mkdir(path.join(repositoryRoot, "config/testing"), { recursive: true }),
mkdir(path.join(repositoryRoot, "artifacts/tests/coverage"), {
recursive: true,
}),
...modulePaths.map(async (modulePath) => {
const absolutePath = path.join(repositoryRoot, modulePath);
await mkdir(path.dirname(absolutePath), { recursive: true });
await writeFile(absolutePath, "export const covered = true;\n");
}),
]);
const summary = Object.fromEntries([
["total", metrics(modulePaths.length)],
...modulePaths.map((modulePath) => [modulePath, fullMetrics]),
]);
await Promise.all([
writeFile(
path.join(repositoryRoot, "config/testing/policy.json"),
`${JSON.stringify(cliPolicy)}\n`,
),
writeFile(
path.join(repositoryRoot, "artifacts/tests/coverage/summary.json"),
`${JSON.stringify(summary)}\n`,
),
]);
await execFileAsync(
process.execPath,
[
"scripts/check-risk-coverage.ts",
"--repository-root",
repositoryRoot,
"--policy",
"config/testing/policy.json",
"--summary",
"artifacts/tests/coverage/summary.json",
"--artifact",
"artifacts/quality/risk-coverage.json",
],
{
cwd: process.cwd(),
encoding: "utf8",
timeout: 30_000,
maxBuffer: 256 * 1024,
},
);
const artifact = JSON.parse(
await readFile(
path.join(repositoryRoot, "artifacts/quality/risk-coverage.json"),
"utf8",
),
) as Record<string, unknown>;
expect(rawPolicy["schemaVersion"]).toBe(2);
expect(artifact).toMatchObject({
schemaVersion: 3,
policy: "config/testing/policy.json",
summary: "artifacts/tests/coverage/summary.json",
counterBearingTotal: modulePaths.length,
instrumentedCounterBearingTotal: modulePaths.length,
counterlessTotal: 0,
counterlessModules: [],
});
expect(artifact).not.toHaveProperty("executableTotal");
expect(artifact).not.toHaveProperty("instrumentedExecutableTotal");
expect(artifact).not.toHaveProperty("nonExecutableTotal");
expect(artifact).not.toHaveProperty("nonExecutableModules");
});
it("rejects arbitrary coverage paths instead of silently allowing inflation", () => {
const parsedPolicy = parseRiskCoveragePolicy(
policy({ repositoryBaseline: 1, generatedPaths: [] }),