import { createHash } from "node:crypto"; import { describe, expect, it } from "vitest"; import { DEFAULT_LAYERS, dedup } from "../dedup.js"; describe("dedup", () => { it("keeps the highest-score representative on nodeId collision", () => { const hits = [ { nodeId: "a", score: 0.5, properties: {} }, { nodeId: "a", score: 0.9, properties: {} }, ]; const out = dedup(hits); expect(out).toHaveLength(1); expect(out[0].score).toBe(0.9); }); it("collapses slug collisions across distinct nodeIds", () => { const hits = [ { nodeId: "a", score: 0.9, properties: { slug: "adam-langley" } }, { nodeId: "b", score: 0.6, properties: { slug: "adam-langley" } }, ]; const out = dedup(hits); expect(out.map((h) => h.nodeId)).toEqual(["a"]); }); it("collapses canonicalName collisions case-insensitively, falls back to name", () => { const hits = [ { nodeId: "a", score: 0.9, properties: { canonicalName: "Acme Co" } }, { nodeId: "b", score: 0.6, properties: { name: "acme co" } }, ]; const out = dedup(hits); expect(out.map((h) => h.nodeId)).toEqual(["a"]); }); it("collapses contentHash collisions (compiledTruth wins over content)", () => { const hits = [ { nodeId: "a", score: 0.9, properties: { compiledTruth: "X" } }, { nodeId: "b", score: 0.6, properties: { content: "X" } }, ]; const out = dedup(hits); // hash("X") matches across both → "a" wins by score. expect(out.map((h) => h.nodeId)).toEqual(["a"]); const h = createHash("sha256").update("X").digest("hex").slice(0, 16); expect(h).toBeDefined(); }); it("skips a layer for hits missing its key — no false collision", () => { const hits = [ { nodeId: "a", score: 0.9, properties: {} }, { nodeId: "b", score: 0.6, properties: {} }, ]; const out = dedup(hits); expect(out.map((h) => h.nodeId)).toEqual(["a", "b"]); }); it("honours layer subset", () => { const hits = [ { nodeId: "a", score: 0.9, properties: { slug: "same" } }, { nodeId: "b", score: 0.6, properties: { slug: "same" } }, ]; // nodeId-only dedup keeps both because nodeIds differ. const out = dedup(hits, ["nodeId"]); expect(out).toHaveLength(2); }); it("preserves descending-score order in the output", () => { const hits = [ { nodeId: "a", score: 0.3, properties: {} }, { nodeId: "b", score: 0.9, properties: {} }, { nodeId: "c", score: 0.6, properties: {} }, ]; const out = dedup(hits); expect(out.map((h) => h.score)).toEqual([0.9, 0.6, 0.3]); }); it("exports the default-layers constant for reference", () => { expect(DEFAULT_LAYERS).toEqual([ "nodeId", "slug", "canonicalName", "contentHash", ]); }); });