From b07d56c1f4e2758c61fd5206abcea6e9b206e742 Mon Sep 17 00:00:00 2001 From: JUN Date: Wed, 23 Sep 2026 21:28:15 +0900 Subject: [PATCH] test(update): spell expected mise owner paths the way the detector reports them On Windows two update-mise tests failed in a lane=all run (windows 7/9): the detector reports installPath and toolRoot for a drive-letter or UNC path with forward slashes, so the lexical and resolved candidates compare in one spelling, while the fixture built its expectations with native path.join (backslashes). Detection itself was correct: installer, tool, backend and install boundary all matched, and the 8.3 RUNNER~1 prefix was identical on both sides. The fixture now spells its expected owner paths through reportedPath, and a platform-independent test pins the reported spelling for backslash and forward-slash Windows inputs, so a change to it fails on every OS instead of only on the Windows shards. --- tests/update/update-mise.test.ts | 42 +++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/tests/update/update-mise.test.ts b/tests/update/update-mise.test.ts index d3b3a52cce2..a613ed3c9cc 100644 --- a/tests/update/update-mise.test.ts +++ b/tests/update/update-mise.test.ts @@ -24,6 +24,15 @@ const BACKEND = 'short = "ocx-local"\nfull = "npm:@bitkyc08/opencodex"\nexplicit const metadataProbe = (exists: (path: string) => boolean) => (path: string): "present" | "absent" => exists(path) ? "present" : "absent"; +/** + * The detector reports owner paths in one spelling for every candidate: a drive-letter or UNC path + * uses forward slashes (so lexical and resolved candidates compare), POSIX paths are unchanged. + * Expected values built with native path.join must be spelled the same way. + */ +function reportedPath(path: string): string { + return /^[A-Za-z]:[\\/]/.test(path) || path.startsWith("\\\\") ? path.replaceAll("\\", "/") : path; +} + function misePackage(root: string, version = "2.59.0"): string { const toolRoot = join(root, "custom mise data", "installs", "ocx-local"); const packagePath = join( @@ -52,8 +61,8 @@ describe("mise installation ownership", () => { owner: { tool: "ocx-local", backend: "npm:@bitkyc08/opencodex", - installPath: join(root, "custom mise data", "installs", "ocx-local", "2.59.0"), - toolRoot: join(root, "custom mise data", "installs", "ocx-local"), + installPath: reportedPath(join(root, "custom mise data", "installs", "ocx-local", "2.59.0")), + toolRoot: reportedPath(join(root, "custom mise data", "installs", "ocx-local")), }, }); expect(detectInstallFromPath(packagePath)).toBe("mise"); @@ -76,7 +85,7 @@ describe("mise installation ownership", () => { const floating = join(toolRoot, "latest", exact.slice(join(toolRoot, "2.59.0").length + 1)); expect(detectInstallOwnershipFromPath(floating)).toMatchObject({ installer: "mise", - owner: { tool: "ocx-local", installPath: join(toolRoot, "2.59.0") }, + owner: { tool: "ocx-local", installPath: reportedPath(join(toolRoot, "2.59.0")) }, }); } finally { rmSync(root, { recursive: true, force: true }); @@ -101,6 +110,33 @@ describe("mise installation ownership", () => { } }); + test("reports a Windows install in forward-slash spelling whatever the input separators", () => { + const metadata = "C:/Users/RUNNER~1/AppData/Local/mise/installs/ocx-local/.mise.backend.toml"; + const deps = { + exists: () => false, + probe: (path: string) => (path === metadata ? "present" : "absent") as "present" | "absent", + readFile: () => BACKEND, + realpath: (value: string) => value, + }; + const expected = { + installer: "mise", + owner: { + tool: "ocx-local", + backend: "npm:@bitkyc08/opencodex", + installPath: "C:/Users/RUNNER~1/AppData/Local/mise/installs/ocx-local/2.59.0", + toolRoot: "C:/Users/RUNNER~1/AppData/Local/mise/installs/ocx-local", + }, + }; + for (const packagePath of [ + "C:\\Users\\RUNNER~1\\AppData\\Local\\mise\\installs\\ocx-local\\2.59.0\\node_modules\\@bitkyc08\\opencodex\\bin", + "C:/Users/RUNNER~1/AppData/Local/mise/installs/ocx-local/2.59.0/node_modules/@bitkyc08/opencodex/bin", + ]) { + expect(detectInstallOwnershipFromPath(packagePath, deps)).toEqual(expected); + } + expect(reportedPath("C:\\a\\b")).toBe("C:/a/b"); + expect(reportedPath("/tmp/mise\\state")).toBe("/tmp/mise\\state"); + }); + test("does not infer mise ownership from a .mise path or mise on PATH", () => { const path = "/tmp/.mise/node_modules/@bitkyc08/opencodex/bin"; expect(detectInstallOwnershipFromPath(path, {