sflow
Version:
sflow is a powerful and highly-extensible library designed for processing and manipulating streams of data effortlessly. Inspired by the functional programming paradigm, it provides a rich set of utilities for transforming streams, including chunking, fil
138 lines (113 loc) • 3.71 kB
text/typescript
import { expectTypeOf } from "expect-type";
import { maps } from "./maps";
import { sflow } from "./sflow";
describe("maps function", () => {
it("keeps type definitions", async () => {
const ret = await sflow([1, 2, 3])
.map((x) => x * 2)
.map((x) => {
expectTypeOf(x).toEqualTypeOf<number>();
return x + 1;
})
.toArray();
expectTypeOf(ret).toEqualTypeOf<number[]>();
expect(ret).toEqual([3, 5, 7]);
});
it("transforms values synchronously", async () => {
const transformStream = maps((x: number) => x * 2);
const writer = transformStream.writable.getWriter();
const reader = transformStream.readable.getReader();
writer.write(1);
writer.write(2);
writer.write(3);
writer.close();
const results = [];
while (true) {
const { value, done } = await reader.read();
if (done) break;
results.push(value);
}
expect(results).toEqual([2, 4, 6]);
});
it("transforms values asynchronously", async () => {
const transformStream = maps(async (x: number) => {
return new Promise((resolve) => setTimeout(() => resolve(x * 2), 10));
});
const writer = transformStream.writable.getWriter();
const reader = transformStream.readable.getReader();
writer.write(1);
writer.write(2);
writer.write(3);
writer.close();
const results = [];
while (true) {
const { value, done } = await reader.read();
if (done) break;
results.push(value);
}
expect(results).toEqual([2, 4, 6]);
});
it("provides index to mapping function", async () => {
const transformStream = maps((x: number, i: number) => `${x}-${i}`);
const writer = transformStream.writable.getWriter();
const reader = transformStream.readable.getReader();
writer.write(10);
writer.write(20);
writer.write(30);
writer.close();
const results = [];
while (true) {
const { value, done } = await reader.read();
if (done) break;
results.push(value);
}
expect(results).toEqual(["10-0", "20-1", "30-2"]);
});
it("works with sflow pipeline", async () => {
const result = await sflow([1, 2, 3, 4])
.map((x) => x * 2)
.toArray();
expect(result).toEqual([2, 4, 6, 8]);
});
it("handles different input and output types", async () => {
const result = await sflow(["1", "2", "3"])
.map((x) => parseInt(x, 10))
.toArray();
expect(result).toEqual([1, 2, 3]);
});
it("can transform objects", async () => {
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" },
];
const result = await sflow(users)
.map((user) => ({ ...user, active: true }))
.toArray();
expect(result).toEqual([
{ id: 1, name: "Alice", active: true },
{ id: 2, name: "Bob", active: true },
{ id: 3, name: "Charlie", active: true },
]);
});
it("maintains order of items", async () => {
// Using different delays to ensure order is maintained even with async operations
const transformStream = maps(async (x: number) => {
const delay = x === 2 ? 30 : 10; // Make the middle item take longer
return new Promise((resolve) => setTimeout(() => resolve(x), delay));
});
const writer = transformStream.writable.getWriter();
const reader = transformStream.readable.getReader();
writer.write(1);
writer.write(2);
writer.write(3);
writer.close();
const results = [];
while (true) {
const { value, done } = await reader.read();
if (done) break;
results.push(value);
}
expect(results).toEqual([1, 2, 3]);
});
});