blob: 62294b9c0e1b6e492132021ae0e479e3db3ed2b4 [file] [log] [blame]
// 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;
}