1 // 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 7 function Foo() {} 8 function Bar() {} 9 10 function assertIteratorResult(value, done, result) { 11 assertEquals({ value: value, done: done}, result); 12 } 13 14 function 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 21 var iter; 22 function* nextGenerator() { yield iter.next(); } 23 function* throwGenerator() { yield iter.throw(new Bar); } 24 25 // Throw on a suspendedStart iterator. 26 iter = nextGenerator(); 27 assertThrows(function() { iter.throw(new Foo) }, Foo) 28 assertThrows(function() { iter.throw(new Foo) }, Foo) 29 assertIteratorIsClosed(iter); 30 31 // The same. 32 iter = throwGenerator(); 33 assertThrows(function() { iter.throw(new Foo) }, Foo) 34 assertThrows(function() { iter.throw(new Foo) }, Foo) 35 assertIteratorIsClosed(iter); 36 37 // Next on an executing iterator raises a TypeError. 38 iter = nextGenerator(); 39 assertThrows(function() { iter.next() }, TypeError) 40 assertIteratorIsClosed(iter); 41 42 // Throw on an executing iterator raises a TypeError. 43 iter = throwGenerator(); 44 assertThrows(function() { iter.next() }, TypeError) 45 assertIteratorIsClosed(iter); 46 47 // Next on an executing iterator doesn't change the state of the 48 // generator. 49 iter = (function* () { 50 try { 51 iter.next(); 52 yield 1; 53 } catch (e) { 54 try { 55 // This next() should raise the same exception, because the first 56 // next() left the iter in the executing state. 57 iter.next(); 58 yield 2; 59 } catch (e) { 60 yield 3; 61 } 62 } 63 yield 4; 64 })(); 65 assertIteratorResult(3, false, iter.next()); 66 assertIteratorResult(4, false, iter.next()); 67 assertIteratorIsClosed(iter); 68