import { afterEach, beforeEach, describe, expect, it, vi } from "vite-plus/test"; import { serializeRenderedMarkdownFragment } from "./markdown-clipboard"; const TEXT_NODE = 3; const ELEMENT_NODE = 1; class FakeText { readonly nodeType = TEXT_NODE; readonly childNodes: ReadonlyArray = []; constructor(readonly textContent: string) {} } class FakeElement { readonly nodeType = ELEMENT_NODE; readonly childNodes: Array = []; readonly classList = { contains: (name: string) => this.classNames.includes(name), }; constructor( readonly tagName: string, private readonly classNames: ReadonlyArray = [], ) {} get localName(): string { return this.tagName.toLowerCase(); } get textContent(): string { return this.childNodes.map((child) => child.textContent).join(""); } append(...children: Array): this { this.childNodes.push(...children); return this; } getAttribute(): string | null { return null; } hasAttribute(): boolean { return false; } } function asNode(element: FakeElement): Node { return element as unknown as Node; } function shikiCodeLine(text: string): FakeElement { const token = new FakeElement("SPAN").append(new FakeText(text)); return new FakeElement("SPAN", ["line"]).append(token); } describe("serializeRenderedMarkdownFragment", () => { beforeEach(() => { vi.stubGlobal("Node", { TEXT_NODE, ELEMENT_NODE }); }); afterEach(() => { vi.unstubAllGlobals(); }); it("wraps inline code in backticks", () => { const paragraph = new FakeElement("P").append( new FakeText("run "), new FakeElement("CODE").append(new FakeText("git status")), new FakeText(" first"), ); const container = new FakeElement("DIV").append(paragraph); expect(serializeRenderedMarkdownFragment(asNode(container))).toBe("run `git status` first"); }); it("keeps a highlighted block code selection plain when its pre wrapper is outside the range", () => { const code = new FakeElement("CODE").append( shikiCodeLine("git show-ref --verify refs/remotes/origin/opt/deploy/dev"), ); const container = new FakeElement("DIV").append(code); expect(serializeRenderedMarkdownFragment(asNode(container))).toBe( "git show-ref --verify refs/remotes/origin/opt/deploy/dev", ); }); it("keeps a multi-line code selection plain instead of inline-wrapping it", () => { const code = new FakeElement("CODE").append(new FakeText("first line\nsecond line")); const container = new FakeElement("DIV").append(code); expect(serializeRenderedMarkdownFragment(asNode(container))).toBe("first line\nsecond line"); }); });