From f9a77c5c27aede4e5978eb55d9b7af781b680a1d Mon Sep 17 00:00:00 2001 From: João Augusto Costa Branco Marado Torres Date: Tue, 24 Jun 2025 12:08:41 -0300 Subject: feat!: initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: João Augusto Costa Branco Marado Torres --- src/utils/iterator.test.ts | 122 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/utils/iterator.test.ts (limited to 'src/utils/iterator.test.ts') diff --git a/src/utils/iterator.test.ts b/src/utils/iterator.test.ts new file mode 100644 index 0000000..dda0e0a --- /dev/null +++ b/src/utils/iterator.test.ts @@ -0,0 +1,122 @@ +import { describe, it } from "@std/testing/bdd"; +import { + createAsyncIterator, + filterDuplicate, + findMapAsync, + surelyIterable, +} from "./iterator.ts"; +import { assertEquals } from "@std/assert"; + +describe("surelyIterable", () => { + it("returns the iterable as-is if input is already iterable", () => { + const input = [1, 2, 3]; + const result = surelyIterable(input); + assertEquals([...result], [1, 2, 3]); + }); + + it("wraps a non-iterable value in an array", () => { + const input = 42; + const result = surelyIterable(input); + assertEquals([...result], [42]); + }); + + it("wraps null in an array", () => { + const input = null; + const result = surelyIterable(input); + assertEquals([...result], [null]); + }); + + it("wraps undefined in an array", () => { + const input = undefined; + const result = surelyIterable(input); + assertEquals([...result], [undefined]); + }); + + it("wraps an object that is not iterable", () => { + const input = { a: 1 }; + const result = surelyIterable(input); + assertEquals([...result], [{ a: 1 }]); + }); + + it("handles a Set correctly", () => { + const input = new Set([1, 2, 3]); + const result = surelyIterable(input); + assertEquals([...result], [1, 2, 3]); + }); +}); + +describe("createAsyncIterator", () => { + it("yields resolved values in order", async () => { + const values = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]; + const results: number[] = []; + for await (const value of createAsyncIterator(values)) { + results.push(value); + } + assertEquals(results, [1, 2, 3]); + }); + + it("handles empty array", async () => { + const results: unknown[] = []; + for await (const value of createAsyncIterator([])) { + results.push(value); + } + assertEquals(results, []); + }); +}); + +describe("filterDuplicate", () => { + it("filters duplicate objects by key", () => { + const items = [ + { id: 1, name: "a" }, + { id: 2, name: "b" }, + { id: 1, name: "c" }, + ]; + const result = filterDuplicate(items, (i) => i.id); + assertEquals(result.length, 2); + assertEquals(result[0].name, "a"); + assertEquals(result[1].name, "b"); + }); + + it("handles empty iterable", () => { + const result = filterDuplicate([], (x) => x); + assertEquals(result, []); + }); + + it("keeps first occurrence only", () => { + const input = [1, 2, 3, 1, 2, 4]; + const result = filterDuplicate(input, (x) => x); + assertEquals(result, [1, 2, 3, 4]); + }); +}); + +describe("findMapAsync", () => { + it("returns first successful result", async () => { + const arr = [1, 2, 3]; + const i = 2; + const result = await findMapAsync(arr, (x) => { + if (x === i) return Promise.resolve(x); + throw new Error("not found"); + }); + assertEquals(result, i); + }); + + it("returns undefined if all reject", async () => { + const arr = [1, 2]; + const result = await findMapAsync(arr, () => { + throw new Error("fail"); + }); + assertEquals(result, undefined); + }); + + it("short-circuits after first success", async () => { + const calls: number[] = []; + const arr = [1, 2, 3]; + const i = arr.length - 1; + await findMapAsync(arr, (x) => { + calls.push(x); + if (x === i) return Promise.resolve("ok"); + throw new Error("fail"); + }); + assertEquals(calls, arr.slice(0, i)); + }); +}); -- cgit v1.2.3