destructuring-default.js (7350B)
1 load(libdir + 'asserts.js'); 2 load(libdir + 'eqArrayHelper.js'); 3 4 var arrayPattern = '[a = 1, b = 2, c = 3, d = 4, e = 5, f = 6]'; 5 var objectPattern = '{0: a = 1, 1: b = 2, 2: c = 3, 3: d = 4, 4: e = 5, 5: f = 6}'; 6 var objectPatternShorthand = '{a = 1, b = 2, c = 3, d = 4, e = 5, f = 6}'; 7 var nestedPattern = '{a: a = 1, b: [b = 2] = [], c: {c: [c]} = {c: [3]}, d: {d, e} = {d: 4, e: 5}, f: f = 6}'; 8 9 function testAll(fn) { 10 assertEqArray(fn(arrayPattern, []), [1, 2, 3, 4, 5, 6]); 11 assertEqArray(fn(arrayPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]); 12 assertEqArray(fn(arrayPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]); 13 assertEqArray(fn(arrayPattern, [0, false]), [0, false, 3, 4, 5, 6]); 14 15 assertEqArray(fn(objectPattern, []), [1, 2, 3, 4, 5, 6]); 16 assertEqArray(fn(objectPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]); 17 assertEqArray(fn(objectPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]); 18 assertEqArray(fn(objectPattern, [0, false]), [0, false, 3, 4, 5, 6]); 19 20 assertEqArray(fn(objectPatternShorthand, {}), [1, 2, 3, 4, 5, 6]); 21 assertEqArray(fn(objectPatternShorthand, {a: 2, b: 3, c: 4, d: 5, e: 6, f: 7, g: 8, h: 9}), [2, 3, 4, 5, 6, 7]); 22 assertEqArray(fn(objectPatternShorthand, {a: undefined, b: 0, c: false, d: null, e: "", f: undefined}), 23 [1, 0, false, null, "", 6]); 24 assertEqArray(fn(objectPatternShorthand, {a: 0, b: false}), [0, false, 3, 4, 5, 6]); 25 assertEqArray(fn(nestedPattern, {}), [1, 2, 3, 4, 5, 6]); 26 assertEqArray(fn(nestedPattern, {a: 2, b: [], c: undefined}), [2, 2, 3, 4, 5, 6]); 27 assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}}), [1, 3, 4, 4, 5, 6]); 28 assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}, d: {d: 5, e: 6}}), [1, 3, 4, 5, 6, 6]); 29 } 30 31 function testVar(pattern, input) { 32 return new Function('input', 33 'var ' + pattern + ' = input;' + 34 'return [a, b, c, d, e, f];' 35 )(input); 36 } 37 testAll(testVar); 38 39 function testLet(pattern, input) { 40 return new Function('input', 41 'let ' + pattern + ' = input;' + 42 'return [a, b, c, d, e, f];' 43 )(input); 44 } 45 testAll(testLet); 46 47 function testConst(pattern, input) { 48 return new Function('input', 49 'const ' + pattern + ' = input;' + 50 'return [a, b, c, d, e, f];' 51 )(input); 52 } 53 testAll(testConst); 54 55 function testGlobal(pattern, input) { 56 return new Function('input', 57 '(' + pattern + ' = input);' + 58 'return [a, b, c, d, e, f];' 59 )(input); 60 } 61 testAll(testGlobal); 62 63 function testClosure(pattern, input) { 64 return new Function('input', 65 'var rest; (function () {' + 66 '(' + pattern + ' = input);' + 67 '})();' + 68 'return [a, b, c, d, e, f];' 69 )(input); 70 } 71 testAll(testClosure); 72 73 function testArgument(pattern, input) { 74 return new Function('input', 75 'return (function (' + pattern + ') {' + 76 'return [a, b, c, d, e, f]; })(input);' 77 )(input); 78 } 79 testAll(testArgument); 80 81 function testArgumentFunction(pattern, input) { 82 return new Function(pattern, 83 'return [a, b, c, d, e, f];' 84 )(input); 85 } 86 testAll(testArgumentFunction); 87 88 function testThrow(pattern, input) { 89 return new Function('input', 90 'try { throw input }' + 91 'catch(' + pattern + ') {' + 92 'return [a, b, c, d, e, f]; }' 93 )(input); 94 } 95 testAll(testThrow); 96 97 // test global const 98 const [ca = 1, cb = 2] = []; 99 assertEq(ca, 1); 100 assertEq(cb, 2); 101 102 const {a: {a: cc = 3} = {a: undefined}} = {}; 103 assertEq(cc, 3); 104 105 // test that the assignment happens in source order 106 var a = undefined, b = undefined, c = undefined; 107 ({a: a = 1, c: c = 2, b: b = 3} = { 108 get a() { 109 assertEq(a, undefined); 110 assertEq(c, undefined); 111 assertEq(b, undefined); 112 return undefined; 113 }, 114 get b() { 115 assertEq(a, 1); 116 assertEq(c, 2); 117 assertEq(b, undefined); 118 return 4; 119 }, 120 get c() { 121 assertEq(a, 1); 122 assertEq(c, undefined); 123 assertEq(b, undefined); 124 return undefined; 125 } 126 }); 127 assertEq(b, 4); 128 129 assertThrowsInstanceOf(() => { var {a: {a} = null} = {}; }, TypeError); 130 assertThrowsInstanceOf(() => { var [[a] = 2] = []; }, TypeError); 131 132 // destructuring assignment might have duplicate variable names. 133 var [a = 1, a = 2] = [3]; 134 assertEq(a, 2); 135 136 // assignment to properties of default params 137 [a = {y: 2}, a.x = 1] = []; 138 assertEq(typeof a, 'object'); 139 assertEq(a.x, 1); 140 assertEq(a.y, 2); 141 142 // defaults are evaluated even if there is no binding 143 var evaled = false; 144 ({a: {} = (evaled = true, {})} = {}); 145 assertEq(evaled, true); 146 evaled = false; 147 assertThrowsInstanceOf(() => { [[] = (evaled = true, 2)] = [] }, TypeError); 148 assertEq(evaled, true); 149 150 assertThrowsInstanceOf(() => new Function('var [...rest = defaults] = [];'), SyntaxError); 151 152 new Function(` 153 b = undefined; 154 for (var [a, b = 10] in " ") {} 155 assertEq(b, 10);`)(); 156 157 new Function(` 158 b = undefined; 159 for (let [a, c = 10] in " ") { b = c; } 160 assertEq(b, 10);`)(); 161 162 new Function(` 163 b = undefined; 164 for (let [a, c = (x => y)] in " ") { b = c; } 165 assertEq(typeof b, "function");`)(); 166 167 new Function(` 168 b = undefined; 169 for (let [a, __proto__ = 10] in " ") { b = __proto__; } 170 assertEq(b, 10);`)(); 171 172 new Function(` 173 b = undefined; 174 for (let [a, __proto__ = (x => y)] in " ") { b = __proto__; } 175 assertEq(typeof b, "function");`)(); 176 177 new Function(` 178 b = undefined; 179 for (var {1: b = 10} in " ") {} 180 assertEq(b, 10);`)(); 181 182 new Function(` 183 b = undefined; 184 for (let {1: c = 10} in " ") { b = c; } 185 assertEq(b, 10);`)(); 186 187 new Function(` 188 b = undefined; 189 for (let { c = 10 } in " ") { b = c; } 190 assertEq(b, 10);`)(); 191 192 new Function(` 193 b = undefined; 194 assertEq(Number.prototype.a, undefined); 195 for (var { a: c = (x => y) } in [{}]) { b = c; } 196 assertEq(typeof b, "function");`)(); 197 198 new Function(` 199 b = undefined; 200 Object.defineProperty(String.prototype, "__proto__", 201 { value: undefined, configurable: true }); 202 for (var { __proto__: c = (x => y) } in [{}]) { b = c; } 203 delete String.prototype.__proto__; 204 assertEq(typeof b, "function");`)(); 205 206 new Function(` 207 b = undefined; 208 for (var { a: c = (x => y) } of [{ a: undefined }]) { b = c; } 209 assertEq(typeof b, "function");`)(); 210 211 new Function(` 212 b = undefined; 213 for (var { __proto__: c = (x => y) } of [{ ["__proto__"]: undefined }]) { b = c; } 214 assertEq(typeof b, "function");`)(); 215 216 new Function(` 217 b = undefined; 218 var ts = Function.prototype.toString; 219 Function.prototype.toString = () => 'hi'; 220 String.prototype.hi = 42; 221 for (var { [(x => y)]: c } in [0]) { b = c; } 222 Function.prototype.toString = ts; 223 delete String.prototype.hi; 224 assertEq(b, 42);`)(); 225 226 new Function(` 227 b = undefined; 228 var ts = Function.prototype.toString; 229 Function.prototype.toString = () => 'hi'; 230 String.prototype.hi = 42; 231 for (var { [(x => y)]: __proto__ } in [0]) { b = __proto__; } 232 Function.prototype.toString = ts; 233 delete String.prototype.hi; 234 assertEq(b, 42);`)(); 235 236 new Function(` 237 b = undefined; 238 var ts = Function.prototype.toString; 239 Function.prototype.toString = () => 'hi'; 240 for (var { [(x => y)]: c } of [{ 'hi': 42 }]) { b = c; } 241 Function.prototype.toString = ts; 242 assertEq(b, 42);`)(); 243 244 new Function(` 245 b = undefined; 246 var ts = Function.prototype.toString; 247 Function.prototype.toString = () => 'hi'; 248 for (var { [(x => y)]: __proto__ } of [{ hi: 42 }]) { b = __proto__; } 249 Function.prototype.toString = ts; 250 assertEq(b, 42);`)();