Unified · Split
| @@ -273,3 +273,28 @@ describe("resolveInlineCodeFileLinkMeta", () => { · 272 unmodified lines | |||
| 273 | expect(resolveInlineCodeFileLinkMeta(".plans/worktree-management-v1.md")).toBeNull(); | 273 | expect(resolveInlineCodeFileLinkMeta(".plans/worktree-management-v1.md")).toBeNull(); |
| 274 | }); | 274 | }); |
| 275 | }); | 275 | }); |
| 276 | |||
| 277 | describe("directory paths with a trailing separator", () => { | ||
| 278 | it("keeps the final segment for a POSIX directory path", () => { | ||
| 279 | expect(resolveMarkdownFileLinkMeta("/tmp/favicons/", "/repo/project")).toMatchObject({ | ||
| 280 | basename: "favicons", | ||
| 281 | }); | ||
| 282 | }); | ||
| 283 | |||
| 284 | it("keeps the final segment for a Windows directory path", () => { | ||
| 285 | expect( | ||
| 286 | resolveMarkdownFileLinkMeta("C:\\Users\\kelchm\\.claude\\", "/repo/project"), | ||
| 287 | ).toMatchObject({ basename: ".claude" }); | ||
| 288 | }); | ||
| 289 | |||
| 290 | it("matches the label of the same path without a trailing separator", () => { | ||
| 291 | const withSlash = resolveMarkdownFileLinkMeta("/tmp/favicons/", "/repo/project"); | ||
| 292 | const withoutSlash = resolveMarkdownFileLinkMeta("/tmp/favicons", "/repo/project"); | ||
| 293 | expect(withSlash?.basename).toBe(withoutSlash?.basename); | ||
| 294 | }); | ||
| 295 | |||
| 296 | it("does not produce an empty label for the filesystem root", () => { | ||
| 297 | const meta = resolveMarkdownFileLinkMeta("/tmp/", "/repo/project"); | ||
| 298 | expect(meta?.basename).not.toBe(""); | ||
| 299 | }); | ||
| 300 | }); | ||
| @@ -359,8 +359,12 @@ export function resolveInlineCodeFileLinkMeta( · 358 unmodified lines | |||
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | function basenameOfPath(path: string): string { | 361 | function basenameOfPath(path: string): string { |
| 362 | const separatorIndex = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")); | 362 | // A trailing separator is a valid way to write a directory, so trim it before |
| 363 | return separatorIndex >= 0 ? path.slice(separatorIndex + 1) : path; | 363 | // taking the final segment. Without this the segment reads as empty and the |
| 364 | // chip renders with no label at all. | ||
| 365 | const trimmed = path.replace(/[/\\]+$/, "") || path; | ||
| 366 | const separatorIndex = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\")); | ||
| 367 | return separatorIndex >= 0 ? trimmed.slice(separatorIndex + 1) : trimmed; | ||
| 364 | } | 368 | } |
| 365 | 369 | ||
| 366 | function workspaceRelativePath(path: string, workspaceRoot: string | undefined): string | null { | 370 | function workspaceRelativePath(path: string, workspaceRoot: string | undefined): string | null { |