@@ -113,180 +113,6 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
113
113
}
114
114
}
115
115
116
- export class UserCodeRunner extends ExternalCompileRunnerBase {
117
- readonly testDir = "tests/cases/user/" ;
118
- kind ( ) : TestRunnerKind {
119
- return "user" ;
120
- }
121
- report ( result : ExecResult ) {
122
- // eslint-disable-next-line no-null/no-null
123
- return result . status === 0 && ! result . stdout . length && ! result . stderr . length ? null : `Exit Code: ${ result . status }
124
- Standard output:
125
- ${ sortErrors ( stripAbsoluteImportPaths ( result . stdout . toString ( ) . replace ( / \r \n / g, "\n" ) ) ) }
126
-
127
-
128
- Standard error:
129
- ${ stripAbsoluteImportPaths ( result . stderr . toString ( ) . replace ( / \r \n / g, "\n" ) ) } `;
130
- }
131
- }
132
-
133
- export class DockerfileRunner extends ExternalCompileRunnerBase {
134
- readonly testDir = "tests/cases/docker/" ;
135
- kind ( ) : TestRunnerKind {
136
- return "docker" ;
137
- }
138
- override initializeTests ( ) : void {
139
- // Read in and evaluate the test list
140
- const testList = this . tests && this . tests . length ? this . tests : this . getTestFiles ( ) ;
141
-
142
- // eslint-disable-next-line @typescript-eslint/no-this-alias
143
- const cls = this ;
144
- describe ( `${ this . kind ( ) } code samples` , function ( this : Mocha . Suite ) {
145
- this . timeout ( cls . timeout ) ; // 20 minutes
146
- before ( ( ) => {
147
- // cached because workspace is hashed to determine cacheability
148
- cls . exec ( "docker" , [ "build" , "." , "-t" , "typescript/typescript" , "-f" , cls . testDir + "Dockerfile" ] , {
149
- cwd : IO . getWorkspaceRoot ( ) ,
150
- env : { ...process . env , DOCKER_BUILDKIT : "1" } , // We need buildkit to allow Dockerfile.dockerignore to work.
151
- } ) ;
152
- } ) ;
153
- for ( const test of testList ) {
154
- const directory = typeof test === "string" ? test : test . file ;
155
- const cwd = path . join ( IO . getWorkspaceRoot ( ) , cls . testDir , directory ) ;
156
- it ( `should build ${ directory } successfully` , ( ) => {
157
- const imageName = `tstest/${ directory } ` ;
158
- cls . exec ( "docker" , [ "build" , "--no-cache" , "." , "-t" , imageName ] , { cwd } ) ; // --no-cache so the latest version of the repos referenced is always fetched
159
- const cp : typeof import ( "child_process" ) = require ( "child_process" ) ;
160
- Baseline . runBaseline ( `${ cls . kind ( ) } /${ directory } .log` , cls . report ( cp . spawnSync ( `docker` , [ "run" , imageName ] , { cwd, timeout : cls . timeout , shell : true } ) ) ) ;
161
- } ) ;
162
- }
163
- } ) ;
164
- }
165
-
166
- private timeout = 1_200_000 ; // 20 minutes;
167
- private exec ( command : string , args : string [ ] , options : { cwd : string ; env ?: NodeJS . ProcessEnv } ) : void {
168
- const cp : typeof import ( "child_process" ) = require ( "child_process" ) ;
169
- const stdio = isWorker ? "pipe" : "inherit" ;
170
- const res = cp . spawnSync ( isWorker ? `${ command } 2>&1` : command , args , { timeout : this . timeout , shell : true , stdio, ...options } ) ;
171
- if ( res . status !== 0 ) {
172
- throw new Error ( `${ command } ${ args . join ( " " ) } for ${ options . cwd } failed: ${ res . stdout && res . stdout . toString ( ) } ` ) ;
173
- }
174
- }
175
- report ( result : ExecResult ) {
176
- // eslint-disable-next-line no-null/no-null
177
- return result . status === 0 && ! result . stdout . length && ! result . stderr . length ? null : `Exit Code: ${ result . status }
178
- Standard output:
179
- ${ sanitizeDockerfileOutput ( result . stdout . toString ( ) ) }
180
-
181
-
182
- Standard error:
183
- ${ sanitizeDockerfileOutput ( result . stderr . toString ( ) ) } `;
184
- }
185
- }
186
-
187
- function sanitizeDockerfileOutput ( result : string ) : string {
188
- return [
189
- normalizeNewlines ,
190
- stripANSIEscapes ,
191
- stripRushStageNumbers ,
192
- stripWebpackHash ,
193
- sanitizeVersionSpecifiers ,
194
- sanitizeTimestamps ,
195
- sanitizeSizes ,
196
- sanitizeUnimportantGulpOutput ,
197
- stripAbsoluteImportPaths ,
198
- ] . reduce ( ( result , f ) => f ( result ) , result ) ;
199
- }
200
-
201
- function normalizeNewlines ( result : string ) : string {
202
- return result . replace ( / \r \n / g, "\n" ) ;
203
- }
204
-
205
- function stripANSIEscapes ( result : string ) : string {
206
- return result . replace ( / \x1b \[ [ 0 - 9 ; ] * [ a - z A - Z ] / g, "" ) ;
207
- }
208
-
209
- function stripRushStageNumbers ( result : string ) : string {
210
- return result . replace ( / \d + o f \d + : / g, "XX of XX:" ) ;
211
- }
212
-
213
- function stripWebpackHash ( result : string ) : string {
214
- return result . replace ( / H a s h : \w + / g, "Hash: [redacted]" ) ;
215
- }
216
-
217
- function sanitizeSizes ( result : string ) : string {
218
- return result . replace ( / \d + ( \. \d + ) ? ( ( K i | M ) B | b y t e s ) / g, "X KiB" ) ;
219
- }
220
-
221
- /**
222
- * Gulp's output order within a `parallel` block is nondeterministic (and there's no way to configure it to execute in series),
223
- * so we purge as much of the gulp output as we can
224
- */
225
- function sanitizeUnimportantGulpOutput ( result : string ) : string {
226
- return result . replace ( / ^ .* ( \] ( S t a r t i n g ) | ( F i n i s h e d ) ) .* $ / gm, "" ) // "gulp" task start/end messages (nondeterministic order)
227
- . replace ( / ^ .* ( \] . ( f i n i s h e d ) | ( s t a r t e d ) ) .* $ / gm, "" ) // "just" task start/end messages (nondeterministic order)
228
- . replace ( / ^ .* \] R e s p a w n e d t o P I D : \d + .* $ / gm, "" ) // PID of child is OS and system-load dependent (likely stableish in a container but still dangerous)
229
- . replace ( / \n + / g, "\n" )
230
- . replace ( / \/ t m p \/ y a r n - - .* ?\/ n o d e / g, "" ) ;
231
- }
232
-
233
- function sanitizeTimestamps ( result : string ) : string {
234
- return result . replace ( / \[ \d ? \d : \d \d : \d \d ( A | P ) M \] / g, "[XX:XX:XX XM]" )
235
- . replace ( / \[ \d ? \d : \d \d : \d \d \] / g, "[XX:XX:XX]" )
236
- . replace ( / \/ \d + - \d + - [ \d _ T Z ] + - d e b u g .l o g / g, "\/XXXX-XX-XXXXXXXXX-debug.log" )
237
- . replace ( / \d + \/ \d + \/ \d + \d + : \d + : \d + ( A M | P M ) / g, "XX/XX/XX XX:XX:XX XM" )
238
- . replace ( / \d + ( \. \d + ) ? s e c ( o n d s ? ) ? / g, "? seconds" )
239
- . replace ( / \d + ( \. \d + ) ? m i n ( u t e s ? ) ? / g, "" )
240
- . replace ( / \d + ( \. \d + ) ? ? m ? s / g, "?s" )
241
- . replace ( / \( \? s \) / g, "" ) ;
242
- }
243
-
244
- function sanitizeVersionSpecifiers ( result : string ) : string {
245
- return result
246
- . replace ( / \d + .\d + .\d + - i n s i d e r s .\d \d \d \d \d \d \d \d / g, "X.X.X-insiders.xxxxxxxx" )
247
- . replace ( / R u s h M u l t i - P r o j e c t B u i l d T o o l ( \d + ) \. \d + \. \d + / g, "Rush Multi-Project Build Tool $1.X.X" )
248
- . replace ( / ( [ @ v \( ) ] ) \d + \. \d + \. \d + / g, "$1X.X.X" )
249
- . replace ( / w e b p a c k ( \d + ) \. \d + \. \d + / g, "webpack $1.X.X" )
250
- . replace ( / W e b p a c k v e r s i o n : ( \d + ) \. \d + \. \d + / g, "Webpack version: $1.X.X" ) ;
251
- }
252
-
253
- /**
254
- * Import types and some other error messages use absolute paths in errors as they have no context to be written relative to;
255
- * This is problematic for error baselines, so we grep for them and strip them out.
256
- */
257
- function stripAbsoluteImportPaths ( result : string ) {
258
- const workspaceRegexp = new RegExp ( IO . getWorkspaceRoot ( ) . replace ( / \\ / g, "\\\\" ) , "g" ) ;
259
- return result
260
- . replace ( / i m p o r t \( " .* ?\/ t e s t s \/ c a s e s \/ u s e r \/ / g, `import("/` )
261
- . replace ( / M o d u l e ' " .* ?\/ t e s t s \/ c a s e s \/ u s e r \/ / g, `Module '"/` )
262
- . replace ( workspaceRegexp , "../../.." ) ;
263
- }
264
-
265
- function sortErrors ( result : string ) {
266
- return ts . flatten ( splitBy ( result . split ( "\n" ) , s => / ^ \S + / . test ( s ) ) . sort ( compareErrorStrings ) ) . join ( "\n" ) ;
267
- }
268
-
269
- const errorRegexp = / ^ ( .+ \. [ t j ] s x ? ) \( ( \d + ) , ( \d + ) \) ( : e r r o r T S .* ) / ;
270
- function compareErrorStrings ( a : string [ ] , b : string [ ] ) {
271
- ts . Debug . assertGreaterThanOrEqual ( a . length , 1 ) ;
272
- ts . Debug . assertGreaterThanOrEqual ( b . length , 1 ) ;
273
- const matchA = a [ 0 ] . match ( errorRegexp ) ;
274
- if ( ! matchA ) {
275
- return - 1 ;
276
- }
277
- const matchB = b [ 0 ] . match ( errorRegexp ) ;
278
- if ( ! matchB ) {
279
- return 1 ;
280
- }
281
- const [ , errorFileA , lineNumberStringA , columnNumberStringA , remainderA ] = matchA ;
282
- const [ , errorFileB , lineNumberStringB , columnNumberStringB , remainderB ] = matchB ;
283
- return ts . comparePathsCaseSensitive ( errorFileA , errorFileB ) ||
284
- ts . compareValues ( parseInt ( lineNumberStringA ) , parseInt ( lineNumberStringB ) ) ||
285
- ts . compareValues ( parseInt ( columnNumberStringA ) , parseInt ( columnNumberStringB ) ) ||
286
- ts . compareStringsCaseSensitive ( remainderA , remainderB ) ||
287
- ts . compareStringsCaseSensitive ( a . slice ( 1 ) . join ( "\n" ) , b . slice ( 1 ) . join ( "\n" ) ) ;
288
- }
289
-
290
116
export class DefinitelyTypedRunner extends ExternalCompileRunnerBase {
291
117
readonly testDir = "../DefinitelyTyped/types/" ;
292
118
override workingDirectory = this . testDir ;
@@ -304,31 +130,3 @@ Standard error:
304
130
${ result . stderr . toString ( ) . replace ( / \r \n / g, "\n" ) } `;
305
131
}
306
132
}
307
-
308
- /**
309
- * Split an array into multiple arrays whenever `isStart` returns true.
310
- * @example
311
- * splitBy([1,2,3,4,5,6], isOdd)
312
- * ==> [[1, 2], [3, 4], [5, 6]]
313
- * where
314
- * const isOdd = n => !!(n % 2)
315
- */
316
- function splitBy < T > ( xs : T [ ] , isStart : ( x : T ) => boolean ) : T [ ] [ ] {
317
- const result = [ ] ;
318
- let group : T [ ] = [ ] ;
319
- for ( const x of xs ) {
320
- if ( isStart ( x ) ) {
321
- if ( group . length ) {
322
- result . push ( group ) ;
323
- }
324
- group = [ x ] ;
325
- }
326
- else {
327
- group . push ( x ) ;
328
- }
329
- }
330
- if ( group . length ) {
331
- result . push ( group ) ;
332
- }
333
- return result ;
334
- }
0 commit comments