blob: 8db10a4e0a7ebd58a15ac238bf295ae27f63ef5d [file] [log] [blame]
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var gTestfile = "for-loop.js";
//-----------------------------------------------------------------------------
var BUGNUMBER = 985733;
var summary =
"ES6 for-loop semantics for for(;;) loops whose heads contain lexical "
"declarations";
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
function isError(code, type)
{
try
{
Function(code);
throw new Error("didn't throw");
}
catch (e)
{
assertEq(e instanceof type, true,
"unexpected error for `" + code + "`: got " + e);
}
}
function isOK(code)
{
Function(code);
}
isError("for (const x; ; ) ;", SyntaxError);
isError("for (const x = 5, y; ; ) ;", SyntaxError);
isError("for (const [z]; ; ) ;", SyntaxError);
//isError("for (const [z, z]; ; ) ;", SyntaxError);
//isError("for (const [z, z] = [0, 1]; ; ) ;", SyntaxError);
isOK("for (let x; ; ) ;");
isOK("for (let x = 5, y; ; ) ;");
// I'm fairly sure this is supposed to work: the negative-lookahead rules in
// IterationStatement ensure that |for (let| *always* is a loop header starting
// with a lexical declaration. But I'm not 100% certain, so these tests might
// need to be fixed when we implement the negative-lookahead restrictions.
isOK("for (let [z] = [3]; ; ) ;");
isError("for (let [z, z]; ; ) ;", SyntaxError); // because missing initializer
// This is wrong! Per 13.2.1.1, "It is a Syntax Error if the BoundNames of
// BindingList contains any duplicate entries." But we don't implement this
// yet, so it becomes a TypeError at runtime.
isError("for (let [z, z] = [0, 1]; ; ) ;", TypeError);
// A for-loop with lexical declarations, with a mixture of bindings that are and
// aren't aliased. (The mixture stress-tests any code that incorrectly assumes
// all bindings are aliased.)
var funcs = [];
for (let [i, j, k] = [0, 1, 2]; i < 10; i++)
funcs.push(() => i);
assertEq(funcs[0](), 0);
assertEq(funcs[1](), 1);
assertEq(funcs[2](), 2);
assertEq(funcs[3](), 3);
assertEq(funcs[4](), 4);
assertEq(funcs[5](), 5);
assertEq(funcs[6](), 6);
assertEq(funcs[7](), 7);
assertEq(funcs[8](), 8);
assertEq(funcs[9](), 9);
var outer = "OUTER V IGNORE";
var save;
for (let outer = (save = function() { return outer; }); ; )
break;
assertEq(save(), save);
var funcs = [];
function t(i, name, expect)
{
assertEq(funcs[i].name, name);
assertEq(funcs[i](), expect);
}
if (save() !== "OUTER V IGNORE")
{
var v = "OUTER V IGNORE";
var i = 0;
for (let v = (funcs.push(function init() { return v; }),
0);
v = (funcs.push(function test() { return v; }),
v + 1);
v = (funcs.push(function incr() { return v; }),
v + 1))
{
v = (funcs.push(function body() { return v; }),
v + 1);
i++;
if (i >= 3)
break;
}
t(0, "init", 2);
t(1, "test", 2);
t(2, "body", 2);
t(3, "incr", 5);
t(4, "test", 5);
t(5, "body", 5);
t(6, "incr", 8);
t(7, "test", 8);
t(8, "body", 8);
assertEq(funcs.length, 9);
}
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");