test: take Word re-saves of the corpus as a third author

corpus/word/ holds each document saved again by Word — rsids,
proofErr, separator notes, theme docDefaults — asserted to read like
the docx-lib original and survive our round trip. The formula fixture
is reauthored: a hand-wrapped MathNumerator doubled m:num/m:den, which
Word refuses to open, and the radical gets a visible degree.
This commit is contained in:
Steffen Becker committed 2026-08-30 10:06:44 +00:00
1 parent c19d082099
commit bc3c25ece1
18 files changed
+24 -5

No files matched your search

+1 -1
View File
@@ -27,7 +27,7 @@ Tests live in `tests/` (outside `src/`, so `svelte-check` ignores them), jsdom v
`roundtrip.test.ts` covers the ODF export↔import round trip + a foreign-doc/style-resolver leg;
`lo-roundtrip.test.ts` re-saves through LibreOffice and **self-skips** without `soffice`, so
`npm test`/CI stay green; `corpus.test.ts` round-trips the committed `tests/corpus/`
documents (authored by `render-parity/make-fixtures.mjs`, never by our own exporter);
documents (by `make-fixtures.mjs` + Word re-saves in `corpus/word/`, never our exporter);
`fuzz-roundtrip.test.ts` round-trips seeded random documents (`fuzzDoc.ts` generator);
`schema-validation.test.ts` validates the `kitchenSink.ts` exports against the vendored
schemas in `tests/schemas/` (self-skips without `xmllint`); `package-lint.test.ts` checks the semantic invariants schemas can't express (unique ids, dangling references); `tests/unit/` holds fast helper tests. All test tooling stays a
+17
View File
@@ -58,6 +58,23 @@ describe.skipIf(!files.length)('the authored corpus', () => {
});
}
// Word re-saves of the same documents (tests/corpus/word/): Word rewrites the file
// in its own dialect — rsids, proofErr, separator notes, theme docDefaults — which
// neither the docx lib nor LibreOffice produce, so this is the third author here.
const WORD = join(FIX, 'word');
const wordFiles = existsSync(WORD)
? readdirSync(WORD).filter((f) => /^\d\d-.+\.docx$/.test(f)).sort()
: [];
for (const f of wordFiles) {
it(`word/${f} reads like the original and survives the round trip`, async () => {
const doc = importDocx(new Uint8Array(readFileSync(join(WORD, f)))).content as N;
expect(outline(doc), 'matches the docx-lib original').toEqual(outline(importAny(f, load(f))));
const margins = { top: 2, bottom: 2, left: 2, right: 2 };
const again = importDocx(await buildDocx(doc, margins, 'portrait'));
expect(outline(again.content)).toEqual(outline(doc));
});
}
// The same document in both formats, and each one exported as the other: the four
// legs a document takes through this editor have to agree on what it says.
for (const name of files.filter((f) => f.endsWith('.docx')).map((f) => f.slice(0, -5))) {
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6 -4
View File
@@ -12,7 +12,7 @@ import {
Table, TableRow, TableCell, WidthType, convertMillimetersToTwip,
Header, Footer, PageNumber, TabStopType,
FootnoteReferenceRun, ImageRun, ExternalHyperlink, UnderlineType,
Math as DocxMath, MathRun, MathFraction, MathNumerator, MathDenominator, MathRadical,
Math as DocxMath, MathRun, MathFraction, MathRadical,
} from 'docx';
const OUT = join(dirname(fileURLToPath(import.meta.url)), '..', 'corpus');
@@ -265,9 +265,11 @@ await write('13-images.docx', [{
}]);
// 14. OMML formulas: one inline in the sentence, one alone on its line.
// numerator/denominator take the runs directly — the lib mints m:num/m:den itself,
// and a hand-wrapped MathNumerator doubles the element, which Word refuses to open.
const frac = () => new MathFraction({
numerator: [new MathNumerator([new MathRun('a')])],
denominator: [new MathDenominator([new MathRun('b')])],
numerator: [new MathRun('a')],
denominator: [new MathRun('b')],
});
await write('14-formulas.docx', [{
properties: { page },
@@ -278,7 +280,7 @@ await write('14-formulas.docx', [{
new TextRun(' in the sentence.'),
] }),
new Paragraph({ children: [new DocxMath({ children: [
new MathRadical({ children: [new MathRun('x')], degree: [] }), new MathRun('+1'),
new MathRadical({ children: [new MathRun('x')], degree: [new MathRun('3')] }), new MathRun('+1'),
] })] }),
para(LOREM),
],