From d3bac382a200d513c424c25bb0d1feaf3bb8fe09 Mon Sep 17 00:00:00 2001 From: Tianlan Zhou Date: Sat, 5 Aug 2023 01:30:23 +0800 Subject: [PATCH] Runtime: `yield*` should throw if not iterable (#636) --- packages/runtime/runtime.js | 5 ++--- test/tests.es6.js | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/runtime/runtime.js b/packages/runtime/runtime.js index 1ea704e90..efaa79b01 100644 --- a/packages/runtime/runtime.js +++ b/packages/runtime/runtime.js @@ -487,7 +487,7 @@ var runtime = (function (exports) { }; function values(iterable) { - if (iterable) { + if (iterable || iterable === "") { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) { return iteratorMethod.call(iterable); @@ -517,8 +517,7 @@ var runtime = (function (exports) { } } - // Return an iterator with no values. - return { next: doneResult }; + throw new TypeError(typeof iterable + " is not iterable"); } exports.values = values; diff --git a/test/tests.es6.js b/test/tests.es6.js index aa1b2a818..7e7383028 100644 --- a/test/tests.es6.js +++ b/test/tests.es6.js @@ -1504,6 +1504,28 @@ describe("delegated yield", function() { check(gen(iterator), [], "1foo"); }); + it("should work with empty string", function() { + function* f() { + yield* ""; + }; + + assert.deepEqual(f().next(), { value: undefined, done: true }); + }); + + it("should throw if not iterable", function() { + function* f(x) { + yield* x; + }; + + assert.throws(() => f(undefined).next(), TypeError); + assert.throws(() => f(null).next(), TypeError); + assert.throws(() => f(false).next(), TypeError); + assert.throws(() => f(true).next(), TypeError); + assert.throws(() => f(0).next(), TypeError); + assert.throws(() => f(1).next(), TypeError); + assert.throws(() => f({}).next(), TypeError); + }); + it("should throw if the delegated iterable's iterator doesn't have .next", function() { var it = function* () { yield* {