mirror of
https://github.com/morluto/rea.git
synced 2026-11-10 00:36:35 +00:00
* fix(evidence)!: keep one Evidence identity across Windows path case On Windows, an existing caller path now takes its filesystem spelling when that spelling differs from the resolved path by letter case alone. One file spelled `C:\Temp\x.bin`, `c:\temp\x.bin` or `C:\TEMP\X.BIN` produces one `parameters.path`, `normalized_result` path and `evidence_id`, matching the existing separator and `.` folding. `caller_input_path` keeps the input. Links, junctions, `subst` drives, 8.3 short names and paths that do not exist yet keep the caller spelling, so no link is followed and requested output names keep their case. BREAKING CHANGE: Windows Evidence produced from a path spelled in a case other than its filesystem spelling now gets a different `evidence_id`. Fixes #9373 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(entropy): keep Windows casing lookup optional * ci(entropy): select Windows identity verification --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
87 lines
3.1 KiB
TypeScript
87 lines
3.1 KiB
TypeScript
import { expect, it, vi } from "vitest";
|
|
|
|
import { absoluteCallerPath } from "../../../src/filesystem/callerPath.js";
|
|
|
|
it("resolves absolute POSIX paths independently of an unavailable cwd", () => {
|
|
const cwd = vi.spyOn(process, "cwd").mockImplementation(() => {
|
|
throw new Error("working directory was removed");
|
|
});
|
|
try {
|
|
expect(
|
|
absoluteCallerPath("/cache//rea/kuna/.", { platform: "linux" }),
|
|
).toBe("/cache/rea/kuna/");
|
|
expect(
|
|
absoluteCallerPath("sample", { cwd: "/explicit", platform: "linux" }),
|
|
).toBe("/explicit/sample");
|
|
} finally {
|
|
cwd.mockRestore();
|
|
}
|
|
});
|
|
|
|
it("keeps POSIX parent components for the filesystem to resolve", () => {
|
|
const posix = { cwd: "/work", platform: "linux" } as const;
|
|
expect(absoluteCallerPath("link/../sample", posix)).toBe(
|
|
"/work/link/../sample",
|
|
);
|
|
expect(absoluteCallerPath("/abs/link/../sample", posix)).toBe(
|
|
"/abs/link/../sample",
|
|
);
|
|
expect(absoluteCallerPath("../sample", posix)).toBe("/work/../sample");
|
|
});
|
|
|
|
it("removes only POSIX spellings that cannot change the named file", () => {
|
|
const posix = { cwd: "/work/", platform: "darwin" } as const;
|
|
expect(absoluteCallerPath("./module.wasm", posix)).toBe("/work/module.wasm");
|
|
expect(absoluteCallerPath("a//./b", posix)).toBe("/work/a/b");
|
|
expect(absoluteCallerPath("/x/./y", posix)).toBe("/x/y");
|
|
expect(absoluteCallerPath("sample", { ...posix, cwd: "/" })).toBe("/sample");
|
|
expect(absoluteCallerPath("/", posix)).toBe("/");
|
|
// A trailing separator or `.` still requires a directory.
|
|
expect(absoluteCallerPath("sample/", posix)).toBe("/work/sample/");
|
|
expect(absoluteCallerPath("sample/.", posix)).toBe("/work/sample/");
|
|
expect(absoluteCallerPath("a//b//", posix)).toBe("/work/a/b/");
|
|
});
|
|
|
|
it("makes a relative POSIX cwd absolute before appending the path", () => {
|
|
const cwd = vi.spyOn(process, "cwd").mockReturnValue("/work");
|
|
try {
|
|
expect(
|
|
absoluteCallerPath("sample", { cwd: "fixtures/../x", platform: "linux" }),
|
|
).toBe("/work/fixtures/../x/sample");
|
|
} finally {
|
|
cwd.mockRestore();
|
|
}
|
|
});
|
|
|
|
it("uses lexical resolution on Windows, where it is exact", () => {
|
|
const win32 = { cwd: "C:\\work", platform: "win32" } as const;
|
|
expect(absoluteCallerPath("link\\..\\sample", win32)).toBe(
|
|
"C:\\work\\sample",
|
|
);
|
|
expect(absoluteCallerPath("D:\\x\\..\\y", win32)).toBe("D:\\y");
|
|
});
|
|
|
|
it("normalizes separator spellings of absolute Windows paths (#4707)", () => {
|
|
const win32 = { cwd: "C:\\work", platform: "win32" } as const;
|
|
for (const spelling of [
|
|
"C:\\Users\\u\\h.exe",
|
|
"C:/Users/u/h.exe",
|
|
"C:\\\\Users\\\\u\\\\h.exe",
|
|
"C://Users//u//h.exe",
|
|
])
|
|
expect(absoluteCallerPath(spelling, win32)).toBe("C:\\Users\\u\\h.exe");
|
|
});
|
|
|
|
it("keeps unselected Windows share paths lexical", () => {
|
|
expect(
|
|
absoluteCallerPath("\\\\unselected-server\\share\\Source.JS", {
|
|
platform: "win32",
|
|
}),
|
|
).toBe("\\\\unselected-server\\share\\Source.JS");
|
|
expect(
|
|
absoluteCallerPath("C:\\CaseSensitive\\Different.js", {
|
|
platform: "win32",
|
|
}),
|
|
).toBe("C:\\CaseSensitive\\Different.js");
|
|
});
|