import { describe, expect, it } from "bun:test"
import {
isSafeSourceId,
parseSourceAnnotatedMarkdown,
stripSourceMarkup,
} from "./source-annotations"
describe("source annotation parsing", () => {
it("turns allowed response source spans into internal citation links", () => {
const parsed = parseSourceAnnotatedMarkdown(
'Alpha Beta [x] Gamma',
new Set(["S1"]),
)
expect(parsed.markdown).toBe("Alpha [Beta \\[x\\]](#sm-source:S1) Gamma")
})
it("renders repeated allowed citations as separate internal links", () => {
const parsed = parseSourceAnnotatedMarkdown(
'First and Second',
new Set(["S1"]),
)
expect(parsed.markdown).toBe(
"[First](#sm-source:S1) and [Second](#sm-source:S1)",
)
})
it("renders unknown or unsafe source ids as plain text", () => {
expect(
parseSourceAnnotatedMarkdown(
'Unknown plain',
new Set(["S1"]),
).markdown,
).toBe("Unknown plain")
expect(
parseSourceAnnotatedMarkdown(
'Unsafe plain',
new Set(["bad/id"]),
).markdown,
).toBe("Unsafe plain")
})
it("keeps unclosed, incomplete, nested, and malformed source markup safe", () => {
expect(
parseSourceAnnotatedMarkdown(
'Lead unfinished answer',
new Set(["S1"]),
).markdown,
).toBe("Lead unfinished answer")
expect(
parseSourceAnnotatedMarkdown("Lead A B C',
new Set(["S1", "S2"]),
).markdown,
).toBe("Outer A B C")
expect(
parseSourceAnnotatedMarkdown(
"Malformed plain",
new Set(["S1"]),
).markdown,
).toBe("Malformed plain")
})
it("does not mutate inline code or fenced code blocks", () => {
const input =
'`code`\n```\nfenced\n```'
expect(parseSourceAnnotatedMarkdown(input, new Set(["S1"])).markdown).toBe(
input,
)
})
it("turns known bare memory ids into internal citation links", () => {
const parsed = parseSourceAnnotatedMarkdown(
"Fact [S1]. Combined [S1, S2]. Unknown [S3].",
new Set(["S1", "S2"]),
)
expect(parsed.markdown).toBe(
"Fact [S1](#sm-source:S1). Combined [S1](#sm-source:S1) [S2](#sm-source:S2). Unknown [S3].",
)
})
it("does not reinterpret normal markdown as bare memory citations", () => {
const input = [
"[S1](https://example.com)",
"[S1][ref]",
"[S1]: https://example.com",
"",
"\\[S1]",
"`[S1]`",
"```",
"[S1]",
"```",
].join("\n")
expect(parseSourceAnnotatedMarkdown(input, new Set(["S1"])).markdown).toBe(
input,
)
})
it("strips source markup for copy text", () => {
expect(
stripSourceMarkup('Alpha Beta'),
).toBe("Alpha Beta")
})
it("recovers a duplicated malformed closing tag from model output", () => {
const input =
'Pinki got soup for dinner at the church todaytoday.'
expect(
parseSourceAnnotatedMarkdown(input, new Set(["S1", "S2"])).markdown,
).toBe(
"Pinki got soup [for dinner at the church](#sm-source:S1) [today](#sm-source:S2).",
)
expect(stripSourceMarkup(input)).toBe(
"Pinki got soup for dinner at the church today.",
)
})
it("accepts a quoted malformed closing tag without duplicated text", () => {
expect(
parseSourceAnnotatedMarkdown(
'Alpha Beta Gamma',
new Set(["S1"]),
).markdown,
).toBe("Alpha [Beta](#sm-source:S1) Gamma")
})
it("allows only source ids that are safe in internal fragments", () => {
expect(isSafeSourceId("S1._:-")).toBe(true)
expect(isSafeSourceId("bad/id")).toBe(false)
expect(isSafeSourceId("bad space")).toBe(false)
})
})