UNPKG

itertools-ts

Version:

Extended itertools port for TypeScript and JavaScript. Provides a huge set of functions for working with iterable collections (including async ones)

1,064 lines (1,015 loc) 30.7 kB
import { asyncTimeout, createAsyncGeneratorFixture, createAsyncIterableFixture, createAsyncIteratorFixture, createGeneratorFixture, createIterableFixture, createIteratorFixture, createMapFixture, expectToBeCloseToArray, // @ts-ignore } from "../fixture"; import { AsyncStream, Comparable, multi, single, } from "../../src"; describe.each([ ...dataProviderForOfCount(), ])( "Stream Infinite Of Count Test", (inputParams, limit, expected) => { it("", async () => { // When const stream = AsyncStream.ofCount(...inputParams); const result = await stream.limit(limit).toArray(); // Then expectToBeCloseToArray(result, expected); }); } ); describe.each([ ...dataProviderForOfCycle(), ])( "Stream Infinite Of Cycle Test", (iterable, limit, expected) => { it("", async () => { // When const stream = AsyncStream.ofCycle(iterable); const result = await stream.limit(limit).toArray(); // Then expect(result).toEqual(expected); }); } ); describe.each([ ...dataProviderForOfRepeat(), ])( "Stream Infinite Of Repeat Test", (itemToRepeat, limit, expected) => { it("", async () => { // When const stream = AsyncStream.ofRepeat(itemToRepeat); const result = await stream.limit(limit).toArray(); // Then expect(result).toEqual(expected); }); } ); function dataProviderForOfCount(): Array<[Array<number>, number, Array<number>]> { return [ [ [1, 2], 5, [1, 3, 5, 7, 9], ], [ [0, -1], 5, [0, -1, -2, -3, -4], ], ]; } function dataProviderForOfCycle(): Array<[Array<number>, number, Array<number>]> { return [ [ [0, 1, 2], 10, [0, 1, 2, 0, 1, 2, 0, 1, 2, 0], ], ]; } function dataProviderForOfRepeat(): Array<[number, number, Array<number>]> { return [ [ 1, 5, [1, 1, 1, 1, 1], ], ]; } describe.each([ ...dataProviderForMath(), ])( "AsyncStream Math Test", (input, streamFactory, expected) => { it("", async () => { // Given const result = await streamFactory(input); // Then expect(result).toEqual(expected); }); } ); function dataProviderForMath(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (data: any) => Promise<Array<any>>, Array<any> ]> { return [ [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: Iterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .runningAverage() .toArray(), [1, 1.5, 2], ], [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: Iterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .runningDifference() .toArray(), [-1, -3, -6], ], [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: Iterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .runningMax(1) .toArray(), [1, 1, 2, 3], ], [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: Iterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .runningMin(1) .toArray(), [1, 1, 1, 1], ], [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: Iterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .runningProduct() .toArray(), [1, 2, 6], ], [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: Iterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .runningTotal() .toArray(), [1, 3, 6], ], ]; } describe.each([ ...dataProviderForMulti(), ])( "AsyncStream Multi Test", (input, streamFactory, expected) => { it("", async () => { // Given const result = await streamFactory(input); // Then expect(result).toEqual(expected); }); } ); function dataProviderForMulti(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (data: any) => Promise<Array<any>>, Array<any> ]> { return [ [ [1, 2, 3, 4, 5], (iterable: Iterable<number>): Promise<Array<[number, number, number, number, number, string]>> => AsyncStream.of(iterable) .zipWith( createAsyncGeneratorFixture([11, 22, 33]), createIterableFixture([111, 222, 333, 444]), createIteratorFixture([1111, 2222, 3333]), new Set([11111, 22222, 33333]), 'abcdefg', ) .toArray(), [ [1, 11, 111, 1111, 11111, 'a'], [2, 22, 222, 2222, 22222, 'b'], [3, 33, 333, 3333, 33333, 'c'], ], ], [ [1, 2, 3, 4, 5], (iterable: Iterable<number>): Promise<Array<[number?, number?, number?, number?, number?, string?]>> => AsyncStream.of(iterable) .zipLongestWith( createGeneratorFixture([11, 22, 33]), createAsyncIterableFixture([111, 222, 333, 444]), createIteratorFixture([1111, 2222, 3333]), new Set([11111, 22222, 33333]), 'abcdefg', ) .toArray(), [ [1, 11, 111, 1111, 11111, 'a'], [2, 22, 222, 2222, 22222, 'b'], [3, 33, 333, 3333, 33333, 'c'], [4, undefined, 444, undefined, undefined, 'd'], [5, undefined, undefined, undefined, undefined, 'e'], [undefined, undefined, undefined, undefined, undefined, 'f'], [undefined, undefined, undefined, undefined, undefined, 'g'], ], ], [ [1, 2, 3, 4, 5], (iterable: Iterable<number>): Promise<Array<[number | string, number | string, number | string, number | string, number | string, string]>> => AsyncStream.of(iterable) .zipFilledWith( 'filler', createAsyncGeneratorFixture([11, 22, 33]), createAsyncIterableFixture([111, 222, 333, 444]), createAsyncIteratorFixture([1111, 2222, 3333]), new Set([11111, 22222, 33333]), 'abcdefg', ) .toArray(), [ [1, 11, 111, 1111, 11111, 'a'], [2, 22, 222, 2222, 22222, 'b'], [3, 33, 333, 3333, 33333, 'c'], [4, 'filler', 444, 'filler', 'filler', 'd'], [5, 'filler', 'filler', 'filler', 'filler', 'e'], ['filler', 'filler', 'filler', 'filler', 'filler', 'f'], ['filler', 'filler', 'filler', 'filler', 'filler', 'g'], ], ], [ [1, 2, 3], (iterable: Iterable<number>): Promise<Array<[number, number, number, number, number, string]>> => AsyncStream.of(iterable) .zipEqualWith( createGeneratorFixture([11, 22, 33]), createAsyncIterableFixture([111, 222, 333]), createAsyncIteratorFixture([1111, 2222, 3333]), new Set([11111, 22222, 33333]), 'abc', ) .toArray(), [ [1, 11, 111, 1111, 11111, 'a'], [2, 22, 222, 2222, 22222, 'b'], [3, 33, 333, 3333, 33333, 'c'], ], ], [ [1, 2], (iterable: Iterable<number | string>): Promise<Array<number | string>> => AsyncStream.of(iterable) .chainWith(createAsyncGeneratorFixture([3, 4])) .chainWith(createAsyncIterableFixture([5])) .chainWith(createAsyncIteratorFixture([6])) .chainWith(new Set([7])) .chainWith(AsyncStream.of(createMapFixture([8, 9])).map((item) => item[1])) .chainWith('abc') .toArray(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c'], ], [ [1, 2], (iterable: Iterable<number | string>): Promise<Array<[number | string, number | string]>> => AsyncStream.of(iterable) .chainWith(createGeneratorFixture([3, 4])) .chainWith(createAsyncIterableFixture([5])) .chainWith(createAsyncIteratorFixture([6])) .chainWith(new Set([7])) .chainWith(AsyncStream.of(createMapFixture([8])).map((item) => item[1])) .chainWith('abc') .zipWith([11, 22, 33, 44, 55, 66, 77, 88, 'x', 'y', 'z']) .toArray(), [[1, 11], [2, 22], [3, 33], [4, 44], [5, 55], [6, 66], [7, 77], [8, 88], ['a', 'x'], ['b', 'y'], ['c', 'z']], ], ]; } describe.each([ ...dataProviderForPeek(), ])( "AsyncStream Peek Test", (input, leftChainFunc, rightChainFunc, expectedPeeked, expectedResult) => { it("", async () => { // Given const stream = leftChainFunc(input); const peeked: Array<unknown> = []; // When stream.peek((item) => { peeked.push(item); }); // And when const result = await rightChainFunc(stream).toArray(); // Then expect(peeked).toEqual(expectedPeeked); expect(result).toEqual(expectedResult); }); } ); describe.each([ ...dataProviderForPeek(), ])( "AsyncStream Peek Stream Test", (input, leftChainFunc, rightChainFunc, expectedPeeked, expectedResult) => { it("", async () => { // Given const stream = leftChainFunc(input); const peeked: Array<unknown> = []; // When stream.peekStream(async (stream) => { for await (const item of stream) { peeked.push(item); } }); // And when const result = await rightChainFunc(stream).toArray(); // Then expect(peeked).toEqual(expectedPeeked); expect(result).toEqual(expectedResult); }); } ); function dataProviderForPeek(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (iterable: any) => AsyncStream<any>, (stream: AsyncStream<any>) => AsyncStream<any>, Array<unknown>, Array<unknown>, ]> { return [ [ createAsyncIterableFixture([5, 4, 3, 2, 1]), (iterable: AsyncIterable<number>): AsyncStream<number> => AsyncStream.of(iterable), (stream: AsyncStream<number>): AsyncStream<number> => stream, [5, 4, 3, 2, 1], [5, 4, 3, 2, 1], ], [ createAsyncIterableFixture([1, 2, 3, 4, 5]), (iterable: AsyncIterable<number>): AsyncStream<[number, number]> => AsyncStream.of(iterable) .zipWith([11, 22, 33, 44, 55]), (stream: AsyncStream<[number, number]>): AsyncStream<[number, number]> => stream .limit(3), [[1, 11], [2, 22], [3, 33], [4, 44], [5, 55]], [[1, 11], [2, 22], [3, 33]], ], [ createAsyncIterableFixture([9, 8, 7, 6, 5, 4, 3, 2, 1]), (iterable: Iterable<number>): AsyncStream<number> => AsyncStream.of(iterable) .filter((x) => x % 2 !== 0) .sort(), (stream: AsyncStream<number>): AsyncStream<[number, number]> => stream .map((x) => x + 1) .pairwise(), [1, 3, 5, 7, 9], [[2, 4], [4, 6], [6, 8], [8, 10]], ], ]; } describe.each([ ...dataProviderForReduce(), ])( "AsyncStream Reduce Test", (input, streamFactory, expected) => { it("", async () => { // Given const result = await streamFactory(input); // Then expect(result).toEqual(expected); }); } ); function dataProviderForReduce(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (data: any) => any, any ]> { return [ [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toValue((carry, item) => carry + item, 0), 0, ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toAverage(), 0, ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toRange(), 6, ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toCount(), 6, ], [ createAsyncGeneratorFixture([2, 1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toFirst(), 2, ], [ createAsyncGeneratorFixture([2, 1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toFirstAndLast(), [2, 5], ], [ createAsyncGeneratorFixture([2, 3, 1, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toLast(), 5, ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toMax(), 3, ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toMin(), -3, ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .toMinMax((item) => -item), [3, -3], ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable).toProduct(), -36, ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .filter((value) => value > 0) .toSum(), 6, ], ]; } describe.each([ ...dataProviderForSet(), ])( "AsyncStream Set Test", (input, streamFactory, expected) => { it("", async () => { // Given const result = await streamFactory(input); // Then expect(result).toEqual(expected); }); } ); describe.each([ ...dataProviderForPartialIntersection(), ])( "AsyncStream Set Partial Intersection Test", (input, minIntersectionCount, streamFactory, expected) => { it("", async () => { // Given const result = await streamFactory(minIntersectionCount, input); // Then expect(result).toEqual(expected); }); } ); function dataProviderForSet(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (data: any) => Promise<Array<any>>, Array<any> ]> { return [ [ createAsyncGeneratorFixture([1, 2, 3, '1', '2', '3']), (iterable: AsyncIterable<number | string>): Promise<Array<number | string>> => AsyncStream.of(iterable) .distinct() .toArray(), [1, 2, 3, '1', '2', '3'], ], [ createAsyncGeneratorFixture([ { 'name': 'John', 'id': 1 }, { 'name': 'Mary', 'id': 2 }, { 'name': 'Mary', 'id': 3 }, { 'name': 'John', 'id': 4 }, { 'name': 'Jane', 'id': 5 }, ]), (iterable: AsyncIterable<Record<string, number | string>>): Promise<Array<Record<string, number | string>>> => AsyncStream.of(iterable) .distinct((datum: Record<string, number | string>) => datum['name']) .toArray(), [ { 'name': 'John', 'id': 1 }, { 'name': 'Mary', 'id': 2 }, { 'name': 'Jane', 'id': 5 }, ], ], [ [ createAsyncGeneratorFixture([1, 2, 3, 4, 5]), createAsyncGeneratorFixture([2, 3, 4, 5, 6, 7]), createAsyncGeneratorFixture(['3', 4, 5, 6, 7, 8, 9]), ], (iterables: Array<AsyncIterable<string | number>>): Promise<Array<string | number>> => AsyncStream.of(iterables.shift()!) .intersectionWith(...iterables) .toArray(), [4, 5], ], [ [ createAsyncGeneratorFixture([1, 2, 3, 4, 5, 6]), createAsyncGeneratorFixture([3, 4, 5, 6, 7, 8]), createAsyncGeneratorFixture([5, 6, 7, 8, 9, 10]), ], (iterables: Array<AsyncIterable<number>>): Promise<Array<number>> => AsyncStream.of(iterables.shift()!) .symmetricDifferenceWith(...iterables) .toArray(), [1, 2, 9, 10], ], [ [ createAsyncGeneratorFixture([1, 2, 3, 4, 5]), createAsyncGeneratorFixture([2, 3, 4, 5, 6]), createAsyncGeneratorFixture([3, 4, 5, 6, 7]), ], (iterables: Array<AsyncIterable<number>>): Promise<Array<number>> => AsyncStream.of(iterables.shift()!) .unionWith(...iterables) .toArray(), [1, 2, 3, 4, 5, 6, 7], ], [ [ createAsyncGeneratorFixture([1, 2, 3]), createAsyncGeneratorFixture([11, 22]), createAsyncGeneratorFixture(['a', 'b']), ], (iterables: Array<AsyncIterable<number | string>>): Promise<Array<Array<number | string>>> => AsyncStream.of(iterables.shift()!) .cartesianProductWith(...iterables) .toArray(), [ [1, 11, 'a'], [1, 11, 'b'], [1, 22, 'a'], [1, 22, 'b'], [2, 11, 'a'], [2, 11, 'b'], [2, 22, 'a'], [2, 22, 'b'], [3, 11, 'a'], [3, 11, 'b'], [3, 22, 'a'], [3, 22, 'b'], ], ], ]; } function dataProviderForPartialIntersection(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, number, (minIntersectionCount: number, data: any) => Promise<Array<any>>, Array<unknown> ]> { return [ [ [ createAsyncGeneratorFixture([1, 2]), createAsyncIterableFixture([2, 3, 4]), [2, 3, 4, 5, 6], ], 3, (minIntersectionCount: number, iterables: Array<Iterable<number> | AsyncIterable<number>>): Promise<Array<number>> => AsyncStream.of(iterables.shift()!) .partialIntersectionWith(minIntersectionCount, ...iterables) .toArray(), [2], ], [ [ createAsyncIterableFixture([1, 2, 3, 4, 5, 6, 7, 8, 9]), createAsyncGeneratorFixture(['1', '2', 3, 4, 5, 6, 7, '8', '9']), [1, 3, 5, 7, 9, 11], ], 2, (minIntersectionCount: number, iterables: Array<Iterable<number> | AsyncIterable<number>>): Promise<Array<number>> => AsyncStream.of(iterables.shift()!) .partialIntersectionWith(minIntersectionCount, ...iterables) .toArray(), [1, 3, 4, 5, 6, 7, 9], ], ]; } describe.each([ ...dataProviderForSingle(), ])( "AsyncStream Single Test", (input, streamFactory, expected) => { it("", async () => { // Given const result = await streamFactory(input); // Then expect(result).toEqual(expected); }); } ); function dataProviderForSingle(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (data: any) => Promise<Array<any>>, Array<any> ]> { return [ [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .filter((value) => value > 0) .compress(createAsyncGeneratorFixture([0, 1, 1])) .toArray(), [2, 3], ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .dropWhile((value) => Math.abs(value) < 3) .compress(createAsyncGeneratorFixture([0, 1])) .toArray(), [-3], ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .takeWhile((value) => Math.abs(value) < 3) .toArray(), [1, -1, 2, -2], ], [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: AsyncIterable<number>): Promise<Array<[number, number]>> => AsyncStream.of(iterable) .enumerate() .toArray(), [[0, 1], [1, 2], [2, 3]], ], [ createAsyncGeneratorFixture([['a', 1], ['b', 2], ['c', 3]]), (iterable: AsyncIterable<[string, number]>): Promise<Array<string>> => AsyncStream.of(iterable) .keys() .toArray(), ['a', 'b', 'c'], ], [ createAsyncGeneratorFixture([['a', 1], ['b', 2], ['c', 3]]), (iterable: AsyncIterable<[string, number]>): Promise<Array<number>> => AsyncStream.of(iterable) .values() .toArray(), [1, 2, 3], ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .filter((value) => value > 0) .toArray(), [1, 2, 3], ], [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .map((item) => item + 1) .toArray(), [2, 3, 4], ], [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: AsyncIterable<number>): Promise<Array<unknown>> => AsyncStream.of(iterable) .flatMap((item) => single.repeatAsync(item, (item as number) + 1)) .toArray(), [1, 1, 2, 2, 2, 3, 3, 3, 3], ], [ createAsyncGeneratorFixture([1, 2, [3, 4], [5, 6], 7, 8]), (iterable: AsyncIterable<unknown>): Promise<Array<unknown>> => AsyncStream.of(iterable) .flatMap(async (item) => { await asyncTimeout(1); return item; }) .toArray(), [1, 2, 3, 4, 5, 6, 7, 8], ], [ createAsyncGeneratorFixture([1, 2, [3, 4], [5, 6], 7, 8]), (iterable: AsyncIterable<unknown>): Promise<Array<unknown>> => AsyncStream.of(iterable) .flatten() .toArray(), [1, 2, 3, 4, 5, 6, 7, 8], ], [ createAsyncGeneratorFixture([-3, -2, -1, 0, 1, 2, 3, 4, 5]), (iterable: AsyncIterable<number>): Promise<Array<number[]>> => AsyncStream.of(iterable) .filter((value) => value > 0) .chunkwise(2) .toArray(), [[1, 2], [3, 4], [5]], ], [ createAsyncGeneratorFixture([-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), (iterable: AsyncIterable<number>): Promise<Array<number[]>> => AsyncStream.of(iterable) .filter((value) => value >= 0) .chunkwiseOverlap(3, 1) .toArray(), [[0, 1, 2], [2, 3, 4], [4, 5, 6], [6, 7, 8], [8, 9]], ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>): Promise<Array<[number, number]>> => AsyncStream.of(iterable) .filter((value) => value > 0) .pairwise() .toArray(), [[1, 2], [2, 3]], ], [ createAsyncGeneratorFixture([1, 2, 3, 4, 5, 6, 7]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .limit(5) .toArray(), [1, 2, 3, 4, 5], ], [ createAsyncGeneratorFixture([]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .limit(0) .chainWith(createAsyncGeneratorFixture([1, 2, 3])) .toArray(), [1, 2, 3], ], [ createAsyncGeneratorFixture([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .skip(3, 2) .toArray(), [1, 2, 6, 7, 8, 9, 10], ], [ createAsyncGeneratorFixture([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .slice(2, 4) .toArray(), [3, 4, 5, 6], ], [ createAsyncGeneratorFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>): Promise<Array<[string, number[]]>> => AsyncStream.of(iterable) .filter((value) => value % 2 !== 0) .groupBy((item) => item > 0 ? 'pos' : 'neg', undefined) .toArray(), [['pos', [1, 3]], ['neg', [-1, -3]]], ], [ createAsyncGeneratorFixture([2, 3, 1, 2, -3, -2, 5, 7, 3]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .sort((lhs, rhs) => lhs - rhs) .toArray(), [-3, -2, 1, 2, 2, 3, 3, 5, 7], ], ]; } describe.each([ ...dataProviderForSummaryTrue(), ])( "AsyncStream Summary Test True", (input, streamFactory) => { it("", async () => { // Given const result = await streamFactory(input); // Then expect(result).toBeTruthy(); }); } ); describe.each([ ...dataProviderForSummaryFalse(), ])( "AsyncStream Summary Test False", (input, streamFactory) => { it("", async () => { // Given const result = await streamFactory(input); // Then expect(result).toBeFalsy(); }); } ); function dataProviderForSummaryTrue(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (data: any) => Promise<boolean> ]> { return [ [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .allMatch((x) => x > 0), ], [ createAsyncIterableFixture([1, 2, 3, 4, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .allUnique(), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .anyMatch(async (x) => { await asyncTimeout(1); return x === 3; }), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .anyMatch((x) => x > 0), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .exactlyN(3), ], [ createAsyncIterableFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .filter((item) => item > 0) .runningTotal() .isSorted(), ], [ createAsyncIterableFixture([5, -1, 4, -2, 3, -3, 2, -4, 1, -5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .filter((item) => item > 0) .isReversed(), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .noneMatch((x) => x === 9), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .runningTotal() .sameWith([1, 4, 9]), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .runningTotal() .sameCountWith([11, 22, 33]), ], ]; } function dataProviderForSummaryFalse(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (data: any) => Promise<boolean> ]> { return [ [ createAsyncIterableFixture([1, 3, -5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .allMatch(async (x) => { await asyncTimeout(1); return x > 0; }), ], [ createAsyncIterableFixture([1, 2, 1, 3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .allUnique(), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .anyMatch((x) => x > 10), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .exactlyN(4), ], [ createAsyncIterableFixture([1, -1, 2, -2, 3, -3]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .runningTotal() .isSorted(), ], [ createAsyncIterableFixture([5, -1, 4, -2, 3, -3, 2, -4, 1, -5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .isReversed(), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .noneMatch(async (x) => { await asyncTimeout(1); return x === 3; }), ], [ createAsyncIterableFixture([1, 3, 5]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .runningTotal() .sameWith([1, 4, 10]), ], [ createAsyncIterableFixture([]), (iterable: AsyncIterable<number>) => AsyncStream.of(iterable) .sameCountWith([1, 2, 3]), ], ]; } describe.each([ ...dataProviderForTransform(), ])( "AsyncStream Transform Test", (input, streamFactory, expected) => { it("", async () => { // Given const result = await streamFactory(input); // Then expect(result).toEqual(expected); }); } ); describe.each([ ...dataProviderForTee(), ])( "AsyncStream Transform Tee Test", (input, count, extraOperations, expected) => { it("", async () => { // Given const inputStream = AsyncStream.of(input); const result = []; // When const streams = inputStream.tee(count); for (const [stream, func] of multi.zipEqual(streams, extraOperations)) { result.push(await func(stream).toArray()); } // Then expect(streams.length).toEqual(count); expect(result).toEqual(expected); }); } ); function dataProviderForTransform(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, (data: any) => Promise<any>, any ]> { return [ [ createAsyncGeneratorFixture([1, 2, 3]), (iterable: AsyncIterable<number>): Promise<Array<number>> => AsyncStream.of(iterable) .toArray(), [1, 2, 3], ], [ createAsyncGeneratorFixture([1, 1, 2, 2, 3, 3]), (iterable: AsyncIterable<number>): Promise<Set<number>> => AsyncStream.of(iterable) .toSet(), new Set([1, 2, 3]), ], [ createAsyncGeneratorFixture([['a', 1], ['b', 2], ['c', 3]]), (iterable: AsyncIterable<[string, number]>): Promise<Map<string, number>> => AsyncStream.of(iterable) .toMap(), new Map([['a', 1], ['b', 2], ['c', 3]]), ], ]; } function dataProviderForTee(): Array<[ AsyncIterable<any> | AsyncIterator<any> | Iterable<any> | Iterator<any>, number, Array<(stream: AsyncStream<any>) => AsyncStream<any>>, Array<any> ]> { return [ [ createIterableFixture([1, 2, 3]), 3, [ (stream: AsyncStream<number>) => stream, (stream: AsyncStream<number>) => stream.map((datum) => datum * 2), (stream: AsyncStream<number>) => stream.map((datum) => datum ** 3), ], [ [1, 2, 3], [2, 4, 6], [1, 8, 27], ], ], [ new Set([1, 2, 3]), 3, [ (stream: AsyncStream<number>) => stream, (stream: AsyncStream<number>) => stream.map((datum) => datum * 2), (stream: AsyncStream<number>) => stream .map((datum) => datum ** 3) .filter((datum) => datum < 10), ], [ [1, 2, 3], [2, 4, 6], [1, 8], ], ], ]; }