UNPKG

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

150 lines (134 loc) 5.13 kB
import { range } from "rambda"; import { forEachs, mergeAscends, mergeDescends, sflow } from "./index"; it("merge asc", async () => { const req1 = sflow([0, 1, 2]); const req2 = sflow([1, 2, 3]); const req3 = sflow([0, 4, 5]); const ret = [0, 0, 1, 1, 2, 2, 3, 4, 5]; expect( await sflow(mergeAscends((x) => x, [req1, req2, req3])).toArray(), ).toEqual(ret); }); it.skip("drains correctly for different length flow", async () => { const s = [0, 1, 2].map(() => jest.fn()); const f = [0, 1, 2].map(() => jest.fn()); const end = jest.fn(); const c = mergeAscends( (x) => x, [ sflow([1]).onStart(s[0]).onFlush(f[0]), sflow([4, 5]).onStart(s[0]).onFlush(f[1]), sflow([7, 8, 9]).onStart(s[0]).onFlush(f[2]), ], ).onFlush(end); const r = c.getReader(); expect(f[0]).not.toHaveBeenCalled(); expect(f[1]).not.toHaveBeenCalled(); expect((await r.read()).value).toBe(1); // pulled from [0|1|2] got [1,4,7] emit 1, f0 drain expect((await r.read()).value).toBe(4); // pulled from [0| | ] got [_,4,7] emit 4, expect(f[0]).toHaveBeenCalled(); expect(f[1]).toHaveBeenCalled(); expect((await r.read()).value).toBe(5); // pulled from [ |1| ] got [_,5,7] emit 5 expect(f[2]).not.toHaveBeenCalled(); expect((await r.read()).value).toBe(7); // pulled from [ | |2] got [_,_,7] emit 7 expect(f[2]).toHaveBeenCalled(); expect((await r.read()).value).toBe(8); // pulled from [ | |2] got [_,_,8] emit 8 expect((await r.read()).value).toBe(9); // pulled from [ | |2] got [_,_,9] emit 9 expect(end).not.toHaveBeenCalled(); expect((await r.read()).value).toBe(undefined); // pulled from [ | |2] got [_,_,_] drain expect(end).toHaveBeenCalled(); }); it.skip("merge asc lazy", async () => { const fn1 = jest.fn(); const req1 = sflow([0, 1, 2]).byLazy(forEachs(fn1)); const fn2 = jest.fn(); const req2 = sflow([1, 2, 3]).byLazy(forEachs(fn2)); const fn3 = jest.fn(); const req3 = sflow([0, 4, 5]).byLazy(forEachs(fn3)); const _ret = [0, 0, 1, 1, 2, 2, 3, 4, 5]; const _emi = [1, 3, 2, 1, 2, 1, 2, 3, 3]; // emit order const r = sflow(mergeAscends((x) => x, [req1, req2, req3])); expect(fn1).toHaveBeenCalledTimes(0); expect(fn2).toHaveBeenCalledTimes(0); expect(fn3).toHaveBeenCalledTimes(0); const reader = r.getReader(); expect(fn1).toHaveBeenCalledTimes(0); expect(fn2).toHaveBeenCalledTimes(0); expect(fn3).toHaveBeenCalledTimes(0); await reader.read(); expect(fn1).toHaveBeenCalledTimes(2); expect(fn2).toHaveBeenCalledTimes(2); expect(fn3).toHaveBeenCalledTimes(1); await reader.read(); expect(fn1).toHaveBeenCalledTimes(2); expect(fn2).toHaveBeenCalledTimes(2); expect(fn3).toHaveBeenCalledTimes(2); await reader.read(); expect(fn1).toHaveBeenCalledTimes(3); expect(fn2).toHaveBeenCalledTimes(2); expect(fn3).toHaveBeenCalledTimes(3); }); it("curried", async () => { const req1 = sflow([0, 1, 2]); const req2 = sflow([1, 2, 3]); const req3 = sflow([0, 4, 5]); const ret = [0, 0, 1, 1, 2, 2, 3, 4, 5]; expect( await sflow([req1, req2, req3]) .through(mergeAscends((x: number) => x)) // merge all flows into one by ascend order .toArray(), ).toEqual(ret); }); it("merge desc by invert use of asc", async () => { const req1 = sflow([0, 1, 2].toReversed()); const req2 = sflow([1, 2, 3].toReversed()); const req3 = sflow([0, 4, 5].toReversed()); const ret = [0, 0, 1, 1, 2, 2, 3, 4, 5].toReversed(); expect( await sflow(mergeAscends((x) => -x, [req1, req2, req3])) // .peek(console.log) .toArray(), ).toEqual(ret); }); it("merge desc by desc export", async () => { const req1 = sflow([0, 1, 2].toReversed()); const req2 = sflow([1, 2, 3].toReversed()); const req3 = sflow([0, 4, 5].toReversed()); const ret = [0, 0, 1, 1, 2, 2, 3, 4, 5].toReversed(); expect( await sflow(mergeDescends((x) => x, [req1, req2, req3])) // .peek(console.log) .toArray(), ).toEqual(ret); }); it("merge a super long asc", async () => { const req1 = sflow(range(0, 9999).map((e) => 1 + e * 2)); // 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 ... const req2 = sflow(range(0, 9999).map((e) => 2 + e * 3)); // 2, 5, 8, 11, 14, 17, 20, 23, 26, 29 ... const req3 = sflow(range(0, 9999).map((e) => 3 + e * 5)); // 3, 8, 13, 18, 23, 28, 33, 38, 43, 48 ... const ret = range(0, 9999) .flatMap((e) => [1 + e * 2, 2 + e * 3, 3 + e * 5]) .sort((a, b) => a - b); expect( await sflow(mergeAscends((x) => x, [req1, req2, req3])) // .peek(console.log) .toArray(), ).toEqual(ret); // cost about 60ms in my machine }); it("not throws asc", async () => { const req1 = sflow([1, 2, 3]); const req2 = sflow([0, 4, 5]); expect( await sflow(mergeAscends((x) => x, [req1, req2])) // .peek(console.log) .toArray(), ).toEqual([0, 1, 2, 3, 4, 5]); }); it("throws not asc", async () => { const req1 = sflow([1, 2, 0]); // not asc const req2 = sflow([0, 4, 5]); await expect( sflow(mergeAscends((x) => x, [req1, req2])) // .peek(console.log) .toArray(), ).rejects.toThrow("ascending"); });