@@ -19,6 +19,41 @@ import {flags, refs, sharedWorkerTeardowns} from './state.cjs';
1919import { isRunningInThread , isRunningInChildProcess } from './utils.cjs' ;
2020
2121const currentlyUnhandled = setUpCurrentlyUnhandled ( ) ;
22+ let runner ;
23+
24+ // Override process.exit with an undetectable replacement
25+ // to report when it is called from a test (which it should never be).
26+ const { apply} = Reflect ;
27+ const realExit = process . exit ;
28+
29+ async function exit ( code , forceSync = false ) {
30+ dependencyTracking . flush ( ) ;
31+ const flushing = channel . flush ( ) ;
32+ if ( ! forceSync ) {
33+ await flushing ;
34+ }
35+
36+ apply ( realExit , process , [ code ] ) ;
37+ }
38+
39+ const handleProcessExit = ( fn , receiver , args ) => {
40+ const error = new Error ( 'Unexpected process.exit()' ) ;
41+ Error . captureStackTrace ( error , handleProcessExit ) ;
42+ const { stack} = serializeError ( '' , true , error ) ;
43+ channel . send ( { type : 'process-exit' , stack} ) ;
44+
45+ // Make sure to extract the code only from `args` rather than e.g. `Array.prototype`.
46+ // This level of paranoia is usually unwarranted, but we're dealing with test code
47+ // that has already colored outside the lines.
48+ const code = args . length > 0 ? args [ 0 ] : undefined ;
49+
50+ // Force a synchronous exit as guaranteed by the real process.exit().
51+ exit ( code , true ) ;
52+ } ;
53+
54+ process . exit = new Proxy ( realExit , {
55+ apply : handleProcessExit ,
56+ } ) ;
2257
2358const run = async options => {
2459 setOptions ( options ) ;
@@ -29,16 +64,6 @@ const run = async options => {
2964 global . console = Object . assign ( global . console , new console . Console ( { stdout, stderr, colorMode : true } ) ) ;
3065 }
3166
32- async function exit ( code ) {
33- if ( ! process . exitCode ) {
34- process . exitCode = code ;
35- }
36-
37- dependencyTracking . flush ( ) ;
38- await channel . flush ( ) ;
39- process . exit ( ) ; // eslint-disable-line unicorn/no-process-exit
40- }
41-
4267 let checkSelectedByLineNumbers ;
4368 try {
4469 checkSelectedByLineNumbers = lineNumberSelection ( {
@@ -50,7 +75,7 @@ const run = async options => {
5075 checkSelectedByLineNumbers = ( ) => false ;
5176 }
5277
53- const runner = new Runner ( {
78+ runner = new Runner ( {
5479 checkSelectedByLineNumbers,
5580 experiments : options . experiments ,
5681 failFast : options . failFast ,
0 commit comments