summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/Generators/delegating-yield-2.js
blob: 34cb3f4a9f34860ee1d8da45a0c5c1ca341846b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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);