@@ -8,11 +8,11 @@ var child_process = require('child_process');
88var stream = require ( 'stream' ) ;
99var util = require ( 'util' ) ;
1010var Timer = process . binding ( 'timer_wrap' ) . Timer ;
11+ var execSync = require ( 'child_process' ) . execSync ;
1112
12- var testRoot = process . env . NODE_TEST_DIR ? path . resolve ( process . env . NODE_TEST_DIR ) : __dirname ;
13+ var testRoot = process . env . NODE_TEST_DIR ? fs . realpathSync ( process . env . NODE_TEST_DIR ) : __dirname ;
1314
14- exports . testDir = __dirname ;
15- exports . fixturesDir = path . join ( exports . testDir , 'fixtures' ) ;
15+ exports . fixturesDir = path . join ( __dirname , 'fixtures' ) ;
1616exports . tmpDirName = 'tmp' ;
1717// PORT should match the definition in test/testpy/__init__.py.
1818exports . PORT = + process . env . NODE_COMMON_PORT || 12346 ;
@@ -28,14 +28,15 @@ exports.isOSX = process.platform === 'darwin';
2828exports . enoughTestMem = os . totalmem ( ) > 0x40000000 ; /* 1 Gb */
2929
3030var cpus = os . cpus ( ) ;
31- exports . enoughTestCpu = cpus . length > 1 || cpus [ 0 ] . speed > 999 ;
31+ exports . enoughTestCpu = Array . isArray ( cpus ) && ( cpus . length > 1 || cpus [ 0 ] . speed > 999 ) ;
3232
3333exports . rootDir = exports . isWindows ? 'c:\\' : '/' ;
3434exports . buildType = process . config . target_defaults . default_configuration ;
3535
3636function rimrafSync ( p ) {
37+ var st = void 0 ;
3738 try {
38- var st = fs . lstatSync ( p ) ;
39+ st = fs . lstatSync ( p ) ;
3940 } catch ( e ) {
4041 if ( e . code === 'ENOENT' ) return ;
4142 }
@@ -146,8 +147,8 @@ Object.defineProperty(exports, 'opensslCli', { get: function () {
146147
147148 if ( exports . isWindows ) opensslCli += '.exe' ;
148149
149- var openssl_cmd = child_process . spawnSync ( opensslCli , [ 'version' ] ) ;
150- if ( openssl_cmd . status !== 0 || openssl_cmd . error !== undefined ) {
150+ var opensslCmd = child_process . spawnSync ( opensslCli , [ 'version' ] ) ;
151+ if ( opensslCmd . status !== 0 || opensslCmd . error !== undefined ) {
151152 // openssl command cannot be executed
152153 opensslCli = false ;
153154 }
@@ -175,12 +176,6 @@ if (exports.isWindows) {
175176 exports . PIPE = exports . tmpDir + '/test.sock' ;
176177}
177178
178- if ( exports . isWindows ) {
179- exports . faketimeCli = false ;
180- } else {
181- exports . faketimeCli = path . join ( __dirname , '..' , 'tools' , 'faketime' , 'src' , 'faketime' ) ;
182- }
183-
184179var ifaces = os . networkInterfaces ( ) ;
185180exports . hasIPv6 = Object . keys ( ifaces ) . some ( function ( name ) {
186181 return ( / l o / . test ( name ) && ifaces [ name ] . some ( function ( info ) {
@@ -189,6 +184,27 @@ exports.hasIPv6 = Object.keys(ifaces).some(function (name) {
189184 ) ;
190185} ) ;
191186
187+ /*
188+ * Check that when running a test with
189+ * `$node --abort-on-uncaught-exception $file child`
190+ * the process aborts.
191+ */
192+ exports . childShouldThrowAndAbort = function ( ) {
193+ var testCmd = '' ;
194+ if ( ! exports . isWindows ) {
195+ // Do not create core files, as it can take a lot of disk space on
196+ // continuous testing and developers' machines
197+ testCmd += 'ulimit -c 0 && ' ;
198+ }
199+ testCmd += process . argv [ 0 ] + ' --abort-on-uncaught-exception ' ;
200+ testCmd += process . argv [ 1 ] + ' child' ;
201+ var child = child_process . exec ( testCmd ) ;
202+ child . on ( 'exit' , function onExit ( exitCode , signal ) {
203+ var errMsg = 'Test should have aborted ' + ( 'but instead exited with exit code ' + exitCode ) + ( ' and signal ' + signal ) ;
204+ assert ( exports . nodeProcessAborted ( exitCode , signal ) , errMsg ) ;
205+ } ) ;
206+ } ;
207+
192208exports . ddCommand = function ( filename , kilobytes ) {
193209 if ( exports . isWindows ) {
194210 var p = path . resolve ( exports . fixturesDir , 'create-file.js' ) ;
@@ -198,26 +214,6 @@ exports.ddCommand = function (filename, kilobytes) {
198214 }
199215} ;
200216
201- exports . spawnCat = function ( options ) {
202- var spawn = require ( 'child_process' ) . spawn ;
203-
204- if ( exports . isWindows ) {
205- return spawn ( 'more' , [ ] , options ) ;
206- } else {
207- return spawn ( 'cat' , [ ] , options ) ;
208- }
209- } ;
210-
211- exports . spawnSyncCat = function ( options ) {
212- var spawnSync = require ( 'child_process' ) . spawnSync ;
213-
214- if ( exports . isWindows ) {
215- return spawnSync ( 'more' , [ ] , options ) ;
216- } else {
217- return spawnSync ( 'cat' , [ ] , options ) ;
218- }
219- } ;
220-
221217exports . spawnPwd = function ( options ) {
222218 var spawn = require ( 'child_process' ) . spawn ;
223219
@@ -241,6 +237,8 @@ exports.spawnSyncPwd = function (options) {
241237exports . platformTimeout = function ( ms ) {
242238 if ( process . config . target_defaults . default_configuration === 'Debug' ) ms = 2 * ms ;
243239
240+ if ( global . __coverage__ ) ms = 4 * ms ;
241+
244242 if ( exports . isAix ) return 2 * ms ; // default localhost speed is slower on AIX
245243
246244 if ( process . arch !== 'arm' ) return ms ;
@@ -254,8 +252,8 @@ exports.platformTimeout = function (ms) {
254252 return ms ; // ARMv8+
255253} ;
256254
257- var knownGlobals = [ setTimeout , setInterval , setImmediate , clearTimeout , clearInterval , clearImmediate , console , constructor , // Enumerable in V8 3.21.
258- Buffer , process , global ] ;
255+ var knownGlobals = [ Buffer , clearImmediate , clearInterval , clearTimeout , console , constructor , // Enumerable in V8 3.21.
256+ global , process , setImmediate , setInterval , setTimeout ] ;
259257
260258if ( global . gc ) {
261259 knownGlobals . push ( global . gc ) ;
@@ -335,8 +333,14 @@ function leakedGlobals() {
335333 var leaked = [ ] ;
336334
337335 for ( var val in global ) {
338- if ( - 1 === knownGlobals . indexOf ( global [ val ] ) ) leaked . push ( val ) ;
339- } return leaked ;
336+ if ( ! knownGlobals . includes ( global [ val ] ) ) leaked . push ( val ) ;
337+ } if ( global . __coverage__ ) {
338+ return leaked . filter ( function ( varname ) {
339+ return ! / ^ ( c o v _ | _ _ c o v ) / . test ( varname ) ;
340+ } ) ;
341+ } else {
342+ return leaked ;
343+ }
340344}
341345exports . leakedGlobals = leakedGlobals ;
342346
@@ -347,8 +351,7 @@ process.on('exit', function () {
347351 if ( ! exports . globalCheck ) return ;
348352 var leaked = leakedGlobals ( ) ;
349353 if ( leaked . length > 0 ) {
350- console . error ( 'Unknown globals: %s' , leaked ) ;
351- assert . ok ( false , 'Unknown global found' ) ;
354+ fail ( 'Unexpected global(s) found: ' + leaked . join ( ', ' ) ) ;
352355 }
353356} ) ;
354357
@@ -370,7 +373,7 @@ function runCallChecks(exitCode) {
370373}
371374
372375exports . mustCall = function ( fn , expected ) {
373- if ( typeof expected !== 'number' ) expected = 1 ;
376+ if ( expected === undefined ) expected = 1 ; else if ( typeof expected !== 'number' ) throw new TypeError ( 'Invalid expected value: ' + expected ) ;
374377
375378 var context = {
376379 expected : expected ,
@@ -407,8 +410,42 @@ exports.fileExists = function (pathname) {
407410 }
408411} ;
409412
410- exports . fail = function ( msg ) {
413+ exports . canCreateSymLink = function ( ) {
414+ // On Windows, creating symlinks requires admin privileges.
415+ // We'll only try to run symlink test if we have enough privileges.
416+ // On other platforms, creating symlinks shouldn't need admin privileges
417+ if ( exports . isWindows ) {
418+ // whoami.exe needs to be the one from System32
419+ // If unix tools are in the path, they can shadow the one we want,
420+ // so use the full path while executing whoami
421+ var whoamiPath = path . join ( process . env [ 'SystemRoot' ] , 'System32' , 'whoami.exe' ) ;
422+
423+ var err = false ;
424+ var output = '' ;
425+
426+ try {
427+ output = execSync ( whoamiPath + ' /priv' , { timout : 1000 } ) ;
428+ } catch ( e ) {
429+ err = true ;
430+ } finally {
431+ if ( err || ! output . includes ( 'SeCreateSymbolicLinkPrivilege' ) ) {
432+ return false ;
433+ }
434+ }
435+ }
436+
437+ return true ;
438+ } ;
439+
440+ function fail ( msg ) {
411441 assert . fail ( null , null , msg ) ;
442+ }
443+ exports . fail = fail ;
444+
445+ exports . mustNotCall = function ( msg ) {
446+ return function mustNotCall ( ) {
447+ fail ( msg || 'function should not have been called' ) ;
448+ } ;
412449} ;
413450
414451exports . skip = function ( msg ) {
@@ -461,9 +498,9 @@ exports.nodeProcessAborted = function nodeProcessAborted(exitCode, signal) {
461498 // one of them (exit code or signal) needs to be set to one of
462499 // the expected exit codes or signals.
463500 if ( signal !== null ) {
464- return expectedSignals . indexOf ( signal ) > - 1 ;
501+ return expectedSignals . includes ( signal ) ;
465502 } else {
466- return expectedExitCodes . indexOf ( exitCode ) > - 1 ;
503+ return expectedExitCodes . includes ( exitCode ) ;
467504 }
468505} ;
469506
@@ -491,4 +528,56 @@ exports.expectWarning = function (name, expected) {
491528 // get each message only once.
492529 expected . splice ( expected . indexOf ( warning . message ) , 1 ) ;
493530 } , expected . length ) ) ;
531+ } ;
532+
533+ Object . defineProperty ( exports , 'hasIntl' , {
534+ get : function ( ) {
535+ return process . binding ( 'config' ) . hasIntl ;
536+ }
537+ } ) ;
538+
539+ // https://github.com/w3c/testharness.js/blob/master/testharness.js
540+ exports . WPT = {
541+ test : function ( fn , desc ) {
542+ try {
543+ fn ( ) ;
544+ } catch ( err ) {
545+ if ( err instanceof Error ) err . message = 'In ' + desc + ':\n ' + err . message ;
546+ throw err ;
547+ }
548+ } ,
549+ assert_equals : assert . strictEqual ,
550+ assert_true : function ( value , message ) {
551+ return assert . strictEqual ( value , true , message ) ;
552+ } ,
553+ assert_false : function ( value , message ) {
554+ return assert . strictEqual ( value , false , message ) ;
555+ } ,
556+ assert_throws : function ( code , func , desc ) {
557+ assert . throws ( func , function ( err ) {
558+ return typeof err === 'object' && 'name' in err && err . name === code . name ;
559+ } , desc ) ;
560+ } ,
561+ assert_array_equals : assert . deepStrictEqual ,
562+ assert_unreached : function ( desc ) {
563+ assert . fail ( undefined , undefined , 'Reached unreachable code: ' + desc ) ;
564+ }
565+ } ;
566+
567+ // Useful for testing expected internal/error objects
568+ exports . expectsError = function expectsError ( _ref ) {
569+ var code = _ref . code ,
570+ type = _ref . type ,
571+ message = _ref . message ;
572+
573+ return function ( error ) {
574+ assert . strictEqual ( error . code , code ) ;
575+ if ( type !== undefined ) assert ( error instanceof type , error + ' is not the expected type ' + type ) ;
576+ if ( message instanceof RegExp ) {
577+ assert ( message . test ( error . message ) , error . message + ' does not match ' + message ) ;
578+ } else if ( typeof message === 'string' ) {
579+ assert . strictEqual ( error . message , message ) ;
580+ }
581+ return true ;
582+ } ;
494583} ;
0 commit comments