MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1const failures = [];
2
3function assertArrayEq(name, got, expected) {
4 const ok = got.length === expected.length &&
5 got.every((v, i) => v === expected[i]);
6 if (!ok) {
7 failures.push(`${name}: expected [${expected.join(', ')}], got [${got.join(', ')}]`);
8 }
9}
10
11function collectForInLet() {
12 const funcs = [];
13 for (let key in { a: 1, b: 1, c: 1 }) {
14 funcs.push(() => key);
15 }
16 return funcs.map(fn => fn());
17}
18
19function collectForInConst() {
20 const funcs = [];
21 for (const key in { a: 1, b: 1, c: 1 }) {
22 funcs.push(() => key);
23 }
24 return funcs.map(fn => fn());
25}
26
27function collectForOfLet() {
28 const funcs = [];
29 for (let value of ['x', 'y', 'z']) {
30 funcs.push(() => value);
31 }
32 return funcs.map(fn => fn());
33}
34
35function collectForOfConst() {
36 const funcs = [];
37 for (const value of ['x', 'y', 'z']) {
38 funcs.push(() => value);
39 }
40 return funcs.map(fn => fn());
41}
42
43function collectForOfDestructureLet() {
44 const funcs = [];
45 for (let [k, v] of [['a', 1], ['b', 2], ['c', 3]]) {
46 funcs.push(() => `${k}:${v}`);
47 }
48 return funcs.map(fn => fn());
49}
50
51assertArrayEq('for-in let closure', collectForInLet(), ['a', 'b', 'c']);
52assertArrayEq('for-in const closure', collectForInConst(), ['a', 'b', 'c']);
53assertArrayEq('for-of let closure', collectForOfLet(), ['x', 'y', 'z']);
54assertArrayEq('for-of const closure', collectForOfConst(), ['x', 'y', 'z']);
55assertArrayEq(
56 'for-of let destructuring closure',
57 collectForOfDestructureLet(),
58 ['a:1', 'b:2', 'c:3']
59);
60
61if (failures.length > 0) {
62 console.log('Binding loop closure failures:');
63 for (let i = 0; i < failures.length; i++) {
64 console.log(` ${i + 1}. ${failures[i]}`);
65 }
66 throw new Error(`Found ${failures.length} binding-loop closure regression(s)`);
67}
68
69console.log('PASS: binding loop closures');