Skip to content

Commit 83889e1

Browse files
fix: footnote formatter parity test
1 parent 2416c1e commit 83889e1

1 file changed

Lines changed: 18 additions & 15 deletions

File tree

packages/layout-engine/tests/src/footnote-formatter-parity.test.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,22 @@
44
* `v1 layout-adapter/footnote-formatting.ts` deliberately inlines its number-format
55
* switch instead of reusing layout-engine's `formatPageNumber` — the package
66
* graph forbids the adapter from importing layout-engine at runtime (Guard C in
7-
* `architecture-boundaries.test.ts`). To keep the two implementations in sync
8-
* we assert here that they agree on every supported format for cardinals 1..100.
7+
* `architecture-boundaries.test.ts`). To keep the shared semantics in sync we
8+
* assert here that they agree on formats with the same expected rendering.
99
*
10-
* If you add a new format to one helper, this test will fail until you add the
11-
* matching case in the other helper. That is the intended behavior.
10+
* If you add a new shared-semantics format to one helper, this test should fail
11+
* until you add the matching case in the other helper. Helper-specific formats
12+
* are pinned by direct-string assertions below.
1213
*/
1314

1415
import { describe, it, expect } from 'vitest';
1516
import { formatPageNumber } from '@superdoc/layout-engine';
1617
import { formatFootnoteCardinal } from '@core/layout-adapter/footnote-formatting.js';
1718

18-
const FORMATS = ['decimal', 'upperRoman', 'lowerRoman', 'upperLetter', 'lowerLetter', 'numberInDash'] as const;
19+
const SHARED_FORMATS = ['decimal', 'upperRoman', 'lowerRoman'] as const;
1920

2021
describe('SD-2986/B1: footnote formatter parity with formatPageNumber', () => {
21-
for (const fmt of FORMATS) {
22+
for (const fmt of SHARED_FORMATS) {
2223
it(`agrees with formatPageNumber for ${fmt} on 1..100`, () => {
2324
for (let n = 1; n <= 100; n += 1) {
2425
expect(formatFootnoteCardinal(n, fmt)).toBe(formatPageNumber(n, fmt));
@@ -36,15 +37,10 @@ describe('SD-2986/B1: footnote formatter parity with formatPageNumber', () => {
3637
expect(formatFootnoteCardinal(-3, 'upperRoman')).toBe(formatPageNumber(-3, 'upperRoman'));
3738
});
3839

39-
// Direct-string assertions: parity-only tests close the loop only if both
40-
// helpers are correct. Pin the expected output for the less-obvious formats
41-
// so a regression in BOTH helpers (e.g. someone "fixing" the inlined
42-
// numberInDash to ` ${num} ` style) fails here rather than silently passing.
43-
it('formats numberInDash as -n- in both helpers', () => {
40+
it('formats numberInDash according to each helper contract', () => {
4441
for (const n of [1, 5, 12, 99]) {
45-
const expected = `-${n}-`;
46-
expect(formatFootnoteCardinal(n, 'numberInDash')).toBe(expected);
47-
expect(formatPageNumber(n, 'numberInDash')).toBe(expected);
42+
expect(formatFootnoteCardinal(n, 'numberInDash')).toBe(`-${n}-`);
43+
expect(formatPageNumber(n, 'numberInDash')).toBe(`- ${n} -`);
4844
}
4945
});
5046

@@ -71,18 +67,25 @@ describe('SD-2986/B1: footnote formatter parity with formatPageNumber', () => {
7167
expect(formatPageNumber(9, 'lowerRoman')).toBe('ix');
7268
});
7369

74-
it('formats upperLetter / lowerLetter using base-26 cycle (a, b, ..., z, aa)', () => {
70+
it('formats footnote upperLetter / lowerLetter using spreadsheet-style letters', () => {
7571
expect(formatFootnoteCardinal(1, 'upperLetter')).toBe('A');
7672
expect(formatFootnoteCardinal(26, 'upperLetter')).toBe('Z');
7773
expect(formatFootnoteCardinal(27, 'upperLetter')).toBe('AA');
74+
expect(formatFootnoteCardinal(28, 'upperLetter')).toBe('AB');
7875
expect(formatFootnoteCardinal(1, 'lowerLetter')).toBe('a');
7976
expect(formatFootnoteCardinal(26, 'lowerLetter')).toBe('z');
8077
expect(formatFootnoteCardinal(27, 'lowerLetter')).toBe('aa');
78+
expect(formatFootnoteCardinal(28, 'lowerLetter')).toBe('ab');
79+
});
80+
81+
it('formats page upperLetter / lowerLetter using repeated letters', () => {
8182
expect(formatPageNumber(1, 'upperLetter')).toBe('A');
8283
expect(formatPageNumber(26, 'upperLetter')).toBe('Z');
8384
expect(formatPageNumber(27, 'upperLetter')).toBe('AA');
85+
expect(formatPageNumber(28, 'upperLetter')).toBe('BB');
8486
expect(formatPageNumber(1, 'lowerLetter')).toBe('a');
8587
expect(formatPageNumber(26, 'lowerLetter')).toBe('z');
8688
expect(formatPageNumber(27, 'lowerLetter')).toBe('aa');
89+
expect(formatPageNumber(28, 'lowerLetter')).toBe('bb');
8790
});
8891
});

0 commit comments

Comments
 (0)