Files
HealthLog/src/__tests__/linear-fit-single-implementation-guard.test.ts
T
Marc-André Bombeck c0d387025d test(guards): strip comments the way the compiler reads them, in every guard
Forty-two guard files carried their own comment stripper, block comments
first in one non-greedy pass, so a /* inside a line comment opened a
block that hid the code after it, and the stricter copies hid code
behind a /* inside a string, which every e2e route glob has. They all
read through the shared stripComments now, and it scans the way the
parser does: strings, template literals and regular expressions keep
every character, a comment inside a template expression goes, and line
numbers are kept. A parity test strips every source file both ways,
with the scanner and with the TypeScript parser, and fails on the first
that differs.

No guard reports anything new. Each one fails when the stripper returns
nothing; three of them passed on an empty file and assert that the code
they ban is read at all now.
2026-10-23 18:09:10 +02:00

79 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Structural guard: a least-squares line is fitted in `lib/stats/linear-fit`.
*
* Six readers fitted one by hand, four with the determinant form
* `n·Σxy − Σx·Σy` and two with centred sums, and two charts carried the same
* function twice. The matcher flags either form of the slope outside the
* implementation. Comments are stripped first; the planted cases prove the
* matcher fires.
*/
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import {
readSource,
readSourceText,
stripComments,
walkSourceFiles,
} from "./helpers/source-files";
const SRC = join(process.cwd(), "src");
const ALLOWED: Record<string, string> = {
"lib/stats/linear-fit.ts": "The implementation.",
};
const HAND_ROLLED_SLOPE =
/\bn\s*\*\s*sum_?xy\s*-\s*sum_?x\s*\*\s*sum_?y\b|\bsxy\s*\/\s*sxx\b|\bsumXy\s*-\s*\(\s*sumX\s*\*\s*sumY\s*\)\s*\/\s*n\b/i;
describe("one least-squares line", () => {
it("the matcher fires on a hand-rolled slope", () => {
expect(
HAND_ROLLED_SLOPE.test(
"const slope = (n * sumXY - sumX * sumY) / denominator;",
),
).toBe(true);
expect(HAND_ROLLED_SLOPE.test("const slope = sxy / sxx;")).toBe(true);
expect(
HAND_ROLLED_SLOPE.test("const sxy = sumXy - (sumX * sumY) / n;"),
).toBe(true);
expect(HAND_ROLLED_SLOPE.test("const fit = linearFit(xs, ys);")).toBe(
false,
);
});
it("no file outside the implementation fits its own", () => {
const files = walkSourceFiles(SRC, { floor: 3000 }).filter(
(file) =>
!file.startsWith("generated/") &&
!file.includes("__tests__/") &&
!/\.test\.tsx?$/.test(file),
);
const offenders = files.filter(
(file) =>
!(file in ALLOWED) &&
HAND_ROLLED_SLOPE.test(stripComments(readSourceText(join(SRC, file)))),
);
expect(offenders).toEqual([]);
// The six readers now call the implementation: a sweep that finds fewer
// call sites read the wrong tree or lost one.
const callers = files.filter((file) =>
/\b(?:linearFit|fitFromSums|trendLineByTime)\s*\(/.test(
stripComments(readSourceText(join(SRC, file))),
),
);
expect(callers.length).toBeGreaterThanOrEqual(7);
// The implementation itself matches, so the sweep read real files.
expect(
HAND_ROLLED_SLOPE.test(
stripComments(
readSource(
"src/lib/stats/linear-fit.ts",
"export function linearFit",
),
),
),
).toBe(true);
});
});