Commit c63e83c1 authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

[inspector] added step-into test to cover most stepInto cases

This test helps to prevent regressions during work on new break locations.

BUG=none
R=dgozman@chromium.org

Review-Url: https://codereview.chromium.org/2719763002
Cr-Commit-Position: refs/heads/master@{#43458}
parent 4d7fa10c
Checks possible break locations.
Running test: testEval
break at:
function testEval() {
#eval('// comment only');
eval('// comment only\n');
break at:
// comment onl#y
break at:
eval('// comment only');
#eval('// comment only\n');
}
break at:
// comment only#
break at:
eval('// comment only\n');
#}
Running test: testProcedure
break at:
function testProcedure() {
#procedure();
}
break at:
function procedure() {
var a = #1;
var b = 2;
break at:
var a = 1;
var b = #2;
}
break at:
var b = 2;
#}
break at:
procedure();
#}
Running test: testIf
break at:
var a;
#if (true) a = true;
if (!a) {
break at:
var a;
if (true) #a = true;
if (!a) {
break at:
if (true) a = true;
#if (!a) {
a = true;
break at:
} else {
#a = false;
}
break at:
}
#if (returnTrue()) {
a = false;
break at:
function returnTrue() {
#return true;
}
break at:
return true;
#}
break at:
if (returnTrue()) {
#a = false;
} else {
break at:
}
#}
Running test: testEmptyFunction
break at:
function testEmptyFunction() {
#emptyFunction();
}
break at:
function emptyFunction() {#}
break at:
emptyFunction();
#}
Running test: testCallArguments
break at:
function testCallArguments() {
#twoArguments(emptyFunction(), emptyFunction());
}
break at:
function emptyFunction() {#}
break at:
function testCallArguments() {
twoArguments(emptyFunction(), #emptyFunction());
}
break at:
function emptyFunction() {#}
break at:
function testCallArguments() {
#twoArguments(emptyFunction(), emptyFunction());
}
break at:
function twoArguments(a1, a2) {
#}
break at:
twoArguments(emptyFunction(), emptyFunction());
#}
Running test: testNested
break at:
}
#nested1();
}
break at:
}
#return nested2();
}
break at:
}
#nested3();
return;
break at:
function nested3() {
#}
nested3();
break at:
nested3();
#return;
}
break at:
return;
#}
return nested2();
break at:
return nested2();
#}
nested1();
break at:
nested1();
#}
Running test: testCallAtReturn
break at:
function testCallAtReturn() {
#return returnCall();
}
break at:
function returnCall() {
#return return42();
}
break at:
function return42() {
#return 42;
}
break at:
return 42;
#}
break at:
return return42();
#}
break at:
return returnCall();
#}
Running test: testWith
break at:
function testWith() {
#with (returnObject()) {
foo();
break at:
function returnObject() {
#return ({ foo: () => 42 });
}
break at:
return ({ foo: () => 42 });
#}
break at:
with (returnObject()) {
#foo();
}
break at:
function returnObject() {
return ({ foo: () => #42 });
}
break at:
function returnObject() {
return ({ foo: () => 42# });
}
break at:
}
#with({}) {
return;
break at:
with({}) {
#return;
}
break at:
}
#}
Running test: testForLoop
break at:
function testForLoop() {
for (var i = #0; i < 1; ++i) {}
for (var i = 0; i < 1; ++i) i;
break at:
function testForLoop() {
for (var i = 0; i #< 1; ++i) {}
for (var i = 0; i < 1; ++i) i;
break at:
function testForLoop() {
for (var i = 0; i < 1; ++#i) {}
for (var i = 0; i < 1; ++i) i;
break at:
function testForLoop() {
for (var i = 0; i #< 1; ++i) {}
for (var i = 0; i < 1; ++i) i;
break at:
for (var i = 0; i < 1; ++i) {}
for (var i = #0; i < 1; ++i) i;
for (var i = 0; i < 0; ++i) {}
break at:
for (var i = 0; i < 1; ++i) {}
for (var i = 0; i #< 1; ++i) i;
for (var i = 0; i < 0; ++i) {}
break at:
for (var i = 0; i < 1; ++i) {}
for (var i = 0; i < 1; ++i) #i;
for (var i = 0; i < 0; ++i) {}
break at:
for (var i = 0; i < 1; ++i) {}
for (var i = 0; i < 1; ++#i) i;
for (var i = 0; i < 0; ++i) {}
break at:
for (var i = 0; i < 1; ++i) {}
for (var i = 0; i #< 1; ++i) i;
for (var i = 0; i < 0; ++i) {}
break at:
for (var i = 0; i < 1; ++i) i;
for (var i = #0; i < 0; ++i) {}
}
break at:
for (var i = 0; i < 1; ++i) i;
for (var i = 0; i #< 0; ++i) {}
}
break at:
for (var i = 0; i < 0; ++i) {}
#}
Running test: testForOfLoop
break at:
function testForOfLoop() {
for (var k of #[]) {}
for (var k of [1]) k;
break at:
function testForOfLoop() {
for (var k #of []) {}
for (var k of [1]) k;
break at:
for (var k of []) {}
for (var k of #[1]) k;
var a = [];
break at:
for (var k of []) {}
for (var k #of [1]) k;
var a = [];
break at:
for (var k of []) {}
for (var k of [1]) #k;
var a = [];
break at:
for (var k of []) {}
for (var k #of [1]) k;
var a = [];
break at:
for (var k of [1]) k;
var a = #[];
for (var k of a) {}
break at:
var a = [];
for (var k of #a) {}
}
break at:
var a = [];
for (var k #of a) {}
}
break at:
for (var k of a) {}
#}
Running test: testForInLoop
break at:
function testForInLoop() {
var o = #{};
for (var k in o) {}
break at:
var o = {};
for (var k in #o) {}
for (var k in o) k;
break at:
for (var k in o) {}
for (var k in #o) k;
for (var k in { a:1 }) {}
break at:
for (var k in o) k;
for (var k in #{ a:1 }) {}
for (var k in { a:1 }) k;
break at:
for (var k in o) k;
for (var #k in { a:1 }) {}
for (var k in { a:1 }) k;
break at:
for (var k in { a:1 }) {}
for (var k in #{ a:1 }) k;
}
break at:
for (var k in { a:1 }) {}
for (var #k in { a:1 }) k;
}
break at:
for (var k in { a:1 }) {}
for (var k in { a:1 }) #k;
}
break at:
for (var k in { a:1 }) {}
for (var #k in { a:1 }) k;
}
break at:
for (var k in { a:1 }) k;
#}
Running test: testSimpleExpressions
break at:
function testSimpleExpressions() {
#1 + 2 + 3;
var a = 1;
break at:
1 + 2 + 3;
var a = #1;
++a;
break at:
var a = 1;
#++a;
a--;
break at:
++a;
#a--;
}
break at:
a--;
#}
Running test: testGetter
break at:
function testGetter() {
#getterFoo();
}
break at:
Object.defineProperty(this, 'getterFoo', {
get: () => #return42
});
break at:
Object.defineProperty(this, 'getterFoo', {
get: () => return42#
});
break at:
function testGetter() {
#getterFoo();
}
break at:
function return42() {
#return 42;
}
break at:
return 42;
#}
break at:
getterFoo();
#}
Running test: testChainedCalls
break at:
function testChainedCalls() {
#obj.foo().boo()();
}
break at:
var obj = {
foo: () => (#{
boo: () => return42
break at:
boo: () => return42
})#
};
break at:
function testChainedCalls() {
obj.foo().#boo()();
}
break at:
foo: () => ({
boo: () => #return42
})
break at:
foo: () => ({
boo: () => return42#
})
break at:
function testChainedCalls() {
obj.foo().boo()#();
}
break at:
function return42() {
#return 42;
}
break at:
return 42;
#}
break at:
obj.foo().boo()();
#}
Running test: testChainedWithNative
break at:
function testChainedWithNative() {
#Array.from([1]).concat([2]).map(v => v * 2);
}
break at:
function testChainedWithNative() {
Array.from([1]).concat([2]).map(v => v #* 2);
}
break at:
function testChainedWithNative() {
Array.from([1]).concat([2]).map(v => v * 2#);
}
break at:
function testChainedWithNative() {
Array.from([1]).concat([2]).map(v => v #* 2);
}
break at:
function testChainedWithNative() {
Array.from([1]).concat([2]).map(v => v * 2#);
}
break at:
Array.from([1]).concat([2]).map(v => v * 2);
#}
Running test: testPromiseThen
break at:
function testPromiseThen() {
#return Promise.resolve().then(v => v * 2).then(v => v * 2);
}
break at:
return Promise.resolve().then(v => v * 2).then(v => v * 2);
#}
Running test: testSwitch
break at:
function testSwitch() {
for (var i = #0; i < 3; ++i) {
switch(i) {
break at:
function testSwitch() {
for (var i = 0; i #< 3; ++i) {
switch(i) {
break at:
for (var i = 0; i < 3; ++i) {
#switch(i) {
case 0: continue;
break at:
switch(i) {
case 0: #continue;
case 1: return42(); break;
break at:
function testSwitch() {
for (var i = 0; i < 3; ++#i) {
switch(i) {
break at:
function testSwitch() {
for (var i = 0; i #< 3; ++i) {
switch(i) {
break at:
for (var i = 0; i < 3; ++i) {
#switch(i) {
case 0: continue;
break at:
case 0: continue;
case 1: #return42(); break;
default: return;
break at:
function return42() {
#return 42;
}
break at:
return 42;
#}
break at:
case 0: continue;
case 1: return42(); #break;
default: return;
break at:
function testSwitch() {
for (var i = 0; i < 3; ++#i) {
switch(i) {
break at:
function testSwitch() {
for (var i = 0; i #< 3; ++i) {
switch(i) {
break at:
for (var i = 0; i < 3; ++i) {
#switch(i) {
case 0: continue;
break at:
case 1: return42(); break;
default: #return;
}
break at:
}
#}
Running test: testGenerator
break at:
function testGenerator() {
var gen = #idMaker();
return42();
break at:
function* idMaker() {
#yield 1;
yield 2;
break at:
gen.next().value;
#debugger;
gen.next().value;
break at:
debugger;
#gen.next().value;
return42();
break at:
yield 1;
#yield 2;
yield 3;
break at:
yield 2;
#yield 3;
}
break at:
yield 3;
#}
break at:
gen.next().value;
#}
Running test: testCaughtException
break at:
try {
#throwException()
} catch (e) {
break at:
function throwException() {
#throw new Error();
}
break at:
} catch (e) {
#return;
}
break at:
}
#}
Running test: testClasses
break at:
function testClasses() {
#class Cat {
constructor(name) {
break at:
}
#class Lion extends Cat {
constructor(name) {
break at:
}
#new Lion().speak();
}
break at:
constructor(name) {
#super(name);
}
break at:
constructor(name) {
#this.name = name;
}
break at:
this.name = name;
#}
break at:
super(name);
#}
break at:
}
new Lion().#speak();
}
break at:
speak() {
#super.speak();
}
break at:
speak() {
#}
}
break at:
super.speak();
#}
}
break at:
new Lion().speak();
#}
Running test: testAsyncAwait
break at:
async function testAsyncAwait() {
await #asyncFoo();
await awaitBoo();
break at:
async function asyncFoo() {
await Promise.resolve().#then(v => v * 2);
return42();
break at:
async function asyncFoo() {
await Promise.#resolve().then(v => v * 2);
return42();
break at:
async function asyncFoo() {
await Promise.resolve().#then(v => v * 2);
return42();
break at:
async function asyncFoo() {
#await Promise.resolve().then(v => v * 2);
return42();
break at:
function return42() {
#return 42;
}
break at:
return 42;
#}
break at:
async function asyncBoo() {
await Promise.#resolve();
}
break at:
async function asyncBoo() {
#await Promise.resolve();
}
Running test: testPromiseAsyncWithCode
break at:
var nextTest;
var testPromise = #new Promise(resolve => nextTest = resolve);
async function main() {
break at:
var nextTest;
var testPromise = new Promise(resolve => nextTest #= resolve);
async function main() {
break at:
var nextTest;
var testPromise = new Promise(resolve => nextTest = resolve#);
async function main() {
break at:
}
#main();
return testPromise;
break at:
}
#setTimeout(returnCall, 0);
await foo();
break at:
setTimeout(returnCall, 0);
await #foo();
await foo();
break at:
var resolveNested;
var p = #new Promise(resolve => resolveNested = resolve);
setTimeout(resolveNested, 0);
break at:
var resolveNested;
var p = new Promise(resolve => resolveNested #= resolve);
setTimeout(resolveNested, 0);
break at:
var resolveNested;
var p = new Promise(resolve => resolveNested = resolve#);
setTimeout(resolveNested, 0);
break at:
var p = new Promise(resolve => resolveNested = resolve);
#setTimeout(resolveNested, 0);
await p;
break at:
setTimeout(resolveNested, 0);
await #p;
}
break at:
setTimeout(resolveNested, 0);
#await p;
}
break at:
function return42() {
#return 42;
}
break at:
return 42;
#}
break at:
async function main() {
async function foo#() {
var resolveNested;
break at:
var resolveNested;
var p = #new Promise(resolve => resolveNested = resolve);
setTimeout(resolveNested, 0);
break at:
var resolveNested;
var p = new Promise(resolve => resolveNested #= resolve);
setTimeout(resolveNested, 0);
break at:
var resolveNested;
var p = new Promise(resolve => resolveNested = resolve#);
setTimeout(resolveNested, 0);
break at:
var p = new Promise(resolve => resolveNested = resolve);
#setTimeout(resolveNested, 0);
await p;
break at:
setTimeout(resolveNested, 0);
await #p;
}
break at:
setTimeout(resolveNested, 0);
#await p;
}
// Copyright 2017 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.
print('Checks possible break locations.');
InspectorTest.addScript(`
function testEval() {
eval('// comment only');
eval('// comment only\\n');
}
// function without return
function procedure() {
var a = 1;
var b = 2;
}
function testProcedure() {
procedure();
}
function returnTrue() {
return true;
}
function testIf() {
var a;
if (true) a = true;
if (!a) {
a = true;
} else {
a = false;
}
if (returnTrue()) {
a = false;
} else {
a = true;
}
}
function emptyFunction() {}
function testEmptyFunction() {
emptyFunction();
}
function twoArguments(a1, a2) {
}
function testCallArguments() {
twoArguments(emptyFunction(), emptyFunction());
}
function testNested() {
function nested1() {
function nested2() {
function nested3() {
}
nested3();
return;
}
return nested2();
}
nested1();
}
function return42() {
return 42;
}
function returnCall() {
return return42();
}
function testCallAtReturn() {
return returnCall();
}
function returnObject() {
return ({ foo: () => 42 });
}
function testWith() {
with (returnObject()) {
foo();
}
with({}) {
return;
}
}
function testForLoop() {
for (var i = 0; i < 1; ++i) {}
for (var i = 0; i < 1; ++i) i;
for (var i = 0; i < 0; ++i) {}
}
function testForOfLoop() {
for (var k of []) {}
for (var k of [1]) k;
var a = [];
for (var k of a) {}
}
function testForInLoop() {
var o = {};
for (var k in o) {}
for (var k in o) k;
for (var k in { a:1 }) {}
for (var k in { a:1 }) k;
}
function testSimpleExpressions() {
1 + 2 + 3;
var a = 1;
++a;
a--;
}
Object.defineProperty(this, 'getterFoo', {
get: () => return42
});
function testGetter() {
getterFoo();
}
var obj = {
foo: () => ({
boo: () => return42
})
};
function testChainedCalls() {
obj.foo().boo()();
}
function testChainedWithNative() {
Array.from([1]).concat([2]).map(v => v * 2);
}
function testPromiseThen() {
return Promise.resolve().then(v => v * 2).then(v => v * 2);
}
function testSwitch() {
for (var i = 0; i < 3; ++i) {
switch(i) {
case 0: continue;
case 1: return42(); break;
default: return;
}
}
}
function* idMaker() {
yield 1;
yield 2;
yield 3;
}
function testGenerator() {
var gen = idMaker();
return42();
gen.next().value;
debugger;
gen.next().value;
return42();
gen.next().value;
return42();
gen.next().value;
}
function throwException() {
throw new Error();
}
function testCaughtException() {
try {
throwException()
} catch (e) {
return;
}
}
function testClasses() {
class Cat {
constructor(name) {
this.name = name;
}
speak() {
}
}
class Lion extends Cat {
constructor(name) {
super(name);
}
speak() {
super.speak();
}
}
new Lion().speak();
}
async function asyncFoo() {
await Promise.resolve().then(v => v * 2);
return42();
await asyncBoo();
}
async function asyncBoo() {
await Promise.resolve();
}
async function testAsyncAwait() {
await asyncFoo();
await awaitBoo();
}
// TODO(kozyatinskiy): fix this.
async function testPromiseAsyncWithCode() {
var nextTest;
var testPromise = new Promise(resolve => nextTest = resolve);
async function main() {
async function foo() {
var resolveNested;
var p = new Promise(resolve => resolveNested = resolve);
setTimeout(resolveNested, 0);
await p;
}
setTimeout(returnCall, 0);
await foo();
await foo();
nextTest();
}
main();
return testPromise;
}
//# sourceURL=test.js`);
InspectorTest.setupScriptMap();
Protocol.Debugger.onPaused(message => {
var frames = message.params.callFrames;
if (frames.length === 1) {
Protocol.Debugger.stepInto();
return;
}
var scriptId = frames[0].location.scriptId;
InspectorTest.log('break at:');
InspectorTest.logCallFrameSourceLocation(frames[0])
.then(() => Protocol.Debugger.stepInto());
});
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({ expression: 'Object.keys(this).filter(name => name.indexOf(\'test\') === 0)', returnByValue: true })
.then(runTests);
function runTests(message) {
var tests = message.result.result.value;
InspectorTest.runTestSuite(tests.map(test => eval(`(function ${test}(next) {
Protocol.Runtime.evaluate({ expression: 'debugger; ${test}()', awaitPromise: ${test.indexOf('testPromise') === 0}})
.then(next);
})`)));
}
......@@ -113,6 +113,32 @@ InspectorTest.logCallFrames = function(callFrames)
}
}
InspectorTest.logCallFrameSourceLocation = function(callFrame)
{
var scriptId = callFrame.location.scriptId;
if (!InspectorTest._scriptMap || !InspectorTest._scriptMap.has(scriptId)) {
InspectorTest.log("InspectorTest.setupScriptMap should be called before Protocol.Debugger.enable.");
InspectorTest.completeTest();
}
var script = InspectorTest._scriptMap.get(scriptId);
if (!script.scriptSource) {
return Protocol.Debugger.getScriptSource({ scriptId })
.then(message => script.scriptSource = message.result.scriptSource)
.then(dumpSourceWithLocation);
}
return Promise.resolve().then(dumpSourceWithLocation);
function dumpSourceWithLocation() {
var location = callFrame.location;
var lines = script.scriptSource.split('\n');
var line = lines[location.lineNumber];
line = line.slice(0, location.columnNumber) + '#' + (line.slice(location.columnNumber) || '');
lines[location.lineNumber] = line;
InspectorTest.log(lines.slice(Math.max(location.lineNumber - 1, 0), location.lineNumber + 2).join('\n'));
InspectorTest.log('');
}
}
InspectorTest.logAsyncStackTrace = function(asyncStackTrace)
{
while (asyncStackTrace) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment