Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: https://github.com/nodejs/node/pull/63489 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: René <contact.9a5d6388@renegade334.me.uk> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: James M Snell <jasnell@gmail.com>
218 lines
6.1 KiB
JavaScript
218 lines
6.1 KiB
JavaScript
// Flags: --experimental-stream-iter
|
|
'use strict';
|
|
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const {
|
|
from,
|
|
fromSync,
|
|
bytes,
|
|
bytesSync,
|
|
text,
|
|
textSync,
|
|
arrayBuffer,
|
|
arrayBufferSync,
|
|
array,
|
|
arraySync,
|
|
} = require('stream/iter');
|
|
|
|
// =============================================================================
|
|
// bytesSync / bytes
|
|
// =============================================================================
|
|
|
|
async function testBytesSyncBasic() {
|
|
const data = bytesSync(fromSync('hello'));
|
|
assert.deepStrictEqual(data, new TextEncoder().encode('hello'));
|
|
}
|
|
|
|
async function testBytesSyncLimit() {
|
|
assert.throws(
|
|
() => bytesSync(fromSync('hello world'), { limit: 3 }),
|
|
{ name: 'RangeError' },
|
|
);
|
|
}
|
|
|
|
async function testBytesAsync() {
|
|
const data = await bytes(from('hello-async'));
|
|
assert.deepStrictEqual(data, new TextEncoder().encode('hello-async'));
|
|
}
|
|
|
|
async function testBytesAsyncLimit() {
|
|
await assert.rejects(
|
|
() => bytes(from('hello world'), { limit: 3 }),
|
|
{ name: 'RangeError' },
|
|
);
|
|
}
|
|
|
|
async function testBytesAsyncAbort() {
|
|
await assert.rejects(
|
|
() => bytes(from('data'), { signal: AbortSignal.abort() }),
|
|
{ name: 'AbortError' },
|
|
);
|
|
}
|
|
|
|
async function testBytesEmpty() {
|
|
const data = await bytes(from([]));
|
|
assert.ok(data instanceof Uint8Array);
|
|
assert.strictEqual(data.byteLength, 0);
|
|
}
|
|
|
|
// =============================================================================
|
|
// arrayBufferSync / arrayBuffer
|
|
// =============================================================================
|
|
|
|
async function testArrayBufferSyncBasic() {
|
|
const ab = arrayBufferSync(fromSync(new Uint8Array([1, 2, 3])));
|
|
assert.ok(ab instanceof ArrayBuffer);
|
|
assert.strictEqual(ab.byteLength, 3);
|
|
const view = new Uint8Array(ab);
|
|
assert.deepStrictEqual(view, new Uint8Array([1, 2, 3]));
|
|
}
|
|
|
|
async function testArrayBufferAsync() {
|
|
const ab = await arrayBuffer(from(new Uint8Array([10, 20, 30])));
|
|
assert.ok(ab instanceof ArrayBuffer);
|
|
assert.strictEqual(ab.byteLength, 3);
|
|
const view = new Uint8Array(ab);
|
|
assert.deepStrictEqual(view, new Uint8Array([10, 20, 30]));
|
|
}
|
|
|
|
// =============================================================================
|
|
// arraySync / array
|
|
// =============================================================================
|
|
|
|
async function testArraySyncBasic() {
|
|
function* gen() {
|
|
yield new Uint8Array([1]);
|
|
yield new Uint8Array([2]);
|
|
yield new Uint8Array([3]);
|
|
}
|
|
const chunks = arraySync(fromSync(gen()));
|
|
assert.strictEqual(chunks.length, 3);
|
|
assert.deepStrictEqual(chunks[0], new Uint8Array([1]));
|
|
assert.deepStrictEqual(chunks[1], new Uint8Array([2]));
|
|
assert.deepStrictEqual(chunks[2], new Uint8Array([3]));
|
|
}
|
|
|
|
async function testArraySyncLimit() {
|
|
function* gen() {
|
|
yield new Uint8Array(100);
|
|
yield new Uint8Array(100);
|
|
}
|
|
const source = fromSync(gen());
|
|
assert.throws(
|
|
() => arraySync(source, { limit: 50 }),
|
|
{ name: 'RangeError' },
|
|
);
|
|
}
|
|
|
|
async function testArrayAsync() {
|
|
async function* gen() {
|
|
yield [new Uint8Array([1])];
|
|
yield [new Uint8Array([2])];
|
|
}
|
|
const chunks = await array(gen());
|
|
assert.strictEqual(chunks.length, 2);
|
|
assert.deepStrictEqual(chunks[0], new Uint8Array([1]));
|
|
assert.deepStrictEqual(chunks[1], new Uint8Array([2]));
|
|
}
|
|
|
|
async function testArrayAsyncLimit() {
|
|
async function* gen() {
|
|
yield [new Uint8Array(100)];
|
|
yield [new Uint8Array(100)];
|
|
}
|
|
await assert.rejects(
|
|
() => array(gen(), { limit: 50 }),
|
|
{ name: 'RangeError' },
|
|
);
|
|
}
|
|
|
|
// =============================================================================
|
|
// Non-array batch tolerance
|
|
// =============================================================================
|
|
|
|
// Regression test: consumers should tolerate sources that yield raw
|
|
// Uint8Array or string values instead of Uint8Array[] batches.
|
|
async function testConsumersNonArrayBatch() {
|
|
const encoder = new TextEncoder();
|
|
|
|
// Source yields raw Uint8Array, not wrapped in an array
|
|
async function* rawSource() {
|
|
yield encoder.encode('hello');
|
|
yield encoder.encode(' world');
|
|
}
|
|
const result = await text(rawSource());
|
|
assert.strictEqual(result, 'hello world');
|
|
|
|
// bytes() with raw chunks
|
|
async function* rawSource2() {
|
|
yield encoder.encode('ab');
|
|
}
|
|
const data = await bytes(rawSource2());
|
|
assert.strictEqual(data.length, 2);
|
|
assert.strictEqual(data[0], 97); // 'a'
|
|
assert.strictEqual(data[1], 98); // 'b'
|
|
|
|
// array() with raw chunks
|
|
async function* rawSource3() {
|
|
yield encoder.encode('x');
|
|
yield encoder.encode('y');
|
|
}
|
|
const arr = await array(rawSource3());
|
|
assert.strictEqual(arr.length, 2);
|
|
}
|
|
|
|
async function testConsumersNonArrayBatchSync() {
|
|
const encoder = new TextEncoder();
|
|
|
|
function* rawSyncSource() {
|
|
yield encoder.encode('sync');
|
|
yield encoder.encode('data');
|
|
}
|
|
const result = textSync(rawSyncSource());
|
|
assert.strictEqual(result, 'syncdata');
|
|
|
|
const data = bytesSync(rawSyncSource());
|
|
assert.strictEqual(data.length, 8);
|
|
|
|
const arr = arraySync(rawSyncSource());
|
|
assert.strictEqual(arr.length, 2);
|
|
}
|
|
|
|
// Consumers accept string sources directly (normalized via from/fromSync)
|
|
async function testBytesStringSource() {
|
|
const result = await bytes('hello-bytes');
|
|
assert.strictEqual(new TextDecoder().decode(result), 'hello-bytes');
|
|
}
|
|
|
|
function testBytesSyncStringSource() {
|
|
const result = bytesSync('hello-sync');
|
|
assert.strictEqual(new TextDecoder().decode(result), 'hello-sync');
|
|
}
|
|
|
|
async function testTextStringSource() {
|
|
const { text } = require('stream/iter');
|
|
const result = await text('direct-string');
|
|
assert.strictEqual(result, 'direct-string');
|
|
}
|
|
|
|
Promise.all([
|
|
testBytesSyncBasic(),
|
|
testBytesSyncLimit(),
|
|
testBytesAsync(),
|
|
testBytesAsyncLimit(),
|
|
testBytesAsyncAbort(),
|
|
testBytesEmpty(),
|
|
testArrayBufferSyncBasic(),
|
|
testArrayBufferAsync(),
|
|
testArraySyncBasic(),
|
|
testArraySyncLimit(),
|
|
testArrayAsync(),
|
|
testArrayAsyncLimit(),
|
|
testConsumersNonArrayBatch(),
|
|
testConsumersNonArrayBatchSync(),
|
|
testBytesStringSource(),
|
|
testBytesSyncStringSource(),
|
|
testTextStringSource(),
|
|
]).then(common.mustCall());
|