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
1415import { describe , it , expect } from 'vitest' ;
1516import { formatPageNumber } from '@superdoc/layout-engine' ;
1617import { 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
2021describe ( '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