]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - tests/stress/custom-iterators.js
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / tests / stress / custom-iterators.js
diff --git a/tests/stress/custom-iterators.js b/tests/stress/custom-iterators.js
new file mode 100644 (file)
index 0000000..fd6413f
--- /dev/null
@@ -0,0 +1,322 @@
+// This test checks the behavior of custom iterable objects.
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return {
+            done: this.__key === 42,
+            value: this.__key++
+        };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+    }
+};
+var expected = 0;
+for (var value of iter) {
+    if (value !== expected++)
+        throw "Error: bad value: " + value;
+}
+if (returnCalled)
+    throw "Error: return is called.";
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return {
+            done: this.__key === 42,
+            value: this.__key++
+        };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        return {
+            done: true,
+            value: undefined
+        };
+    }
+};
+
+try {
+    for (var value of iter) {
+        throw "Error: Terminate iteration.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: Terminate iteration.")
+        throw "Error: bad error thrown: " + e;
+}
+if (!returnCalled)
+    throw "Error: return is not called.";
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return {
+            done: this.__key === 42,
+            value: this.__key++
+        };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        return {
+            done: true,
+            value: undefined
+        };
+    }
+};
+
+for (var value of iter) {
+    break;
+}
+if (!returnCalled)
+    throw "Error: return is not called.";
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    get next() {
+        throw "Error: looking up next.";
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+    }
+};
+try {
+    for (var value of iter) {
+        throw "Error: Iteration should not occur.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: looking up next.")
+        throw "Error: bad error thrown: " + e;
+}
+if (returnCalled)
+    throw "Error: return is called.";
+
+
+
+var iter = {
+    __key: 0,
+    next: function () {
+        return {
+            done: this.__key === 42,
+            value: this.__key++
+        };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    get return() {
+        throw "Error: looking up return."
+    }
+};
+try {
+    for (var value of iter) {
+        throw "Error: Terminate iteration.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: looking up return.")
+        throw "Error: bad error thrown: " + e;
+}
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        throw "Error: next is called."
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        return {
+            done: true,
+            value: undefined
+        };
+    }
+};
+
+try {
+    for (var value of iter) {
+        throw "Error: Terminate iteration.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: next is called.")
+        throw "Error: bad error thrown: " + e;
+}
+if (returnCalled)
+    throw "Error: return is called.";
+
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return { done: false, value: 42 };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        throw "Error: return is called.";
+    }
+};
+
+try {
+    for (var value of iter) {
+        throw "Error: Terminate iteration.";
+    }
+} catch (e) {
+    if (String(e) !== "Error: Terminate iteration.")
+        throw "Error: bad error thrown: " + e;
+}
+if (!returnCalled)
+    throw "Error: return is not called.";
+
+
+var returnCalled = false;
+var iter = {
+    __key: 0,
+    next: function () {
+        return { done: false, value: 42 };
+    },
+    [Symbol.iterator]: function () {
+        return this;
+    },
+    return: function () {
+        returnCalled = true;
+        throw "Error: return is called.";
+    }
+};
+try {
+    for (var value of iter) {
+        break;
+    }
+} catch (e) {
+    if (String(e) !== "Error: return is called.")
+        throw "Error: bad error thrown: " + e;
+}
+if (!returnCalled)
+    throw "Error: return is not called.";
+
+
+var primitives = [
+    undefined,
+    null,
+    42,
+    "string",
+    true,
+    Symbol("Cocoa")
+];
+
+function iteratorInterfaceErrorTest(notIteratorResult) {
+    var returnCalled = false;
+    var iter = {
+        __key: 0,
+        next: function () {
+            return notIteratorResult;
+        },
+        [Symbol.iterator]: function () {
+            return this;
+        },
+        return: function () {
+            returnCalled = true;
+            return undefined;
+        }
+    };
+    try {
+        for (var value of iter) {
+            throw "Error: Iteration should not occur.";
+        }
+    } catch (e) {
+        if (String(e) !== "TypeError: Iterator result interface is not an object.")
+            throw "Error: bad error thrown: " + e;
+    }
+    if (returnCalled)
+        throw "Error: return is called.";
+}
+
+function iteratorInterfaceErrorTestReturn(notIteratorResult) {
+    var returnCalled = false;
+    var iter = {
+        __key: 0,
+        next: function () {
+            return { done: false, value: 42 };
+        },
+        [Symbol.iterator]: function () {
+            return this;
+        },
+        return: function () {
+            returnCalled = true;
+            return notIteratorResult;
+        }
+    };
+    try {
+        for (var value of iter) {
+            throw "Error: Terminate iteration.";
+        }
+    } catch (e) {
+        if (String(e) !== "Error: Terminate iteration.")
+            throw "Error: bad error thrown: " + e;
+    }
+    if (!returnCalled)
+        throw "Error: return is not called.";
+}
+
+primitives.forEach(iteratorInterfaceErrorTest);
+primitives.forEach(iteratorInterfaceErrorTestReturn);
+
+
+function iteratorInterfaceBreakTestReturn(notIteratorResult) {
+    var returnCalled = false;
+    var iter = {
+        __key: 0,
+        next: function () {
+            return { done: false, value: 42 };
+        },
+        [Symbol.iterator]: function () {
+            return this;
+        },
+        return: function () {
+            returnCalled = true;
+            return notIteratorResult;
+        }
+    };
+    try {
+        for (var value of iter) {
+            break;
+        }
+    } catch (e) {
+        if (String(e) !== "TypeError: Iterator result interface is not an object.")
+            throw "Error: bad error thrown: " + e;
+    }
+    if (!returnCalled)
+        throw "Error: return is not called.";
+}
+
+primitives.forEach(iteratorInterfaceBreakTestReturn);