From bab7be00804a1a6ea5d96aa623a04ae1826de4c2 Mon Sep 17 00:00:00 2001 From: Eric Bower Date: Wed, 22 Nov 2023 14:27:20 -0500 Subject: [PATCH] wrap --- lib/call.ts | 16 ++++++++++++---- test/call.test.ts | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/call.ts b/lib/call.ts index 39341caa9..66782f80d 100644 --- a/lib/call.ts +++ b/lib/call.ts @@ -9,6 +9,8 @@ function isPromise(p: unknown): boolean { if (!p) return false; return isFunc((p as PromiseLike).then); } +// iterator must implement both `.next` and `.throw` +// built-in iterators are not considered iterators to `call()` function isIterator(it: unknown): boolean { if (!it) return false; return isFunc((it as Iterator).next) && @@ -68,12 +70,18 @@ export function call(callable: Callable): Operation> { return action(function* (resolve, reject) { try { let op = typeof callable === "function" ? callable() : callable; - if (isIterable(op)) { - resolve(yield* op as Operation); + if (isPromise(op)) { + resolve(yield* expect(op as Promise)); } else if (isIterator(op)) { resolve(yield* op as Operation); - } else if (isPromise(op)) { - resolve(yield* expect(op as Promise)); + } else if (isIterable(op)) { + let iterable = op as Iterable; + let iter = iterable[Symbol.iterator](); + if (isIterator(iter)) { + resolve(yield* op as Operation); + } else { + resolve(op as T); + } } else { resolve(op as T); } diff --git a/test/call.test.ts b/test/call.test.ts index 804ce028d..95108b8ee 100644 --- a/test/call.test.ts +++ b/test/call.test.ts @@ -62,7 +62,24 @@ describe("call", () => { await expect(run(() => call(() => 42))).resolves.toEqual(42); }); - it.only("evaluates a vanilla function that returns an iterable", async () => { + it("evaluates a vanilla function that returns an iterable string", async () => { await expect(run(() => call(() => "123"))).resolves.toEqual("123"); }); + + it("evaluates a vanilla function that returns an iterable array", async () => { + await expect(run(() => call(() => [1, 2, 3]))).resolves.toEqual([1, 2, 3]); + }); + + it("evaluates a vanilla function that returns an iterable map", async () => { + let map = new Map(); + map.set("1", 1); + map.set("2", 2); + map.set("3", 3); + await expect(run(() => call(() => map))).resolves.toEqual(map); + }); + + it("evaluates a vanilla function that returns an iterable set", async () => { + let arr = new Set([1, 2, 3]); + await expect(run(() => call(() => arr))).resolves.toEqual(arr); + }); });