@@ -4,6 +4,7 @@ const path = require('node:path');
44const test = require ( 'node:test' ) ;
55const fs = require ( 'node:fs/promises' ) ;
66const assert = require ( 'node:assert/strict' ) ;
7+ const { hostname } = require ( 'node:os' ) ;
78
89const stackFramesRegexp = / (?< = \n ) ( \s + ) ( ( .+ ?) \s + \( ) ? (?: \( ? ( .+ ?) : ( \d + ) (?: : ( \d + ) ) ? ) \) ? ( \s + \{ ) ? ( \[ \d + m ) ? ( \n | $ ) / g;
910const windowNewlineRegexp = / \r / g;
@@ -100,6 +101,97 @@ async function spawnAndAssert(filename, transform = (x) => x, { tty = false, ...
100101 await assertSnapshot ( transform ( `${ stdout } ${ stderr } ` ) , filename ) ;
101102}
102103
104+ function replaceTestDuration ( str ) {
105+ return str
106+ . replaceAll ( / d u r a t i o n _ m s : [ 0 - 9 . ] + / g, 'duration_ms: *' )
107+ . replaceAll ( / d u r a t i o n _ m s [ 0 - 9 . ] + / g, 'duration_ms *' ) ;
108+ }
109+
110+ const root = path . resolve ( __dirname , '..' , '..' ) ;
111+ const color = '(\\[\\d+m)' ;
112+ const stackTraceBasePath = new RegExp ( `${ color } \\(${ root . replaceAll ( / [ \\ ^ $ * + ? . ( ) | [ \] { } ] / g, '\\$&' ) } /?${ color } (.*)${ color } \\)` , 'g' ) ;
113+
114+ function replaceSpecDuration ( str ) {
115+ return str
116+ . replaceAll ( / [ 0 - 9 . ] + m s / g, '*ms' )
117+ . replaceAll ( / d u r a t i o n _ m s [ 0 - 9 . ] + / g, 'duration_ms *' )
118+ . replace ( stackTraceBasePath , '$3' ) ;
119+ }
120+
121+ function replaceJunitDuration ( str ) {
122+ return str
123+ . replaceAll ( / t i m e = " [ 0 - 9 . ] + " / g, 'time="*"' )
124+ . replaceAll ( / d u r a t i o n _ m s [ 0 - 9 . ] + / g, 'duration_ms *' )
125+ . replaceAll ( `hostname="${ hostname ( ) } "` , 'hostname="HOSTNAME"' )
126+ . replaceAll ( / f i l e = " [ ^ " ] * " / g, 'file="*"' )
127+ . replace ( stackTraceBasePath , '$3' ) ;
128+ }
129+
130+ function removeWindowsPathEscaping ( str ) {
131+ return common . isWindows ? str . replaceAll ( / \\ \\ / g, '\\' ) : str ;
132+ }
133+
134+ function replaceTestLocationLine ( str ) {
135+ return str . replaceAll ( / ( j s : ) ( \d + ) ( : \d + ) / g, '$1(LINE)$3' ) ;
136+ }
137+
138+ // The Node test coverage returns results for all files called by the test. This
139+ // will make the output file change if files like test/common/index.js change.
140+ // This transform picks only the first line and then the lines from the test
141+ // file.
142+ function pickTestFileFromLcov ( str ) {
143+ const lines = str . split ( / \n / ) ;
144+ const firstLineOfTestFile = lines . findIndex (
145+ ( line ) => line . startsWith ( 'SF:' ) && line . trim ( ) . endsWith ( 'output.js' ) ,
146+ ) ;
147+ const lastLineOfTestFile = lines . findIndex (
148+ ( line , index ) => index > firstLineOfTestFile && line . trim ( ) === 'end_of_record' ,
149+ ) ;
150+ return (
151+ lines [ 0 ] + '\n' + lines . slice ( firstLineOfTestFile , lastLineOfTestFile + 1 ) . join ( '\n' ) + '\n'
152+ ) ;
153+ }
154+
155+ const defaultTransform = transform (
156+ replaceWindowsLineEndings ,
157+ replaceStackTrace ,
158+ removeWindowsPathEscaping ,
159+ transformProjectRoot ( ) ,
160+ replaceWindowsPaths ,
161+ replaceTestDuration ,
162+ replaceTestLocationLine ,
163+ ) ;
164+ const specTransform = transform (
165+ replaceSpecDuration ,
166+ replaceWindowsLineEndings ,
167+ replaceStackTrace ,
168+ replaceWindowsPaths ,
169+ ) ;
170+ const junitTransform = transform (
171+ replaceJunitDuration ,
172+ replaceWindowsLineEndings ,
173+ replaceStackTrace ,
174+ replaceWindowsPaths ,
175+ ) ;
176+ const lcovTransform = transform (
177+ replaceWindowsLineEndings ,
178+ replaceStackTrace ,
179+ transformProjectRoot ( ) ,
180+ replaceWindowsPaths ,
181+ pickTestFileFromLcov ,
182+ ) ;
183+
184+ function ensureCwdIsProjectRoot ( ) {
185+ if ( process . cwd ( ) !== root ) {
186+ process . chdir ( root ) ;
187+ }
188+ }
189+
190+ function canColorize ( ) {
191+ // Loading it lazily to avoid breaking `NODE_REGENERATE_SNAPSHOTS`.
192+ return require ( 'internal/tty' ) . getColorDepth ( ) > 2 ;
193+ }
194+
103195module . exports = {
104196 assertSnapshot,
105197 getSnapshotPath,
@@ -111,4 +203,11 @@ module.exports = {
111203 spawnAndAssert,
112204 transform,
113205 transformProjectRoot,
206+ replaceTestDuration,
207+ defaultTransform,
208+ specTransform,
209+ junitTransform,
210+ lcovTransform,
211+ ensureCwdIsProjectRoot,
212+ canColorize,
114213} ;
0 commit comments