import { describe, expect, it } from "vitest"; import { inferLanguage, labelCodeFences, promoteStandaloneCodeSpans, repairCodeBlocks, restoreUrlLinks, } from "../lib/code"; describe("inferLanguage", () => { it("returns nothing for empty or whitespace-only code", () => { expect(inferLanguage("")).toBeUndefined(); expect(inferLanguage(" \n ")).toBeUndefined(); }); describe("shell", () => { it("recognises a command as the first word", () => { expect(inferLanguage("pwd")).toBe("bash"); expect(inferLanguage("git status")).toBe("bash"); expect(inferLanguage("brew install ripgrep")).toBe("bash"); }); it("recognises an explicit prompt marker", () => { expect(inferLanguage("$ git status")).toBe("bash"); expect(inferLanguage("> ls -la")).toBe("bash"); }); it("recognises a home-relative path", () => { expect(inferLanguage("~/Documents/Code")).toBe("bash"); }); it("recognises a pipeline between known commands", () => { expect(inferLanguage("git log --oneline | head -20")).toBe("bash"); }); it("ignores comments when looking at the first word", () => { expect(inferLanguage("# check the branch\ngit branch --show-current")).toBe("bash"); }); }); describe("json", () => { it("recognises a parseable object", () => { expect(inferLanguage('{\n "model": "gpt-oss"\n}')).toBe("json"); }); it("recognises a parseable array", () => { expect(inferLanguage('["a", "b"]')).toBe("json"); }); it("does not claim malformed braces", () => { expect(inferLanguage("{ not actually json")).not.toBe("json"); }); }); describe("typescript", () => { it("recognises type annotations", () => { expect(inferLanguage("function add(a: number, b: number) {\n return a + b;\n}")).toBe("ts"); }); it("recognises interfaces and type aliases", () => { expect(inferLanguage("interface User {\n id: string;\n}")).toBe("ts"); expect(inferLanguage("type Id = string | number;")).toBe("ts"); }); it("does not label plain JavaScript, which is ambiguous", () => { // Guessing wrong costs the highlighting, so this stays unlabelled. expect(inferLanguage("console.log('hi')")).toBeUndefined(); expect(inferLanguage("const x = [1, 2, 3].map((n) => n * 2);")).toBeUndefined(); }); }); describe("python", () => { it("recognises a function definition", () => { expect(inferLanguage("def greet(name):\n return f'hi {name}'")).toBe("python"); }); it("recognises imports and self", () => { expect(inferLanguage("from pathlib import Path")).toBe("python"); expect(inferLanguage("class A:\n def go(self):\n pass")).toBe("python"); }); }); it("leaves genuinely ambiguous content alone", () => { expect(inferLanguage("some plain text\nacross two lines")).toBeUndefined(); }); }); describe("promoteStandaloneCodeSpans", () => { it("promotes a paragraph that is one inline span", () => { // The reported case: asking for a command and getting a lone chip back. expect(promoteStandaloneCodeSpans("`pwd`")).toBe("```bash\npwd\n```"); }); it("promotes the same span on its own line within a larger answer", () => { const promoted = promoteStandaloneCodeSpans("Here you go:\n\n`pwd`\n\nThat prints the path."); expect(promoted).toContain("```bash\npwd\n```"); expect(promoted).toContain("Here you go:"); expect(promoted).toContain("That prints the path."); }); it("tolerates a sentence-ending period", () => { expect(promoteStandaloneCodeSpans("`pwd`.")).toBe("```bash\npwd\n```"); }); it("leaves a span embedded in a sentence alone", () => { const input = "Run `pwd` to see where you are."; expect(promoteStandaloneCodeSpans(input)).toBe(input); }); it("leaves a bulleted span alone", () => { const input = "- `pwd -P` resolves symlinks"; expect(promoteStandaloneCodeSpans(input)).toBe(input); }); it("never rewrites a span-like line inside an existing fence", () => { const input = "```bash\n`not-a-span`\n```"; expect(promoteStandaloneCodeSpans(input)).toBe(input); }); it("fences a span whose language cannot be inferred, without guessing one", () => { expect(promoteStandaloneCodeSpans("`Get-Location`")).toBe("```\nGet-Location\n```"); }); it("is idempotent", () => { const once = promoteStandaloneCodeSpans("`pwd`"); expect(promoteStandaloneCodeSpans(once)).toBe(once); }); it("is a no-op on ordinary prose", () => { const input = "There is no code here at all."; expect(promoteStandaloneCodeSpans(input)).toBe(input); }); }); describe("restoreUrlLinks", () => { it("unwraps a fence that is nothing but URLs", () => { // The reported case: "here are the links" arriving as a code block, so the // one thing a URL is for, being clicked, does not work. const input = [ "```", "https://github.com/jasonkneen/openclicky", "https://github.com/unn-Known1/clickyX", "```", ].join("\n"); expect(restoreUrlLinks(input)).toBe( [ "[https://github.com/jasonkneen/openclicky](https://github.com/jasonkneen/openclicky)", "[https://github.com/unn-Known1/clickyX](https://github.com/unn-Known1/clickyX)", ].join("\n"), ); }); it("unwraps a URL fence even when the model labelled it", () => { expect(restoreUrlLinks("```bash\nhttps://example.com\n```")).toBe( "[https://example.com](https://example.com)", ); }); it("links a bare URL standing alone on a line", () => { expect(restoreUrlLinks("https://example.com")).toBe("[https://example.com](https://example.com)"); }); it("links a lone inline span holding a URL", () => { expect(restoreUrlLinks("`https://example.com`")).toBe( "[https://example.com](https://example.com)", ); }); it("keeps a bulleted list of links a bulleted list", () => { const input = "- https://a.example\n- https://b.example"; expect(restoreUrlLinks(input)).toBe( "- [https://a.example](https://a.example)\n- [https://b.example](https://b.example)", ); }); it("keeps an ordered list marker", () => { expect(restoreUrlLinks("1. https://example.com")).toBe( "1. [https://example.com](https://example.com)", ); }); it("drops sentence punctuation that is not part of the address", () => { expect(restoreUrlLinks("See this:\n\nhttps://example.com.")).toContain( "[https://example.com](https://example.com)", ); }); it("brackets a destination that contains parentheses", () => { const url = "https://en.wikipedia.org/wiki/Foo_(bar)"; expect(restoreUrlLinks(url)).toBe(`[${url}](<${url}>)`); }); it("escapes brackets in the label, which an IPv6 literal contains", () => { // Unescaped, the `]` in the label ends the link text early and the rest of // the address is left as prose outside the link. expect(restoreUrlLinks("http://[::1]:8080/")).toBe( "[http://\\[::1\\]:8080/](http://[::1]:8080/)", ); }); it("never touches a fence holding real code", () => { const input = "```bash\ncurl https://example.com | jq .\n```"; expect(restoreUrlLinks(input)).toBe(input); }); it("never touches a fence when one line is not a URL", () => { const input = "```\nhttps://example.com\nnot a url\n```"; expect(restoreUrlLinks(input)).toBe(input); }); it("leaves a URL embedded in a sentence alone", () => { const input = "The docs at https://example.com cover it."; expect(restoreUrlLinks(input)).toBe(input); }); it("leaves a markdown link the model already wrote alone", () => { const input = "[OpenClickly](https://github.com/jasonkneen/openclicky)"; expect(restoreUrlLinks(input)).toBe(input); }); it("preserves a fence that is never closed and is real code", () => { expect(restoreUrlLinks("```\ngit log")).toBe("```\ngit log"); }); it("is idempotent", () => { const once = restoreUrlLinks("```\nhttps://example.com\n```"); expect(restoreUrlLinks(once)).toBe(once); }); it("is a no-op on ordinary prose", () => { const input = "There are no addresses in this sentence."; expect(restoreUrlLinks(input)).toBe(input); }); }); describe("repairCodeBlocks", () => { it("promotes a lone command and labels it in one pass", () => { expect(repairCodeBlocks("`pwd`")).toBe("```bash\npwd\n```"); }); it("does not fence a lone URL", () => { // Restoring links runs before promotion, so a recovered URL never becomes a // fence again. Fencing it here was the bug the user saw. const repaired = repairCodeBlocks("`https://example.com`"); expect(repaired).not.toContain("```"); expect(repaired).toBe("[https://example.com](https://example.com)"); }); it("unwraps a fenced list of links and leaves no fence behind", () => { const repaired = repairCodeBlocks("```\nhttps://a.example\nhttps://b.example\n```"); expect(repaired).not.toContain("```"); expect(repaired).toContain("[https://a.example](https://a.example)"); }); it("still labels a bare multi-line fence", () => { expect(repairCodeBlocks("```\ngit status\n```")).toBe("```bash\ngit status\n```"); }); it("handles a promoted block and a plain fence in the same answer", () => { const repaired = repairCodeBlocks("First:\n\n`pwd`\n\nThen:\n\n```\nls -la\n```"); expect(repaired).toContain("```bash\npwd\n```"); expect(repaired).toContain("```bash\nls -la\n```"); }); }); describe("labelCodeFences", () => { it("labels a bare fence", () => { const labelled = labelCodeFences("```\ngit status\n```"); expect(labelled).toBe("```bash\ngit status\n```"); }); it("leaves an already labelled fence exactly as the model wrote it", () => { expect(labelCodeFences("```rust\nfn main() {}\n```")).toBe("```rust\nfn main() {}\n```"); }); it("labels each block independently", () => { const labelled = labelCodeFences(["```", "pwd", "```", "", "```", '{"a": 1}', "```"].join("\n")); expect(labelled).toContain("```bash"); expect(labelled).toContain("```json"); }); it("leaves an unlabellable block bare rather than guessing", () => { const input = "```\njust some words\n```"; expect(labelCodeFences(input)).toBe(input); }); it("preserves surrounding prose", () => { const labelled = labelCodeFences("Before:\n\n```\nls\n```\n\nAfter."); expect(labelled).toContain("Before:"); expect(labelled).toContain("After."); expect(labelled).toContain("```bash"); }); it("handles a fence that is never closed", () => { expect(labelCodeFences("```\ngit log")).toContain("```bash"); }); it("is a no-op on markdown with no fences", () => { const input = "Just a paragraph with `inline code` in it."; expect(labelCodeFences(input)).toBe(input); }); it("is idempotent", () => { const once = labelCodeFences("```\nls\n```"); expect(labelCodeFences(once)).toBe(once); }); it("does not mistake a closing fence for a new opening one", () => { // A closing ``` and an opening bare ``` are identical lines. Treating the // closing one as an opening fence swallowed everything after it, so the // second block never got labelled. const input = "```bash\npwd\n```\n\n```\nls -la\n```"; expect(labelCodeFences(input)).toContain("```bash\nls -la\n```"); }); it("labels a later block even when an earlier one is already labelled", () => { const input = "```rust\nfn main() {}\n```\n\n```\npwd\n```"; const labelled = labelCodeFences(input); expect(labelled).toContain("```rust"); expect(labelled).toContain("```bash\npwd\n```"); }); it("preserves a language the model chose, including multi-word freeform tags", () => { expect(labelCodeFences("```c++\nint main() {}\n```")).toContain("```c++"); expect(labelCodeFences("```objective-c\nint x;\n```")).toContain("```objective-c"); }); it("preserves indentation of a nested fence", () => { expect(labelCodeFences(" ```\n ls\n ```")).toContain(" ```bash"); }); });