1function assert(actual, expected, message) { 2 if (arguments.length == 1) 3 expected = true; 4 5 if (actual === expected) 6 return; 7 8 if (actual !== null && expected !== null 9 && typeof actual == 'object' && typeof expected == 'object' 10 && actual.toString() === expected.toString()) 11 return; 12 13 throw Error("assertion failed: got |" + actual + "|" + 14 ", expected |" + expected + "|" + 15 (message ? " (" + message + ")" : "")); 16} 17 18// load more elaborate version of assert if available 19try { __loadScript("test_assert.js"); } catch(e) {} 20 21/*----------------*/ 22 23var log_str = ""; 24 25function log(str) 26{ 27 log_str += str + ","; 28} 29 30function f(a, b, c) 31{ 32 var x = 10; 33 log("a="+a); 34 function g(d) { 35 function h() { 36 log("d=" + d); 37 log("x=" + x); 38 } 39 log("b=" + b); 40 log("c=" + c); 41 h(); 42 } 43 g(4); 44 return g; 45} 46 47var g1 = f(1, 2, 3); 48g1(5); 49 50assert(log_str, "a=1,b=2,c=3,d=4,x=10,b=2,c=3,d=5,x=10,", "closure1"); 51 52function test_closure1() 53{ 54 function f2() 55 { 56 var val = 1; 57 58 function set(a) { 59 val = a; 60 } 61 function get(a) { 62 return val; 63 } 64 return { "set": set, "get": get }; 65 } 66 67 var obj = f2(); 68 obj.set(10); 69 var r; 70 r = obj.get(); 71 assert(r, 10, "closure2"); 72} 73 74function test_closure2() 75{ 76 var expr_func = function myfunc1(n) { 77 function myfunc2(n) { 78 return myfunc1(n - 1); 79 } 80 if (n == 0) 81 return 0; 82 else 83 return myfunc2(n); 84 }; 85 var r; 86 r = expr_func(1); 87 assert(r, 0, "expr_func"); 88} 89 90function test_closure3() 91{ 92 function fib(n) 93 { 94 if (n <= 0) 95 return 0; 96 else if (n == 1) 97 return 1; 98 else 99 return fib(n - 1) + fib(n - 2); 100 } 101 102 var fib_func = function fib1(n) 103 { 104 if (n <= 0) 105 return 0; 106 else if (n == 1) 107 return 1; 108 else 109 return fib1(n - 1) + fib1(n - 2); 110 }; 111 112 assert(fib(6), 8, "fib"); 113 assert(fib_func(6), 8, "fib_func"); 114} 115 116function test_arrow_function() 117{ 118 "use strict"; 119 120 function f1() { 121 return (() => arguments)(); 122 } 123 function f2() { 124 return (() => this)(); 125 } 126 function f3() { 127 return (() => eval("this"))(); 128 } 129 function f4() { 130 return (() => eval("new.target"))(); 131 } 132 var a; 133 134 a = f1(1, 2); 135 assert(a.length, 2); 136 assert(a[0] === 1 && a[1] === 2); 137 138 assert(f2.call("this_val") === "this_val"); 139 assert(f3.call("this_val") === "this_val"); 140 assert(new f4() === f4); 141 142 var o1 = { f() { return this; } }; 143 var o2 = { f() { 144 return (() => eval("super.f()"))(); 145 } }; 146 o2.__proto__ = o1; 147 148 assert(o2.f() === o2); 149} 150 151function test_with() 152{ 153 var o1 = { x: "o1", y: "o1" }; 154 var x = "local"; 155 eval('var z="var_obj";'); 156 assert(z === "var_obj"); 157 with (o1) { 158 assert(x === "o1"); 159 assert(eval("x") === "o1"); 160 var f = function () { 161 o2 = { x: "o2" }; 162 with (o2) { 163 assert(x === "o2"); 164 assert(y === "o1"); 165 assert(z === "var_obj"); 166 assert(eval("x") === "o2"); 167 assert(eval("y") === "o1"); 168 assert(eval("z") === "var_obj"); 169 assert(eval('eval("x")') === "o2"); 170 } 171 }; 172 f(); 173 } 174} 175 176function test_eval_closure() 177{ 178 var tab; 179 180 tab = []; 181 for(let i = 0; i < 3; i++) { 182 eval("tab.push(function g1() { return i; })"); 183 } 184 for(let i = 0; i < 3; i++) { 185 assert(tab[i]() === i); 186 } 187 188 tab = []; 189 for(let i = 0; i < 3; i++) { 190 let f = function f() { 191 eval("tab.push(function g2() { return i; })"); 192 }; 193 f(); 194 } 195 for(let i = 0; i < 3; i++) { 196 assert(tab[i]() === i); 197 } 198} 199 200function test_eval_const() 201{ 202 const a = 1; 203 var success = false; 204 var f = function () { 205 eval("a = 1"); 206 }; 207 try { 208 f(); 209 } catch(e) { 210 success = (e instanceof TypeError); 211 } 212 assert(success); 213} 214 215test_closure1(); 216test_closure2(); 217test_closure3(); 218test_arrow_function(); 219test_with(); 220test_eval_closure(); 221test_eval_const(); 222