// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test generator states.
function Foo() {}
function Bar() {}
function assertIteratorResult(value, done, result) {
assertEquals({ value: value, done: done}, result);
}
function assertIteratorIsClosed(iter) {
assertIteratorResult(undefined, true, iter.next());
// Next and throw on a closed iterator.
assertDoesNotThrow(function() { iter.next(); });
assertThrows(function() { iter.throw(new Bar); }, Bar);
}
var iter;
function* nextGenerator() { yield iter.next(); }
function* throwGenerator() { yield iter.throw(new Bar); }
// Throw on a suspendedStart iterator.
iter = nextGenerator();
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertIteratorIsClosed(iter);
// The same.
iter = throwGenerator();
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertIteratorIsClosed(iter);
// Next on an executing iterator raises a TypeError.
iter = nextGenerator();
assertThrows(function() { iter.next() }, TypeError)
assertIteratorIsClosed(iter);
// Throw on an executing iterator raises a TypeError.
iter = throwGenerator();
assertThrows(function() { iter.next() }, TypeError)
assertIteratorIsClosed(iter);
// Next on an executing iterator doesn't change the state of the
// generator.
iter = (function* () {
try {
iter.next();
yield 1;
} catch (e) {
try {
// This next() should raise the same exception, because the first
// next() left the iter in the executing state.
iter.next();
yield 2;
} catch (e) {
yield 3;
}
}
yield 4;
})();
assertIteratorResult(3, false, iter.next());
assertIteratorResult(4, false, iter.next());
assertIteratorIsClosed(iter);