OLD | NEW |
| (Empty) |
1 // Copyright 2013 the V8 project authors. All rights reserved. | |
2 // Redistribution and use in source and binary forms, with or without | |
3 // modification, are permitted provided that the following conditions are | |
4 // met: | |
5 // | |
6 // * Redistributions of source code must retain the above copyright | |
7 // notice, this list of conditions and the following disclaimer. | |
8 // * Redistributions in binary form must reproduce the above | |
9 // copyright notice, this list of conditions and the following | |
10 // disclaimer in the documentation and/or other materials provided | |
11 // with the distribution. | |
12 // * Neither the name of Google Inc. nor the names of its | |
13 // contributors may be used to endorse or promote products derived | |
14 // from this software without specific prior written permission. | |
15 // | |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | |
28 // Flags: --harmony-generators --expose-gc | |
29 | |
30 // Test generator iteration. | |
31 | |
32 var GeneratorFunction = (function*(){yield 1;}).__proto__.constructor; | |
33 | |
34 function assertIteratorResult(value, done, result) { | |
35 assertEquals({ value: value, done: done}, result); | |
36 } | |
37 | |
38 function assertIteratorIsClosed(iter) { | |
39 assertIteratorResult(undefined, true, iter.next()); | |
40 assertDoesNotThrow(function() { iter.next(); }); | |
41 } | |
42 | |
43 function assertThrownIteratorIsClosed(iter) { | |
44 // TODO(yusukesuzuki): Since status of a thrown generator is "executing", | |
45 // following tests are failed. | |
46 // https://code.google.com/p/v8/issues/detail?id=3096 | |
47 // assertIteratorIsClosed(iter); | |
48 } | |
49 | |
50 function TestGeneratorResultPrototype() { | |
51 function* g() { yield 1; } | |
52 var iter = g(); | |
53 var result = iter.next(); | |
54 | |
55 assertSame(Object.prototype, Object.getPrototypeOf(result)); | |
56 property_names = Object.getOwnPropertyNames(result); | |
57 property_names.sort(); | |
58 assertEquals(["done", "value"], property_names); | |
59 assertIteratorResult(1, false, result); | |
60 } | |
61 TestGeneratorResultPrototype() | |
62 | |
63 function TestGenerator(g, expected_values_for_next, | |
64 send_val, expected_values_for_send) { | |
65 function testNext(thunk) { | |
66 var iter = thunk(); | |
67 for (var i = 0; i < expected_values_for_next.length; i++) { | |
68 var v1 = expected_values_for_next[i]; | |
69 var v2 = i == expected_values_for_next.length - 1; | |
70 // var v3 = iter.next(); | |
71 assertIteratorResult(v1, v2, iter.next()); | |
72 } | |
73 assertIteratorIsClosed(iter); | |
74 } | |
75 function testSend(thunk) { | |
76 var iter = thunk(); | |
77 for (var i = 0; i < expected_values_for_send.length; i++) { | |
78 assertIteratorResult(expected_values_for_send[i], | |
79 i == expected_values_for_send.length - 1, | |
80 iter.next(send_val)); | |
81 } | |
82 assertIteratorIsClosed(iter); | |
83 } | |
84 function testThrow(thunk) { | |
85 for (var i = 0; i < expected_values_for_next.length; i++) { | |
86 var iter = thunk(); | |
87 for (var j = 0; j < i; j++) { | |
88 assertIteratorResult(expected_values_for_next[j], | |
89 j == expected_values_for_next.length - 1, | |
90 iter.next()); | |
91 } | |
92 function Sentinel() {} | |
93 assertThrows(function () { iter.throw(new Sentinel); }, Sentinel); | |
94 assertThrownIteratorIsClosed(iter); | |
95 } | |
96 } | |
97 | |
98 testNext(g); | |
99 testSend(g); | |
100 testThrow(g); | |
101 | |
102 testNext(function*() { return yield* g(); }); | |
103 testSend(function*() { return yield* g(); }); | |
104 testThrow(function*() { return yield* g(); }); | |
105 | |
106 if (g instanceof GeneratorFunction) { | |
107 testNext(function() { return new g(); }); | |
108 testSend(function() { return new g(); }); | |
109 testThrow(function() { return new g(); }); | |
110 } | |
111 } | |
112 | |
113 TestGenerator(function* g1() { }, | |
114 [undefined], | |
115 "foo", | |
116 [undefined]); | |
117 | |
118 TestGenerator(function* g2() { yield 1; }, | |
119 [1, undefined], | |
120 "foo", | |
121 [1, undefined]); | |
122 | |
123 TestGenerator(function* g3() { yield 1; yield 2; }, | |
124 [1, 2, undefined], | |
125 "foo", | |
126 [1, 2, undefined]); | |
127 | |
128 TestGenerator(function* g4() { yield 1; yield 2; return 3; }, | |
129 [1, 2, 3], | |
130 "foo", | |
131 [1, 2, 3]); | |
132 | |
133 TestGenerator(function* g5() { return 1; }, | |
134 [1], | |
135 "foo", | |
136 [1]); | |
137 | |
138 TestGenerator(function* g6() { var x = yield 1; return x; }, | |
139 [1, undefined], | |
140 "foo", | |
141 [1, "foo"]); | |
142 | |
143 TestGenerator(function* g7() { var x = yield 1; yield 2; return x; }, | |
144 [1, 2, undefined], | |
145 "foo", | |
146 [1, 2, "foo"]); | |
147 | |
148 TestGenerator(function* g8() { for (var x = 0; x < 4; x++) { yield x; } }, | |
149 [0, 1, 2, 3, undefined], | |
150 "foo", | |
151 [0, 1, 2, 3, undefined]); | |
152 | |
153 // Generator with arguments. | |
154 TestGenerator( | |
155 function g9() { | |
156 return (function*(a, b, c, d) { | |
157 yield a; yield b; yield c; yield d; | |
158 })("fee", "fi", "fo", "fum"); | |
159 }, | |
160 ["fee", "fi", "fo", "fum", undefined], | |
161 "foo", | |
162 ["fee", "fi", "fo", "fum", undefined]); | |
163 | |
164 // Too few arguments. | |
165 TestGenerator( | |
166 function g10() { | |
167 return (function*(a, b, c, d) { | |
168 yield a; yield b; yield c; yield d; | |
169 })("fee", "fi"); | |
170 }, | |
171 ["fee", "fi", undefined, undefined, undefined], | |
172 "foo", | |
173 ["fee", "fi", undefined, undefined, undefined]); | |
174 | |
175 // Too many arguments. | |
176 TestGenerator( | |
177 function g11() { | |
178 return (function*(a, b, c, d) { | |
179 yield a; yield b; yield c; yield d; | |
180 })("fee", "fi", "fo", "fum", "I smell the blood of an Englishman"); | |
181 }, | |
182 ["fee", "fi", "fo", "fum", undefined], | |
183 "foo", | |
184 ["fee", "fi", "fo", "fum", undefined]); | |
185 | |
186 // The arguments object. | |
187 TestGenerator( | |
188 function g12() { | |
189 return (function*(a, b, c, d) { | |
190 for (var i = 0; i < arguments.length; i++) { | |
191 yield arguments[i]; | |
192 } | |
193 })("fee", "fi", "fo", "fum", "I smell the blood of an Englishman"); | |
194 }, | |
195 ["fee", "fi", "fo", "fum", "I smell the blood of an Englishman", | |
196 undefined], | |
197 "foo", | |
198 ["fee", "fi", "fo", "fum", "I smell the blood of an Englishman", | |
199 undefined]); | |
200 | |
201 // Access to captured free variables. | |
202 TestGenerator( | |
203 function g13() { | |
204 return (function(a, b, c, d) { | |
205 return (function*() { | |
206 yield a; yield b; yield c; yield d; | |
207 })(); | |
208 })("fee", "fi", "fo", "fum"); | |
209 }, | |
210 ["fee", "fi", "fo", "fum", undefined], | |
211 "foo", | |
212 ["fee", "fi", "fo", "fum", undefined]); | |
213 | |
214 // Abusing the arguments object. | |
215 TestGenerator( | |
216 function g14() { | |
217 return (function*(a, b, c, d) { | |
218 arguments[0] = "Be he live"; | |
219 arguments[1] = "or be he dead"; | |
220 arguments[2] = "I'll grind his bones"; | |
221 arguments[3] = "to make my bread"; | |
222 yield a; yield b; yield c; yield d; | |
223 })("fee", "fi", "fo", "fum"); | |
224 }, | |
225 ["Be he live", "or be he dead", "I'll grind his bones", "to make my bread", | |
226 undefined], | |
227 "foo", | |
228 ["Be he live", "or be he dead", "I'll grind his bones", "to make my bread", | |
229 undefined]); | |
230 | |
231 // Abusing the arguments object: strict mode. | |
232 TestGenerator( | |
233 function g15() { | |
234 return (function*(a, b, c, d) { | |
235 "use strict"; | |
236 arguments[0] = "Be he live"; | |
237 arguments[1] = "or be he dead"; | |
238 arguments[2] = "I'll grind his bones"; | |
239 arguments[3] = "to make my bread"; | |
240 yield a; yield b; yield c; yield d; | |
241 })("fee", "fi", "fo", "fum"); | |
242 }, | |
243 ["fee", "fi", "fo", "fum", undefined], | |
244 "foo", | |
245 ["fee", "fi", "fo", "fum", undefined]); | |
246 | |
247 // GC. | |
248 TestGenerator(function* g16() { yield "baz"; gc(); yield "qux"; }, | |
249 ["baz", "qux", undefined], | |
250 "foo", | |
251 ["baz", "qux", undefined]); | |
252 | |
253 // Receivers. | |
254 TestGenerator( | |
255 function g17() { | |
256 function* g() { yield this.x; yield this.y; } | |
257 var o = { start: g, x: 1, y: 2 }; | |
258 return o.start(); | |
259 }, | |
260 [1, 2, undefined], | |
261 "foo", | |
262 [1, 2, undefined]); | |
263 | |
264 TestGenerator( | |
265 function g18() { | |
266 function* g() { yield this.x; yield this.y; } | |
267 var iter = new g; | |
268 iter.x = 1; | |
269 iter.y = 2; | |
270 return iter; | |
271 }, | |
272 [1, 2, undefined], | |
273 "foo", | |
274 [1, 2, undefined]); | |
275 | |
276 TestGenerator( | |
277 function* g19() { | |
278 var x = 1; | |
279 yield x; | |
280 with({x:2}) { yield x; } | |
281 yield x; | |
282 }, | |
283 [1, 2, 1, undefined], | |
284 "foo", | |
285 [1, 2, 1, undefined]); | |
286 | |
287 TestGenerator( | |
288 function* g20() { yield (1 + (yield 2) + 3); }, | |
289 [2, NaN, undefined], | |
290 "foo", | |
291 [2, "1foo3", undefined]); | |
292 | |
293 TestGenerator( | |
294 function* g21() { return (1 + (yield 2) + 3); }, | |
295 [2, NaN], | |
296 "foo", | |
297 [2, "1foo3"]); | |
298 | |
299 TestGenerator( | |
300 function* g22() { yield (1 + (yield 2) + 3); yield (4 + (yield 5) + 6); }, | |
301 [2, NaN, 5, NaN, undefined], | |
302 "foo", | |
303 [2, "1foo3", 5, "4foo6", undefined]); | |
304 | |
305 TestGenerator( | |
306 function* g23() { | |
307 return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6)); | |
308 }, | |
309 [2, NaN, 5, NaN, NaN], | |
310 "foo", | |
311 [2, "1foo3", 5, "4foo6", "foofoo"]); | |
312 | |
313 // Rewind a try context with and without operands on the stack. | |
314 TestGenerator( | |
315 function* g24() { | |
316 try { | |
317 return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6)); | |
318 } catch (e) { | |
319 throw e; | |
320 } | |
321 }, | |
322 [2, NaN, 5, NaN, NaN], | |
323 "foo", | |
324 [2, "1foo3", 5, "4foo6", "foofoo"]); | |
325 | |
326 // Yielding in a catch context, with and without operands on the stack. | |
327 TestGenerator( | |
328 function* g25() { | |
329 try { | |
330 throw (yield (1 + (yield 2) + 3)) | |
331 } catch (e) { | |
332 if (typeof e == 'object') throw e; | |
333 return e + (yield (4 + (yield 5) + 6)); | |
334 } | |
335 }, | |
336 [2, NaN, 5, NaN, NaN], | |
337 "foo", | |
338 [2, "1foo3", 5, "4foo6", "foofoo"]); | |
339 | |
340 // Yield with no arguments yields undefined. | |
341 TestGenerator( | |
342 function* g26() { return yield yield }, | |
343 [undefined, undefined, undefined], | |
344 "foo", | |
345 [undefined, "foo", "foo"]); | |
346 | |
347 // A newline causes the parser to stop looking for an argument to yield. | |
348 TestGenerator( | |
349 function* g27() { | |
350 yield | |
351 3 | |
352 return | |
353 }, | |
354 [undefined, undefined], | |
355 "foo", | |
356 [undefined, undefined]); | |
357 | |
358 // TODO(wingo): We should use TestGenerator for these, except that | |
359 // currently yield* will unconditionally propagate a throw() to the | |
360 // delegate iterator, which fails for these iterators that don't have | |
361 // throw(). See http://code.google.com/p/v8/issues/detail?id=3484. | |
362 (function() { | |
363 function* g28() { | |
364 yield* [1, 2, 3]; | |
365 } | |
366 var iter = g28(); | |
367 assertIteratorResult(1, false, iter.next()); | |
368 assertIteratorResult(2, false, iter.next()); | |
369 assertIteratorResult(3, false, iter.next()); | |
370 assertIteratorResult(undefined, true, iter.next()); | |
371 })(); | |
372 | |
373 (function() { | |
374 function* g29() { | |
375 yield* "abc"; | |
376 } | |
377 var iter = g29(); | |
378 assertIteratorResult("a", false, iter.next()); | |
379 assertIteratorResult("b", false, iter.next()); | |
380 assertIteratorResult("c", false, iter.next()); | |
381 assertIteratorResult(undefined, true, iter.next()); | |
382 })(); | |
383 | |
384 // Generator function instances. | |
385 TestGenerator(GeneratorFunction(), | |
386 [undefined], | |
387 "foo", | |
388 [undefined]); | |
389 | |
390 TestGenerator(new GeneratorFunction(), | |
391 [undefined], | |
392 "foo", | |
393 [undefined]); | |
394 | |
395 TestGenerator(GeneratorFunction('yield 1;'), | |
396 [1, undefined], | |
397 "foo", | |
398 [1, undefined]); | |
399 | |
400 TestGenerator( | |
401 function() { return GeneratorFunction('x', 'y', 'yield x + y;')(1, 2) }, | |
402 [3, undefined], | |
403 "foo", | |
404 [3, undefined]); | |
405 | |
406 // Access to this with formal arguments. | |
407 TestGenerator( | |
408 function () { | |
409 return ({ x: 42, g: function* (a) { yield this.x } }).g(0); | |
410 }, | |
411 [42, undefined], | |
412 "foo", | |
413 [42, undefined]); | |
414 | |
415 // Test that yield* re-yields received results without re-boxing. | |
416 function TestDelegatingYield() { | |
417 function results(results) { | |
418 var i = 0; | |
419 function next() { | |
420 return results[i++]; | |
421 } | |
422 var iter = { next: next }; | |
423 var ret = {}; | |
424 ret[Symbol.iterator] = function() { return iter; }; | |
425 return ret; | |
426 } | |
427 function* yield_results(expected) { | |
428 return yield* results(expected); | |
429 } | |
430 function collect_results(iterable) { | |
431 var iter = iterable[Symbol.iterator](); | |
432 var ret = []; | |
433 var result; | |
434 do { | |
435 result = iter.next(); | |
436 ret.push(result); | |
437 } while (!result.done); | |
438 return ret; | |
439 } | |
440 // We have to put a full result for the end, because the return will re-box. | |
441 var expected = [{value: 1}, 13, "foo", {value: 34, done: true}]; | |
442 | |
443 // Sanity check. | |
444 assertEquals(expected, collect_results(results(expected))); | |
445 assertEquals(expected, collect_results(yield_results(expected))); | |
446 } | |
447 TestDelegatingYield(); | |
448 | |
449 function TestTryCatch(instantiate) { | |
450 function* g() { yield 1; try { yield 2; } catch (e) { yield e; } yield 3; } | |
451 function Sentinel() {} | |
452 | |
453 function Test1(iter) { | |
454 assertIteratorResult(1, false, iter.next()); | |
455 assertIteratorResult(2, false, iter.next()); | |
456 assertIteratorResult(3, false, iter.next()); | |
457 assertIteratorIsClosed(iter); | |
458 } | |
459 Test1(instantiate(g)); | |
460 | |
461 function Test2(iter) { | |
462 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
463 assertThrownIteratorIsClosed(iter); | |
464 } | |
465 Test2(instantiate(g)); | |
466 | |
467 function Test3(iter) { | |
468 assertIteratorResult(1, false, iter.next()); | |
469 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
470 assertThrownIteratorIsClosed(iter); | |
471 } | |
472 Test3(instantiate(g)); | |
473 | |
474 function Test4(iter) { | |
475 assertIteratorResult(1, false, iter.next()); | |
476 assertIteratorResult(2, false, iter.next()); | |
477 var exn = new Sentinel; | |
478 assertIteratorResult(exn, false, iter.throw(exn)); | |
479 assertIteratorResult(3, false, iter.next()); | |
480 assertIteratorIsClosed(iter); | |
481 } | |
482 Test4(instantiate(g)); | |
483 | |
484 function Test5(iter) { | |
485 assertIteratorResult(1, false, iter.next()); | |
486 assertIteratorResult(2, false, iter.next()); | |
487 var exn = new Sentinel; | |
488 assertIteratorResult(exn, false, iter.throw(exn)); | |
489 assertIteratorResult(3, false, iter.next()); | |
490 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
491 assertThrownIteratorIsClosed(iter); | |
492 } | |
493 Test5(instantiate(g)); | |
494 | |
495 function Test6(iter) { | |
496 assertIteratorResult(1, false, iter.next()); | |
497 assertIteratorResult(2, false, iter.next()); | |
498 var exn = new Sentinel; | |
499 assertIteratorResult(exn, false, iter.throw(exn)); | |
500 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
501 assertThrownIteratorIsClosed(iter); | |
502 } | |
503 Test6(instantiate(g)); | |
504 | |
505 function Test7(iter) { | |
506 assertIteratorResult(1, false, iter.next()); | |
507 assertIteratorResult(2, false, iter.next()); | |
508 assertIteratorResult(3, false, iter.next()); | |
509 assertIteratorIsClosed(iter); | |
510 } | |
511 Test7(instantiate(g)); | |
512 } | |
513 TestTryCatch(function (g) { return g(); }); | |
514 TestTryCatch(function* (g) { return yield* g(); }); | |
515 | |
516 function TestTryFinally(instantiate) { | |
517 function* g() { yield 1; try { yield 2; } finally { yield 3; } yield 4; } | |
518 function Sentinel() {} | |
519 function Sentinel2() {} | |
520 | |
521 function Test1(iter) { | |
522 assertIteratorResult(1, false, iter.next()); | |
523 assertIteratorResult(2, false, iter.next()); | |
524 assertIteratorResult(3, false, iter.next()); | |
525 assertIteratorResult(4, false, iter.next()); | |
526 assertIteratorIsClosed(iter); | |
527 } | |
528 Test1(instantiate(g)); | |
529 | |
530 function Test2(iter) { | |
531 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
532 assertThrownIteratorIsClosed(iter); | |
533 } | |
534 Test2(instantiate(g)); | |
535 | |
536 function Test3(iter) { | |
537 assertIteratorResult(1, false, iter.next()); | |
538 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
539 assertThrownIteratorIsClosed(iter); | |
540 } | |
541 Test3(instantiate(g)); | |
542 | |
543 function Test4(iter) { | |
544 assertIteratorResult(1, false, iter.next()); | |
545 assertIteratorResult(2, false, iter.next()); | |
546 assertIteratorResult(3, false, iter.throw(new Sentinel)); | |
547 assertThrows(function() { iter.next(); }, Sentinel); | |
548 assertThrownIteratorIsClosed(iter); | |
549 } | |
550 Test4(instantiate(g)); | |
551 | |
552 function Test5(iter) { | |
553 assertIteratorResult(1, false, iter.next()); | |
554 assertIteratorResult(2, false, iter.next()); | |
555 assertIteratorResult(3, false, iter.throw(new Sentinel)); | |
556 assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2); | |
557 assertThrownIteratorIsClosed(iter); | |
558 } | |
559 Test5(instantiate(g)); | |
560 | |
561 function Test6(iter) { | |
562 assertIteratorResult(1, false, iter.next()); | |
563 assertIteratorResult(2, false, iter.next()); | |
564 assertIteratorResult(3, false, iter.next()); | |
565 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
566 assertThrownIteratorIsClosed(iter); | |
567 } | |
568 Test6(instantiate(g)); | |
569 | |
570 function Test7(iter) { | |
571 assertIteratorResult(1, false, iter.next()); | |
572 assertIteratorResult(2, false, iter.next()); | |
573 assertIteratorResult(3, false, iter.next()); | |
574 assertIteratorResult(4, false, iter.next()); | |
575 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
576 assertThrownIteratorIsClosed(iter); | |
577 } | |
578 Test7(instantiate(g)); | |
579 | |
580 function Test8(iter) { | |
581 assertIteratorResult(1, false, iter.next()); | |
582 assertIteratorResult(2, false, iter.next()); | |
583 assertIteratorResult(3, false, iter.next()); | |
584 assertIteratorResult(4, false, iter.next()); | |
585 assertIteratorIsClosed(iter); | |
586 } | |
587 Test8(instantiate(g)); | |
588 } | |
589 TestTryFinally(function (g) { return g(); }); | |
590 TestTryFinally(function* (g) { return yield* g(); }); | |
591 | |
592 function TestNestedTry(instantiate) { | |
593 function* g() { | |
594 try { | |
595 yield 1; | |
596 try { yield 2; } catch (e) { yield e; } | |
597 yield 3; | |
598 } finally { | |
599 yield 4; | |
600 } | |
601 yield 5; | |
602 } | |
603 function Sentinel() {} | |
604 function Sentinel2() {} | |
605 | |
606 function Test1(iter) { | |
607 assertIteratorResult(1, false, iter.next()); | |
608 assertIteratorResult(2, false, iter.next()); | |
609 assertIteratorResult(3, false, iter.next()); | |
610 assertIteratorResult(4, false, iter.next()); | |
611 assertIteratorResult(5, false, iter.next()); | |
612 assertIteratorIsClosed(iter); | |
613 } | |
614 Test1(instantiate(g)); | |
615 | |
616 function Test2(iter) { | |
617 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); | |
618 assertThrownIteratorIsClosed(iter); | |
619 } | |
620 Test2(instantiate(g)); | |
621 | |
622 function Test3(iter) { | |
623 assertIteratorResult(1, false, iter.next()); | |
624 assertIteratorResult(4, false, iter.throw(new Sentinel)); | |
625 assertThrows(function() { iter.next(); }, Sentinel); | |
626 assertThrownIteratorIsClosed(iter); | |
627 } | |
628 Test3(instantiate(g)); | |
629 | |
630 function Test4(iter) { | |
631 assertIteratorResult(1, false, iter.next()); | |
632 assertIteratorResult(4, false, iter.throw(new Sentinel)); | |
633 assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2); | |
634 assertThrownIteratorIsClosed(iter); | |
635 } | |
636 Test4(instantiate(g)); | |
637 | |
638 function Test5(iter) { | |
639 assertIteratorResult(1, false, iter.next()); | |
640 assertIteratorResult(2, false, iter.next()); | |
641 var exn = new Sentinel; | |
642 assertIteratorResult(exn, false, iter.throw(exn)); | |
643 assertIteratorResult(3, false, iter.next()); | |
644 assertIteratorResult(4, false, iter.next()); | |
645 assertIteratorResult(5, false, iter.next()); | |
646 assertIteratorIsClosed(iter); | |
647 } | |
648 Test5(instantiate(g)); | |
649 | |
650 function Test6(iter) { | |
651 assertIteratorResult(1, false, iter.next()); | |
652 assertIteratorResult(2, false, iter.next()); | |
653 var exn = new Sentinel; | |
654 assertIteratorResult(exn, false, iter.throw(exn)); | |
655 assertIteratorResult(4, false, iter.throw(new Sentinel2)); | |
656 assertThrows(function() { iter.next(); }, Sentinel2); | |
657 assertThrownIteratorIsClosed(iter); | |
658 } | |
659 Test6(instantiate(g)); | |
660 | |
661 function Test7(iter) { | |
662 assertIteratorResult(1, false, iter.next()); | |
663 assertIteratorResult(2, false, iter.next()); | |
664 var exn = new Sentinel; | |
665 assertIteratorResult(exn, false, iter.throw(exn)); | |
666 assertIteratorResult(3, false, iter.next()); | |
667 assertIteratorResult(4, false, iter.throw(new Sentinel2)); | |
668 assertThrows(function() { iter.next(); }, Sentinel2); | |
669 assertThrownIteratorIsClosed(iter); | |
670 } | |
671 Test7(instantiate(g)); | |
672 | |
673 // That's probably enough. | |
674 } | |
675 TestNestedTry(function (g) { return g(); }); | |
676 TestNestedTry(function* (g) { return yield* g(); }); | |
677 | |
678 function TestRecursion() { | |
679 function TestNextRecursion() { | |
680 function* g() { yield iter.next(); } | |
681 var iter = g(); | |
682 return iter.next(); | |
683 } | |
684 function TestSendRecursion() { | |
685 function* g() { yield iter.next(42); } | |
686 var iter = g(); | |
687 return iter.next(); | |
688 } | |
689 function TestThrowRecursion() { | |
690 function* g() { yield iter.throw(1); } | |
691 var iter = g(); | |
692 return iter.next(); | |
693 } | |
694 assertThrows(TestNextRecursion, Error); | |
695 assertThrows(TestSendRecursion, Error); | |
696 assertThrows(TestThrowRecursion, Error); | |
697 } | |
698 TestRecursion(); | |
OLD | NEW |