@@ -181,11 +181,7 @@ const createMatcherFor = (consoleMethod, matcherName) =>
181181 // Avoid using Jest's built-in spy since it can't be removed.
182182 console [ consoleMethod ] = consoleSpy
183183
184- try {
185- callback ( )
186- } catch ( error ) {
187- caughtError = error
188- } finally {
184+ const onFinally = ( ) => {
189185 // Restore the unspied method so that unexpected errors fail tests.
190186 console [ consoleMethod ] = originalMethod
191187
@@ -289,11 +285,56 @@ const createMatcherFor = (consoleMethod, matcherName) =>
289285
290286 return { pass : true }
291287 }
288+
289+ let returnPromise = null
290+ try {
291+ const result = callback ( )
292+
293+ if (
294+ typeof result === 'object' &&
295+ result !== null &&
296+ typeof result . then === 'function'
297+ ) {
298+ // `act` returns a thenable that can't be chained.
299+ // Once `act(async () => {}).then(() => {}).then(() => {})` works
300+ // we can just return `result.then(onFinally, error => ...)`
301+ returnPromise = new Promise ( ( resolve , reject ) => {
302+ result
303+ . then (
304+ ( ) => {
305+ resolve ( onFinally ( ) )
306+ } ,
307+ error => {
308+ caughtError = error
309+ return resolve ( onFinally ( ) )
310+ } ,
311+ )
312+ // In case onFinally throws we need to reject from this matcher
313+ . catch ( error => {
314+ reject ( error )
315+ } )
316+ } )
317+ }
318+ } catch ( error ) {
319+ caughtError = error
320+ } finally {
321+ return returnPromise === null ? onFinally ( ) : returnPromise
322+ }
292323 } else {
293324 // Any uncaught errors or warnings should fail tests in production mode.
294- callback ( )
325+ const result = callback ( )
295326
296- return { pass : true }
327+ if (
328+ typeof result === 'object' &&
329+ result !== null &&
330+ typeof result . then === 'function'
331+ ) {
332+ return result . then ( ( ) => {
333+ return { pass : true }
334+ } )
335+ } else {
336+ return { pass : true }
337+ }
297338 }
298339 }
299340
0 commit comments