feat(smartduplex): improve backpressure handling and web/node stream interoperability
This commit is contained in:
152
test/test.nodewebhelpers.ts
Normal file
152
test/test.nodewebhelpers.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { expect, tap } from '@push.rocks/tapbundle';
|
||||
import * as fs from 'fs';
|
||||
import * as stream from 'stream';
|
||||
import { nodewebhelpers } from '../ts/index.js';
|
||||
|
||||
// =============================================
|
||||
// createWebReadableStreamFromFile
|
||||
// =============================================
|
||||
|
||||
tap.test('nodewebhelpers: createWebReadableStreamFromFile should read a file', async () => {
|
||||
const webStream = nodewebhelpers.createWebReadableStreamFromFile('./test/assets/readabletext.txt');
|
||||
const reader = webStream.getReader();
|
||||
|
||||
const chunks: Uint8Array[] = [];
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) break;
|
||||
chunks.push(value);
|
||||
}
|
||||
|
||||
expect(chunks.length).toBeGreaterThan(0);
|
||||
const content = Buffer.concat(chunks).toString();
|
||||
expect(content.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
// =============================================
|
||||
// convertNodeReadableToWebReadable
|
||||
// =============================================
|
||||
|
||||
tap.test('nodewebhelpers: convertNodeReadableToWebReadable should convert', async () => {
|
||||
const nodeReadable = fs.createReadStream('./test/assets/readabletext.txt');
|
||||
const webReadable = nodewebhelpers.convertNodeReadableToWebReadable(nodeReadable);
|
||||
|
||||
const reader = webReadable.getReader();
|
||||
const chunks: Uint8Array[] = [];
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) break;
|
||||
chunks.push(value);
|
||||
}
|
||||
|
||||
expect(chunks.length).toBeGreaterThan(0);
|
||||
const content = Buffer.concat(chunks).toString();
|
||||
expect(content.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
// =============================================
|
||||
// convertWebReadableToNodeReadable
|
||||
// =============================================
|
||||
|
||||
tap.test('nodewebhelpers: convertWebReadableToNodeReadable should convert', async (tools) => {
|
||||
const data = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"
|
||||
const webReadable = new ReadableStream<Uint8Array>({
|
||||
start(controller) {
|
||||
controller.enqueue(data);
|
||||
controller.close();
|
||||
},
|
||||
});
|
||||
|
||||
const nodeReadable = nodewebhelpers.convertWebReadableToNodeReadable(webReadable);
|
||||
|
||||
const chunks: Buffer[] = [];
|
||||
const done = tools.defer();
|
||||
|
||||
nodeReadable.on('data', (chunk: Buffer) => {
|
||||
chunks.push(chunk);
|
||||
});
|
||||
|
||||
nodeReadable.on('end', () => {
|
||||
const result = Buffer.concat(chunks).toString();
|
||||
expect(result).toEqual('Hello');
|
||||
done.resolve();
|
||||
});
|
||||
|
||||
await done.promise;
|
||||
});
|
||||
|
||||
// =============================================
|
||||
// convertNodeWritableToWebWritable
|
||||
// =============================================
|
||||
|
||||
tap.test('nodewebhelpers: convertNodeWritableToWebWritable should convert', async () => {
|
||||
const chunks: Buffer[] = [];
|
||||
const nodeWritable = new stream.Writable({
|
||||
write(chunk, encoding, callback) {
|
||||
chunks.push(chunk);
|
||||
callback();
|
||||
},
|
||||
});
|
||||
|
||||
const webWritable = nodewebhelpers.convertNodeWritableToWebWritable(nodeWritable);
|
||||
const writer = webWritable.getWriter();
|
||||
|
||||
await writer.write(new Uint8Array([65, 66, 67])); // "ABC"
|
||||
await writer.close();
|
||||
|
||||
const result = Buffer.concat(chunks).toString();
|
||||
expect(result).toEqual('ABC');
|
||||
});
|
||||
|
||||
// =============================================
|
||||
// convertWebWritableToNodeWritable
|
||||
// =============================================
|
||||
|
||||
tap.test('nodewebhelpers: convertWebWritableToNodeWritable should convert', async (tools) => {
|
||||
const chunks: Uint8Array[] = [];
|
||||
|
||||
const webWritable = new WritableStream<Uint8Array>({
|
||||
write(chunk) {
|
||||
chunks.push(chunk);
|
||||
},
|
||||
});
|
||||
|
||||
const nodeWritable = nodewebhelpers.convertWebWritableToNodeWritable(webWritable);
|
||||
|
||||
const done = tools.defer();
|
||||
nodeWritable.write(Buffer.from('Hello'), (err) => {
|
||||
expect(err).toBeFalsy();
|
||||
nodeWritable.end(() => {
|
||||
expect(chunks.length).toBeGreaterThan(0);
|
||||
done.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
await done.promise;
|
||||
});
|
||||
|
||||
// =============================================
|
||||
// Round-trip: Node → Web → Node
|
||||
// =============================================
|
||||
|
||||
tap.test('nodewebhelpers: round-trip Node → Web → Node readable', async (tools) => {
|
||||
const nodeReadable = fs.createReadStream('./test/assets/readabletext.txt');
|
||||
const webReadable = nodewebhelpers.convertNodeReadableToWebReadable(nodeReadable);
|
||||
const nodeReadable2 = nodewebhelpers.convertWebReadableToNodeReadable(webReadable);
|
||||
|
||||
const chunks: Buffer[] = [];
|
||||
const done = tools.defer();
|
||||
|
||||
nodeReadable2.on('data', (chunk: Buffer) => {
|
||||
chunks.push(chunk);
|
||||
});
|
||||
|
||||
nodeReadable2.on('end', () => {
|
||||
expect(chunks.length).toBeGreaterThan(0);
|
||||
done.resolve();
|
||||
});
|
||||
|
||||
await done.promise;
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
Reference in New Issue
Block a user