-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cf80b0a
commit 9fe6217
Showing
4 changed files
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
|
||
import { assertEquals } from "./test_util.ts"; | ||
|
||
function monitorPromises(outputArray: string[]) { | ||
const promiseIds = new Map(); | ||
|
||
function identify(promise) { | ||
if (!promiseIds.has(promise)) | ||
promiseIds.set(promise, "p" + (promiseIds.size + 1)); | ||
return promiseIds.get(promise); | ||
} | ||
|
||
Deno.core.setPromiseHooks((promise, parentPromise) => { | ||
outputArray.push(`init ${identify(promise)}` + (parentPromise ? ` from ${identify(parentPromise)}` : ``)); | ||
}, (promise) => { | ||
outputArray.push(`before ${identify(promise)}`); | ||
}, (promise) => { | ||
outputArray.push(`after ${identify(promise)}`); | ||
}, (promise) => { | ||
outputArray.push(`resolve ${identify(promise)}`); | ||
}); | ||
} | ||
|
||
Deno.test(async function promiseHookBasic() { | ||
// Bogus await here to ensure any pending promise resolution from the | ||
// test runtime has a chance to run and avoid contaminating our results. | ||
await Promise.resolve(null); | ||
|
||
const hookResults: string[] = []; | ||
monitorPromises(hookResults); | ||
|
||
async function asyncFn() { | ||
await Promise.resolve(15); | ||
await Promise.resolve(20); | ||
Promise.reject(new Error()).catch(() => {}); | ||
} | ||
|
||
// The function above is equivalent to: | ||
// function asyncFn() { | ||
// return new Promise(resolve => { | ||
// Promise.resolve(15).then(() => { | ||
// Promise.resolve(20).then(() => { | ||
// Promise.reject(new Error()).catch(() => {}); | ||
// resolve(); | ||
// }); | ||
// }); | ||
// }); | ||
// } | ||
|
||
await asyncFn(); | ||
|
||
assertEquals(hookResults, [ | ||
"init p1", // Creates the promise representing the return of `asyncFn()`. | ||
"init p2", // Creates the promise representing `Promise.resolve(15)`. | ||
"resolve p2", // The previous promise resolves to `15` immediately. | ||
"init p3 from p2", // Creates the promise that is resolved after the first `await` of the function. Equivalent to `p2.then(...)`. | ||
"init p4 from p1", // The resolution above gives time for other pending code to run. Creates the promise that is resolved | ||
// from the `await` at `await asyncFn()`, the last code to run. Equivalent to `asyncFn().then(...)`. | ||
"before p3", // Begins executing the code after `await Promise.resolve(15)`. | ||
"init p5", // Creates the promise representing `Promise.resolve(20)`. | ||
"resolve p5", // The previous promise resolves to `20` immediately. | ||
"init p6 from p5", // Creates the promise that is resolved after the second `await` of the function. Equivalent to `p5.then(...)`. | ||
"resolve p3", // The promise representing the code right after the first await is marked as resolved. | ||
"after p3", // We are now after the resolution code of the promise above. | ||
"before p6", // Begins executing the code after `await Promise.resolve(20)`. | ||
"init p7", // Creates a new promise representing `Promise.reject(new Error())`. | ||
"resolve p7", // This promise is "resolved" immediately to a rejection with an error instance. | ||
"init p8 from p7", // Creates a new promise for the `.catch` of the previous promise. | ||
"resolve p1", // At this point the promise of the function is resolved. | ||
"resolve p6", // This concludes the resolution of the code after `await Promise.resolve(20)`. | ||
"after p6", // We are now after the resolution code of the promise above. | ||
"before p8", // The `.catch` block is pending execution, it begins to execute. | ||
"resolve p8", // It does nothing and resolves to `undefined`. | ||
"after p8", // We are after the resolution of the `.catch` block. | ||
"before p4", // Now we begin the execution of the code that happens after `await asyncFn();`. | ||
]); | ||
}); | ||
|
||
Deno.test(async function promiseHookMultipleConsumers() { | ||
const hookResultsFirstConsumer: string[] = []; | ||
const hookResultsSecondConsumer: string[] = []; | ||
|
||
monitorPromises(hookResultsFirstConsumer); | ||
monitorPromises(hookResultsSecondConsumer); | ||
|
||
async function asyncFn() { | ||
await Promise.resolve(15); | ||
await Promise.resolve(20); | ||
Promise.reject(new Error()).catch(() => {}); | ||
} | ||
await asyncFn(); | ||
|
||
// Two invocations of `setPromiseHooks` should yield the exact same results, in the same order. | ||
assertEquals( | ||
hookResultsFirstConsumer, | ||
hookResultsSecondConsumer, | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters