test: cross-format fuzz leg, ODT vs DOCX round-trip

The same seeded documents go through buildOdt->importOdt and
buildDocx->importDocx; the two imports must agree, so one exporter
silently losing what the other keeps now fails with the seed named.
Column widths are ignored here (ODT leaves defaults implicit, DOCX
always writes w:tcW); each format's own leg still covers them.
This commit is contained in:
Steffen Becker committed 2026-08-15 22:58:29 +02:00
1 parent 76856f4aff
commit 47bbbfc7dd
1 file changed
+26
+26
View File
@@ -3,6 +3,8 @@
import { describe, it, expect } from 'vitest';
import { buildOdt } from '../src/lib/export/odt';
import { importOdt } from '../src/lib/import/odt';
import { buildDocx } from '../src/lib/export/docx';
import { importDocx } from '../src/lib/import/docx';
import { normalize, firstDiff } from './normalize';
import { genDoc, mulberry32 } from './fuzzDoc';
@@ -30,4 +32,28 @@ describe('fuzz round-trip: editor → buildOdt → importOdt', () => {
expect.soft(diff, `seed ${seed} (re-run genDoc(mulberry32(${seed})) to reproduce)`).toBeNull();
}
}, 120_000);
// ODT leaves default column widths implicit where DOCX always writes w:tcW; ignore
// them in the cross-format comparison (each format's own leg still covers widths).
function stripColwidth(node: any): any {
if (node.attrs?.colwidth) {
delete node.attrs.colwidth;
if (!Object.keys(node.attrs).length) delete node.attrs;
}
for (const c of node.content ?? []) stripColwidth(c);
return node;
}
// Cross-format: the same document through both pipelines must import identically —
// catches one exporter silently losing what the other keeps.
it('50 seeded documents agree between the ODT and DOCX round-trips', async () => {
for (let seed = 1; seed <= 50; seed++) {
const doc = genDoc(mulberry32(seed));
const viaOdt = importOdt(await buildOdt(doc, margins, 'portrait')).content;
const viaDocx = importDocx(await buildDocx(doc, margins, 'portrait')).content;
const diff = firstDiff(stripColwidth(stripFontHoist(normalize(viaOdt))),
stripColwidth(stripFontHoist(normalize(viaDocx))));
expect.soft(diff, `seed ${seed}: ODT vs DOCX import (genDoc(mulberry32(${seed})))`).toBeNull();
}
}, 120_000);
});