|
1 // Test yield* with iter.throw and monkeypatching. |
|
2 |
|
3 function* g1() { return (yield 1); } |
|
4 function* g2() { try { yield 1; } catch (e) { yield e; } } |
|
5 function* delegate(iter) { return yield* iter; } |
|
6 var GeneratorObjectPrototype = Object.getPrototypeOf(g1).prototype; |
|
7 var GeneratorObjectPrototype_throw = GeneratorObjectPrototype.throw; |
|
8 |
|
9 // An uncaught delegated throw. |
|
10 var inner = g1(); |
|
11 var outer = delegate(inner); |
|
12 assertIteratorNext(outer, 1); |
|
13 assertThrowsValue(function () { outer.throw(42) }, 42); |
|
14 assertThrowsValue(function () { outer.throw(42) }, 42); |
|
15 |
|
16 // A caught delegated throw. |
|
17 inner = g2(); |
|
18 outer = delegate(inner); |
|
19 assertIteratorNext(outer, 1); |
|
20 assertIteratorResult(outer.throw(42), 42, false); |
|
21 assertThrowsValue(function () { outer.throw(42) }, 42); |
|
22 assertThrowsValue(function () { outer.throw(42) }, 42); |
|
23 |
|
24 // What would be an uncaught delegated throw, but with a monkeypatched iterator. |
|
25 inner = g1(); |
|
26 outer = delegate(inner); |
|
27 assertIteratorNext(outer, 1); |
|
28 inner.throw = function(e) { return e*2; }; |
|
29 assertEq(84, outer.throw(42)); |
|
30 assertIteratorDone(outer, undefined); |
|
31 |
|
32 // Monkeypatching inner.next. |
|
33 inner = g1(); |
|
34 outer = delegate(inner); |
|
35 inner.next = function() { return { value: 13, done: true } }; |
|
36 assertIteratorDone(outer, 13); |
|
37 |
|
38 // What would be a caught delegated throw, but with a monkeypunched prototype. |
|
39 inner = g2(); |
|
40 outer = delegate(inner); |
|
41 assertIteratorNext(outer, 1); |
|
42 delete GeneratorObjectPrototype.throw; |
|
43 var outer_throw_42 = GeneratorObjectPrototype_throw.bind(outer, 42); |
|
44 assertThrowsValue(outer_throw_42, 42); |
|
45 assertThrowsValue(outer_throw_42, 42); |
|
46 |
|
47 // Monkeypunch a different throw handler. |
|
48 inner = g2(); |
|
49 outer = delegate(inner); |
|
50 outer_throw_42 = GeneratorObjectPrototype_throw.bind(outer, 42); |
|
51 assertIteratorNext(outer, 1); |
|
52 GeneratorObjectPrototype.throw = function(e) { return e*2; } |
|
53 assertEq(84, outer_throw_42()); |
|
54 assertEq(84, outer_throw_42()); |
|
55 // This continues indefinitely. |
|
56 assertEq(84, outer_throw_42()); |
|
57 assertIteratorDone(outer, undefined); |
|
58 |
|
59 // The same, but restoring the original pre-monkey throw. |
|
60 inner = g2(); |
|
61 outer = delegate(inner); |
|
62 outer_throw_42 = GeneratorObjectPrototype_throw.bind(outer, 42); |
|
63 assertIteratorNext(outer, 1); |
|
64 assertEq(84, outer_throw_42()); |
|
65 assertEq(84, outer_throw_42()); |
|
66 GeneratorObjectPrototype.throw = GeneratorObjectPrototype_throw; |
|
67 assertIteratorResult(outer_throw_42(), 42, false); |
|
68 assertIteratorDone(outer, undefined); |
|
69 |
|
70 if (typeof reportCompare == "function") |
|
71 reportCompare(true, true); |