| 112 | } |
| 113 | |
| 114 | async scheduleTests( |
| 115 | tests: Array<Test>, |
| 116 | watcher: TestWatcher, |
| 117 | ): Promise<AggregatedResult> { |
| 118 | await this._setupReporters(tests); |
| 119 | |
| 120 | const onTestFileStart = this._dispatcher.onTestFileStart.bind( |
| 121 | this._dispatcher, |
| 122 | ); |
| 123 | const timings: Array<number> = []; |
| 124 | const testContexts = new Set<TestContext>(); |
| 125 | for (const test of tests) { |
| 126 | testContexts.add(test.context); |
| 127 | if (test.duration) { |
| 128 | timings.push(test.duration); |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | const aggregatedResults = createAggregatedResults(tests.length); |
| 133 | const estimatedTime = Math.ceil( |
| 134 | getEstimatedTime(timings, this._globalConfig.maxWorkers) / 1000, |
| 135 | ); |
| 136 | |
| 137 | const runInBand = shouldRunInBand(tests, timings, this._globalConfig); |
| 138 | |
| 139 | const onResult = async (test: Test, testResult: TestResult) => { |
| 140 | if (watcher.isInterrupted()) { |
| 141 | return; |
| 142 | } |
| 143 | |
| 144 | if (testResult.testResults.length === 0) { |
| 145 | const message = 'Your test suite must contain at least one test.'; |
| 146 | |
| 147 | return onFailure(test, { |
| 148 | message, |
| 149 | stack: new Error(message).stack, |
| 150 | }); |
| 151 | } |
| 152 | |
| 153 | // Throws when the context is leaked after executing a test. |
| 154 | if (testResult.leaks) { |
| 155 | const message = |
| 156 | `${chalk.red.bold( |
| 157 | 'EXPERIMENTAL FEATURE!\n', |
| 158 | )}Your test suite is leaking memory. Please ensure all references are cleaned.\n` + |
| 159 | '\n' + |
| 160 | 'There is a number of things that can leak memory:\n' + |
| 161 | ' - Async operations that have not finished (e.g. fs.readFile).\n' + |
| 162 | ' - Timers not properly mocked (e.g. setInterval, setTimeout).\n' + |
| 163 | ' - Keeping references to the global scope.'; |
| 164 | |
| 165 | return onFailure(test, { |
| 166 | message, |
| 167 | stack: new Error(message).stack, |
| 168 | }); |
| 169 | } |
| 170 | |
| 171 | addResult(aggregatedResults, testResult); |