| 1 | import { describe, expect, it } from "vitest"; |
| 2 | import { isDotGitName, unsafeTreeName, unsafeTreePath } from "../../src/lib/tree-names.js"; |
| 3 | |
| 4 | describe("tree entry names", () => { |
| 5 | it("accepts ordinary names", () => { |
| 6 | for (const n of ["README.md", ".gitignore", ".github", "git", "a b", "50%", ".git-blame-ignore-revs", "gitk~1"]) expect(unsafeTreeName(n)).toBeNull(); |
| 7 | }); |
| 8 | |
| 9 | it("refuses . and .. and separators", () => { |
| 10 | for (const n of ["", ".", "..", "a/b", "a\\b", "a\0b"]) expect(unsafeTreeName(n)).not.toBeNull(); |
| 11 | }); |
| 12 | |
| 13 | it("refuses every spelling a checkout would treat as .git", () => { |
| 14 | for (const n of [".git", ".GIT", ".Git", ".git.", ".git ", ".git. .", "git~1", "GIT~1", ".git", ".git", ".git"]) { |
| 15 | expect(isDotGitName(n)).toBe(true); |
| 16 | expect(unsafeTreeName(n)).not.toBeNull(); |
| 17 | } |
| 18 | }); |
| 19 | |
| 20 | it("refuses long names", () => { |
| 21 | expect(unsafeTreeName("a".repeat(255))).toBeNull(); |
| 22 | expect(unsafeTreeName("a".repeat(256))).not.toBeNull(); |
| 23 | }); |
| 24 | |
| 25 | it("checks every segment of a path", () => { |
| 26 | expect(unsafeTreePath("src/lib/a.ts")).toBeNull(); |
| 27 | expect(unsafeTreePath("/src//lib/")).toBeNull(); |
| 28 | for (const p of ["", "/", "a/../b", "./a", ".git/config", "sub/.GIT/hooks/pre-commit", "x/git~1/y", "a\\b", "a\0", "sub/.git./x"]) expect(unsafeTreePath(p)).not.toBeNull(); |
| 29 | expect(unsafeTreePath("a/".repeat(2100))).not.toBeNull(); |
| 30 | }); |
| 31 | }); |