-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Expand file tree
/
Copy pathbackupJournal.test.ts
More file actions
88 lines (73 loc) · 2.79 KB
/
Copy pathbackupJournal.test.ts
File metadata and controls
88 lines (73 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import {
existsSync,
mkdirSync,
mkdtempSync,
readdirSync,
readFileSync,
rmSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { backupPathForResponse, snapshotBeforeWrite } from "./backupJournal";
const tempDirs: string[] = [];
afterEach(() => {
for (const dir of tempDirs.splice(0)) {
rmSync(dir, { recursive: true, force: true });
}
});
function createProjectDir(): string {
const projectDir = mkdtempSync(join(tmpdir(), "hf-backup-journal-"));
tempDirs.push(projectDir);
return projectDir;
}
describe("snapshotBeforeWrite", () => {
it("copies the current file bytes before overwrite", () => {
const projectDir = createProjectDir();
mkdirSync(join(projectDir, "compositions"), { recursive: true });
const file = join(projectDir, "compositions", "scene.html");
writeFileSync(file, "before");
const result = snapshotBeforeWrite(projectDir, file);
writeFileSync(file, "after");
expect(result.backupPath && existsSync(result.backupPath)).toBe(true);
expect(readFileSync(result.backupPath!, "utf-8")).toBe("before");
expect(backupPathForResponse(projectDir, result.backupPath)).toMatch(
/^\.hyperframes\/backup\//,
);
});
it("creates backups for zero-byte files", () => {
const projectDir = createProjectDir();
const file = join(projectDir, "empty.html");
writeFileSync(file, "");
const result = snapshotBeforeWrite(projectDir, file);
expect(result.backupPath && existsSync(result.backupPath)).toBe(true);
expect(readFileSync(result.backupPath!, "utf-8")).toBe("");
});
it("prunes older backups for the same file", () => {
const projectDir = createProjectDir();
const file = join(projectDir, "index.html");
writeFileSync(file, "0");
for (let i = 1; i <= 5; i += 1) {
writeFileSync(file, String(i));
snapshotBeforeWrite(projectDir, file, { keepPerFile: 3 });
}
expect(readdirSync(join(projectDir, ".hyperframes", "backup"))).toHaveLength(3);
});
it("does not prune backups for paths with colliding sanitized names", () => {
const projectDir = createProjectDir();
const first = join(projectDir, "My File.html");
const second = join(projectDir, "My_File.html");
writeFileSync(first, "space");
writeFileSync(second, "underscore");
snapshotBeforeWrite(projectDir, first, { keepPerFile: 1 });
snapshotBeforeWrite(projectDir, second, { keepPerFile: 1 });
const backups = readdirSync(join(projectDir, ".hyperframes", "backup"));
expect(backups).toHaveLength(2);
expect(
backups
.map((name) => readFileSync(join(projectDir, ".hyperframes", "backup", name), "utf-8"))
.sort(),
).toEqual(["space", "underscore"]);
});
});