| 1 | // Run: tsx src/__tests__/attachment-display.test.ts |
| 2 | |
| 3 | import { baseName, formatAttachmentRefForDisplay, formatAttachmentRefForSubmit, parseAttachmentRefsForDisplay, replaceAttachmentRefsForDisplay, restoreAttachmentRefsForSubmit, sortDisplayAttachments } from "../lib/attachmentDisplay"; |
| 4 | |
| 5 | let passed = 0; |
| 6 | let failed = 0; |
| 7 | |
| 8 | function eq(a: unknown, b: unknown, label: string) { |
| 9 | if (JSON.stringify(a) === JSON.stringify(b)) { |
| 10 | process.stdout.write(` PASS ${label}\n`); |
| 11 | passed += 1; |
| 12 | } else { |
| 13 | process.stdout.write(` FAIL ${label}: expected ${JSON.stringify(b)}, got ${JSON.stringify(a)}\n`); |
| 14 | failed += 1; |
| 15 | } |
| 16 | } |
| 17 | |
| 18 | console.log("\nattachment display"); |
| 19 | |
| 20 | const named = parseAttachmentRefsForDisplay( |
| 21 | "review @[DS30000.sl2](.reasonix/attachments/clipboard-20260610-121238.444775-000002.sl2) and @[park.png](.reasonix/attachments/clipboard-20260610-121238.444775-000001.png)", |
| 22 | ); |
| 23 | |
| 24 | eq(named.text, "review and", "removes named display refs from message text"); |
| 25 | eq( |
| 26 | named.attachments.map((a) => ({ path: a.path, name: a.name, kind: a.kind, ext: a.ext })), |
| 27 | [ |
| 28 | { |
| 29 | path: ".reasonix/attachments/clipboard-20260610-121238.444775-000002.sl2", |
| 30 | name: "DS30000.sl2", |
| 31 | kind: "file", |
| 32 | ext: "SL2", |
| 33 | }, |
| 34 | { |
| 35 | path: ".reasonix/attachments/clipboard-20260610-121238.444775-000001.png", |
| 36 | name: "park.png", |
| 37 | kind: "image", |
| 38 | ext: "PNG", |
| 39 | }, |
| 40 | ], |
| 41 | "preserves original display names for attachment cards", |
| 42 | ); |
| 43 | eq( |
| 44 | sortDisplayAttachments(named.attachments).map((a) => a.name), |
| 45 | ["park.png", "DS30000.sl2"], |
| 46 | "sorts images before files while keeping groups stable", |
| 47 | ); |
| 48 | eq( |
| 49 | replaceAttachmentRefsForDisplay("see @[DS30000.sl2](.reasonix/attachments/clipboard-20260610-121238.444775-000002.sl2)"), |
| 50 | "see [file:DS30000.sl2]", |
| 51 | "compact previews use named display refs", |
| 52 | ); |
| 53 | eq( |
| 54 | restoreAttachmentRefsForSubmit("review @[DS30000.sl2](.reasonix/attachments/clipboard-20260610-121238.444775-000002.sl2), then @[park.png](.reasonix/attachments/clipboard-20260610-121238.444775-000001.png)"), |
| 55 | "review @.reasonix/attachments/clipboard-20260610-121238.444775-000002.sl2, then @.reasonix/attachments/clipboard-20260610-121238.444775-000001.png", |
| 56 | "restores named display refs for submit", |
| 57 | ); |
| 58 | eq( |
| 59 | formatAttachmentRefForDisplay({ path: ".reasonix/attachments/clipboard-20260610-121238.444775-000001.png", name: "park.png", source: "attachment" }), |
| 60 | "@[park.png](.reasonix/attachments/clipboard-20260610-121238.444775-000001.png)", |
| 61 | "formats attachment display refs for edit replay", |
| 62 | ); |
| 63 | eq( |
| 64 | formatAttachmentRefForSubmit({ path: ".reasonix/attachments/clipboard-20260610-121238.444775-000001.png" }), |
| 65 | "@.reasonix/attachments/clipboard-20260610-121238.444775-000001.png", |
| 66 | "formats raw attachment refs for edit replay submit", |
| 67 | ); |
| 68 | eq(baseName("C:\\Users\\Abyss\\Desktop\\DS30000.sl2"), "DS30000.sl2", "extracts Windows path basenames"); |
| 69 | eq(baseName("/Users/abyss/Desktop/park.png"), "park.png", "extracts POSIX path basenames"); |
| 70 | |
| 71 | const escaped = parseAttachmentRefsForDisplay("look at @docs/my\\ report\\ 2026.pdf now"); |
| 72 | eq(escaped.text, "look at now", "removes an escaped workspace ref from message text"); |
| 73 | eq( |
| 74 | escaped.attachments.map((a) => ({ path: a.path, name: a.name, kind: a.kind, source: a.source })), |
| 75 | [{ path: "docs/my report 2026.pdf", name: "my report 2026.pdf", kind: "file", source: "workspace" }], |
| 76 | "escaped workspace ref becomes one full badge with the unescaped path", |
| 77 | ); |
| 78 | eq( |
| 79 | formatAttachmentRefForDisplay({ path: "docs/my report 2026.pdf", name: "my report 2026.pdf", source: "workspace" }), |
| 80 | "@docs/my\\ report\\ 2026.pdf", |
| 81 | "workspace display refs escape whitespace for lossless edit replay", |
| 82 | ); |
| 83 | eq( |
| 84 | formatAttachmentRefForSubmit({ path: "docs/my report 2026.pdf" }), |
| 85 | "@docs/my\\ report\\ 2026.pdf", |
| 86 | "workspace submit refs escape whitespace so @-token parsing resolves them", |
| 87 | ); |
| 88 | |
| 89 | console.log(`\n${passed} passed, ${failed} failed, ${passed + failed} total`); |
| 90 | if (failed > 0) process.exit(1); |
| 91 |