| 1 | package config |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | "testing" |
| 6 | ) |
| 7 | |
| 8 | // TestWorkspaceSlugShortPathUnchanged: existing short paths must keep their |
| 9 | // exact historical slug so on-disk project directories keep resolving. |
| 10 | func TestWorkspaceSlugShortPathUnchanged(t *testing.T) { |
| 11 | setRuntimeGOOS(t, "linux") |
| 12 | got := WorkspaceSlug("/Users/me/proj") |
| 13 | if got != "-Users-me-proj" { |
| 14 | t.Fatalf("WorkspaceSlug short path = %q, want -Users-me-proj", got) |
| 15 | } |
| 16 | } |
| 17 | |
| 18 | // TestWorkspaceSlugBoundsDeepPaths: a workspace path whose flattened slug |
| 19 | // exceeds the 255-byte filename component limit used to make every derived |
| 20 | // directory (project sessions, auto-memory) uncreatable with ENAMETOOLONG. |
| 21 | func TestWorkspaceSlugBoundsDeepPaths(t *testing.T) { |
| 22 | deep := "/data/" + strings.Repeat("deeply-nested-workspace-segment/", 12) + "proj" |
| 23 | slug := WorkspaceSlug(deep) |
| 24 | if len(slug) > 255 { |
| 25 | t.Fatalf("slug length = %d, exceeds 255-byte component limit", len(slug)) |
| 26 | } |
| 27 | // Distinct deep paths must not collapse to one slug. |
| 28 | other := "/data/" + strings.Repeat("deeply-nested-workspace-segment/", 12) + "proj2" |
| 29 | if WorkspaceSlug(other) == slug { |
| 30 | t.Fatal("distinct deep paths share one slug") |
| 31 | } |
| 32 | // Deterministic across calls. |
| 33 | if WorkspaceSlug(deep) != slug { |
| 34 | t.Fatal("slug is not deterministic") |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | func TestBoundFilenameComponentRuneBoundary(t *testing.T) { |
| 39 | // A multi-byte-rune input truncated mid-rune must back off to a valid |
| 40 | // boundary, not emit invalid UTF-8 into a filename. |
| 41 | long := strings.Repeat("工作区", 100) |
| 42 | got := BoundFilenameComponent(long, 255) |
| 43 | if len(got) > 255 { |
| 44 | t.Fatalf("bounded component length = %d, want <= 255", len(got)) |
| 45 | } |
| 46 | if strings.Contains(got, "�") { |
| 47 | t.Fatalf("bounded component contains replacement char: %q", got) |
| 48 | } |
| 49 | } |
| 50 |