summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/destructuring/array-iterator-close.js
blob: ed35135dba1ec1feee12bc6de02e44f41e205da2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Tests that IteratorClose is called in array destructuring patterns.

function test() {
    var returnCalled = 0;
    var returnCalledExpected = 0;
    var iterable = {};

    // empty [] calls IteratorClose regardless of "done" on the result.
    iterable[Symbol.iterator] = makeIterator({
        next: function() {
            return { done: true };
        },
        ret: function() {
            returnCalled++;
            return {};
        }
    });
    var [] = iterable;
    assertEq(returnCalled, ++returnCalledExpected);

    iterable[Symbol.iterator] = makeIterator({
        ret: function() {
            returnCalled++;
            return {};
        }
    });
    var [] = iterable;
    assertEq(returnCalled, ++returnCalledExpected);

    // Non-empty destructuring calls IteratorClose if iterator is not done by
    // the end of destructuring.
    var [a,b] = iterable;
    assertEq(returnCalled, ++returnCalledExpected);
    var [c,] = iterable;
    assertEq(returnCalled, ++returnCalledExpected);

    // throw in lhs ref calls IteratorClose
    function throwlhs() {
        throw "in lhs";
    }
    assertThrowsValue(function() {
        0, [...{}[throwlhs()]] = iterable;
    }, "in lhs");
    assertEq(returnCalled, ++returnCalledExpected);

    // throw in lhs ref calls IteratorClose with falsy "done".
    iterable[Symbol.iterator] = makeIterator({
        next: function() {
            // "done" is undefined.
            return {};
        },
        ret: function() {
            returnCalled++;
            return {};
        }
    });
    assertThrowsValue(function() {
        0, [...{}[throwlhs()]] = iterable;
    }, "in lhs");
    assertEq(returnCalled, ++returnCalledExpected);

    // throw in iter.next doesn't call IteratorClose
    iterable[Symbol.iterator] = makeIterator({
        next: function() {
            throw "in next";
        },
        ret: function() {
            returnCalled++;
            return {};
        }
    });
    assertThrowsValue(function() {
        var [d] = iterable;
    }, "in next");
    assertEq(returnCalled, returnCalledExpected);

    // "return" must return an Object.
    iterable[Symbol.iterator] = makeIterator({
        ret: function() {
            returnCalled++;
            return 42;
        }
    });
    assertThrowsInstanceOf(function() {
        var [] = iterable;
    }, TypeError);
    assertEq(returnCalled, ++returnCalledExpected);
}

test();

if (typeof reportCompare === "function")
    reportCompare(0, 0);