perf: cache guard inventory checks

This commit is contained in:
Peter Steinberger
2026-04-25 10:01:33 +01:00
parent 70b3ba2fed
commit f7d276b842
6 changed files with 124 additions and 89 deletions

View File

@@ -2,14 +2,14 @@ import { describe, expect, it } from "vitest";
import { collectArchitectureSmells, main } from "../scripts/check-architecture-smells.mjs";
import { createCapturedIo } from "./helpers/captured-io.js";
const smellsPromise = collectArchitectureSmells();
describe("architecture smell inventory", () => {
it("produces stable sorted output", async () => {
const first = await collectArchitectureSmells();
const second = await collectArchitectureSmells();
const smells = await smellsPromise;
expect(second).toEqual(first);
expect(
[...first].toSorted(
[...smells].toSorted(
(left, right) =>
left.category.localeCompare(right.category) ||
left.file.localeCompare(right.file) ||
@@ -18,7 +18,7 @@ describe("architecture smell inventory", () => {
left.specifier.localeCompare(right.specifier) ||
left.reason.localeCompare(right.reason),
),
).toEqual(first);
).toEqual(smells);
});
it("script json output matches the collector", async () => {
@@ -27,6 +27,6 @@ describe("architecture smell inventory", () => {
expect(exitCode).toBe(0);
expect(captured.readStderr()).toBe("");
expect(JSON.parse(captured.readStdout())).toEqual(await collectArchitectureSmells());
expect(JSON.parse(captured.readStdout())).toEqual(await smellsPromise);
});
});

View File

@@ -16,14 +16,26 @@ function buildFixtureScope() {
});
}
const fixtureScope = buildFixtureScope();
const publicSurfaceEnvelope = analyzeTopology({
repoRoot,
scope: fixtureScope,
report: "public-surface-usage",
});
const singleOwnerEnvelope = analyzeTopology({
repoRoot,
scope: fixtureScope,
report: "single-owner-shared",
});
const unusedEnvelope = analyzeTopology({
repoRoot,
scope: fixtureScope,
report: "unused-public-surface",
});
describe("ts-topology", () => {
it("collapses canonical symbols exported by multiple public subpaths", () => {
const envelope = analyzeTopology({
repoRoot,
scope: buildFixtureScope(),
report: "public-surface-usage",
});
const sharedThing = envelope.records.find((record) =>
const sharedThing = publicSurfaceEnvelope.records.find((record) =>
record.exportNames.includes("sharedThing"),
);
@@ -38,16 +50,13 @@ describe("ts-topology", () => {
});
it("counts renamed imports, namespace imports, type-only imports, and test-only consumers", () => {
const envelope = analyzeTopology({
repoRoot,
scope: buildFixtureScope(),
report: "public-surface-usage",
});
const aliasedThing = envelope.records.find((record) =>
const aliasedThing = publicSurfaceEnvelope.records.find((record) =>
record.exportNames.includes("aliasedThing"),
);
const sharedType = envelope.records.find((record) => record.exportNames.includes("SharedType"));
const testOnlyThing = envelope.records.find((record) =>
const sharedType = publicSurfaceEnvelope.records.find((record) =>
record.exportNames.includes("SharedType"),
);
const testOnlyThing = publicSurfaceEnvelope.records.find((record) =>
record.exportNames.includes("testOnlyThing"),
);
@@ -65,33 +74,17 @@ describe("ts-topology", () => {
});
it("surfaces single-owner shared and unused reports correctly", () => {
const singleOwner = analyzeTopology({
repoRoot,
scope: buildFixtureScope(),
report: "single-owner-shared",
});
const unused = analyzeTopology({
repoRoot,
scope: buildFixtureScope(),
report: "unused-public-surface",
});
expect(singleOwner.records.map((record) => record.exportNames[0])).toContain(
expect(singleOwnerEnvelope.records.map((record) => record.exportNames[0])).toContain(
"singleOwnerHelper",
);
expect(singleOwner.records.map((record) => record.exportNames[0])).not.toContain("sharedThing");
expect(unused.records.map((record) => record.exportNames[0])).toEqual(["unusedThing"]);
expect(singleOwnerEnvelope.records.map((record) => record.exportNames[0])).not.toContain(
"sharedThing",
);
expect(unusedEnvelope.records.map((record) => record.exportNames[0])).toEqual(["unusedThing"]);
});
it("renders stable text summaries for the public-surface report", () => {
const envelope = analyzeTopology({
repoRoot,
scope: buildFixtureScope(),
report: "public-surface-usage",
limit: 3,
});
expect(renderTextReport(envelope, 3)).toMatchInlineSnapshot(`
expect(renderTextReport({ ...publicSurfaceEnvelope, limit: 3 }, 3)).toMatchInlineSnapshot(`
"Scope: custom
Public exports analyzed: 6
Production-used exports: 4