Skip to content

Commit ece83b6

Browse files
caio-pizzolVladaHarbour
authored andcommitted
test: add even/odd header variant tests for layout engine and per-rId layout
- Layout engine: verify oddEvenHeadersFooters drives physical-page parity for margin inflation (odd pages get odd-header height, even pages get even-header height), and that the option being unset keeps default behavior - HeaderFooterPerRidLayout: verify even/odd header refs inherited from earlier sections produce per-section layout cache entries
1 parent ac63995 commit ece83b6

2 files changed

Lines changed: 157 additions & 0 deletions

File tree

packages/layout-engine/layout-engine/src/index.test.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,92 @@ describe('layoutDocument', () => {
883883
expect(section2Page!.margins.top).toBeGreaterThanOrEqual(72 + tallFirst - 1);
884884
});
885885

886+
it('uses physical page number for even/odd variant selection when oddEvenHeadersFooters is enabled', () => {
887+
const m = { top: 72, bottom: 72, left: 72, right: 72, header: 36, footer: 36 };
888+
889+
// Single section with alternateHeaders. Odd physical pages get 'odd' variant,
890+
// even physical pages get 'even' variant. Each variant has a different header
891+
// height so we can verify the correct one drives margin inflation.
892+
const sb0: FlowBlock = {
893+
kind: 'sectionBreak',
894+
id: 'sb-0',
895+
type: 'continuous',
896+
margins: m,
897+
headerRefs: { default: 'd0', even: 'e0', odd: 'o0' },
898+
attrs: { isFirstSection: true, sectionIndex: 0 },
899+
};
900+
901+
const lineHeight = 20;
902+
const blocks: FlowBlock[] = [sb0, { kind: 'paragraph', id: 'p0', runs: [] }];
903+
const measures: Measure[] = [
904+
{ kind: 'sectionBreak' },
905+
makeMeasure(Array(80).fill(lineHeight)), // enough content for multiple pages
906+
];
907+
908+
const evenHeight = 120;
909+
const oddHeight = 80;
910+
const sectionMetadata: SectionMetadata[] = [
911+
{ sectionIndex: 0, headerRefs: { default: 'd0', even: 'e0', odd: 'o0' } },
912+
];
913+
914+
const layout = layoutDocument(blocks, measures, {
915+
pageSize: { w: 612, h: 792 },
916+
margins: m,
917+
sectionMetadata,
918+
oddEvenHeadersFooters: true,
919+
headerContentHeightsByRId: new Map([
920+
['e0', evenHeight],
921+
['o0', oddHeight],
922+
]),
923+
});
924+
925+
expect(layout.pages.length).toBeGreaterThanOrEqual(2);
926+
927+
// Page 1 (physical 1, odd): odd variant → margin inflated by oddHeight
928+
const page1 = layout.pages[0];
929+
expect(page1.margins.top).toBeGreaterThanOrEqual(36 + oddHeight - 1);
930+
931+
// Page 2 (physical 2, even): even variant → margin inflated by evenHeight
932+
const page2 = layout.pages[1];
933+
expect(page2.margins.top).toBeGreaterThanOrEqual(36 + evenHeight - 1);
934+
// Even margin should be larger than odd margin since evenHeight > oddHeight
935+
expect(page2.margins.top).toBeGreaterThan(page1.margins.top);
936+
});
937+
938+
it('does not use even/odd variants when oddEvenHeadersFooters is not set', () => {
939+
const m = { top: 72, bottom: 72, left: 72, right: 72, header: 36, footer: 36 };
940+
const sb0: FlowBlock = {
941+
kind: 'sectionBreak',
942+
id: 'sb-0',
943+
type: 'continuous',
944+
margins: m,
945+
headerRefs: { default: 'd0', even: 'e0' },
946+
attrs: { isFirstSection: true, sectionIndex: 0 },
947+
};
948+
949+
const lineHeight = 20;
950+
const blocks: FlowBlock[] = [sb0, { kind: 'paragraph', id: 'p0', runs: [] }];
951+
const measures: Measure[] = [{ kind: 'sectionBreak' }, makeMeasure(Array(80).fill(lineHeight))];
952+
953+
const tallEven = 200;
954+
const layout = layoutDocument(blocks, measures, {
955+
pageSize: { w: 612, h: 792 },
956+
margins: m,
957+
sectionMetadata: [{ sectionIndex: 0, headerRefs: { default: 'd0', even: 'e0' } }],
958+
// oddEvenHeadersFooters NOT set
959+
headerContentHeightsByRId: new Map([
960+
['e0', tallEven],
961+
['d0', 10],
962+
]),
963+
});
964+
965+
// Without oddEvenHeadersFooters, all pages use 'default' variant —
966+
// margins should NOT be inflated by the even header height
967+
for (const page of layout.pages) {
968+
expect(page.margins.top).toBeLessThan(36 + tallEven);
969+
}
970+
});
971+
886972
it('applies section break margins to subsequent pages', () => {
887973
const sectionBreakBlock: FlowBlock = {
888974
kind: 'sectionBreak',

packages/super-editor/src/editors/v1/core/header-footer/HeaderFooterPerRidLayout.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,75 @@ describe('layoutPerRIdHeaderFooters', () => {
129129
expect(deps.headerLayoutsByRId.has('rId-header-first')).toBe(true);
130130
expect(deps.headerLayoutsByRId.has('rId-header-orphan')).toBe(false);
131131
});
132+
133+
it('lays out even/odd header refs inherited from earlier sections', async () => {
134+
const deps = {
135+
headerLayoutsByRId: new Map(),
136+
footerLayoutsByRId: new Map(),
137+
};
138+
139+
const layout: Layout = {
140+
pageSize: { w: 612, h: 792 },
141+
pages: [
142+
{ number: 1, fragments: [], sectionIndex: 0 },
143+
{ number: 2, fragments: [], sectionIndex: 0 },
144+
{ number: 3, fragments: [], sectionIndex: 1 },
145+
],
146+
};
147+
148+
const sectionMetadata: SectionMetadata[] = [
149+
{
150+
sectionIndex: 0,
151+
pageSize: { w: 612, h: 792 },
152+
margins: { top: 72, right: 72, bottom: 72, left: 72, header: 36 },
153+
headerRefs: {
154+
default: 'rId-default',
155+
even: 'rId-even',
156+
odd: 'rId-odd',
157+
},
158+
},
159+
{
160+
sectionIndex: 1,
161+
pageSize: { w: 612, h: 792 },
162+
margins: { top: 72, right: 72, bottom: 72, left: 72, header: 36 },
163+
headerRefs: {
164+
default: 'rId-default-s1',
165+
// even and odd NOT defined — should be inherited from section 0
166+
},
167+
},
168+
];
169+
170+
await layoutPerRIdHeaderFooters(
171+
{
172+
headerBlocksByRId: new Map([
173+
['rId-default', [makeParagraph('h-default', 'Default')]],
174+
['rId-even', [makeParagraph('h-even', 'Even header')]],
175+
['rId-odd', [makeParagraph('h-odd', 'Odd header')]],
176+
['rId-default-s1', [makeParagraph('h-default-s1', 'Section 1 default')]],
177+
]),
178+
footerBlocksByRId: new Map(),
179+
constraints: {
180+
width: 468,
181+
height: 648,
182+
pageWidth: 612,
183+
pageHeight: 792,
184+
margins: { left: 72, right: 72, top: 72, bottom: 72, header: 36 },
185+
overflowBaseHeight: 36,
186+
},
187+
},
188+
layout,
189+
sectionMetadata,
190+
deps,
191+
);
192+
193+
// Section 0 should have default, even, and odd layouts
194+
expect(deps.headerLayoutsByRId.has('rId-default::s0')).toBe(true);
195+
expect(deps.headerLayoutsByRId.has('rId-even::s0')).toBe(true);
196+
expect(deps.headerLayoutsByRId.has('rId-odd::s0')).toBe(true);
197+
198+
// Section 1 should have its own default, plus inherited even and odd from section 0
199+
expect(deps.headerLayoutsByRId.has('rId-default-s1::s1')).toBe(true);
200+
expect(deps.headerLayoutsByRId.has('rId-even::s1')).toBe(true);
201+
expect(deps.headerLayoutsByRId.has('rId-odd::s1')).toBe(true);
202+
});
132203
});

0 commit comments

Comments
 (0)