import { describe, it, expect } from "vitest"; import { extractCardReference } from "@/lib/linking/reference"; describe("extractCardReference", () => { it("finds a bracketed reference at the end of the subject", () => { expect(extractCardReference("feat(stock): inline qty editing [#42]")).toBe(42); }); it("finds one anywhere in the message, including the body", () => { expect(extractCardReference("[#7] fix: thing")).toBe(7); expect(extractCardReference("fix: thing\n\nRefs [#7]\n")).toBe(7); }); it("returns null when there is none", () => { expect(extractCardReference("feat(stock): inline qty editing")).toBeNull(); expect(extractCardReference("")).toBeNull(); }); it("ignores a bare #42 without brackets", () => { // Bare hashes appear constantly in prose — colours, issue numbers from // other systems, ordinals. Requiring brackets makes the reference a // deliberate act rather than a guess. expect(extractCardReference("fix: matches #42 in the old tracker")).toBeNull(); expect(extractCardReference("style: use #ff8a5c")).toBeNull(); }); it("takes the first reference when several appear", () => { // One commit links to at most one card, so a second reference cannot be // honoured. First wins, deterministically. expect(extractCardReference("fix: thing [#3] and also [#9]")).toBe(3); }); it("rejects zero and negative numbers", () => { expect(extractCardReference("fix: thing [#0]")).toBeNull(); expect(extractCardReference("fix: thing [#-4]")).toBeNull(); }); it("rejects a non-numeric reference", () => { expect(extractCardReference("fix: thing [#abc]")).toBeNull(); expect(extractCardReference("fix: thing [#]")).toBeNull(); }); it("tolerates whitespace inside the brackets", () => { expect(extractCardReference("fix: thing [# 42 ]")).toBe(42); }); it("rejects an absurdly large number rather than overflowing", () => { expect(extractCardReference(`fix: thing [#${"9".repeat(20)}]`)).toBeNull(); }); });