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

[inspector] added master test for break locations

BUG=none
R=dgozman@chromium.org

Review-Url: https://codereview.chromium.org/2710903003
Cr-Commit-Position: refs/heads/master@{#43459}
parent c63e83c1
Checks Debugger.getPossibleBreakpoints
// 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.
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;
#}
function returnFunction() {
#return returnObject;
#}
async function testPromiseComplex() {
var nextTest;
var testPromise = #new Promise(resolve => nextTest #= resolve#);
async function main() {
async function foo() {
#await Promise.resolve();
#return 42;
#}
var x = #1;
var y = #2;
#returnFunction(#emptyFunction(), x++, --y, x => 2 #* x#, #returnCall())#().a = #await #foo((a => 2 #*a#)#(5));
#nextTest();
#}
#main();
#return testPromise;
#}
function twiceDefined() {
return a + b;
}
function twiceDefined() {
#return a + b;
#}
// 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 Debugger.getPossibleBreakpoints');
var source = read('test/inspector/debugger/resources/break-locations.js');
InspectorTest.addScript(source);
Protocol.Debugger.onceScriptParsed()
.then(message => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber : 0, scriptId: message.params.scriptId }}))
.then(dumpAllLocations)
.then(InspectorTest.completeTest);
Protocol.Debugger.enable();
function dumpAllLocations(message) {
if (message.error) {
InspectorTest.logMessage(message);
return;
}
var lines = source.split('\n');
var locations = message.result.locations.sort((loc1, loc2) => {
if (loc2.lineNumber !== loc1.lineNumber) return loc2.lineNumber - loc1.lineNumber;
return loc2.columnNumber - loc1.columnNumber;
});
for (var location of locations) {
var line = lines[location.lineNumber];
line = line.slice(0, location.columnNumber) + '#' + line.slice(location.columnNumber);
lines[location.lineNumber] = line;
}
lines = lines.filter(line => line.indexOf('//# sourceURL=') === -1);
InspectorTest.log(lines.join('\n'));
return message;
}
// 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.
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;
}
function returnFunction() {
return returnObject;
}
async function testPromiseComplex() {
var nextTest;
var testPromise = new Promise(resolve => nextTest = resolve);
async function main() {
async function foo() {
await Promise.resolve();
return 42;
}
var x = 1;
var y = 2;
returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)(5));
nextTest();
}
main();
return testPromise;
}
function twiceDefined() {
return a + b;
}
function twiceDefined() {
return a + b;
}
//# sourceURL=break-locations.js
......@@ -960,3 +960,130 @@ break at:
#await p;
}
Running test: testPromiseComplex
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:
}
var x = #1;
var y = 2;
break at:
var x = 1;
var y = #2;
returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)(5));
break at:
var y = 2;
#returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)(5));
nextTest();
break at:
function emptyFunction() {#}
break at:
var y = 2;
returnFunction(emptyFunction(), x++, --y, x => 2 * x, #returnCall())().a = await foo((a => 2 *a)(5));
nextTest();
break at:
function returnCall() {
#return return42();
}
break at:
function return42() {
#return 42;
}
break at:
return 42;
#}
break at:
return return42();
#}
break at:
var y = 2;
#returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)(5));
nextTest();
break at:
function returnFunction() {
#return returnObject;
}
break at:
return returnObject;
#}
break at:
var y = 2;
returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())#().a = await foo((a => 2 *a)(5));
nextTest();
break at:
function returnObject() {
#return ({ foo: () => 42 });
}
break at:
return ({ foo: () => 42 });
#}
break at:
var y = 2;
returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await #foo((a => 2 *a)(5));
nextTest();
break at:
var y = 2;
returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 #*a)(5));
nextTest();
break at:
var y = 2;
returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a#)(5));
nextTest();
break at:
var y = 2;
returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await #foo((a => 2 *a)(5));
nextTest();
break at:
async function foo() {
await Promise.#resolve();
return 42;
break at:
async function foo() {
#await Promise.resolve();
return 42;
......@@ -4,245 +4,6 @@
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;
......@@ -256,6 +17,8 @@ Protocol.Debugger.onPaused(message => {
.then(() => Protocol.Debugger.stepInto());
});
InspectorTest.loadScript('test/inspector/debugger/resources/break-locations.js');
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({ expression: 'Object.keys(this).filter(name => name.indexOf(\'test\') === 0)', returnByValue: true })
.then(runTests);
......
......@@ -53,6 +53,7 @@ class UtilsExtension : public v8::Extension {
"native function print();"
"native function quit();"
"native function setlocale();"
"native function read();"
"native function load();"
"native function compileAndRunWithOrigin();"
"native function setCurrentTimeMSForTest();"
......@@ -78,6 +79,12 @@ class UtilsExtension : public v8::Extension {
.ToLocalChecked())
.FromJust()) {
return v8::FunctionTemplate::New(isolate, UtilsExtension::SetLocale);
} else if (name->Equals(context,
v8::String::NewFromUtf8(isolate, "read",
v8::NewStringType::kNormal)
.ToLocalChecked())
.FromJust()) {
return v8::FunctionTemplate::New(isolate, UtilsExtension::Read);
} else if (name->Equals(context,
v8::String::NewFromUtf8(isolate, "load",
v8::NewStringType::kNormal)
......@@ -173,27 +180,49 @@ class UtilsExtension : public v8::Extension {
setlocale(LC_NUMERIC, *str);
}
static void Load(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Length() != 1 || !args[0]->IsString()) {
fprintf(stderr, "Internal error: load gets one string argument.");
Exit();
}
v8::String::Utf8Value str(args[0]);
v8::Isolate* isolate = args.GetIsolate();
static bool ReadFile(v8::Isolate* isolate, v8::Local<v8::Value> name,
v8::internal::Vector<const char>* chars) {
v8::String::Utf8Value str(name);
bool exists = false;
std::string filename(*str, str.length());
v8::internal::Vector<const char> chars =
v8::internal::ReadFile(filename.c_str(), &exists);
*chars = v8::internal::ReadFile(filename.c_str(), &exists);
if (!exists) {
isolate->ThrowException(
v8::String::NewFromUtf8(isolate, "Error loading file",
v8::String::NewFromUtf8(isolate, "Error reading file",
v8::NewStringType::kNormal)
.ToLocalChecked());
return;
return false;
}
return true;
}
static void Read(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Length() != 1 || !args[0]->IsString()) {
fprintf(stderr, "Internal error: read gets one string argument.");
Exit();
}
v8::internal::Vector<const char> chars;
v8::Isolate* isolate = args.GetIsolate();
if (ReadFile(isolate, args[0], &chars)) {
args.GetReturnValue().Set(
v8::String::NewFromUtf8(isolate, chars.start(),
v8::NewStringType::kNormal, chars.length())
.ToLocalChecked());
}
}
static void Load(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Length() != 1 || !args[0]->IsString()) {
fprintf(stderr, "Internal error: load gets one string argument.");
Exit();
}
v8::internal::Vector<const char> chars;
v8::Isolate* isolate = args.GetIsolate();
if (ReadFile(isolate, args[0], &chars)) {
ExecuteStringTask task(chars);
v8::Global<v8::Context> context(isolate, isolate->GetCurrentContext());
task.Run(isolate, context);
}
ExecuteStringTask task(chars);
v8::Global<v8::Context> context(isolate, isolate->GetCurrentContext());
task.Run(isolate, context);
}
static void CompileAndRunWithOrigin(
......
......@@ -269,3 +269,7 @@ InspectorTest._dispatchMessage = function(messageObject)
InspectorTest.completeTest();
}
}
InspectorTest.loadScript = function(fileName) {
InspectorTest.addScript(read(fileName));
}
......@@ -13,6 +13,7 @@ from testrunner.objects import testcase
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
PROTOCOL_TEST_JS = "protocol-test.js"
EXPECTED_SUFFIX = "-expected.txt"
RESOURCES_FOLDER = "resources"
class InspectorProtocolTestSuite(testsuite.TestSuite):
......@@ -24,6 +25,8 @@ class InspectorProtocolTestSuite(testsuite.TestSuite):
for dirname, dirs, files in os.walk(os.path.join(self.root), followlinks=True):
for dotted in [x for x in dirs if x.startswith('.')]:
dirs.remove(dotted)
if dirname.endswith(os.path.sep + RESOURCES_FOLDER):
continue
dirs.sort()
files.sort()
for filename in files:
......
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