rest-elements.js   [plain text]


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 testSyntaxError(script, message) {
    var error = null;
    try {
        eval(script);
    } catch (e) {
        error = e;
    }
    if (!error)
        throw new Error("Expected syntax error not thrown");

    if (String(error) !== message)
        throw new Error("Bad error: " + String(error));
}

(function () {
    var [a, b, ...c] = "Cocoa";
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(JSON.stringify(c), String.raw`["c","o","a"]`);
}());

(function () {
    var [a, b, ...c] = "Co";
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(JSON.stringify(c), String.raw`[]`);
}());

(function () {
    var [a, b, ...c] = "C";
    shouldBe(a, 'C');
    shouldBe(b, undefined);
    shouldBe(JSON.stringify(c), String.raw`[]`);
}());

(function () {
    var a, b, c;
    [a, b, ...c] = "Cocoa";
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(JSON.stringify(c), String.raw`["c","o","a"]`);
}());

(function () {
    var a, b, c;
    [a, b, ...c] = "Co";
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(JSON.stringify(c), String.raw`[]`);
}());

(function () {
    var a, b, c;
    [a, b, ...c] = "C";
    shouldBe(a, 'C');
    shouldBe(b, undefined);
    shouldBe(JSON.stringify(c), String.raw`[]`);
}());

(function ([a, b, ...c]) {
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(JSON.stringify(c), String.raw`["c","o","a"]`);
}("Cocoa"));

(function ([a, b, ...c]) {
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(JSON.stringify(c), String.raw`[]`);
}("Co"));

(function ([a, b, ...c]) {
    shouldBe(a, 'C');
    shouldBe(b, undefined);
    shouldBe(JSON.stringify(c), String.raw`[]`);
}("C"));

testSyntaxError(String.raw`var [a, ...b, c] = 20`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
testSyntaxError(String.raw`var [a, ...b,] = 20`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
testSyntaxError(String.raw`var [a, ...b,,] = 20`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
testSyntaxError(String.raw`var [a, ...b = 20] = 20`, String.raw`SyntaxError: Unexpected token '='. Expected a closing ']' following a rest element destructuring pattern.`);
testSyntaxError(String.raw`var [a, ...[b, c]] = 20`, String.raw`SyntaxError: Unexpected token ']'. Expected identifier for a rest element destructuring pattern.`);
testSyntaxError(String.raw`var [a, ...{ b, c }] = 20`, String.raw`SyntaxError: Unexpected token ']'. Expected identifier for a rest element destructuring pattern.`);

testSyntaxError(String.raw`(function ([a, ...b, c]) { })`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
testSyntaxError(String.raw`(function ([a, ...b,]) { })`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
testSyntaxError(String.raw`(function ([a, ...b,,]) { })`, String.raw`SyntaxError: Unexpected token ','. Expected a closing ']' following a rest element destructuring pattern.`);
testSyntaxError(String.raw`(function ([a, ...b = 20,,]) { })`, String.raw`SyntaxError: Unexpected token '='. Expected a closing ']' following a rest element destructuring pattern.`);
testSyntaxError(String.raw`(function ([a, ...[b, c]]) { })`, String.raw`SyntaxError: Unexpected token ']'. Expected identifier for a rest element destructuring pattern.`);
testSyntaxError(String.raw`(function ([a, ...{ b, c }]) { })`, String.raw`SyntaxError: Unexpected token ']'. Expected identifier for a rest element destructuring pattern.`);

shouldThrow(function () {
    [a, ...b, c] = 20;
}, "ReferenceError: Left side of assignment is not a reference.");

shouldThrow(function () {
    [a, ...b,] = 20
}, "ReferenceError: Left side of assignment is not a reference.");

shouldThrow(function () {
    [a, ...b,,] = 20
}, "ReferenceError: Left side of assignment is not a reference.");

shouldThrow(function () {
    [a, ...b = 20] = 20
}, "ReferenceError: Left side of assignment is not a reference.");

(function () {
    var a, b, c;
    [a, b, ...[...c]] = "Cocoa";
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(JSON.stringify(c), String.raw`["c","o","a"]`);
}());

(function () {
    var a, b, c, d, e, f;
    [a, b, ...{ 0: c, 1: d, 2: e, 3: f }] = "Cocoa";
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(c, 'c');
    shouldBe(d, 'o');
    shouldBe(f, undefined);
}());

(function () {
    var a, b, c, d, e;
    [a, b, ...[c, d, ...e]] = "Cocoa";
    shouldBe(a, 'C');
    shouldBe(b, 'o');
    shouldBe(c, 'c');
    shouldBe(d, 'o');
    shouldBe(JSON.stringify(e), String.raw`["a"]`);
}());

function iterator(array) {
    var nextCount = 0;
    var returnCount = 0;
    var original =  array.values();
    return {
        [Symbol.iterator]() {
            return this;
        },

        next() {
            ++nextCount;
            return original.next();
        },

        return() {
            ++returnCount;
            return { done: true };
        },

        reportNext() {
            return nextCount;
        },

        reportReturn() {
            return returnCount;
        }
    };
};

(function () {
    var iter = iterator([1, 2, 3]);
    var [...a] = iter;
    shouldBe(iter.reportNext(), 4);
    shouldBe(iter.reportReturn(), 0);
    shouldBe(JSON.stringify(a), String.raw`[1,2,3]`);
}());

(function () {
    var iter = iterator([1, 2, 3]);
    var [a, b, ...c] = iter;
    shouldBe(iter.reportNext(), 4);
    shouldBe(iter.reportReturn(), 0);
    shouldBe(a, 1);
    shouldBe(b, 2);
    shouldBe(JSON.stringify(c), String.raw`[3]`);
}());

(function () {
    var iter = iterator([1, 2, 3]);
    var [a, b, c, d, ...e] = iter;
    shouldBe(iter.reportNext(), 4);
    shouldBe(iter.reportReturn(), 0);
    shouldBe(a, 1);
    shouldBe(b, 2);
    shouldBe(c, 3);
    shouldBe(d, undefined);
    shouldBe(JSON.stringify(e), String.raw`[]`);
}());

(function () {
    var iter = iterator([1, 2, 3]);
    var a, b;
    [...[a, b]] = iter;
    shouldBe(iter.reportNext(), 4);
    shouldBe(iter.reportReturn(), 0);
    shouldBe(a, 1);
    shouldBe(b, 2);
}());