function assert(actual, expected, message) { if (arguments.length == 1) expected = true; if (actual === expected) return; if (actual !== null && expected !== null && typeof actual == 'object' && typeof expected == 'object' && actual.toString() === expected.toString()) return; throw Error("assertion failed: got |" + actual + "|" + ", expected |" + expected + "|" + (message ? " (" + message + ")" : ""));} // load more elaborate version of assert if availabletry { __loadScript("test_assert.js"); } catch(e) {} /*----------------*/ var log_str = ""; function log(str){ log_str += str + ",";} function f(a, b, c){ var x = 10; log("a="+a); function g(d) { function h() { log("d=" + d); log("x=" + x); } log("b=" + b); log("c=" + c); h(); } g(4); return g;} var g1 = f(1, 2, 3);g1(5); assert(log_str, "a=1,b=2,c=3,d=4,x=10,b=2,c=3,d=5,x=10,", "closure1"); function test_closure1(){ function f2() { var val = 1; function set(a) { val = a; } function get(a) { return val; } return { "set": set, "get": get }; } var obj = f2(); obj.set(10); var r; r = obj.get(); assert(r, 10, "closure2");} function test_closure2(){ var expr_func = function myfunc1(n) { function myfunc2(n) { return myfunc1(n - 1); } if (n == 0) return 0; else return myfunc2(n); }; var r; r = expr_func(1); assert(r, 0, "expr_func");} function test_closure3(){ function fib(n) { if (n <= 0) return 0; else if (n == 1) return 1; else return fib(n - 1) + fib(n - 2); } var fib_func = function fib1(n) { if (n <= 0) return 0; else if (n == 1) return 1; else return fib1(n - 1) + fib1(n - 2); }; assert(fib(6), 8, "fib"); assert(fib_func(6), 8, "fib_func");} function test_arrow_function(){ "use strict"; function f1() { return (() => arguments)(); } function f2() { return (() => this)(); } function f3() { return (() => eval("this"))(); } function f4() { return (() => eval("new.target"))(); } var a; a = f1(1, 2); assert(a.length, 2); assert(a[0] === 1 && a[1] === 2); assert(f2.call("this_val") === "this_val"); assert(f3.call("this_val") === "this_val"); assert(new f4() === f4); var o1 = { f() { return this; } }; var o2 = { f() { return (() => eval("super.f()"))(); } }; o2.__proto__ = o1; assert(o2.f() === o2);} function test_with(){ var o1 = { x: "o1", y: "o1" }; var x = "local"; eval('var z="var_obj";'); assert(z === "var_obj"); with (o1) { assert(x === "o1"); assert(eval("x") === "o1"); var f = function () { o2 = { x: "o2" }; with (o2) { assert(x === "o2"); assert(y === "o1"); assert(z === "var_obj"); assert(eval("x") === "o2"); assert(eval("y") === "o1"); assert(eval("z") === "var_obj"); assert(eval('eval("x")') === "o2"); } }; f(); }} function test_eval_closure(){ var tab; tab = []; for(let i = 0; i < 3; i++) { eval("tab.push(function g1() { return i; })"); } for(let i = 0; i < 3; i++) { assert(tab[i]() === i); } tab = []; for(let i = 0; i < 3; i++) { let f = function f() { eval("tab.push(function g2() { return i; })"); }; f(); } for(let i = 0; i < 3; i++) { assert(tab[i]() === i); }} function test_eval_const(){ const a = 1; var success = false; var f = function () { eval("a = 1"); }; try { f(); } catch(e) { success = (e instanceof TypeError); } assert(success);} test_closure1();test_closure2();test_closure3();test_arrow_function();test_with();test_eval_closure();test_eval_const();
function assert(actual, expected, message) {
if (arguments.length == 1)
expected = true;
if (actual === expected)
return;
if (actual !== null && expected !== null
&& typeof actual == 'object' && typeof expected == 'object'
&& actual.toString() === expected.toString())
return;
throw Error("assertion failed: got |" + actual + "|" +
", expected |" + expected + "|" +
(message ? " (" + message + ")" : ""));
}
// load more elaborate version of assert if available
try { __loadScript("test_assert.js"); } catch(e) {}
/*----------------*/
var log_str = "";
function log(str)
{
log_str += str + ",";
}
function f(a, b, c)
{
var x = 10;
log("a="+a);
function g(d) {
function h() {
log("d=" + d);
log("x=" + x);
}
log("b=" + b);
log("c=" + c);
h();
}
g(4);
return g;
}
var g1 = f(1, 2, 3);
g1(5);
assert(log_str, "a=1,b=2,c=3,d=4,x=10,b=2,c=3,d=5,x=10,", "closure1");
function test_closure1()
{
function f2()
{
var val = 1;
function set(a) {
val = a;
}
function get(a) {
return val;
}
return { "set": set, "get": get };
}
var obj = f2();
obj.set(10);
var r;
r = obj.get();
assert(r, 10, "closure2");
}
function test_closure2()
{
var expr_func = function myfunc1(n) {
function myfunc2(n) {
return myfunc1(n - 1);
}
if (n == 0)
return 0;
else
return myfunc2(n);
};
var r;
r = expr_func(1);
assert(r, 0, "expr_func");
}
function test_closure3()
{
function fib(n)
{
if (n <= 0)
return 0;
else if (n == 1)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
var fib_func = function fib1(n)
{
if (n <= 0)
return 0;
else if (n == 1)
return 1;
else
return fib1(n - 1) + fib1(n - 2);
};
assert(fib(6), 8, "fib");
assert(fib_func(6), 8, "fib_func");
}
function test_arrow_function()
{
"use strict";
function f1() {
return (() => arguments)();
}
function f2() {
return (() => this)();
}
function f3() {
return (() => eval("this"))();
}
function f4() {
return (() => eval("new.target"))();
}
var a;
a = f1(1, 2);
assert(a.length, 2);
assert(a[0] === 1 && a[1] === 2);
assert(f2.call("this_val") === "this_val");
assert(f3.call("this_val") === "this_val");
assert(new f4() === f4);
var o1 = { f() { return this; } };
var o2 = { f() {
return (() => eval("super.f()"))();
} };
o2.__proto__ = o1;
assert(o2.f() === o2);
}
function test_with()
{
var o1 = { x: "o1", y: "o1" };
var x = "local";
eval('var z="var_obj";');
assert(z === "var_obj");
with (o1) {
assert(x === "o1");
assert(eval("x") === "o1");
var f = function () {
o2 = { x: "o2" };
with (o2) {
assert(x === "o2");
assert(y === "o1");
assert(z === "var_obj");
assert(eval("x") === "o2");
assert(eval("y") === "o1");
assert(eval("z") === "var_obj");
assert(eval('eval("x")') === "o2");
}
};
f();
}
}
function test_eval_closure()
{
var tab;
tab = [];
for(let i = 0; i < 3; i++) {
eval("tab.push(function g1() { return i; })");
}
for(let i = 0; i < 3; i++) {
assert(tab[i]() === i);
}
tab = [];
for(let i = 0; i < 3; i++) {
let f = function f() {
eval("tab.push(function g2() { return i; })");
};
f();
}
for(let i = 0; i < 3; i++) {
assert(tab[i]() === i);
}
}
function test_eval_const()
{
const a = 1;
var success = false;
var f = function () {
eval("a = 1");
};
try {
f();
} catch(e) {
success = (e instanceof TypeError);
}
assert(success);
}
test_closure1();
test_closure2();
test_closure3();
test_arrow_function();
test_with();
test_eval_closure();
test_eval_const();