Unified · Split
| @@ -273,3 +273,28 @@ describe("resolveInlineCodeFileLinkMeta", () => { · 272 unmodified lines | ||
| 273 | 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 | 361 | function basenameOfPath(path: string): string { |
| 362 | − const separatorIndex = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")); | |
| 363 | − return separatorIndex >= 0 ? path.slice(separatorIndex + 1) : path; | |
| 362 | + // A trailing separator is a valid way to write a directory, so trim it before | |
| 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 | 370 | function workspaceRelativePath(path: string, workspaceRoot: string | undefined): string | null { |