1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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));
});
});
|