summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/Generators/delegating-yield-2.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_6/Generators/delegating-yield-2.js')
-rw-r--r--js/src/tests/ecma_6/Generators/delegating-yield-2.js71
1 files changed, 71 insertions, 0 deletions
diff --git a/js/src/tests/ecma_6/Generators/delegating-yield-2.js b/js/src/tests/ecma_6/Generators/delegating-yield-2.js
new file mode 100644
index 000000000..918fb33e1
--- /dev/null
+++ b/js/src/tests/ecma_6/Generators/delegating-yield-2.js
@@ -0,0 +1,71 @@
+// 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 e*2; };
+assertEq(84, outer.throw(42));
+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);
+assertThrowsValue(outer_throw_42, 42);
+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 e*2; }
+assertEq(84, outer_throw_42());
+assertEq(84, outer_throw_42());
+// This continues indefinitely.
+assertEq(84, outer_throw_42());
+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());
+assertEq(84, outer_throw_42());
+GeneratorObjectPrototype.throw = GeneratorObjectPrototype_throw;
+assertIteratorResult(outer_throw_42(), 42, false);
+assertIteratorDone(outer, undefined);
+
+if (typeof reportCompare == "function")
+ reportCompare(true, true);