diff --git a/src/export/odsXml.test.ts b/src/export/odsXml.test.ts new file mode 100644 index 0000000..abd65f1 --- /dev/null +++ b/src/export/odsXml.test.ts @@ -0,0 +1,95 @@ +import { test, expect, describe } from "bun:test"; +import { + buildContentXml, + buildManifestXml, + buildStylesXml, + escapeXml, + text, + num, + empty, + ODS_MIMETYPE, +} from "./odsXml.ts"; + +test("the ODS mimetype is the spreadsheet one", () => { + expect(ODS_MIMETYPE).toBe("application/vnd.oasis.opendocument.spreadsheet"); +}); + +describe("escapeXml", () => { + test("escapes the five XML entities", () => { + expect(escapeXml(` "c" 'd'`)).toBe( + "<a & b> "c" 'd'", + ); + }); + + test("leaves ordinary text alone", () => { + expect(escapeXml("Events and Social")).toBe("Events and Social"); + }); +}); + +describe("buildContentXml", () => { + const xml = buildContentXml([ + { + name: "Summary", + rows: [ + [text("Post"), text("Spent")], + [text("Food"), num(1234.56)], + [text("Empty"), empty()], + ], + }, + ]); + + test("declares the spreadsheet document namespaces", () => { + expect(xml).toStartWith(''); + expect(xml).toContain("office:document-content"); + expect(xml).toContain("urn:oasis:names:tc:opendocument:xmlns:office:1.0"); + }); + + test("names the table", () => { + expect(xml).toContain('table:name="Summary"'); + }); + + test("writes numbers as float cells with office:value, not text", () => { + expect(xml).toContain('office:value-type="float" office:value="1234.56"'); + expect(xml).not.toContain('office:value-type="string">1234.56'); + }); + + test("writes text cells as strings", () => { + expect(xml).toContain('office:value-type="string">Food'); + }); + + test("writes empty cells with no value type", () => { + expect(xml).toContain(""); + }); + + test("escapes sheet names and cell text", () => { + const nasty = buildContentXml([ + { name: 'Food & "drink"', rows: [[text("