Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const REES_ANALYZER_NAMES = [
"history",
"docCommentDrift",
"duplication",
"duplicationDelta",
"churnHotspot",
"blameLink",
"approvalIntegrity",
Expand Down
1 change: 1 addition & 0 deletions src/review/enrichment-analyzer-names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const REES_ANALYZER_NAMES = [
"history",
"docCommentDrift",
"duplication",
"duplicationDelta",
"churnHotspot",
"blameLink",
"approvalIntegrity",
Expand Down
33 changes: 33 additions & 0 deletions test/unit/enrichment-analyzers-taxonomy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
buildEnrichmentAnalyzersTaxonomyDocument,
ENRICHMENT_ANALYZERS_URI,
} from "../../src/review/enrichment-analyzers-taxonomy";
import { REES_ANALYZER_NAMES } from "../../src/review/enrichment-analyzer-names";
import { REES_ANALYZER_NAMES as ENGINE_REES_ANALYZER_NAMES } from "../../packages/loopover-engine/src/review/enrichment-analyzer-names";

const metadataPath = join(process.cwd(), "review-enrichment/analyzer-metadata.json");

Expand Down Expand Up @@ -45,3 +47,34 @@ describe("enrichment analyzers taxonomy document", () => {
expect(ENRICHMENT_ANALYZERS_URI).toBe("gittensory://enrichment-analyzers");
});
});

describe("REES_ANALYZER_NAMES stays in sync with analyzer-metadata.json", () => {
const metadataNames = (
JSON.parse(readFileSync(metadataPath, "utf8")) as { analyzers: Array<{ name: string }> }
).analyzers.map((a) => a.name);

it("covers exactly the analyzers the metadata registry defines (no missing, no extra)", () => {
// The canonical name list validates every operator `REES_ANALYZERS` env entry and per-repo
// `.loopover.yml review.enrichment` toggle, so an analyzer present in the metadata registry but absent
// here is silently un-toggleable/un-selectable. Compared as sets against the registry (the source of
// truth) rather than a hardcoded count so a newly-added analyzer can't drift the two apart unnoticed.
expect(new Set(REES_ANALYZER_NAMES)).toEqual(new Set(metadataNames));
});

it("includes duplicationDelta alongside duplication (regression for the one-entry gap)", () => {
expect(REES_ANALYZER_NAMES).toContain("duplication");
expect(REES_ANALYZER_NAMES).toContain("duplicationDelta");
});

it("has no duplicate entries", () => {
expect(new Set(REES_ANALYZER_NAMES).size).toBe(REES_ANALYZER_NAMES.length);
});

it("stays in lockstep with the loopover-engine twin copy (same names, same order)", () => {
// enrichment-analyzer-names.ts is duplicated across the server (`src/`) and the engine package
// (`packages/loopover-engine/src/`) as a leaf module the engine-parity contract keeps byte-identical.
// Assert the two exported lists by value so a name added to one copy but not the other — e.g. the
// duplicationDelta gap this fixes — is caught as a divergence rather than silently drifting.
expect([...ENGINE_REES_ANALYZER_NAMES]).toEqual([...REES_ANALYZER_NAMES]);
});
});