From be19aaa18e4a53792f5f87b2c19f3bf69753493e Mon Sep 17 00:00:00 2001
From: jugglinmike <mike@mikepennisi.com>
Date: Tue, 28 Jun 2016 10:55:18 -0400
Subject: [PATCH] Add tests ensuring iterator is not closed (#702)

A subtle aspect of the for-of iteration protocol concerns abrupt
completions that do *not* trigger iterator closing. Although this detail
is implicit in the current structure of the specification text, some
hosts may violate the protocol by closing the iterator because later
steps *do* specify that behavior.

The V8 engine is one such host--as of this writing, it incorrectly
closes the iterator when accessing the `value` property of the iterator
result produces an abrupt completion.

Add tests verifying that the iterator protocol is not violated in this
way for abrupt completions during the semantics of for-of evaluation.
---
 .../statements/for-of/iterator-next-error.js         | 10 ++++++++++
 .../for-of/iterator-next-result-value-attr-error.js  | 12 ++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/test/language/statements/for-of/iterator-next-error.js b/test/language/statements/for-of/iterator-next-error.js
index bcecc0bb4c..ef4f5da983 100644
--- a/test/language/statements/for-of/iterator-next-error.js
+++ b/test/language/statements/for-of/iterator-next-error.js
@@ -5,16 +5,25 @@ es6id: 13.6.4.13 S5.d
 description: >
     If `nextResult` is an abrupt completion as per IteratorStep (ES6 7.4.5),
     return the completion.
+info: |
+  [...]
+  5. Repeat
+     a. Let nextResult be ? IteratorStep(iterator).
 features: [Symbol.iterator]
 ---*/
 
 var iterable = {};
 var iterationCount = 0;
+var returnCount = 0;
 
 iterable[Symbol.iterator] = function() {
   return {
     next: function() {
       throw new Test262Error();
+    },
+    return: function() {
+      returnCount += 1;
+      return {};
     }
   };
 };
@@ -26,3 +35,4 @@ assert.throws(Test262Error, function() {
 });
 
 assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+assert.sameValue(returnCount, 0, 'Iterator is not closed.');
diff --git a/test/language/statements/for-of/iterator-next-result-value-attr-error.js b/test/language/statements/for-of/iterator-next-result-value-attr-error.js
index 9344c5ec32..9832a497cc 100644
--- a/test/language/statements/for-of/iterator-next-result-value-attr-error.js
+++ b/test/language/statements/for-of/iterator-next-result-value-attr-error.js
@@ -5,11 +5,18 @@ es6id: 13.6.4.13 S5.g
 description: >
     If `nextValue` is an abrupt completion as per IteratorValue (ES6 7.4.4),
     return the completion.
+info: |
+  [...]
+  5. Repeat
+     a. Let nextResult be ? IteratorStep(iterator).
+     b. If nextResult is false, return NormalCompletion(V).
+     c. Let nextValue be ? IteratorValue(nextResult).
 features: [Symbol.iterator]
 ---*/
 
 var iterable = {};
 var iterationCount = 0;
+var returnCount = 0;
 
 iterable[Symbol.iterator] = function() {
   return {
@@ -20,6 +27,10 @@ iterable[Symbol.iterator] = function() {
           throw new Test262Error();
         }
       };
+    },
+    return: function() {
+      returnCount += 1;
+      return {};
     }
   };
 };
@@ -31,3 +42,4 @@ assert.throws(Test262Error, function() {
 });
 
 assert.sameValue(iterationCount, 0, 'The loop body is not evaluated');
+assert.sameValue(returnCount, 0, 'Iterator is not closed.');
-- 
GitLab