| // Copyright 2018 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| let {session, contextGroup, Protocol} = |
| InspectorTest.start('stepOut async function'); |
| |
| session.setupScriptMap(); |
| |
| Protocol.Runtime.enable(); |
| |
| InspectorTest.runAsyncTestSuite([ |
| async function testTrivial() { |
| InspectorTest.log('Check that we have proper async stack at return'); |
| contextGroup.addInlineScript(` |
| async function test() { |
| await Promise.resolve(); |
| await foo(); |
| } |
| |
| async function foo() { |
| await Promise.resolve(); |
| await bar(); |
| } |
| |
| async function bar() { |
| await Promise.resolve(); |
| debugger; |
| }`, 'testTrivial.js'); |
| await runTestAndStepAction('stepOut'); |
| }, |
| |
| async function testStepOutPrecision() { |
| InspectorTest.log('Check that stepOut go to resumed outer generator'); |
| contextGroup.addInlineScript(` |
| function wait() { |
| return new Promise(resolve => setTimeout(resolve, 0)); |
| } |
| function floodWithTimeouts(a) { |
| if (!a.stop) |
| setTimeout(floodWithTimeouts.bind(this, a), 0); |
| } |
| |
| async function test() { |
| let a = {}; |
| floodWithTimeouts(a) |
| await wait(); |
| await foo(); |
| await wait(); |
| a.stop = true; |
| } |
| |
| async function foo() { |
| await Promise.resolve(); |
| await bar(); |
| await wait(); |
| } |
| |
| async function bar() { |
| await Promise.resolve(); |
| debugger; |
| await wait(); |
| }`, 'testStepOutPrecision.js'); |
| await runTestAndStepAction('stepOut'); |
| }, |
| |
| async function testStepIntoAtReturn() { |
| InspectorTest.log('Check that stepInto at return go to resumed outer generator'); |
| contextGroup.addInlineScript(` |
| function wait() { |
| return new Promise(resolve => setTimeout(resolve, 0)); |
| } |
| function floodWithTimeouts(a) { |
| if (!a.stop) |
| setTimeout(floodWithTimeouts.bind(this, a), 0); |
| } |
| |
| async function test() { |
| let a = {}; |
| floodWithTimeouts(a) |
| await wait(); |
| await foo(); |
| a.stop = true; |
| } |
| |
| async function foo() { |
| await Promise.resolve(); |
| await bar(); |
| } |
| |
| async function bar() { |
| await Promise.resolve(); |
| debugger; |
| }`, 'testStepIntoAtReturn.js'); |
| await runTestAndStepAction('stepInto'); |
| }, |
| |
| async function testStepOverAtReturn() { |
| InspectorTest.log('Check that stepOver at return go to resumed outer generator'); |
| contextGroup.addInlineScript(` |
| function wait() { |
| return new Promise(resolve => setTimeout(resolve, 0)); |
| } |
| function floodWithTimeouts(a) { |
| if (!a.stop) |
| setTimeout(floodWithTimeouts.bind(this, a), 0); |
| } |
| |
| async function test() { |
| let a = {}; |
| floodWithTimeouts(a) |
| await wait(); |
| await foo(); |
| a.stop = true; |
| } |
| |
| async function foo() { |
| await Promise.resolve(); |
| await bar(); |
| } |
| |
| async function bar() { |
| await Promise.resolve(); |
| debugger; |
| }`, 'testStepIntoAtReturn.js'); |
| await runTestAndStepAction('stepOver'); |
| }, |
| |
| async function testStepOutFromNotAwaitedCall() { |
| InspectorTest.log('Checks stepOut from not awaited call'); |
| contextGroup.addInlineScript(` |
| function wait() { |
| return new Promise(resolve => setTimeout(resolve, 0)); |
| } |
| function floodWithTimeouts(a) { |
| if (!a.stop) |
| setTimeout(floodWithTimeouts.bind(this, a), 0); |
| } |
| |
| async function test() { |
| let a = {}; |
| floodWithTimeouts(a) |
| await wait(); |
| await foo(); |
| a.stop = true; |
| } |
| |
| async function foo() { |
| let a = {}; |
| floodWithTimeouts(a); |
| await Promise.resolve(); |
| bar(); |
| a.stop = true; |
| } |
| |
| async function bar() { |
| await Promise.resolve(); |
| debugger; |
| }`, 'testStepIntoAtReturn.js'); |
| await runTestAndStepAction('stepOut'); |
| } |
| |
| ]); |
| |
| async function runTestAndStepAction(action) { |
| Protocol.Debugger.enable(); |
| Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128}); |
| let finished = |
| Protocol.Runtime.evaluate({expression: 'test()', awaitPromise: true}) |
| .then(() => false); |
| while (true) { |
| const r = await Promise.race([finished, waitPauseAndDumpStack()]); |
| if (!r) break; |
| Protocol.Debugger[action](); |
| } |
| await Protocol.Debugger.disable(); |
| } |
| |
| async function waitPauseAndDumpStack() { |
| const {params} = await Protocol.Debugger.oncePaused(); |
| session.logCallFrames(params.callFrames); |
| session.logAsyncStackTrace(params.asyncStackTrace); |
| InspectorTest.log(''); |
| return true; |
| } |