t3-code-android-nightly/packages/shared/src/path.test.ts
Jono Kemball 12069eefd7
Some checks are pending
CI / Lint (push) Waiting to run
CI / Typecheck (push) Waiting to run
CI / Build (push) Waiting to run
CI / Test (push) Waiting to run
CI / Test Web (push) Waiting to run
CI / Test Server 1 (push) Waiting to run
CI / Test Server 2 (push) Waiting to run
CI / Test Server 3 (push) Waiting to run
CI / Test Server 4 (push) Waiting to run
CI / Test Server 5 (push) Waiting to run
CI / Test Server 6 (push) Waiting to run
CI / Transfer report artifact (push) Blocked by required conditions
CI / Rust (push) Waiting to run
CI / Mobile Native Changes (push) Waiting to run
CI / Mobile Native Static Analysis (push) Blocked by required conditions
CI / Release Smoke (push) Waiting to run
CI / Check (push) Blocked by required conditions
Forward to Cursor hygiene / POST to Cursor (push) Waiting to run
Deploy T3 Connect relay / Deploy production relay (push) Waiting to run
Mobile EAS Production / EAS production (push) Waiting to run
feat(web): find messages and plans in the current thread (#10439)
Co-authored-by: Yash Singh <saiansh2525@gmail.com>
Co-authored-by: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:24:50 -05:00

99 lines
4.3 KiB
TypeScript

import { describe, expect, it } from "vite-plus/test";
import {
fileBasename,
workspaceRelativeFilePath,
isExplicitRelativePath,
isUncPath,
isWindowsAbsolutePath,
isWindowsDrivePath,
newProjectFolderName,
normalizeProjectPathForComparison,
normalizeProjectPathForDispatch,
} from "./path.ts";
describe("path helpers", () => {
it("detects windows drive paths", () => {
expect(isWindowsDrivePath("C:\\repo")).toBe(true);
expect(isWindowsDrivePath("D:/repo")).toBe(true);
expect(isWindowsDrivePath("/repo")).toBe(false);
});
it("detects UNC paths", () => {
expect(isUncPath("\\\\server\\share\\repo")).toBe(true);
expect(isUncPath("C:\\repo")).toBe(false);
});
it("detects windows absolute paths", () => {
expect(isWindowsAbsolutePath("C:\\repo")).toBe(true);
expect(isWindowsAbsolutePath("\\\\server\\share\\repo")).toBe(true);
expect(isWindowsAbsolutePath("./repo")).toBe(false);
});
it("detects explicit relative paths", () => {
expect(isExplicitRelativePath(".")).toBe(true);
expect(isExplicitRelativePath("..")).toBe(true);
expect(isExplicitRelativePath("./repo")).toBe(true);
expect(isExplicitRelativePath("..\\repo")).toBe(true);
expect(isExplicitRelativePath("~/repo")).toBe(false);
});
it("normalizes a bare Windows drive root the same as one with a trailing separator", () => {
// `C:`, `C:\` and `C:/` all refer to the drive root and must compare equal.
expect(normalizeProjectPathForDispatch("C:")).toBe("C:\\");
expect(normalizeProjectPathForComparison("C:")).toBe("c:\\");
expect(normalizeProjectPathForComparison("C:")).toBe(normalizeProjectPathForComparison("C:\\"));
expect(normalizeProjectPathForComparison("C:")).toBe(normalizeProjectPathForComparison("C:/"));
// Non-root drive paths keep their trailing separator trimmed as before.
expect(normalizeProjectPathForDispatch("C:\\repo\\")).toBe("C:\\repo");
});
it("names a new project's folder from any typed name", () => {
expect(newProjectFolderName("Pinball Stats")).toBe("pinball-stats");
expect(newProjectFolderName(" Café & Crème! ")).toBe("cafe-creme");
expect(newProjectFolderName("../../etc")).toBe("etc");
// Nothing usable left, so the server falls back to a fixed name.
expect(newProjectFolderName("🎱🎱")).toBe("project");
expect(newProjectFolderName(`${"a".repeat(63)} b`)).toBe("a".repeat(63));
// Windows cannot make folders with device names.
expect(newProjectFolderName("Con")).toBe("con-project");
expect(newProjectFolderName("LPT1")).toBe("lpt1-project");
expect(newProjectFolderName("console")).toBe("console");
});
});
describe("fileBasename", () => {
it.each([
["/tmp/favicons/", "favicons"],
["C:\\Users\\kelchm\\.claude\\", ".claude"],
["/tmp/", "tmp"],
["AGENTS.md", "AGENTS.md"],
["/", "/"],
])("labels %s as %s", (path, basename) => {
expect(fileBasename(path)).toBe(basename);
});
});
describe("workspaceRelativeFilePath", () => {
it.each([
["/repo/project/src/main.ts", "/repo/project", "src/main.ts"],
["/repo/project/src/main.ts", "/repo/project/", "src/main.ts"],
["C:\\Users\\mike\\t3code\\apps\\web\\a.ts", "C:/Users/mike/t3code", "apps/web/a.ts"],
["/C:/Users/mike/t3code/apps/web/a.ts", "C:/Users/mike/t3code", "apps/web/a.ts"],
["/Repo/Project/src/main.ts", "/repo/project", null],
["/tmp/case/project/probe.txt", "/tmp/case/Project", null],
["//tmp/case/project/probe.txt", "//tmp/case/Project", null],
["/tmp/case/Project/probe.txt", "/tmp/case/Project", "probe.txt"],
["C:/USERS/mike/t3code/main.ts", "c:/users/MIKE/t3code", "main.ts"],
["/C:/USERS/mike/t3code/main.ts", "/c:/users/MIKE/t3code", "main.ts"],
["\\\\server\\share\\PROJECT\\main.ts", "\\\\Server\\Share\\Project", "main.ts"],
["/tmp/repo/file.ts", "/", "tmp/repo/file.ts"],
["C:/Users/MIKE/main.ts", "c:/", "Users/MIKE/main.ts"],
["\\\\server\\SHARE\\file.ts", "\\\\Server\\Share\\", "file.ts"],
["/tmp/repo/file.ts ", "/tmp/repo", "file.ts "],
["/tmp/report.ts", "/repo/project", null],
["/repo/project-two/a.ts", "/repo/project", null],
["/repo/project/a.ts", undefined, null],
])("relates %s to %s", (path, workspaceRoot, relativePath) => {
expect(workspaceRelativeFilePath(path, workspaceRoot)).toBe(relativePath);
});
});