(scope: () => Thenable<T>)
| 229 | } |
| 230 | |
| 231 | export async function serverAct<T>(scope: () => Thenable<T>): Thenable<T> { |
| 232 | // We require every `act` call to assert console logs |
| 233 | // with one of the assertion helpers. Fails if not empty. |
| 234 | assertConsoleLogsCleared(); |
| 235 | |
| 236 | // $FlowFixMe[cannot-resolve-name]: Flow doesn't know about global Jest object |
| 237 | if (!jest.isMockFunction(setTimeout)) { |
| 238 | throw Error( |
| 239 | "This version of `act` requires Jest's timer mocks " + |
| 240 | '(i.e. jest.useFakeTimers).', |
| 241 | ); |
| 242 | } |
| 243 | |
| 244 | // Create the error object before doing any async work, to get a better |
| 245 | // stack trace. |
| 246 | const error = new Error(); |
| 247 | Error.captureStackTrace(error, act); |
| 248 | |
| 249 | // Call the provided scope function after an async gap. This is an extra |
| 250 | // precaution to ensure that our tests do not accidentally rely on the act |
| 251 | // scope adding work to the queue synchronously. We don't do this in the |
| 252 | // public version of `act`, though we maybe should in the future. |
| 253 | await waitForMicrotasks(); |
| 254 | |
| 255 | const errorHandlerNode = function (err: mixed) { |
| 256 | thrownErrors.push(err); |
| 257 | }; |
| 258 | // We track errors that were logged globally as if they occurred in this scope and then rethrow them. |
| 259 | if (typeof process === 'object') { |
| 260 | // Node environment |
| 261 | process.on('uncaughtException', errorHandlerNode); |
| 262 | } else if ( |
| 263 | typeof window === 'object' && |
| 264 | typeof window.addEventListener === 'function' |
| 265 | ) { |
| 266 | throw new Error('serverAct is not supported in JSDOM environments'); |
| 267 | } |
| 268 | |
| 269 | try { |
| 270 | const promise = scope(); |
| 271 | // $FlowFixMe[prop-missing] |
| 272 | if (promise && typeof promise.catch === 'function') { |
| 273 | // $FlowFixMe[incompatible-use] |
| 274 | promise.catch(() => {}); // Handle below |
| 275 | } |
| 276 | // See if we need to do some work to unblock the promise first. |
| 277 | await waitForTasksAndTimers(error); |
| 278 | const result = await promise; |
| 279 | // Then wait to flush the result. |
| 280 | await waitForTasksAndTimers(error); |
| 281 | |
| 282 | if (thrownErrors.length > 0) { |
| 283 | // Rethrow any errors logged by the global error handling. |
| 284 | const thrownError = aggregateErrors(thrownErrors); |
| 285 | thrownErrors.length = 0; |
| 286 | throw thrownError; |
| 287 | } |
| 288 |
nothing calls this directly
no test coverage detected