| 'use strict'; |
| |
| // https://github.com/nodejs/node/issues/59541 |
| // |
| // Promises created in a context using microtaskMode: "aferEvaluate" (meaning |
| // it has its own microtask queue), when resolved in the surrounding context, |
| // will schedule a task back onto the inner context queue. This test checks that |
| // the async execution progresses normally. |
| |
| const common = require('../common'); |
| const vm = require('vm'); |
| |
| const microtaskMode = 'afterEvaluate'; |
| |
| (async () => { |
| const mustNotCall1 = common.mustNotCall(); |
| |
| await vm.runInNewContext( |
| `Promise.resolve()`, |
| {}, { microtaskMode }); |
| |
| // Expected behavior: resolving an promise created in the inner context, from |
| // the outer context results in the execution flow falling through, unless the |
| // inner context microtask queue is manually drained, which we don't do here. |
| mustNotCall1(); |
| })().then(common.mustNotCall()); |
| |
| (async () => { |
| const mustCall1 = common.mustCall(); |
| const mustCall2 = common.mustCall(); |
| const mustCall3 = common.mustCall(); |
| |
| // Create a new context. |
| const context = vm.createContext({}, { microtaskMode }); |
| |
| setImmediate(() => { |
| // This will drain the context microtask queue, after the `await` statement |
| // below, and allow the promise from the inner context, created below, to be |
| // resolved in the outer context. |
| vm.runInContext('', context); |
| mustCall2(); |
| }); |
| |
| const inner_promise = vm.runInContext( |
| `Promise.resolve()`, |
| context); |
| mustCall1(); |
| |
| await inner_promise; |
| mustCall3(); |
| })().then(common.mustCall()); |
| |
| { |
| const mustNotCall1 = common.mustNotCall(); |
| const mustCall1 = common.mustCall(); |
| |
| const context = vm.createContext({ setImmediate, mustNotCall1 }, { microtaskMode }); |
| |
| // setImmediate() will be run after runInContext() returns, and since the |
| // anonymous function passed to `then` is defined in the inner context, the |
| // thenable job task will be enqueued on the inner context microtask queue, |
| // but at this point, it will not be drained automatically. |
| vm.runInContext(`new Promise(setImmediate).then(() => mustNotCall1())`, context); |
| |
| mustCall1(); |
| } |