Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
import { describe, expect, it } from "@suaveplan/testing/runner";
describe("dep-graph", () => {
it("has no circular imports in the main barrel", {
timeout: 30000,
}, async () => {
// Import the main barrel — if this resolves without error, no circular dep crash
const mod = await import("../src/index.js");
expect(typeof mod).toBe("object");
expect(typeof mod.fromArray).toBe("function");
expect(typeof mod.mapStream).toBe("function");
expect(typeof mod.toArray).toBe("function");
expect(typeof mod.pipeline).toBe("function");
});
it("exports StreamError", { timeout: 30000 }, async () => {
const { StreamError, STREAM_CODES } = await import("../src/index.js");
expect(StreamError).toBeDefined();
expect(STREAM_CODES.ABORTED).toBe("STREAM.ABORTED");
});
});

View File

@@ -0,0 +1,79 @@
import { describe, expect, it } from "@suaveplan/testing/runner";
import * as fc from "fast-check";
import { fromArray } from "../../src/readable/from-array/from-array.js";
import { toArray } from "../../src/sinks/to-array/to-array.js";
import { batchStream } from "../../src/transforms/batch/batch.js";
import { filterStream } from "../../src/transforms/filter/filter.js";
import { mapStream } from "../../src/transforms/map/map.js";
describe("property-based: streams invariants", () => {
it("toArray(fromArray(items)) ≡ items", { timeout: 30000 }, async () => {
await fc.assert(
fc.asyncProperty(fc.array(fc.integer()), async (items) => {
const result = await toArray(fromArray(items));
expect(result).toEqual(items);
}),
{ numRuns: 50 }
);
});
it("batchStream completeness: flattened batches ≡ original", {
timeout: 30000,
}, async () => {
await fc.assert(
fc.asyncProperty(
fc.array(fc.integer(), { minLength: 1 }),
fc.integer({ min: 1, max: 20 }),
async (items, size) => {
const batches = await toArray(
fromArray(items).pipeThrough(batchStream(size))
);
const flat = batches.flat();
expect(flat).toEqual(items);
}
),
{ numRuns: 50 }
);
});
it("mapStream composition: map(f).map(g) ≡ map(x=>g(f(x)))", {
timeout: 30000,
}, async () => {
await fc.assert(
fc.asyncProperty(fc.array(fc.integer()), async (items) => {
const f = (x: number) => x * 2;
const g = (x: number) => x + 1;
const composed = await toArray(
fromArray(items)
.pipeThrough(mapStream(f))
.pipeThrough(mapStream(g))
);
const single = await toArray(
fromArray(items).pipeThrough(mapStream((x) => g(f(x))))
);
expect(composed).toEqual(single);
}),
{ numRuns: 50 }
);
});
it("filterStream: no items fail predicate", {
timeout: 30000,
}, async () => {
await fc.assert(
fc.asyncProperty(
fc.array(fc.integer({ min: -1000, max: 1000 })),
async (items) => {
const pred = (n: number) => n > 0;
const result = await toArray(
fromArray(items).pipeThrough(filterStream(pred))
);
expect(result.every(pred)).toBe(true);
expect(result.length).toBe(items.filter(pred).length);
}
),
{ numRuns: 50 }
);
});
});

View File

@@ -0,0 +1,8 @@
// Ensure `globalThis.crypto` is available in bare-Node vitest runs.
import { webcrypto } from "node:crypto";
type WritableGlobal = { crypto?: Crypto };
const g = globalThis as WritableGlobal;
if (g.crypto === undefined) {
g.crypto = webcrypto as unknown as Crypto;
}