1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --allow-natives-syntax
6
7(function TestBasics() {
8  var a = [1, 2];
9  var b = [...a];
10  assertArrayEquals([1, 2], b)
11
12  assertArrayEquals(['a', 'b', 'c', 'd', 'e', 'f'],
13                    ['a', ...'bc', 'd', ...'ef'])
14})();
15
16
17var log = [];
18
19function* gen(n) {
20  log.push(n, 1);
21  yield 1;
22  log.push(n, 2);
23  yield 2;
24  log.push(n, 3);
25  yield 3;
26  log.push(n, 'done');
27}
28
29function id(v) {
30  log.push(v);
31  return v;
32}
33
34
35(function TestGenerator() {
36  assertArrayEquals([1, 2, 3], [...gen('a')]);
37  assertArrayEquals(['x', 1, 2, 3, 'y', 1, 2, 3, 'z'],
38                    ['x', ...gen('a'), 'y', ...gen('b'), 'z']);
39})();
40
41
42(function TestOrderOfExecution() {
43  log = [];
44  assertArrayEquals(['x', 1, 2, 3, 'y', 1, 2, 3, 'z'],
45                    [id('x'), ...gen('a'), id('y'), ...gen('b'), id('z')]);
46  assertArrayEquals([
47    'x', 'a', 1, 'a', 2, 'a', 3, 'a', 'done',
48    'y', 'b', 1, 'b', 2, 'b', 3, 'b', 'done',
49    'z'
50  ], log);
51})();
52
53
54(function TestNotIterable() {
55  var a;
56  assertThrows(function() {
57    a = [...42];
58  }, TypeError);
59  assertSame(undefined, a);
60
61
62})();
63
64
65(function TestInvalidIterator() {
66  var iter = {
67    [Symbol.iterator]: 42
68  };
69  var a;
70  assertThrows(function() {
71    a = [...iter];
72  }, TypeError);
73  assertSame(undefined, a);
74})();
75
76
77(function TestIteratorNotAnObject() {
78  var iter = {
79    [Symbol.iterator]() {
80      return 42;
81    }
82  };
83  var a;
84  assertThrows(function() {
85    a = [...iter];
86  }, TypeError);
87  assertSame(undefined, a);
88})();
89
90
91(function TestIteratorNoNext() {
92  var iter = {
93    [Symbol.iterator]() {
94      return {};
95    }
96  };
97  var a;
98  assertThrows(function() {
99    a = [...iter];
100  }, TypeError);
101  assertSame(undefined, a);
102})();
103
104
105(function TestIteratorResultDoneThrows() {
106  function MyError() {}
107  var iter = {
108    [Symbol.iterator]() {
109      return {
110        next() {
111          return {
112            get done() {
113              throw new MyError();
114            }
115          }
116        }
117      };
118    }
119  };
120  var a;
121  assertThrows(function() {
122    a = [...iter];
123  }, MyError);
124  assertSame(undefined, a);
125})();
126
127
128(function TestIteratorResultValueThrows() {
129  function MyError() {}
130  var iter = {
131    [Symbol.iterator]() {
132      return {
133        next() {
134          return {
135            done: false,
136            get value() {
137              throw new MyError();
138            }
139          }
140        }
141      };
142    }
143  };
144  var a;
145  assertThrows(function() {
146    a = [...iter];
147  }, MyError);
148  assertSame(undefined, a);
149})();
150
151
152(function TestOptimize() {
153  function f() {
154    return [...'abc'];
155  }
156  assertArrayEquals(['a', 'b', 'c'], f());
157  %OptimizeFunctionOnNextCall(f);
158  assertArrayEquals(['a', 'b', 'c'], f());
159})();
160
161
162(function TestDeoptimize() {
163  var iter = {
164    [Symbol.iterator]() {
165      var i = 0;
166      return {
167        next() {
168          $DeoptimizeFunction(f);
169          return {value: ++i, done: i === 3};
170        }
171      };
172    }
173  };
174  function f() {
175    return [0, ...iter];
176  }
177
178  assertArrayEquals([0, 1, 2], f());
179});
180