-
Notifications
You must be signed in to change notification settings - Fork 65
Expand file tree
/
Copy pathpath-handling.test.ts
More file actions
113 lines (94 loc) · 4.63 KB
/
path-handling.test.ts
File metadata and controls
113 lines (94 loc) · 4.63 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import assert from "node:assert/strict";
import * as path from "node:path";
import { describe, it } from "node:test";
/**
* Tests for cross-platform path handling patterns used throughout the codebase.
* These tests document the correct patterns after fixes were applied.
*
* Fixed locations:
* - chain-execution.ts — uses path.isAbsolute() for absolute path detection
* - settings.ts — uses path.join() for path construction
*/
describe("path.isAbsolute vs startsWith('/')", () => {
// chain-execution.ts:496 uses startsWith("/") to detect absolute paths.
// On Windows, absolute paths look like "C:\\..." or "C:/..." — neither starts with "/".
it("startsWith('/') misses Windows absolute paths", () => {
const windowsAbsolute = "C:\\dev\\pi-subagents\\output.md";
const windowsAbsoluteForward = "C:/dev/pi-subagents/output.md";
// This is what the current code does (chain-execution.ts:496):
assert.equal(windowsAbsolute.startsWith("/"), false,
"Windows backslash absolute path not detected by startsWith('/')");
assert.equal(windowsAbsoluteForward.startsWith("/"), false,
"Windows forward-slash absolute path not detected by startsWith('/')");
// This is what the code SHOULD do:
assert.equal(path.isAbsolute(windowsAbsolute), process.platform === "win32",
"path.isAbsolute correctly identifies Windows paths on Windows");
assert.equal(path.isAbsolute(windowsAbsoluteForward), process.platform === "win32",
"path.isAbsolute correctly identifies forward-slash Windows paths on Windows");
// POSIX paths work with both approaches
assert.equal("/home/user/output.md".startsWith("/"), true);
assert.equal(path.isAbsolute("/home/user/output.md"), true);
});
it("path.isAbsolute is the correct cross-platform check", () => {
// Relative paths — both approaches agree
assert.equal(path.isAbsolute("output.md"), false);
assert.equal(path.isAbsolute("subdir/output.md"), false);
assert.equal("output.md".startsWith("/"), false);
// The only platform-safe check for absolute paths is path.isAbsolute()
if (process.platform === "win32") {
// On Windows, these are absolute:
assert.equal(path.isAbsolute("C:\\output.md"), true);
assert.equal(path.isAbsolute("C:/output.md"), true);
assert.equal(path.isAbsolute("\\\\server\\share"), true); // UNC
// But startsWith("/") catches none of them
assert.equal("C:\\output.md".startsWith("/"), false);
assert.equal("C:/output.md".startsWith("/"), false);
}
});
});
describe("path.join vs template string concatenation", () => {
// settings.ts uses `${chainDir}/${file}` in several places.
// This works but produces inconsistent separators on Windows.
it("template concatenation produces forward slashes regardless of platform", () => {
// chain-execution.ts:496 uses startsWith("/") to detect absolute paths.
const chainDir = "C:\\Users\\marc\\temp\\chain-abc";
const file = "progress.md";
// Template string: always forward slash
const templateResult = `${chainDir}/${file}`;
assert.equal(templateResult, "C:\\Users\\marc\\temp\\chain-abc/progress.md",
"template string produces mixed separators");
// path.join: uses platform separator
const joinResult = path.join(chainDir, file);
if (process.platform === "win32") {
assert.equal(joinResult, "C:\\Users\\marc\\temp\\chain-abc\\progress.md",
"path.join uses consistent backslashes on Windows");
}
});
it("resolveChainPath pattern should use path.join for relative paths", () => {
// settings.ts:216: `${chainDir}/${filePath}` for relative paths
const chainDir = "C:\\temp\\chain-runs\\abc123";
const relative = "synthesis.md";
// Current: string concat
const current = `${chainDir}/${relative}`;
// Fixed: path.join
const fixed = path.join(chainDir, relative);
// On Windows these differ:
if (process.platform === "win32") {
assert.notEqual(current, fixed, "concat and path.join produce different results on Windows");
assert.ok(fixed.includes(path.sep), "path.join uses native separator");
}
});
it("parallel subdir naming should use path.join", () => {
// settings.ts:302,306 pattern: `${subdir}/${task.output}`
const subdir = "parallel-0/0-_code-reviewer";
const output = "review.md";
const templateResult = `${subdir}/${output}`;
const joinResult = path.join(subdir, output);
// Both produce forward slashes here (subdir itself uses /).
// But if subdir comes from path.join on Windows, it would have backslashes.
const windowsSubdir = path.join("parallel-0", "0-_code-reviewer");
const windowsJoin = path.join(windowsSubdir, output);
// Consistent: all native separators
assert.equal(windowsJoin, path.join("parallel-0", "0-_code-reviewer", output));
});
});