/** * Runtime coverage for the in-house markit document engine (src/markit), which * replaced the `markit-ai` package. Each format is generated in-memory via the * shared zip util (src/utils/zip) — no external fixtures — and converted through * the public wrapper (src/utils/markit), locking: docx text, xlsx tables, pptx * slides, epub metadata+spine, shared HTML-table normalization, image * extraction, the nested/relative zip path resolution regression surface, and * the unsupported-format error contract. */ import { describe, expect, it } from "bun:test"; import * as fs from "node:fs/promises"; import * as os from "node:os"; import * as path from "node:path"; import { convertBufferWithMarkit, convertFileWithMarkit } from "@oh-my-pi/pi-coding-agent/utils/markit"; import { zip } from "@oh-my-pi/pi-coding-agent/utils/zip"; import { removeWithRetries } from "@oh-my-pi/pi-utils"; const enc = (s: string): Uint8Array => new TextEncoder().encode(s); const WML = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"; function makeDocx(bodyXml: string): Uint8Array { return zip({ "[Content_Types].xml": enc( ``, ), "_rels/.rels": enc( ``, ), "word/document.xml": enc( `${bodyXml}`, ), }); } describe("markit converters", () => { it("converts docx paragraphs to markdown", async () => { const docx = makeDocx( `First paragraph.Second paragraph.`, ); const result = await convertBufferWithMarkit(docx, ".docx"); expect(result.ok).toBe(true); expect(result.content).toBe("First paragraph.\n\nSecond paragraph."); }); it("converts xlsx sheets to markdown tables", async () => { const xlsx = zip({ "xl/workbook.xml": enc( ``, ), "xl/_rels/workbook.xml.rels": enc( ``, ), "xl/worksheets/sheet1.xml": enc( `NameAgeAlice30`, ), }); const result = await convertBufferWithMarkit(xlsx, ".xlsx"); expect(result.ok).toBe(true); expect(result.content).toContain("## People"); expect(result.content).toContain("| Name | Age |"); expect(result.content).toContain("| --- | --- |"); expect(result.content).toContain("| Alice | 30 |"); }); it("reads an xlsx worksheet through an absolute (/-prefixed) rel target", async () => { const xlsx = zip({ "xl/workbook.xml": enc( ``, ), "xl/_rels/workbook.xml.rels": enc( ``, ), "xl/worksheets/sheet1.xml": enc( `Header42`, ), }); const result = await convertBufferWithMarkit(xlsx, ".xlsx"); expect(result.ok).toBe(true); expect(result.content).toContain("| Header |"); expect(result.content).toContain("| 42 |"); }); it("converts pptx slides with a title heading and body text", async () => { const pptx = zip({ "ppt/presentation.xml": enc( ``, ), "ppt/_rels/presentation.xml.rels": enc( ``, ), "ppt/slides/slide1.xml": enc( `The TitleBody line`, ), }); const result = await convertBufferWithMarkit(pptx, ".pptx"); expect(result.ok).toBe(true); expect(result.content).toContain("# The Title"); expect(result.content).toContain("Body line"); }); it("extracts a pptx image through a ../media relative rel target into imageDir", async () => { const dir = await fs.mkdtemp(path.join(os.tmpdir(), "markit-pptx-")); try { const pptx = zip({ "ppt/presentation.xml": enc( ``, ), "ppt/_rels/presentation.xml.rels": enc( ``, ), "ppt/slides/slide1.xml": enc( ``, ), "ppt/slides/_rels/slide1.xml.rels": enc( ``, ), "ppt/media/image1.png": new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]), }); const pptxPath = path.join(dir, "deck.pptx"); const imageDir = path.join(dir, "imgs"); await Bun.write(pptxPath, pptx); const result = await convertFileWithMarkit(pptxPath, undefined, { imageDir }); expect(result.ok).toBe(true); const written = await fs.readdir(imageDir); expect(written).toHaveLength(1); expect(result.content).toContain(`](${path.join(imageDir, written[0]!)})`); } finally { await removeWithRetries(dir); } }); it("converts epub spine, normalizes HTML tables, and resolves a non-root OPF basePath", async () => { const epub = zip({ "META-INF/container.xml": enc( ``, ), "OEBPS/content.opf": enc( `Nested BookAda`, ), "OEBPS/text/ch1.xhtml": enc( `

Chapter One

Body text.

AB
12
`, ), }); const result = await convertBufferWithMarkit(epub, ".epub"); expect(result.ok).toBe(true); expect(result.content).toContain("**Title:** Nested Book"); expect(result.content).toContain("**Authors:** Ada"); expect(result.content).toContain("## Chapter One"); expect(result.content).toContain("Body text."); // normalizeTablesHtml promotes the first row to a header so GFM renders a table. expect(result.content).toContain("| A | B |"); expect(result.content).toContain("| --- | --- |"); }); it("reports an unsupported format instead of emitting garbage", async () => { const rtf = enc("{\\rtf1\\ansi binary-ish}"); const result = await convertBufferWithMarkit(rtf, ".rtf"); expect(result.ok).toBe(false); expect(result.error).toContain("Unsupported format"); }); });