| function shouldBe(actual, expected) { |
| if (actual !== expected) |
| throw new Error('bad value: ' + actual); |
| } |
| |
| function shouldThrow(func, errorMessage) { |
| var errorThrown = false; |
| var error = null; |
| try { |
| func(); |
| } catch (e) { |
| errorThrown = true; |
| error = e; |
| } |
| if (!errorThrown) |
| throw new Error('not thrown'); |
| if (String(error) !== errorMessage) |
| throw new Error(`bad error: ${String(error)}`); |
| } |
| |
| (function () { |
| var [a, b, c] = [1, 2, 3]; |
| shouldBe(a, 1); |
| shouldBe(b, 2); |
| shouldBe(c, 3); |
| }()); |
| |
| (function () { |
| var [a, b, c] = [1, 2, 3].keys(); |
| shouldBe(a, 0); |
| shouldBe(b, 1); |
| shouldBe(c, 2); |
| }()); |
| |
| (function () { |
| var [a, b, c] = [1, 2, 3].values(); |
| shouldBe(a, 1); |
| shouldBe(b, 2); |
| shouldBe(c, 3); |
| }()); |
| |
| (function () { |
| var [a, , c] = [1, 2, 3].values(); |
| shouldBe(a, 1); |
| shouldBe(c, 3); |
| }()); |
| |
| (function () { |
| var [a, b, c] = [1, , 3].values(); |
| shouldBe(a, 1); |
| shouldBe(b, undefined); |
| shouldBe(c, 3); |
| }()); |
| |
| (function () { |
| var [, b, c] = [1, 2, 3, 4, 5, 6].values(); |
| shouldBe(b, 2); |
| shouldBe(c, 3); |
| }()); |
| |
| (function () { |
| var [a, b, c] = [1].values(); |
| shouldBe(a, 1); |
| shouldBe(b, undefined); |
| shouldBe(c, undefined); |
| }()); |
| |
| (function ([a, b, c]) { |
| shouldBe(a, 1); |
| shouldBe(b, undefined); |
| shouldBe(c, undefined); |
| }([1].values())); |
| |
| (function () { |
| var [a = 0, b = 2, c = 3] = [1].values(); |
| shouldBe(a, 1); |
| shouldBe(b, 2); |
| shouldBe(c, 3); |
| }()); |
| |
| (function () { |
| var [a = 1, b = 2, c = 3] = [undefined, undefined, undefined]; |
| shouldBe(a, 1); |
| shouldBe(b, 2); |
| shouldBe(c, 3); |
| }()); |
| |
| // String with a surrogate pair. |
| (function () { |
| var string = "𠮷野家"; |
| var [a, b, c] = string; |
| shouldBe(string.length, 4); |
| shouldBe(a, '𠮷'); |
| shouldBe(b, '野'); |
| shouldBe(c, '家'); |
| }()); |
| |
| (function () { |
| var set = new Set([1, 2, 3]); |
| var [a, b, c] = set; |
| shouldBe(set.has(a), true); |
| shouldBe(set.has(b), true); |
| shouldBe(set.has(c), true); |
| }()); |
| |
| (function () { |
| var map = new Map([[1, 1], [2, 2], [3, 3]]); |
| var [a, b, c] = map; |
| shouldBe(Array.isArray(a), true); |
| shouldBe(Array.isArray(b), true); |
| shouldBe(Array.isArray(c), true); |
| shouldBe(map.has(a[0]), true); |
| shouldBe(map.has(b[0]), true); |
| shouldBe(map.has(c[0]), true); |
| }()); |
| |
| // Errors |
| |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return 42; |
| } |
| }; |
| }, "TypeError: undefined is not a function (near '...[a, b, c]...')"); |
| |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return {}; |
| } |
| }; |
| }, "TypeError: undefined is not a function (near '...[a, b, c]...')"); |
| |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| next() { |
| throw new Error('out'); |
| } |
| }; |
| }, 'Error: out'); |
| |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| next() { |
| return 42; |
| } |
| }; |
| }, 'TypeError: Iterator result interface is not an object.'); |
| |
| (function () { |
| var ok = 0; |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| return() { |
| ok++; |
| }, |
| |
| next() { |
| return 42; |
| } |
| }; |
| }, 'TypeError: Iterator result interface is not an object.'); |
| |
| shouldBe(ok, 0); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| return() { |
| ok++; |
| }, |
| |
| next() { |
| return { value: 20, done: false }; |
| } |
| }; |
| }, 'TypeError: Iterator result interface is not an object.'); |
| |
| shouldBe(ok, 1); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| return() { |
| ok++; |
| }, |
| |
| next() { |
| return { value: 20, done: true }; |
| } |
| }; |
| |
| shouldBe(a, undefined); |
| shouldBe(b, undefined); |
| shouldBe(c, undefined); |
| shouldBe(ok, 0); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| var n = 0; |
| |
| var done = false; |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| return() { |
| ok++; |
| }, |
| |
| next() { |
| var prev = done; |
| done = true; |
| ++n; |
| return { value: 20, done: prev }; |
| } |
| }; |
| |
| shouldBe(a, 20); |
| shouldBe(b, undefined); |
| shouldBe(c, undefined); |
| shouldBe(n, 2); |
| shouldBe(ok, 0); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| var n = 0; |
| |
| var done = false; |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| return() { |
| ++ok; |
| return { done: true }; |
| }, |
| |
| next() { |
| ++n; |
| return { value: 20, done: false }; |
| } |
| }; |
| |
| shouldBe(a, 20); |
| shouldBe(b, 20); |
| shouldBe(c, 20); |
| shouldBe(n, 3); |
| shouldBe(ok, 1); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| var n = 0; |
| |
| var done = false; |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| return() { |
| ++ok; |
| return { done: true }; |
| }, |
| |
| count: 0, |
| |
| next() { |
| ++n; |
| var done = ++this.count === 3; |
| return { value: 20, done }; |
| } |
| }; |
| |
| shouldBe(a, 20); |
| shouldBe(b, 20); |
| shouldBe(c, undefined); |
| shouldBe(n, 3); |
| shouldBe(ok, 0); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| var n = 0; |
| |
| var done = false; |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| return() { |
| ++ok; |
| return { done: true }; |
| }, |
| |
| count: 0, |
| |
| next() { |
| ++n; |
| var done = ++this.count === 4; |
| return { value: 20, done }; |
| } |
| }; |
| |
| shouldBe(a, 20); |
| shouldBe(b, 20); |
| shouldBe(c, 20); |
| shouldBe(n, 3); |
| shouldBe(ok, 1); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| var n = 0; |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| return() { |
| ok++; |
| throw new Error('out'); |
| }, |
| |
| next() { |
| n++; |
| return { value: 20, done: false }; |
| } |
| }; |
| }, 'Error: out'); |
| |
| shouldBe(n, 3); |
| shouldBe(ok, 1); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| var n = 0; |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| get return() { |
| ok++; |
| throw new Error('out'); |
| }, |
| |
| next() { |
| n++; |
| return { value: 20, done: false }; |
| } |
| }; |
| }, 'Error: out'); |
| |
| shouldBe(n, 3); |
| shouldBe(ok, 1); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| var n = 0; |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| get return() { |
| ok++; |
| throw new Error('ng'); |
| }, |
| |
| next() { |
| n++; |
| throw new Error('out'); |
| } |
| }; |
| }, 'Error: out'); |
| |
| shouldBe(n, 1); |
| shouldBe(ok, 0); |
| }()); |
| |
| (function () { |
| var ok = 0; |
| var n = 0; |
| shouldThrow(function () { |
| var [a, b, c] = { |
| [Symbol.iterator]() { |
| return this; |
| }, |
| |
| get return() { |
| ok++; |
| throw new Error('ng'); |
| }, |
| |
| get next() { |
| ++n; |
| throw new Error('out'); |
| } |
| }; |
| }, 'Error: out'); |
| |
| shouldBe(n, 1); |
| shouldBe(ok, 0); |
| }()); |