1// Copyright JS Foundation and other contributors, http://js.foundation 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15function checkSyntax (str) { 16 try { 17 eval (str); 18 assert (false); 19 } catch (e) { 20 assert (e instanceof SyntaxError); 21 } 22} 23 24function mustThrow (str) { 25 try { 26 eval (str); 27 assert (false); 28 } catch (e) { 29 assert (e instanceof TypeError); 30 } 31} 32 33checkSyntax ("var {a}"); 34checkSyntax ("var {a, o.a}"); 35checkSyntax ("var {a, ...b}"); 36checkSyntax ("var {a, ...b} = 4"); 37checkSyntax ("var {a, ...[b] = 4}"); 38checkSyntax ("var {a,,} = 4"); 39checkSyntax ("var {a :} = 4"); 40checkSyntax ("var {a : ,} = 4"); 41checkSyntax ("var {a : ['foobar']} = 4"); 42checkSyntax ("var {let}"); 43checkSyntax ("var {get = []"); 44checkSyntax ("var {get : 5}"); 45checkSyntax ("var {[a = {},}"); 46checkSyntax ("let {a,a} = []"); 47checkSyntax ("let {a : b, b} = []"); 48checkSyntax ("const {a,a} = []"); 49checkSyntax ("const {a : b, b} = []"); 50checkSyntax ("try { let {$} = $;"); 51checkSyntax ("let a, { 'x': a } = {x : 4};"); 52checkSyntax ("let a, { x: b.c } = {x : 6};"); 53checkSyntax ("let {a:(a)} = {a:1}"); 54 55mustThrow ("var {a} = null"); 56mustThrow ("var {a} = undefined"); 57mustThrow ("function f ({a : {}}) {}; f({});"); 58mustThrow ("function f ({}) {}; f();"); 59 60// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment 61 62// Basic assignment 63(function () { 64 var o = {p: 42, q: true}; 65 var {p, q} = o; 66 67 assert (p === 42); 68 assert (q === true); 69}) (); 70 71// Assignment without declaration 72(function () { 73 var a, b; 74 ({a, b} = {a: 1, b: 2}); 75 76 assert (a === 1); 77 assert (b === 2); 78}) (); 79 80// Assigning to new variable names 81(function () { 82 var o = {p: 42, q: true}; 83 var {p: foo, q: bar} = o; 84 85 assert (foo === 42); 86 assert (bar === true); 87}) (); 88 89// Default values 90(function () { 91 var {a = 10, b = 5} = {a: 3}; 92 93 assert (a === 3); 94 assert (b === 5); 95}) (); 96 97 98// Assigning to new variables names and providing default values 99(function () { 100 var {a: aa = 10, b: bb = 5} = {a: 3}; 101 102 assert (aa === 3); 103 assert (bb === 5); 104}) (); 105 106// Nested object and array destructuring 107(function () { 108 const metadata = { 109 title: 'Scratchpad', 110 translations: [ 111 { 112 locale: 'de', 113 localization_tags: [], 114 last_edit: '2014-04-14T08:43:37', 115 url: '/de/docs/Tools/Scratchpad', 116 title: 'JavaScript-Umgebung' 117 } 118 ], 119 url: '/en-US/docs/Tools/Scratchpad' 120 }; 121 122 let { 123 title: englishTitle, // rename 124 translations: [ 125 { 126 title: localeTitle, // rename 127 }, 128 ], 129 } = metadata; 130 131 assert (englishTitle === "Scratchpad"); 132 assert (localeTitle === "JavaScript-Umgebung"); 133}) (); 134 135// Computed object property names and destructuring 136(function () { 137 let key = 'z'; 138 let {[key]: foo} = {z: 'bar'}; 139 140 assert (foo === "bar"); 141}) (); 142 143// Invalid JavaScript identifier as a property name 144(function () { 145 const foo = { 'fizz-buzz': true }; 146 const { 'fizz-buzz': fizzBuzz } = foo; 147 148 assert (fizzBuzz === true); 149}) (); 150 151// Combined Array and Object Destructuring 152(function () { 153 const props = [ 154 { id: 1, name: 'Fizz'}, 155 { id: 2, name: 'Buzz'}, 156 { id: 3, name: 'FizzBuzz'} 157 ]; 158 159 const [,, { name }] = props; 160 161 assert (name === "FizzBuzz"); 162}) (); 163 164// The prototype chain is looked up when the object is deconstructed 165(function () { 166 var obj = {self: '123'}; 167 Object.getPrototypeOf(obj).prot = '456'; 168 const {self, prot} = obj; 169 assert (self === '123'); 170 assert (prot === '456'); 171}) (); 172 173// Test inner patterns I. 174(function () { 175 var a,b,c,d,e; 176 var o = { a : { b: 2 }, c: 1, d: { e: undefined } }; 177 var { e: { b : a } = { b : 2, a : 1}, d: { e: { b : e = 2} = { b } } } = o; 178 assert (a === 2); 179 assert (b === undefined); 180 assert (c === undefined); 181 assert (d === undefined); 182 assert (e === 2); 183}) (); 184 185// Test inner patterns II. 186(function () { 187 var a,b,c,d,e; 188 var o = { a : [{ b : 2 ,}, d], e : 5 }; 189 190 var { a: [{b, c = 3}, d = 4], e } = o; 191 assert (a === undefined); 192 assert (b === 2); 193 assert (c === 3); 194 assert (d === 4); 195 assert (e === 5); 196}) (); 197 198// Multiple declaration 199(function () { 200 var {a} = {a : 1}, {b} = {b : 2}; 201 202 assert (a === 1); 203 assert (b === 2); 204}) (); 205 206// Force the creation of lexical environment I. 207(function () { 208 const {a} = {a : 1}; 209 eval(); 210 211 assert (a === 1); 212}) (); 213 214// Force the creation of lexical environment II. 215(function () { 216 let {a} = {a : 1}; 217 eval(); 218 219 assert (a === 1); 220}) (); 221 222// Check the parsing of AssignmentElement 223(function () { 224 var a = 6; 225 ({"a": ((a)) } = {a : 7}); 226 assert (a === 7); 227}) (); 228 229try { 230 eval ("var a = 0; -{a} = {a:1}"); 231 assert (false); 232} catch (e) { 233 assert (e instanceof ReferenceError); 234} 235