Index: test/mjsunit/harmony/iterator-close.js |
diff --git a/test/mjsunit/harmony/iterator-close.js b/test/mjsunit/harmony/iterator-close.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..94785de51f48f516a658f4de91c2f05b50e35da0 |
--- /dev/null |
+++ b/test/mjsunit/harmony/iterator-close.js |
@@ -0,0 +1,364 @@ |
+// Copyright 2016 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. |
+ |
+// Flags: --harmony-iterator-close |
+ |
+function* g() { yield 42; return 88 }; |
+ |
+ |
+// Return method is "undefined". |
+{ |
+ g.prototype.return = null; |
+ |
+ assertEquals(undefined, (() => { |
+ for (let x of g()) { break; } |
+ })()); |
+ |
+ assertEquals(undefined, (() => { |
+ for (x of g()) { break; } |
+ })()); |
+ |
+ assertThrowsEquals(() => { |
+ for (let x of g()) { throw 42; } |
+ }, 42); |
+ |
+ assertThrowsEquals(() => { |
+ for (x of g()) { throw 42; } |
+ }, 42); |
+ |
+ assertEquals(42, (() => { |
+ for (let x of g()) { return 42; } |
+ })()); |
+ |
+ assertEquals(42, (() => { |
+ for (x of g()) { return 42; } |
+ })()); |
+ |
+ assertEquals(42, eval('for (let x of g()) { x; }')); |
+ |
+ assertEquals(42, eval('for (let x of g()) { x; }')); |
+} |
+ |
+ |
+// Return method is not callable. |
+{ |
+ g.prototype.return = 666; |
+ |
+ assertThrows(() => { |
+ for (let x of g()) { break; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (x of g()) { break; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (let x of g()) { throw 666; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (x of g()) { throw 666; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (let x of g()) { return 666; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (x of g()) { return 666; } |
+ }, TypeError); |
+ |
+ assertEquals(42, eval('for (let x of g()) { x; }')); |
+ |
+ assertEquals(42, eval('for (let x of g()) { x; }')); |
+} |
+ |
+ |
+// Return method does not return an object. |
+{ |
+ g.prototype.return = () => 666; |
+ |
+ assertThrows(() => { |
+ for (let x of g()) { break; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (x of g()) { break; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (let x of g()) { throw 666; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (x of g()) { throw 666; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (let x of g()) { return 666; } |
+ }, TypeError); |
+ |
+ assertThrows(() => { |
+ for (x of g()) { return 666; } |
+ }, TypeError); |
+ |
+ assertEquals(42, eval('for (let x of g()) { x; }')); |
+ |
+ assertEquals(42, eval('for (x of g()) { x; }')); |
+} |
+ |
+ |
+// Return method returns an object. |
+{ |
+ let log = []; |
+ g.prototype.return = (...args) => { log.push(args); return {} }; |
+ |
+ log = []; |
+ for (let x of g()) { break; } |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ for (x of g()) { break; } |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g()) { throw 42; } |
+ }, 42); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (x of g()) { throw 42; } |
+ }, 42); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertEquals(42, (() => { |
+ for (let x of g()) { return 42; } |
+ })()); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertEquals(42, (() => { |
+ for (x of g()) { return 42; } |
+ })()); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertEquals(42, eval('for (let x of g()) { x; }')); |
+ assertEquals([], log); |
+ |
+ log = []; |
+ assertEquals(42, eval('for (x of g()) { x; }')); |
+ assertEquals([], log); |
+} |
+ |
+ |
+// Return method throws. |
+{ |
+ let log = []; |
+ g.prototype.return = (...args) => { log.push(args); throw 23 }; |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g()) { break; } |
+ }, 23); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (x of g()) { break; } |
+ }, 23); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g()) { throw 42; } |
+ }, 42); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (x of g()) { throw 42; } |
+ }, 42); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g()) { return 42; } |
+ }, 23); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (x of g()) { return 42; } |
+ }, 23); |
+ assertEquals([[]], log); |
+ |
+ log = []; |
+ assertEquals(42, eval('for (let x of g()) { x; }')); |
+ assertEquals([], log); |
+ |
+ log = []; |
+ assertEquals(42, eval('for (x of g()) { x; }')); |
+ assertEquals([], log); |
+} |
+ |
+ |
+// Next method throws. |
+{ |
+ g.prototype.next = () => { throw 666; }; |
+ g.prototype.return = () => { assertUnreachable() }; |
+ |
+ assertThrowsEquals(() => { |
+ for (let x of g()) {} |
+ }, 666); |
+ |
+ assertThrowsEquals(() => { |
+ for (x of g()) {} |
+ }, 666); |
+} |
+ |
+ |
+// Nested loops. |
+{ |
+ function* g1() { yield 1; yield 2; throw 3; } |
+ function* g2() { yield -1; yield -2; throw -3; } |
+ |
+ assertDoesNotThrow(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ if (y == -2) break; |
+ } |
+ if (x == 2) break; |
+ } |
+ }, -3); |
+ |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ } |
+ } |
+ }, -3); |
+ |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ if (y == -2) break; |
+ } |
+ } |
+ }, 3); |
+ |
+ assertDoesNotThrow(() => { |
+ l: for (let x of g1()) { |
+ for (let y of g2()) { |
+ if (y == -2) break l; |
+ } |
+ } |
+ }); |
+ |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ throw 4; |
+ } |
+ } |
+ }, 4); |
+ |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ if (y == -2) throw 4; |
+ } |
+ } |
+ }, 4); |
+ |
+ let log = []; |
+ g1.prototype.return = () => { log.push(1); throw 5 }; |
+ g2.prototype.return = () => { log.push(2); throw -5 }; |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ if (y == -2) break; |
+ } |
+ if (x == 2) break; |
+ } |
+ }, -5); |
+ assertEquals([2, 1], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ } |
+ } |
+ }, -3); |
+ assertEquals([1], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ if (y == -2) break; |
+ } |
+ } |
+ }, -5); |
+ assertEquals([2, 1], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ l: for (let x of g1()) { |
+ for (let y of g2()) { |
+ if (y == -2) break l; |
+ } |
+ } |
+ }, -5); |
+ assertEquals([2, 1], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ throw 4; |
+ } |
+ } |
+ }, 4); |
+ assertEquals([2, 1], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ for (let y of g2()) { |
+ if (y == -2) throw 4; |
+ } |
+ } |
+ }, 4); |
+ assertEquals([2, 1], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ try { |
+ for (let y of g2()) { |
+ } |
+ } catch (_) {} |
+ } |
+ }, 3); |
+ assertEquals([], log); |
+ |
+ log = []; |
+ assertThrowsEquals(() => { |
+ for (let x of g1()) { |
+ try { |
+ for (let y of g2()) { |
+ } |
+ } catch (_) {} |
+ if (x == 2) break; |
+ } |
+ }, 5); |
+ assertEquals([1], log); |
+} |