blob: 98d8ab140f9a6a0827f26d2b8edbe976bfe77188 [file] [log] [blame]
<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function test()
{
function outputErrorSourceRange(range) {
var str = " ".repeat("Source: ".length);
str += " ".repeat(range.startOffset);
str += "^";
str += "~".repeat(Math.max(range.endOffset - range.startOffset - 1, 0));
InspectorTest.log(str);
}
let suite = InspectorTest.createAsyncSuite("Runtime.parse");
suite.addTestCase({
name: "SyntaxErrorType.None",
description: "Test source without an issue.",
test(resolve, reject) {
function testSource(source) {
RuntimeAgent.parse(source, (error, result, message, range) => {
InspectorTest.assert(!error, "Should not be a protocol error.");
InspectorTest.expectThat(result === RuntimeAgent.SyntaxErrorType.None, "Should be SyntaxErrorType None.");
InspectorTest.log("Source: " + source);
InspectorTest.assert(!message);
InspectorTest.assert(!range);
InspectorTest.log("");
});
}
// Complete programs without syntax errors (could have runtime errors).
testSource("");
testSource(";");
testSource("myVariable");
testSource("var x = 1; x");
testSource("[1,2,3]");
testSource("({})");
testSource("({prop:true}).x.x.x");
testSource("if(1)1");
InspectorBackend.runAfterPendingDispatches(resolve);
}
});
suite.addTestCase({
name: "SyntaxErrorType.UnterminatedLiteral",
description: "Test source with an unterminated literal.",
test(resolve, reject) {
function testSource(source) {
RuntimeAgent.parse(source, (error, result, message, range) => {
InspectorTest.assert(!error, "Should not be a protocol error.");
InspectorTest.expectThat(result === RuntimeAgent.SyntaxErrorType.UnterminatedLiteral, "Should be SyntaxErrorType UnterminatedLiteral.");
InspectorTest.log("Source: " + source);
outputErrorSourceRange(range);
InspectorTest.log("Error Message: " + message);
InspectorTest.log("Range: " + JSON.stringify(range));
InspectorTest.log("");
});
}
// A literal that is not yet complete, but would be a single token.
testSource("0b"); // binary
testSource("0o"); // octal
testSource("0x"); // hex
testSource("1e"); // scientific notation number
testSource("'"); // string
testSource("\""); // string
testSource("var \\u007"); // identifier unicode escape
// testSource("/r"); // regexp - Not detected by JavaScriptCore.
InspectorBackend.runAfterPendingDispatches(resolve);
}
});
suite.addTestCase({
name: "SyntaxErrorType.Recoverable",
description: "Test source with a recoverable error.",
test(resolve, reject) {
function testSource(source) {
RuntimeAgent.parse(source, (error, result, message, range) => {
InspectorTest.assert(!error, "Should not be a protocol error.");
InspectorTest.expectThat(result === RuntimeAgent.SyntaxErrorType.Recoverable, "Should be SyntaxErrorType Recoverable.");
InspectorTest.log("Source: " + source);
outputErrorSourceRange(range);
InspectorTest.log("Error Message: " + message);
InspectorTest.log("Error Range: " + JSON.stringify(range));
InspectorTest.log("");
});
}
// Not yet a syntax error, just an incomplete program.
testSource("(");
testSource("{");
testSource("!");
testSource("-"); // unary
testSource("+"); // unary
testSource("~"); // unary
testSource("1,");
testSource("var");
testSource("'use strict'; let"); // When not in strict mode, let is treated as the start of an identifier, not a keyword!
testSource("const");
testSource("var {x"); // destructuring
testSource("var [x"); // destructuring
testSource("var x,");
testSource("if(1)");
testSource("if(1){");
testSource("if(1){}else");
testSource("if(1){}else{");
testSource("while(1)");
testSource("while(1){");
testSource("for(;;)");
testSource("for(;;){");
testSource("()=>"); // arrow function
testSource("()=>{"); // arrow function
testSource("/*"); // comment
testSource("`"); // template string
testSource("`${1}"); // template string
testSource("`${"); // template string
testSource("function");
testSource("function foo");
testSource("function foo(");
testSource("function foo(){");
testSource("(function() {");
testSource("(function() {}");
testSource("(function() {})(");
testSource("switch(x)");
testSource("switch(x){");
testSource("switch(x){case");
testSource("switch(x){case 1");
testSource("switch(x){case 1:");
testSource("class");
testSource("class Klass");
testSource("class Klass {");
testSource("var x = {");
testSource("var x = {prop");
testSource("var x = {prop:");
testSource("var x = {prop:123");
testSource("var x = {prop:123 ");
testSource("var x = {prop:123,");
testSource("var x = {prop:123, ");
testSource("var x = {prop:123, 'prop2'");
testSource("var x = {prop:123, [12");
testSource("var x = {prop:123, [12]");
testSource("var x = {prop:123, [12]:");
testSource("var x = {prop:123, [12]:567");
testSource("var x = [");
testSource("var x = [1");
testSource("var x = [1,");
testSource("var x = [1,[]");
testSource("var x = [1,{}");
InspectorBackend.runAfterPendingDispatches(resolve);
}
});
suite.addTestCase({
name: "SyntaxErrorType.Irrecoverable",
description: "Test source with an irrecoverable issue.",
test(resolve, reject) {
function testSource(source) {
RuntimeAgent.parse(source, (error, result, message, range) => {
InspectorTest.assert(!error, "Should not be a protocol error.");
InspectorTest.expectThat(result === RuntimeAgent.SyntaxErrorType.Irrecoverable, "Should be SyntaxErrorType Irrecoverable.");
InspectorTest.log("Source: " + source);
outputErrorSourceRange(range);
InspectorTest.log("Error Message: " + message);
InspectorTest.log("Error Range: " + JSON.stringify(range));
InspectorTest.log("");
});
}
// SyntaxErrors. Any typing after the syntax error is detected does not matter.
testSource("1$");
testSource("var x = {}}");
testSource("({}))");
testSource("var x = =");
testSource("const x;");
testSource("let x = 1; let x = 2;");
testSource("if x(1)");
InspectorBackend.runAfterPendingDispatches(resolve);
}
});
suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Tests for the Runtime.parse command.</p>
</body>
</html>