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