Files
edentext/tests/unit/frame-offset.test.ts
Steffen Becker bd38c955ae test: every fixture picture is a PNG a browser accepts
The 1x1 fixture carried an IDAT from a different image: its CRC fails and the
zlib stream is truncated. Chromium and WebKit render it anyway, Firefox reports
"Image corrupt or truncated", and the same bytes sat in eleven fixtures.
2026-09-06 19:07:24 +02:00

54 lines
2.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// A top-and-bottom frame's own place: Word's positionH/positionV posOffset, ODF's
// svg:x/svg:y. Both offsets round-trip, and one set below its paragraph's top sinks
// behind that paragraph's text (a full-width float pushes following lines under it).
import { describe, it, expect } from 'vitest';
import { buildOdt } from '../../src/lib/export/odt';
import { buildDocx } from '../../src/lib/export/docx';
import { importOdt, sinkOffsetFrames } from '../../src/lib/import/odt';
import { importDocx } from '../../src/lib/import/docx';
type N = any;
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
const IMG = (attrs: N): N => ({ type: 'image', attrs: { src: PNG, width: 200, height: 120, ...attrs } });
const doc: N = {
type: 'doc',
content: [{
type: 'paragraph',
content: [{ type: 'text', text: 'anchor text' }, IMG({ wrap: 'topBottom', wrapOffset: 3.5, wrapOffsetY: 5.75 })],
}],
};
const frame = (d: N) => d.content[0].content.find((n: N) => n.type === 'image');
const margins = { top: 2, bottom: 2, left: 2, right: 2 };
describe('a top-and-bottom frame’s offsets', () => {
it('round-trips both offsets through ODF', async () => {
const img = frame((await importOdt(await buildOdt(doc, margins, 'portrait'))).content);
expect(img.attrs.wrapOffset).toBeCloseTo(3.5, 2);
expect(img.attrs.wrapOffsetY).toBeCloseTo(5.75, 2);
});
it('round-trips both offsets through DOCX', async () => {
const img = frame(importDocx(await buildDocx(doc, margins, 'portrait')).content);
expect(img.attrs.wrapOffset).toBeCloseTo(3.5, 2);
expect(img.attrs.wrapOffsetY).toBeCloseTo(5.75, 2);
});
it('sinks a frame set below the paragraph top behind its text', () => {
const content = [IMG({ wrap: 'topBottom', wrapOffsetY: 5.75 }), { type: 'text', text: 'hi' }];
sinkOffsetFrames(content);
expect(content.map((n: N) => n.type)).toEqual(['text', 'image']);
});
it('leaves a frame at the paragraph top, and one with no text to stand behind', () => {
const flush = [IMG({ wrap: 'topBottom' }), { type: 'text', text: 'hi' }];
sinkOffsetFrames(flush);
expect(flush.map((n: N) => n.type)).toEqual(['image', 'text']);
const alone = [IMG({ wrap: 'topBottom', wrapOffsetY: 5.75 })];
sinkOffsetFrames(alone);
expect(alone.map((n: N) => n.type)).toEqual(['image']);
});
});