UNPKG

@johngw/stream

Version:

Reactive programming tools using the WHATWG Streams API.

113 lines (98 loc) 2.99 kB
import { ForkableStream } from '@johngw/stream/sinks/ForkableStream' import { fromCollection } from '@johngw/stream/sources/fromCollection' import { write } from '@johngw/stream/sinks/write' import { interval } from '@johngw/stream/sources/interval' import { tap } from '@johngw/stream/transformers/tap' import { timeout } from '@johngw/stream-common' let forkable: ForkableStream<number> let fn: jest.Mock<void, [number]> let readable: ReadableStream<number> beforeEach(() => { forkable = new ForkableStream() fn = jest.fn() readable = fromCollection([1, 2, 3, 4, 5]) }) test('fork before piping', async () => { const promise = forkable.fork().pipeTo(write(fn)) readable.pipeTo(forkable) await promise expect(fn).toHaveBeenCalledTimes(5) }) test('fork after piping', async () => { readable.pipeTo(forkable) await forkable.fork().pipeTo(write(fn)) expect(fn).toHaveBeenCalledTimes(5) }) test('multiple subscribers', async () => { readable.pipeTo(forkable) await Promise.all([ forkable.fork().pipeTo(write(fn)), forkable.fork().pipeTo(write(fn)), forkable.fork().pipeTo(write(fn)), ]) expect(fn).toHaveBeenCalledTimes(15) }) test('finished property', async () => { await readable.pipeTo(forkable) expect(forkable.finished).toBe(true) }) test('finished streams will immediately close forks', async () => { await readable.pipeTo(forkable) await forkable .fork({ pull(controller) { controller.enqueue(6) }, }) .pipeTo(write(fn)) expect(fn).not.toHaveBeenCalled() }) describe('aborting', () => { let fn: jest.Mock<void, [Date]> let forkable: ForkableStream<Date> let abortController: AbortController beforeEach(() => { fn = jest.fn() forkable = new ForkableStream<Date>() abortController = new AbortController() interval(5) .pipeThrough(tap(fn)) .pipeTo(forkable, { signal: abortController.signal }) .catch(() => { // }) }) afterEach(async () => { abortController.abort() }) test('previously aborted streams will error new forks', async () => { abortController.abort() await timeout() await expect(forkable.fork().pipeTo(write())).rejects.toThrow() }) test('aborting an stream will error previous forks', async () => { const fork = forkable.fork().pipeTo(write()) abortController.abort() await expect(fork).rejects.toThrow() }) test('should not affect upstream', async () => { await expect( forkable.fork().pipeTo(write(), { signal: AbortSignal.timeout(10) }) ).rejects.toThrow() await timeout(50) expect(fn.mock.calls.length).toBeGreaterThanOrEqual(5) }) test('will cancel the fork', async () => { let cancelled = false await expect( forkable .fork({ cancel() { cancelled = true }, }) .pipeTo(write(), { signal: AbortSignal.timeout(10) }) ).rejects.toThrow() expect(cancelled).toBe(true) }) })