@warpgogol/forge 2.8.1 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,94 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { runNoteOrphanDetect } from "../note-orphan-detect.ts";
3
+ import { join } from "node:path";
4
+ import { mkdtemp, rm, mkdir, writeFile } from "node:fs/promises";
5
+ import { tmpdir } from "node:os";
6
+
7
+ let tempDir: string;
8
+
9
+ beforeEach(async () => {
10
+ tempDir = await mkdtemp(join(tmpdir(), "forge-orphan-"));
11
+ });
12
+
13
+ afterEach(async () => {
14
+ await rm(tempDir, { recursive: true, force: true });
15
+ });
16
+
17
+ async function createVaultFile(vaultDir: string, relPath: string, content: string) {
18
+ const fullPath = join(vaultDir, relPath);
19
+ const dir = join(fullPath, "..");
20
+ await mkdir(dir, { recursive: true });
21
+ await writeFile(fullPath, content, "utf8");
22
+ }
23
+
24
+ describe("runNoteOrphanDetect", () => {
25
+ it("returns empty when vault directory not found", () => {
26
+ const result = runNoteOrphanDetect(
27
+ { flags: { "vault-dir": "nonexistent" } },
28
+ { workspaceRoot: tempDir },
29
+ );
30
+ expect(result.data?.count).toBe(0);
31
+ expect(result.data?.orphans).toEqual([]);
32
+ expect(result.exitCode).toBe(0);
33
+ });
34
+
35
+ it("detects orphan note with zero inbound links", async () => {
36
+ const vaultDir = join(tempDir, "vault");
37
+ await mkdir(vaultDir, { recursive: true });
38
+ await createVaultFile(vaultDir, "linked.md", "# Linked\n\n[[target]]");
39
+ await createVaultFile(vaultDir, "target.md", "# Target");
40
+ await createVaultFile(vaultDir, "orphan.md", "# Orphan — nobody links to me");
41
+
42
+ const result = runNoteOrphanDetect(
43
+ { flags: { "vault-dir": "vault" } },
44
+ { workspaceRoot: tempDir },
45
+ );
46
+
47
+ const orphanFiles = result.data?.orphans.map((o) => o.file) ?? [];
48
+ expect(orphanFiles).toContain("vault/orphan.md");
49
+ expect(orphanFiles).not.toContain("vault/target.md");
50
+ });
51
+
52
+ it("does not flag notes that are linked via alias", async () => {
53
+ const vaultDir = join(tempDir, "vault");
54
+ await mkdir(vaultDir, { recursive: true });
55
+ await createVaultFile(vaultDir, "note.md", "---\naliases: [MyAlias]\n---\n# Note");
56
+ await createVaultFile(vaultDir, "linker.md", "# Linker\n\n[[MyAlias]]");
57
+
58
+ const result = runNoteOrphanDetect(
59
+ { flags: { "vault-dir": "vault" } },
60
+ { workspaceRoot: tempDir },
61
+ );
62
+
63
+ const orphanFiles = result.data?.orphans.map((o) => o.file) ?? [];
64
+ expect(orphanFiles).not.toContain("note.md");
65
+ });
66
+
67
+ it("counts self-links correctly (self-link does not count as inbound)", async () => {
68
+ const vaultDir = join(tempDir, "vault");
69
+ await mkdir(vaultDir, { recursive: true });
70
+ await createVaultFile(vaultDir, "self.md", "# Self\n\n[[self]]");
71
+
72
+ const result = runNoteOrphanDetect(
73
+ { flags: { "vault-dir": "vault" } },
74
+ { workspaceRoot: tempDir },
75
+ );
76
+
77
+ const orphanFiles = result.data?.orphans.map((o) => o.file) ?? [];
78
+ expect(orphanFiles).toContain("vault/self.md");
79
+ });
80
+
81
+ it("always returns exitCode 0 (warnings, not errors)", async () => {
82
+ const vaultDir = join(tempDir, "vault");
83
+ await mkdir(vaultDir, { recursive: true });
84
+ await createVaultFile(vaultDir, "orphan.md", "# Orphan");
85
+
86
+ const result = runNoteOrphanDetect(
87
+ { flags: { "vault-dir": "vault" } },
88
+ { workspaceRoot: tempDir },
89
+ );
90
+
91
+ expect(result.exitCode).toBe(0);
92
+ expect(result.data?.count).toBeGreaterThan(0);
93
+ });
94
+ });