@@ -111,20 +111,28 @@ export default function runTest262({ test262Dir, testGlobs, polyfillCodeFile, ex
111111 const polyfillCode = fs . readFileSync ( polyfillCodeFile , UTF8 ) ;
112112 const polyfill = new vm . Script ( polyfillCode , { filename : path . resolve ( polyfillCodeFile ) } ) ;
113113
114- let expectedFailures = new Set ( ) ;
114+ let expectedFailureLists = new Map ( ) ;
115115 if ( expectedFailureFiles ) {
116116 for ( const expectedFailureFile of expectedFailureFiles ) {
117117 // Read the expected failures file and put the paths into a Set
118- const files = fs
118+ const files = new Set ( fs
119119 . readFileSync ( expectedFailureFile , UTF8 )
120120 . split ( / \r ? \n / g)
121- . filter ( ( line ) => line && line [ 0 ] !== '#' ) ;
122- for ( const file of files ) {
123- expectedFailures . add ( file ) ;
124- }
121+ . filter ( ( line ) => line && line [ 0 ] !== '#' ) ) ;
122+ expectedFailureLists . set ( expectedFailureFile , files ) ;
125123 }
126124 }
127125
126+ // This function returns a list of any expected-failure files that mention the
127+ // given test filename, or undefined if no lists reference the given filename.
128+ function getRelevantExpectedFailureLists ( testFile ) {
129+ const ret = [ ] ;
130+ for ( const [ expectedFailureFile , expectedFailureTestsSet ] of expectedFailureLists ) {
131+ if ( expectedFailureTestsSet . has ( testFile ) ) ret . push ( expectedFailureFile ) ;
132+ }
133+ return ret . length > 0 ? ret : undefined ;
134+ }
135+
128136 // This function reads in a test262 harness helper file, specified in 'includes'
129137 // in the frontmatter, and caches the resulting vm.Script so it can be used in
130138 // future tests that also include it.
@@ -212,13 +220,14 @@ export default function runTest262({ test262Dir, testGlobs, polyfillCodeFile, ex
212220 }
213221
214222 const failures = [ ] ;
215- const unexpectedPasses = [ ] ;
223+ // Map from Expected Failure file to a Set of unexpected passing tests
224+ const unexpectedPasses = new Map ( ) ;
216225 const longTests = [ ] ;
217226 let passCount = 0 ;
218227 let expectedFailCount = 0 ;
228+ let unexpectedPassCount = 0 ;
219229
220230 // === The test loop ===
221-
222231 for ( const testFile of testFiles ) {
223232 // Set up the VM context with the polyfill first, as if it were built-in
224233 const testContext = { } ;
@@ -255,6 +264,9 @@ export default function runTest262({ test262Dir, testGlobs, polyfillCodeFile, ex
255264 . replace ( '/prototype/' , '/p/' ) ;
256265 const progressDisplayName = path . dirname ( testDisplayName ) ;
257266 progress . tick ( 0 , { test : progressDisplayName } ) ;
267+ // string[] of expected-failure.txt-style files that expect this test to
268+ // fail, or undefined if no files expect this testcase to fail
269+ const expectedFailureLists = getRelevantExpectedFailureLists ( testRelPath ) ;
258270
259271 // Time each test individually in order to report if they take longer than
260272 // 100 ms
@@ -265,14 +277,20 @@ export default function runTest262({ test262Dir, testGlobs, polyfillCodeFile, ex
265277 // end to see if your test failed.
266278 try {
267279 vm . runInContext ( testCode , testContext ) ;
268- passCount ++ ;
269-
270- if ( expectedFailures . has ( testRelPath ) ) {
271- unexpectedPasses . push ( testRelPath ) ;
280+ if ( ! expectedFailureLists ) {
281+ passCount ++ ;
282+ } else {
283+ unexpectedPassCount ++ ;
272284 progress . interrupt ( `UNEXPECTED PASS: ${ testDisplayName } ` ) ;
285+ for ( const list of expectedFailureLists ) {
286+ if ( ! unexpectedPasses . has ( list ) ) {
287+ unexpectedPasses . set ( list , new Set ( ) ) ;
288+ }
289+ unexpectedPasses . get ( list ) . add ( testRelPath ) ;
290+ }
273291 }
274292 } catch ( e ) {
275- if ( expectedFailures . has ( testRelPath ) ) {
293+ if ( expectedFailureLists ) {
276294 expectedFailCount ++ ;
277295 } else {
278296 failures . push ( { file : testRelPath , error : e } ) ;
@@ -308,10 +326,15 @@ export default function runTest262({ test262Dir, testGlobs, polyfillCodeFile, ex
308326 } ) ;
309327 }
310328
311- if ( unexpectedPasses . length > 0 ) {
312- print ( `\n${ color . yellow . bold ( 'WARNING:' ) } Tests passed unexpectedly; remove them from expected-failures.txt?` ) ;
313- unexpectedPasses . forEach ( ( file ) => print ( ` \u2022 ${ file } ` ) ) ;
329+ if ( unexpectedPasses . size > 0 ) {
314330 hasFailures = true ;
331+ print ( `\n${ color . yellow . bold ( 'WARNING:' ) } Tests passed unexpectedly; remove them from their respective files?` ) ;
332+ for ( const [ expectedFailureFile , unexpectedPassesSet ] of unexpectedPasses ) {
333+ print ( ` \u2022 ${ expectedFailureFile } :` ) ;
334+ for ( const unexpectedPass of unexpectedPassesSet ) {
335+ print ( `${ unexpectedPass } ` ) ;
336+ }
337+ }
315338 }
316339
317340 if ( longTests . length > 0 ) {
@@ -324,6 +347,7 @@ export default function runTest262({ test262Dir, testGlobs, polyfillCodeFile, ex
324347 print ( `\n${ total } tests finished in ${ color . bold ( elapsed . toFixed ( 1 ) ) } s` ) ;
325348 print ( color . green ( ` ${ passCount } passed` ) ) ;
326349 print ( color . red ( ` ${ failures . length } failed` ) ) ;
350+ print ( color . red ( ` ${ unexpectedPassCount } passed unexpectedly` ) ) ;
327351 if ( expectedFailCount > 0 ) {
328352 print ( color . cyan ( ` ${ expectedFailCount } expected failures` ) ) ;
329353 }
0 commit comments