From 204afb7ba60fde82a6e9fc4f62b2f4b227a7774e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Bargull?= <andre.bargull@gmail.com>
Date: Fri, 8 Dec 2017 13:23:34 -0800
Subject: [PATCH] Add tests when continue triggers IteratorClose

---
 .../for-of/generator-close-via-continue.js    | 65 +++++++++++++++++++
 .../for-of/iterator-close-via-continue.js     | 64 ++++++++++++++++++
 2 files changed, 129 insertions(+)
 create mode 100644 test/language/statements/for-of/generator-close-via-continue.js
 create mode 100644 test/language/statements/for-of/iterator-close-via-continue.js

diff --git a/test/language/statements/for-of/generator-close-via-continue.js b/test/language/statements/for-of/generator-close-via-continue.js
new file mode 100644
index 0000000000..b8afad37ce
--- /dev/null
+++ b/test/language/statements/for-of/generator-close-via-continue.js
@@ -0,0 +1,65 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+id: sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
+description: >
+  Generators should be closed via their `return` method when iteration is
+  interrupted via a `continue` statement.
+info: |
+  13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet )
+    ...
+    5. Repeat,
+      ...
+      i. Let result be the result of evaluating stmt.
+      ...
+      k. If LoopContinues(result, labelSet) is false, then
+        i. If iterationKind is enumerate, then
+          ...
+        ii. Else,
+          1. Assert: iterationKind is iterate.
+          2. Return ? IteratorClose(iteratorRecord, UpdateEmpty(result, V)).
+      ...
+
+features: [generators]
+---*/
+
+var startedCount = 0;
+var finallyCount = 0;
+var iterationCount = 0;
+function* values() {
+  startedCount += 1;
+  try {
+    yield;
+    $ERROR('This code is unreachable (within `try` block)');
+  } finally {
+    finallyCount += 1;
+  }
+  $ERROR('This code is unreachable (following `try` statement)');
+}
+var iterable = values();
+
+assert.sameValue(
+  startedCount, 0, 'Generator is initialized in suspended state'
+);
+
+L: do {
+  for (var x of iterable) {
+    assert.sameValue(
+      startedCount, 1, 'Generator executes prior to first iteration'
+    );
+    assert.sameValue(
+      finallyCount, 0, 'Generator is paused during first iteration'
+    );
+    iterationCount += 1;
+    continue L;
+  }
+} while (false);
+
+assert.sameValue(
+  startedCount, 1, 'Generator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+  finallyCount, 1, 'Generator is closed after `continue` statement'
+);
diff --git a/test/language/statements/for-of/iterator-close-via-continue.js b/test/language/statements/for-of/iterator-close-via-continue.js
new file mode 100644
index 0000000000..6c98fb6b84
--- /dev/null
+++ b/test/language/statements/for-of/iterator-close-via-continue.js
@@ -0,0 +1,64 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+id: sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
+description: >
+  Iterators should be closed via their `return` method when iteration is
+  interrupted via a `continue` statement.
+info: |
+  13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet )
+    ...
+    5. Repeat,
+      ...
+      i. Let result be the result of evaluating stmt.
+      ...
+      k. If LoopContinues(result, labelSet) is false, then
+        i. If iterationKind is enumerate, then
+          ...
+        ii. Else,
+          1. Assert: iterationKind is iterate.
+          2. Return ? IteratorClose(iteratorRecord, UpdateEmpty(result, V)).
+      ...
+
+features: [Symbol.iterator]
+---*/
+
+var startedCount = 0;
+var returnCount = 0;
+var iterationCount = 0;
+var iterable = {};
+
+iterable[Symbol.iterator] = function() {
+  return {
+    next: function() {
+      startedCount += 1;
+      return { done: false, value: null };
+    },
+    return: function() {
+      returnCount += 1;
+      return {};
+    }
+  };
+};
+
+L: do {
+  for (var x of iterable) {
+    assert.sameValue(
+      startedCount, 1, 'Value is retrieved'
+    );
+    assert.sameValue(
+      returnCount, 0, 'Iterator is not closed'
+    );
+    iterationCount += 1;
+    continue L;
+  }
+} while (false);
+
+assert.sameValue(
+  startedCount, 1, 'Iterator does not restart following interruption'
+);
+assert.sameValue(iterationCount, 1, 'A single iteration occurs');
+assert.sameValue(
+  returnCount, 1, 'Iterator is closed after `continue` statement'
+);
-- 
GitLab