Files
velum-raycast/tests/project-review.test.ts

93 lines
4.5 KiB
TypeScript

import { expect, it } from "bun:test";
import {
canonicalPerson, filenameScanText, groupReviewHits, makeTextBatches, mappingForSelection, mergePeople,
spansBySegment, withoutPlaceholderHits, withoutWhitelistedHits, withoutWhitelistedRules,
} from "../src/lib/project-review";
it("liest Unterstriche in Namen als Leerzeichen und bewahrt bekannte Codebegriffe", () => {
expect(filenameScanText("Max_Mustermann_Abgabe", []))
.toBe("Max Mustermann Abgabe");
expect(filenameScanText("Max_Mustermann_KundenSuite_X", ["KundenSuite_X"]))
.toBe("Max Mustermann KundenSuite_X");
expect(filenameScanText("😀_Max_Mustermann", []))
.toBe("😀 Max Mustermann");
expect(filenameScanText("PERSON_01_Max_Mustermann", ["PERSON_01"]))
.toBe("PERSON_01 Max Mustermann");
});
it("ordnet gebündelte API-Treffer nach Unicode-Positionen den richtigen Dateien zu", () => {
const [batch] = makeTextBatches([
{ key: "eins.txt", text: "😀 Max" },
{ key: "zwei.txt", text: "Max und Max" },
]);
expect(batch.segments).toHaveLength(2);
const second = batch.segments[1];
const spans = spansBySegment(batch, [
{ start: 2, end: 5, original: "Max" },
{ start: second.start, end: second.start + 3, original: "Max" },
{ start: batch.segments[0].end, end: second.start + 1, original: "Grenztreffer" },
]);
expect(spans.get("eins.txt")).toEqual([{ start: 2, end: 5, original: "Max" }]);
expect(spans.get("zwei.txt")).toEqual([{ start: 0, end: 3, original: "Max" }]);
expect(makeTextBatches([{ key: "a", text: "abc" }, { key: "b", text: "def" }], 5)).toHaveLength(2);
});
it("zeigt gleiche Zuordnungen einmal mit der Anzahl ihrer Vorkommen", () => {
const hits = [
{ id: "a", type: "PERSON", original: "Max", placeholder: "PERSON_01", file: "a.txt" },
{ id: "b", type: "PERSON", original: "Max", placeholder: "PERSON_01", file: "b.txt" },
{ id: "c", type: "PERSON", original: "Max", placeholder: "PERSON_02", file: "c.txt" },
{ id: "d", type: "ORT", original: "Max", placeholder: "ORT_01", file: "a.txt" },
];
const groups = groupReviewHits(hits);
expect(groups).toHaveLength(3);
expect(groups.find((group) => group.placeholder === "PERSON_01")?.hits).toHaveLength(2);
expect(groups.find((group) => group.placeholder === "PERSON_01")?.hits.map((hit) => hit.id)).toEqual(["a", "b"]);
});
it("unterdrückt projektweit nur exakt abgewählte Begriffe samt erzwungener Regel", () => {
const whitelist = [{ type: "PERSON", original: " Max Muster " }];
const hits = [
{ id: "1", type: "PERSON", original: "max muster", placeholder: "PERSON_01" },
{ id: "2", type: "ORG", original: "Max Muster", placeholder: "ORG_01" },
{ id: "3", type: "PERSON", original: "Max Mustermann", placeholder: "PERSON_02" },
];
expect(withoutWhitelistedHits(hits, whitelist).map((hit) => hit.id)).toEqual(["2", "3"]);
expect(withoutWhitelistedRules([
{ type: "PERSON", value: "Max Muster" }, { type: "ORG", value: "Max Muster" },
], whitelist)).toEqual([{ type: "ORG", value: "Max Muster" }]);
});
it("zeigt beim erneuten Lauf keine Treffer, die einen bestehenden Platzhalter einschließen", () => {
const hits = [
{ type: "PERSON", original: "PERSON_39, Roman" },
{ type: "KUNDE", original: "KUNDE_100005" },
{ type: "PERSON", original: "Roman" },
{ type: "PERSON", original: "Anlage44" },
{ type: "PASSWORT", original: "ORT_08!" },
];
expect(withoutPlaceholderHits(hits)).toEqual(hits.slice(2));
});
it("fasst ausgewählte Personen zu einem kanonischen Platzhalter zusammen und bewahrt alte Zuordnungen", () => {
let merges = mergePeople({}, "PERSON_02", "PERSON_01");
merges = mergePeople(merges, "PERSON_03", "PERSON_02");
expect(canonicalPerson("PERSON_03", merges)).toBe("PERSON_01");
const previous = { PERSON_09: { original: "Alt", type: "PERSON" } };
const preview = {
...previous,
PERSON_01: { original: "Franz Fuchs", type: "PERSON" },
PERSON_02: { original: "Franz", type: "PERSON" },
PERSON_03: { original: "Hr. Fuchs", type: "PERSON" },
PERSON_04: { original: "Fehlalarm", type: "PERSON" },
};
const accepted = ["PERSON_01", "PERSON_02", "PERSON_03"].map((placeholder) => ({
id: placeholder, type: "PERSON", original: preview[placeholder as keyof typeof preview].original, placeholder,
}));
const mapping = mappingForSelection(preview, previous, accepted, merges);
expect(mapping.PERSON_02.merged_into).toBe("PERSON_01");
expect(mapping.PERSON_03.merged_into).toBe("PERSON_01");
expect(mapping.PERSON_09.original).toBe("Alt");
expect(mapping.PERSON_04).toBeUndefined();
});