diff options
Diffstat (limited to 'js/src/tests/non262/generators/delegating-yield-2.js')
-rw-r--r-- | js/src/tests/non262/generators/delegating-yield-2.js | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/js/src/tests/non262/generators/delegating-yield-2.js b/js/src/tests/non262/generators/delegating-yield-2.js new file mode 100644 index 0000000000..34cb3f4a9f --- /dev/null +++ b/js/src/tests/non262/generators/delegating-yield-2.js @@ -0,0 +1,73 @@ +// Test yield* with iter.throw and monkeypatching. + +function* g1() { return (yield 1); } +function* g2() { try { yield 1; } catch (e) { yield e; } } +function* delegate(iter) { return yield* iter; } +var GeneratorObjectPrototype = Object.getPrototypeOf(g1).prototype; +var GeneratorObjectPrototype_throw = GeneratorObjectPrototype.throw; + +// An uncaught delegated throw. +var inner = g1(); +var outer = delegate(inner); +assertIteratorNext(outer, 1); +assertThrowsValue(function () { outer.throw(42) }, 42); +assertThrowsValue(function () { outer.throw(42) }, 42); + +// A caught delegated throw. +inner = g2(); +outer = delegate(inner); +assertIteratorNext(outer, 1); +assertIteratorResult(outer.throw(42), 42, false); +assertThrowsValue(function () { outer.throw(42) }, 42); +assertThrowsValue(function () { outer.throw(42) }, 42); + +// What would be an uncaught delegated throw, but with a monkeypatched iterator. +inner = g1(); +outer = delegate(inner); +assertIteratorNext(outer, 1); +inner.throw = function(e) { return { value: e*2 }; }; +assertEq(84, outer.throw(42).value); +assertIteratorDone(outer, undefined); + +// Monkeypatching inner.next. +inner = g1(); +outer = delegate(inner); +inner.next = function() { return { value: 13, done: true } }; +assertIteratorDone(outer, 13); + +// What would be a caught delegated throw, but with a monkeypunched prototype. +inner = g2(); +outer = delegate(inner); +assertIteratorNext(outer, 1); +delete GeneratorObjectPrototype.throw; +var outer_throw_42 = GeneratorObjectPrototype_throw.bind(outer, 42); +// yield* protocol violation: no 'throw' method +assertThrowsInstanceOf(outer_throw_42, TypeError); +// Now done, so just throws. +assertThrowsValue(outer_throw_42, 42); + +// Monkeypunch a different throw handler. +inner = g2(); +outer = delegate(inner); +outer_throw_42 = GeneratorObjectPrototype_throw.bind(outer, 42); +assertIteratorNext(outer, 1); +GeneratorObjectPrototype.throw = function(e) { return { value: e*2 }; } +assertEq(84, outer_throw_42().value); +assertEq(84, outer_throw_42().value); +// This continues indefinitely. +assertEq(84, outer_throw_42().value); +assertIteratorDone(outer, undefined); + +// The same, but restoring the original pre-monkey throw. +inner = g2(); +outer = delegate(inner); +outer_throw_42 = GeneratorObjectPrototype_throw.bind(outer, 42); +assertIteratorNext(outer, 1); +assertEq(84, outer_throw_42().value); +assertEq(84, outer_throw_42().value); +GeneratorObjectPrototype.throw = GeneratorObjectPrototype_throw; +assertIteratorResult(outer_throw_42(), 42, false); +assertIteratorDone(outer, undefined); + +if (typeof reportCompare == "function") + reportCompare(true, true); |