blob: 4e8c58029a3a06218f84acb182c7fbf77d7e8547 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// Copyright 2014 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// Test generator states.
6
7function Foo() {}
8function Bar() {}
9
10function assertIteratorResult(value, done, result) {
11 assertEquals({ value: value, done: done}, result);
12}
13
14function assertIteratorIsClosed(iter) {
15 assertIteratorResult(undefined, true, iter.next());
16 // Next and throw on a closed iterator.
17 assertDoesNotThrow(function() { iter.next(); });
18 assertThrows(function() { iter.throw(new Bar); }, Bar);
19}
20
21var iter;
22function* nextGenerator() { yield iter.next(); }
23function* throwGenerator() { yield iter.throw(new Bar); }
24
25// Throw on a suspendedStart iterator.
26iter = nextGenerator();
27assertThrows(function() { iter.throw(new Foo) }, Foo)
Ben Murdoch097c5b22016-05-18 11:27:45 +010028assertIteratorIsClosed(iter);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040029assertThrows(function() { iter.throw(new Foo) }, Foo)
30assertIteratorIsClosed(iter);
31
32// The same.
33iter = throwGenerator();
34assertThrows(function() { iter.throw(new Foo) }, Foo)
35assertThrows(function() { iter.throw(new Foo) }, Foo)
36assertIteratorIsClosed(iter);
37
38// Next on an executing iterator raises a TypeError.
39iter = nextGenerator();
40assertThrows(function() { iter.next() }, TypeError)
41assertIteratorIsClosed(iter);
42
43// Throw on an executing iterator raises a TypeError.
44iter = throwGenerator();
45assertThrows(function() { iter.next() }, TypeError)
46assertIteratorIsClosed(iter);
47
48// Next on an executing iterator doesn't change the state of the
49// generator.
50iter = (function* () {
51 try {
52 iter.next();
53 yield 1;
54 } catch (e) {
55 try {
56 // This next() should raise the same exception, because the first
57 // next() left the iter in the executing state.
58 iter.next();
59 yield 2;
60 } catch (e) {
61 yield 3;
62 }
63 }
64 yield 4;
65})();
66assertIteratorResult(3, false, iter.next());
67assertIteratorResult(4, false, iter.next());
68assertIteratorIsClosed(iter);
Ben Murdoch097c5b22016-05-18 11:27:45 +010069
70
71// A return that doesn't close.
72{
73 let g = function*() { try {return 42} finally {yield 43} };
74
75 let x = g();
76 assertEquals({value: 43, done: false}, x.next());
77 assertEquals({value: 42, done: true}, x.next());
78}
79{
80 let x;
81 let g = function*() { try {return 42} finally {x.throw(666)} };
82
83 x = g();
84 assertThrows(() => x.next(), TypeError); // Still executing.
85}
86{
87 let x;
88 let g = function*() {
89 try {return 42} finally {try {x.throw(666)} catch(e) {}}
90 };
91
92 x = g();
93 assertEquals({value: 42, done: true}, x.next());
94}