@@ -28,22 +28,26 @@ test.describe('router ssg snapshot', () => {
2828 const state = extractState ( html ) ;
2929 expect ( state ) . not . toBeNull ( ) ;
3030
31- const normalizedHtml = normalizeHtml ( html ) ;
31+ const manifestHash = extractManifestHash ( html ) ;
32+ const normalizedHtml = normalizeHtml ( html , manifestHash ) ;
3233 const normalizedState = normalizeStateDump (
33- _dumpState ( JSON . parse ( state ! ) as unknown [ ] , false , '' , null )
34+ _dumpState ( JSON . parse ( state ! ) as unknown [ ] , false , '' , null ) ,
35+ manifestHash
3436 ) ;
3537
3638 if ( process . env . UPDATE_SSG_SNAPSHOT === '1' ) {
3739 await writeFile ( expectedHtmlPath , normalizedHtml , 'utf-8' ) ;
3840 await writeFile ( expectedStatePath , normalizedState , 'utf-8' ) ;
3941 }
4042
41- expect ( normalizedHtml ) . toEqual (
42- ( await readFile ( expectedHtmlPath , 'utf-8' ) ) . replace ( / \r \n / g, '\n' )
43- ) ;
44- expect ( normalizedState ) . toEqual (
45- ( await readFile ( expectedStatePath , 'utf-8' ) ) . replace ( / \r \n / g, '\n' )
46- ) ;
43+ const expectedHtml = ( await readFile ( expectedHtmlPath , 'utf-8' ) ) . replace ( / \r \n / g, '\n' ) ;
44+ const expectedState = ( await readFile ( expectedStatePath , 'utf-8' ) ) . replace ( / \r \n / g, '\n' ) ;
45+
46+ warnIfSizeChanged ( 'readable state dump' , expectedState , normalizedState ) ;
47+ warnIfSizeChanged ( 'HTML' , expectedHtml , normalizedHtml ) ;
48+
49+ expect ( normalizedState ) . toEqual ( expectedState ) ;
50+ expect ( normalizedHtml ) . toEqual ( expectedHtml ) ;
4751 } ) ;
4852} ) ;
4953
@@ -104,31 +108,59 @@ async function buildFixtureApp() {
104108 ) ;
105109}
106110
107- function normalizeHtml ( html : string ) {
108- return html
111+ function extractManifestHash ( html : string ) : string | null {
112+ const match = html . match ( / q : m a n i f e s t - h a s h = " ( [ ^ " ] * ) " / ) ;
113+ return match ? match [ 1 ] : null ;
114+ }
115+
116+ function normalizeHtml ( html : string , manifestHash : string | null ) {
117+ let result = html ;
118+ if ( manifestHash ) {
119+ result = result . replaceAll ( manifestHash , 'MANIFEST_HASH' ) ;
120+ }
121+ result = result
109122 . replace ( / \r \n / g, '\n' )
110123 . replace ( / q : v e r s i o n = " [ ^ " ] * " / g, '' )
111124 . replace ( / q : i n s t a n c e = " [ ^ " ] * " / g, ' q:instance="[instance]"' )
112- . replace ( / q : m a n i f e s t - h a s h = " [ ^ " ] * " / g, ' q:manifest-hash="[manifest]"' )
113125 . replace ( / \/ a s s e t s \/ [ A - Z a - z 0 - 9 _ - ] + - b u n d l e - g r a p h \. j s o n / g, '/assets/xxxxxxxx-bundle-graph.json' )
114126 . replace ( / q - [ A - Z a - z 0 - 9 _ - ] + \. ( j s | c s s ) / g, 'q-xxxxxxxx.$1' )
115127 . replace ( / q F u n c s _ [ A - Z a - z 0 - 9 _ - ] + / g, 'qFuncs_xxxxxx' )
116128 . replace ( / < s c r i p t t y p e = " q w i k \/ s t a t e " [ ^ > ] * > [ \s \S ] * ?< \/ s c r i p t > / , '[state omitted]\n' )
117129 . replace ( / < s c r i p t t y p e = " q w i k \/ v n o d e " [ ^ > ] * > [ \s \S ] * ?< \/ s c r i p t > / , '[vnode map omitted]\n' ) ;
130+ return result ;
118131}
119132
120133function extractState ( html : string ) {
121134 const match = html . match ( / < s c r i p t t y p e = " q w i k \/ s t a t e " [ ^ > ] * > ( [ \s \S ] * ?) < \/ s c r i p t > / ) ;
122135 return match ? match [ 1 ] : null ;
123136}
124137
125- function normalizeStateDump ( stateDump : string ) {
126- return stateDump
138+ function normalizeStateDump ( stateDump : string , manifestHash : string | null ) {
139+ let result = stateDump
127140 . replace ( / \r \n / g, '\n' )
128- . replace ( / m a n i f e s t H a s h " \n \s + \{ s t r i n g \} " [ ^ " ] + " / g, 'manifestHash"\n {string} "[manifest] "' )
141+ . replace ( / m a n i f e s t H a s h " \n \s + \{ s t r i n g \} " [ ^ " ] + " / g, 'manifestHash"\n {string} "MANIFEST_HASH "' )
129142 . replace ( / q F u n c s _ [ A - Z a - z 0 - 9 _ - ] + / g, 'qFuncs_xxxxxx' )
130143 . replace ( / q - [ A - Z a - z 0 - 9 _ - ] + \. ( j s | c s s ) / g, 'q-xxxxxxxx.$1' )
131144 . replaceAll ( / R o o t R e f .* / g, 'RootRef [omitted]' )
132145 . replaceAll ( / Q R L " .* " / g, 'QRL "[omitted]"' )
133146 . replace ( / ^ \( \d + c h a r s \) $ / m, '' ) ;
147+ if ( manifestHash ) {
148+ result = result . replaceAll ( manifestHash , 'MANIFEST_HASH' ) ;
149+ }
150+ return result ;
151+ }
152+
153+ function warnIfSizeChanged ( label : string , expected : string , actual : string ) {
154+ const expectedLen = expected . length ;
155+ const actualLen = actual . length ;
156+ if ( expectedLen === 0 ) {
157+ return ;
158+ }
159+ const pct = Math . abs ( actualLen - expectedLen ) / expectedLen ;
160+ if ( pct > 0.01 ) {
161+ console . error (
162+ `\n\n[ssg-snapshot] ${ label } size changed by ${ ( pct * 100 ) . toFixed ( 1 ) } %: ` +
163+ `${ expectedLen } → ${ actualLen } chars`
164+ ) ;
165+ }
134166}
0 commit comments