145 lines
7.8 KiB
TypeScript
145 lines
7.8 KiB
TypeScript
import { afterEach, describe, expect, it, mock } from "bun:test";
|
|
import { promises as fs } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
|
|
mock.module("@raycast/api", () => ({ environment: { supportPath: tmpdir() } }));
|
|
const project = await import("../src/lib/velum-project");
|
|
const revision = await import("../src/lib/project-revision");
|
|
const roots: string[] = [];
|
|
afterEach(async () => { await Promise.all(roots.splice(0).map((root) => fs.rm(root, { recursive: true, force: true }))); });
|
|
|
|
describe("Nachbearbeitung von Projektständen", () => {
|
|
it("gibt eine Person frei und führt zwei andere nachträglich zusammen", async () => {
|
|
const root = await fs.mkdtemp(join(tmpdir(), "velum-revision-"));
|
|
roots.push(root);
|
|
const source = join(root, "Quelle");
|
|
const support = join(root, "Raycast");
|
|
await fs.mkdir(source);
|
|
const saved = await project.createRun(source, support);
|
|
saved.run.mapping = {
|
|
PERSON_01: { type: "PERSON", original: "Falsch Positiv" },
|
|
PERSON_02: { type: "PERSON", original: "Franz Fuchs" },
|
|
PERSON_03: { type: "PERSON", original: "Hr. Fuchs" },
|
|
PERSON_04: { type: "PERSON", original: "Franz F." },
|
|
};
|
|
saved.run.files = [{ source: "Bericht.txt", output: "PERSON_01-PERSON_03.txt", kind: "text" }];
|
|
await fs.writeFile(join(saved.directory, "files", "PERSON_01-PERSON_03.txt"),
|
|
"PERSON_01 traf PERSON_02 und PERSON_03. PERSON_04 blieb.");
|
|
await project.saveRun(saved.directory, saved.run);
|
|
const result = await revision.reviseProjectRun({
|
|
previous: saved.run, previousDirectory: saved.directory, support,
|
|
release: new Set(["PERSON_01"]), merges: { PERSON_03: "PERSON_02", PERSON_04: "PERSON_02" },
|
|
rewriteDocument: async () => { throw new Error("Unerwartetes Office-Dokument"); },
|
|
});
|
|
expect(result.run.files[0].output).toBe("Falsch Positiv-PERSON_02.txt");
|
|
expect(await fs.readFile(join(result.directory, "files", result.run.files[0].output), "utf8"))
|
|
.toBe("Falsch Positiv traf PERSON_02 und PERSON_02. PERSON_02 blieb.");
|
|
expect(result.run.mapping.PERSON_03.merged_into).toBe("PERSON_02");
|
|
expect(result.run.mapping.PERSON_04.merged_into).toBe("PERSON_02");
|
|
expect(result.run.mapping.PERSON_01).toBeUndefined();
|
|
expect(await project.loadProjectWhitelist(source, support))
|
|
.toEqual([{ type: "PERSON", original: "Falsch Positiv" }]);
|
|
expect(await fs.readFile(join(saved.directory, "files", "PERSON_01-PERSON_03.txt"), "utf8"))
|
|
.toContain("PERSON_03");
|
|
});
|
|
|
|
it("gibt eine konsolidierte Person samt Varianten frei", () => {
|
|
const plan = revision.planProjectRevision({
|
|
PERSON_01: { type: "PERSON", original: "Franz Fuchs" },
|
|
PERSON_02: { type: "PERSON", original: "Franz F.", merged_into: "PERSON_01" },
|
|
PERSON_03: { type: "PERSON", original: "Hr. Fuchs", merged_into: "PERSON_01" },
|
|
}, new Set(["PERSON_01"]), {});
|
|
expect(plan.released).toEqual(["PERSON_01", "PERSON_02", "PERSON_03"]);
|
|
expect(plan.whitelist.map((item) => item.original)).toEqual(["Franz Fuchs", "Franz F.", "Hr. Fuchs"]);
|
|
expect(plan.mapping).toEqual({});
|
|
});
|
|
|
|
it("ersetzt einen vorhandenen Projektordner nur, wenn er noch dem letzten Stand entspricht", async () => {
|
|
const root = await fs.mkdtemp(join(tmpdir(), "velum-revision-place-"));
|
|
roots.push(root);
|
|
const source = join(root, "Quelle");
|
|
const support = join(root, "Raycast");
|
|
await fs.mkdir(source);
|
|
const saved = await project.createRun(source, support);
|
|
saved.run.mapping = { PERSON_01: { type: "PERSON", original: "Falscher Treffer" } };
|
|
saved.run.files = [{ source: "Notiz.txt", output: "PERSON_01.txt", kind: "text" }];
|
|
saved.run.inPlace = true;
|
|
await fs.writeFile(join(saved.directory, "files", "PERSON_01.txt"), "PERSON_01");
|
|
await fs.writeFile(join(source, "PERSON_01.txt"), "PERSON_01");
|
|
await project.saveRun(saved.directory, saved.run);
|
|
await fs.writeFile(join(source, "PERSON_01.txt"), "PERSON_01 mit lokaler Änderung");
|
|
await expect(revision.reviseProjectRun({ previous: saved.run, previousDirectory: saved.directory,
|
|
release: new Set(["PERSON_01"]), merges: {}, support,
|
|
rewriteDocument: async () => { throw new Error("Unerwartetes Office-Dokument"); },
|
|
})).rejects.toThrow("seit dem letzten Stand geändert");
|
|
expect((await project.listRuns(source, support)).length).toBe(1);
|
|
expect(await fs.readFile(join(source, "PERSON_01.txt"), "utf8"))
|
|
.toBe("PERSON_01 mit lokaler Änderung");
|
|
await fs.writeFile(join(source, "PERSON_01.txt"), "PERSON_01");
|
|
const result = await revision.reviseProjectRun({ previous: saved.run, previousDirectory: saved.directory,
|
|
release: new Set(["PERSON_01"]), merges: {}, support,
|
|
rewriteDocument: async () => { throw new Error("Unerwartetes Office-Dokument"); },
|
|
});
|
|
expect(await fs.readFile(join(source, "Falscher Treffer.txt"), "utf8")).toBe("Falscher Treffer");
|
|
expect(await fs.readFile(join(result.directory, "backup", "PERSON_01.txt"), "utf8")).toBe("PERSON_01");
|
|
});
|
|
|
|
it("übergibt Office-Dateien mit einer gezielten Ersetzung an die Dokumentfunktion", async () => {
|
|
const root = await fs.mkdtemp(join(tmpdir(), "velum-revision-doc-"));
|
|
roots.push(root);
|
|
const source = join(root, "Quelle");
|
|
const support = join(root, "Raycast");
|
|
await fs.mkdir(source);
|
|
const saved = await project.createRun(source, support);
|
|
saved.run.mapping = {
|
|
PERSON_01: { type: "PERSON", original: "Falscher Treffer" },
|
|
PERSON_02: { type: "PERSON", original: "Echte Person" },
|
|
};
|
|
saved.run.files = [{ source: "Bericht.docx", output: "Bericht.docx", kind: "document" }];
|
|
await fs.writeFile(join(saved.directory, "files", "Bericht.docx"), "synthetic office bytes");
|
|
await project.saveRun(saved.directory, saved.run);
|
|
let called = false;
|
|
const result = await revision.reviseProjectRun({ previous: saved.run, previousDirectory: saved.directory,
|
|
release: new Set(["PERSON_01"]), merges: {}, support,
|
|
rewriteDocument: async (filename, data, mapping) => {
|
|
called = true;
|
|
expect(filename).toBe("Bericht.docx");
|
|
expect(data.toString()).toBe("synthetic office bytes");
|
|
expect(Object.keys(mapping)).toEqual(["PERSON_01"]);
|
|
return Buffer.from("changed office bytes");
|
|
},
|
|
});
|
|
expect(called).toBe(true);
|
|
expect(await fs.readFile(join(result.directory, "files", "Bericht.docx"), "utf8"))
|
|
.toBe("changed office bytes");
|
|
});
|
|
|
|
it("schützt längere importierte Platzhalter beim Freigeben eines Präfixes", async () => {
|
|
const root = await fs.mkdtemp(join(tmpdir(), "velum-revision-prefix-"));
|
|
roots.push(root);
|
|
const source = join(root, "Quelle");
|
|
const support = join(root, "Raycast");
|
|
await fs.mkdir(source);
|
|
const saved = await project.createRun(source, support);
|
|
saved.run.origin = "imported";
|
|
saved.run.mapping = {
|
|
BEGRIFF_100001: { type: "BEGRIFF", original: "Alpha" },
|
|
BEGRIFF_1000012: { type: "BEGRIFF", original: "Beta" },
|
|
};
|
|
saved.run.matchModes = { BEGRIFF_100001: "anywhere", BEGRIFF_1000012: "anywhere" };
|
|
saved.run.files = [{ source: "Code.txt", output: "BEGRIFF_1000012.txt", kind: "text" }];
|
|
await fs.writeFile(join(saved.directory, "files", "BEGRIFF_1000012.txt"),
|
|
"xBEGRIFF_1000012 und xBEGRIFF_100001");
|
|
await project.saveRun(saved.directory, saved.run);
|
|
const result = await revision.reviseProjectRun({ previous: saved.run, previousDirectory: saved.directory,
|
|
release: new Set(["BEGRIFF_100001"]), merges: {}, support,
|
|
rewriteDocument: async () => { throw new Error("Unerwartetes Office-Dokument"); },
|
|
});
|
|
expect(result.run.origin).toBe("imported");
|
|
expect(result.run.files[0].output).toBe("BEGRIFF_1000012.txt");
|
|
expect(await fs.readFile(join(result.directory, "files", result.run.files[0].output), "utf8"))
|
|
.toBe("xBEGRIFF_1000012 und xAlpha");
|
|
});
|
|
});
|