| 188 | // Runs `jest` continuously (watch mode) and allows the caller to wait for |
| 189 | // conditions on stdout and stderr and to end the process. |
| 190 | export const runContinuous = function ( |
| 191 | dir: string, |
| 192 | args?: Array<string>, |
| 193 | options: RunJestOptions = {}, |
| 194 | ) { |
| 195 | const jestPromise = spawnJest(dir, args, {timeout: 30_000, ...options}, true); |
| 196 | |
| 197 | let stderr = ''; |
| 198 | let stdout = ''; |
| 199 | const pending = new Set<CheckerFunction>(); |
| 200 | const pendingRejection = new WeakMap<CheckerFunction, () => void>(); |
| 201 | |
| 202 | jestPromise.addListener('exit', () => { |
| 203 | for (const fn of pending) { |
| 204 | const reject = pendingRejection.get(fn); |
| 205 | |
| 206 | if (reject) { |
| 207 | console.log('stdout', normalizeStreamString(stdout, options)); |
| 208 | console.log('stderr', normalizeStreamString(stderr, options)); |
| 209 | |
| 210 | reject(); |
| 211 | } |
| 212 | } |
| 213 | }); |
| 214 | |
| 215 | const dispatch = () => { |
| 216 | for (const fn of pending) { |
| 217 | fn({stderr, stdout}); |
| 218 | } |
| 219 | }; |
| 220 | |
| 221 | jestPromise.stdout!.pipe( |
| 222 | new Writable({ |
| 223 | write(chunk, _encoding, callback) { |
| 224 | stdout += chunk.toString('utf8'); |
| 225 | dispatch(); |
| 226 | callback(); |
| 227 | }, |
| 228 | }), |
| 229 | ); |
| 230 | |
| 231 | jestPromise.stderr!.pipe( |
| 232 | new Writable({ |
| 233 | write(chunk, _encoding, callback) { |
| 234 | stderr += chunk.toString('utf8'); |
| 235 | dispatch(); |
| 236 | callback(); |
| 237 | }, |
| 238 | }), |
| 239 | ); |
| 240 | |
| 241 | const continuousRun = { |
| 242 | async end() { |
| 243 | jestPromise.kill(); |
| 244 | |
| 245 | const result = await jestPromise; |
| 246 | |
| 247 | // Not sure why we have to assign here... The ones on `result` are empty strings |