Infrastructure build to support third-party app integrations
This commit is contained in:
82
backend/tests/streams.test.ts
Normal file
82
backend/tests/streams.test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { Readable, type Transform } from 'node:stream';
|
||||
import { pipeline } from 'node:stream/promises';
|
||||
import { batch, jsonArray } from '../lib/streams.js';
|
||||
|
||||
const collect = async <T>(source: Readable, transform: Transform): Promise<T[]> => {
|
||||
const out: T[] = [];
|
||||
await pipeline(source, transform, async (results: AsyncIterable<T>) => {
|
||||
for await (const item of results) out.push(item);
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
describe('batch', () => {
|
||||
it('should group items into fixed-size arrays', async () => {
|
||||
const source = Readable.from([1, 2, 3, 4], { objectMode: true });
|
||||
|
||||
const result = await collect<number[]>(source, batch<number>(2));
|
||||
|
||||
expect(result).toEqual([[1, 2], [3, 4]]);
|
||||
});
|
||||
|
||||
it('should flush a partial trailing batch', async () => {
|
||||
const source = Readable.from([1, 2, 3, 4, 5], { objectMode: true });
|
||||
|
||||
const result = await collect<number[]>(source, batch<number>(2));
|
||||
|
||||
expect(result).toEqual([[1, 2], [3, 4], [5]]);
|
||||
});
|
||||
|
||||
it('should emit nothing for an empty source', async () => {
|
||||
const source = Readable.from([], { objectMode: true });
|
||||
|
||||
const result = await collect<number[]>(source, batch<number>(3));
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should reject a non-positive size', () => {
|
||||
expect(() => batch(0)).toThrow(TypeError);
|
||||
expect(() => batch(1.5)).toThrow(TypeError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('jsonArray', () => {
|
||||
const serialize = async (items: unknown[]): Promise<string> => {
|
||||
const chunks = await collect<string>(
|
||||
Readable.from(items, { objectMode: true }),
|
||||
jsonArray()
|
||||
);
|
||||
return chunks.map(String).join('');
|
||||
};
|
||||
|
||||
it('should serialize objects into a JSON array', async () => {
|
||||
const items = [{ id: 'a' }, { id: 'b' }];
|
||||
|
||||
const output = await serialize(items);
|
||||
|
||||
expect(output).toBe('[{"id":"a"},{"id":"b"}]');
|
||||
expect(JSON.parse(output)).toEqual(items);
|
||||
});
|
||||
|
||||
it('should emit an empty array when the source yields nothing', async () => {
|
||||
const output = await serialize([]);
|
||||
|
||||
expect(output).toBe('[]');
|
||||
expect(JSON.parse(output)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should emit a valid single-element array', async () => {
|
||||
const output = await serialize([{ id: 'only' }]);
|
||||
|
||||
expect(JSON.parse(output)).toEqual([{ id: 'only' }]);
|
||||
});
|
||||
|
||||
it('should propagate serialization errors', async () => {
|
||||
const circular: Record<string, unknown> = {};
|
||||
circular.self = circular;
|
||||
|
||||
await expect(serialize([circular])).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user