80 lines
2.9 KiB
TypeScript
80 lines
2.9 KiB
TypeScript
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 }
|
|
);
|
|
});
|
|
});
|