mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 18:25:13 +08:00
Replaces the `for await (const _ of source) {}` discard idiom with
dump(), which says what it does and does not need an eslint-disable
for the unused loop variable. The eslint-disable directives and
comments that become redundant are removed with it.
Only files that already declare --experimental-stream-iter are
converted, so no test gains an experimental flag it did not already
opt into. Files still using the old idiom are left as they are;
converting them would change what those tests run under and belongs
in a separate discussion.
Loops that break early are left alone: those cancel the source rather
than reading it to completion, which is not what dump() does.
Assisted-by: Claude Opus 5
Signed-off-by: Ethan Arrowood <ethan@arrowood.dev>
PR-URL: https://github.com/nodejs/node/pull/65598
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
707 lines
20 KiB
JavaScript
707 lines
20 KiB
JavaScript
// Flags: --experimental-stream-iter
|
|
'use strict';
|
|
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const { dump, ondrain, push, text } = require('stream/iter');
|
|
const { setImmediate } = require('timers/promises');
|
|
|
|
async function testOndrain() {
|
|
const { writer } = push({ budget: 16384 });
|
|
|
|
// With space available, ondrain resolves immediately
|
|
const drainResult = ondrain(writer);
|
|
assert.ok(drainResult instanceof Promise);
|
|
const result = await drainResult;
|
|
assert.strictEqual(result, true);
|
|
|
|
// After close, ondrain returns null
|
|
writer.end();
|
|
assert.strictEqual(ondrain(writer), null);
|
|
}
|
|
|
|
async function testDropPoliciesReportPhysicalCapacity() {
|
|
const chunk = new Uint8Array(16384);
|
|
|
|
for (const backpressure of ['drop-oldest', 'drop-newest']) {
|
|
const { writer, readable } = push({
|
|
budget: chunk.byteLength,
|
|
backpressure,
|
|
});
|
|
const iterator = readable[Symbol.asyncIterator]();
|
|
|
|
assert.strictEqual(writer.writeSync(chunk), true);
|
|
assert.strictEqual(writer.canWrite, false);
|
|
|
|
let drained = false;
|
|
const drain = ondrain(writer);
|
|
drain.then(common.mustCall(() => { drained = true; }));
|
|
|
|
// Drop policies still accept writes despite having no physical capacity.
|
|
assert.strictEqual(writer.writeSync(chunk), true);
|
|
assert.strictEqual(writer.canWrite, false);
|
|
await setImmediate();
|
|
assert.strictEqual(drained, false);
|
|
|
|
assert.strictEqual((await iterator.next()).done, false);
|
|
assert.strictEqual(await drain, true);
|
|
assert.strictEqual(writer.canWrite, true);
|
|
await iterator.return();
|
|
}
|
|
}
|
|
|
|
async function testOndrainNonDrainable() {
|
|
// Non-drainable objects return null
|
|
assert.strictEqual(ondrain(null), null);
|
|
assert.strictEqual(ondrain({}), null);
|
|
assert.strictEqual(ondrain('string'), null);
|
|
}
|
|
|
|
async function testOndrainProtocolErrorPropagates() {
|
|
const badDrainable = {
|
|
[Symbol.for('Stream.drainableProtocol')]() {
|
|
throw new Error('protocol error');
|
|
},
|
|
};
|
|
assert.throws(
|
|
() => ondrain(badDrainable),
|
|
{ message: 'protocol error' },
|
|
);
|
|
}
|
|
|
|
async function testWriteWithSignalRejects() {
|
|
const kChunk = new Uint8Array(16384);
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
|
|
// Fill the buffer so write will block
|
|
writer.writeSync(kChunk);
|
|
|
|
const ac = new AbortController();
|
|
const writePromise = writer.write(kChunk, { signal: ac.signal });
|
|
|
|
// Signal fires while write is pending
|
|
ac.abort();
|
|
|
|
await assert.rejects(writePromise, { name: 'AbortError' });
|
|
|
|
// Clean up
|
|
const end = writer.end();
|
|
await text(readable);
|
|
await end;
|
|
}
|
|
|
|
async function testWriteWithPreAbortedSignal() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
|
|
// Pre-aborted signal should reject immediately
|
|
await assert.rejects(
|
|
writer.write('data', { signal: AbortSignal.abort() }),
|
|
{ name: 'AbortError' },
|
|
);
|
|
|
|
// Writer should still be usable for other writes
|
|
writer.write('ok');
|
|
const end = writer.end();
|
|
const data = await text(readable);
|
|
assert.strictEqual(data, 'ok');
|
|
await end;
|
|
}
|
|
|
|
async function testCancelledWriteRemovedFromQueue() {
|
|
const kChunk = new Uint8Array(16384);
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
|
|
// Fill the buffer
|
|
writer.writeSync(kChunk);
|
|
|
|
const ac = new AbortController();
|
|
// This write should be queued since buffer is full
|
|
const cancelledWrite = writer.write(kChunk, { signal: ac.signal });
|
|
|
|
// Cancel it
|
|
ac.abort();
|
|
await cancelledWrite.catch(() => {});
|
|
|
|
// Drain to make room for the replacement write
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
await iter.next();
|
|
|
|
// The cancelled write should NOT occupy a pending slot.
|
|
// A new write should succeed now that the buffer has room.
|
|
await writer.write(kChunk);
|
|
const end = writer.end();
|
|
|
|
const result = await iter.next();
|
|
assert.ok(!result.done);
|
|
let totalBytes = 0;
|
|
for (const chunk of result.value) {
|
|
totalBytes += chunk.byteLength;
|
|
}
|
|
assert.strictEqual(totalBytes, 16384);
|
|
assert.strictEqual((await iter.next()).done, true);
|
|
await end;
|
|
}
|
|
|
|
async function testOndrainResolvesFalseOnConsumerBreak() {
|
|
const kChunk = new Uint8Array(16384);
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
|
|
// Fill the buffer so canWrite = false
|
|
writer.writeSync(kChunk);
|
|
|
|
// Also queue a pending write so that reading one chunk
|
|
// doesn't clear backpressure (the pending write refills the buffer)
|
|
const pendingWrite = writer.write(kChunk);
|
|
|
|
// Start a drain wait - still at capacity
|
|
const drainPromise = ondrain(writer);
|
|
|
|
// Consumer returns without draining enough to clear backpressure
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
await iter.return();
|
|
|
|
// Ondrain should resolve false since the consumer terminated
|
|
const result = await drainPromise;
|
|
assert.strictEqual(result, false);
|
|
await pendingWrite.catch(() => {}); // Ignore write rejection
|
|
}
|
|
|
|
async function testOndrainRejectsOnConsumerThrow() {
|
|
const kChunk = new Uint8Array(16384);
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
|
|
// Fill the buffer so canWrite = false
|
|
writer.writeSync(kChunk);
|
|
|
|
// Also queue a pending write so that reading one chunk
|
|
// doesn't clear backpressure (the pending write refills the buffer)
|
|
const pendingWrite = writer.write(kChunk);
|
|
|
|
// Start a drain wait - still at capacity
|
|
const drainPromise = ondrain(writer);
|
|
|
|
// Consumer throws via iterator.throw() before draining enough
|
|
// to clear backpressure. The drain should reject.
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const err = new Error('consumer error');
|
|
const drainRejects = assert.rejects(drainPromise, (e) => e === err);
|
|
const pendingWriteRejects = pendingWrite.catch(() => {});
|
|
await assert.rejects(
|
|
() => iter.throw(err),
|
|
(e) => e === err,
|
|
);
|
|
|
|
await drainRejects;
|
|
await pendingWriteRejects; // Ignore write rejection
|
|
}
|
|
|
|
async function testWritev() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
const enc = new TextEncoder();
|
|
writer.writev([enc.encode('hel'), enc.encode('lo')]);
|
|
writer.endSync();
|
|
const result = await text(readable);
|
|
assert.strictEqual(result, 'hello');
|
|
}
|
|
|
|
async function testWritevSync() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
const enc = new TextEncoder();
|
|
assert.strictEqual(writer.writevSync([enc.encode('hel'), enc.encode('lo')]), true);
|
|
writer.endSync();
|
|
const result = await text(readable);
|
|
assert.strictEqual(result, 'hello');
|
|
}
|
|
|
|
async function testWritevSyncInvalidChunkDoesNotQueue() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
|
|
assert.throws(
|
|
() => writer.writevSync([Symbol('invalid')]),
|
|
{ code: 'ERR_INVALID_ARG_TYPE' },
|
|
);
|
|
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const next = iter.next();
|
|
const result = await Promise.race([
|
|
next.then(() => 'resolved'),
|
|
setImmediate('pending'),
|
|
]);
|
|
assert.strictEqual(result, 'pending');
|
|
|
|
writer.endSync();
|
|
const end = await next;
|
|
assert.strictEqual(end.value, undefined);
|
|
assert.strictEqual(end.done, true);
|
|
}
|
|
|
|
async function testWritevMixedTypes() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
// Mix strings and Uint8Arrays
|
|
writer.writev(['hel', new TextEncoder().encode('lo')]);
|
|
writer.endSync();
|
|
const result = await text(readable);
|
|
assert.strictEqual(result, 'hello');
|
|
}
|
|
|
|
async function testWriteAfterEnd() {
|
|
const { writer } = push();
|
|
writer.endSync();
|
|
// Sync write after end returns false
|
|
assert.strictEqual(writer.writeSync('fail'), false);
|
|
// Async write after end rejects
|
|
await assert.rejects(
|
|
() => writer.write('fail'),
|
|
{ code: 'ERR_INVALID_STATE' },
|
|
);
|
|
}
|
|
|
|
async function testWriteAfterFail() {
|
|
const { writer } = push();
|
|
writer.fail(new Error('failed'));
|
|
// Sync write after fail returns false
|
|
assert.strictEqual(writer.writeSync('fail'), false);
|
|
// Async write after fail rejects with the stored error
|
|
await assert.rejects(
|
|
() => writer.write('fail'),
|
|
{ message: 'failed' },
|
|
);
|
|
}
|
|
|
|
async function testFail() {
|
|
const { writer, readable } = push();
|
|
writer.writeSync('hello');
|
|
writer.fail(new Error('boom'));
|
|
// Second fail is a no-op (already errored)
|
|
writer.fail(new Error('boom2'));
|
|
await assert.rejects(async () => {
|
|
await dump(readable);
|
|
}, { message: 'boom' });
|
|
}
|
|
|
|
async function testEndAsyncReturnValue() {
|
|
const { writer, readable } = push();
|
|
writer.writeSync('hello');
|
|
// Start consuming concurrently (end() waits for drain)
|
|
const consume = (async () => {
|
|
await dump(readable);
|
|
})();
|
|
const total = await writer.end();
|
|
assert.strictEqual(total, 5);
|
|
await consume;
|
|
}
|
|
|
|
async function testEndWithPreAbortedSignal() {
|
|
const { writer, readable } = push();
|
|
const reason = new Error('end aborted');
|
|
|
|
writer.writeSync('hello');
|
|
await assert.rejects(
|
|
writer.end({ signal: AbortSignal.abort(reason) }),
|
|
(error) => error === reason,
|
|
);
|
|
|
|
// A rejected end must leave the writer open.
|
|
writer.writeSync(' world');
|
|
const consume = text(readable);
|
|
assert.strictEqual(await writer.end(), 11);
|
|
assert.strictEqual(await consume, 'hello world');
|
|
}
|
|
|
|
async function testEndSignalAbortWhileDraining() {
|
|
const { writer, readable } = push();
|
|
const controller = new AbortController();
|
|
const reason = new Error('end aborted while draining');
|
|
|
|
writer.writeSync('hello');
|
|
const abortedEnd = writer.end({ signal: controller.signal });
|
|
controller.abort(reason);
|
|
|
|
await assert.rejects(abortedEnd, (error) => error === reason);
|
|
|
|
// Aborting the operation does not undo the end-of-stream signal.
|
|
const completedEnd = writer.end();
|
|
assert.strictEqual(await text(readable), 'hello');
|
|
assert.strictEqual(await completedEnd, 5);
|
|
}
|
|
|
|
async function testFactorySignalAbortWhileDraining() {
|
|
const controller = new AbortController();
|
|
const reason = new Error('stream aborted while draining');
|
|
const { writer, readable } = push({ signal: controller.signal });
|
|
|
|
writer.writeSync('hello');
|
|
const end = writer.end();
|
|
const endRejected = assert.rejects(end, (error) => error === reason);
|
|
controller.abort(reason);
|
|
|
|
await endRejected;
|
|
await assert.rejects(text(readable), (error) => error === reason);
|
|
await assert.rejects(writer.end(), (error) => error === reason);
|
|
}
|
|
|
|
async function testEndAfterEndSyncWaitsForDrain() {
|
|
const { writer, readable } = push();
|
|
writer.writeSync('hello');
|
|
assert.strictEqual(writer.endSync(), -1);
|
|
|
|
let ended = false;
|
|
const end = writer.end().then((n) => {
|
|
ended = true;
|
|
return n;
|
|
});
|
|
|
|
await Promise.resolve();
|
|
assert.strictEqual(ended, false);
|
|
|
|
await dump(readable);
|
|
assert.strictEqual(await end, 5);
|
|
}
|
|
|
|
async function testWriteUint8Array() {
|
|
const { writer, readable } = push();
|
|
writer.write(new Uint8Array([72, 73])); // 'HI'
|
|
writer.endSync();
|
|
const result = await text(readable);
|
|
assert.strictEqual(result, 'HI');
|
|
}
|
|
|
|
async function testOndrainWaitsForDrain() {
|
|
const kChunk = new Uint8Array(16384);
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
writer.writeSync(kChunk); // Fills budget
|
|
|
|
let drainState = 'pending';
|
|
const drainPromise = ondrain(writer).then((v) => { drainState = v; });
|
|
|
|
await setImmediate();
|
|
assert.strictEqual(drainState, 'pending'); // Still waiting
|
|
|
|
// Read to drain
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
await iter.next();
|
|
|
|
await drainPromise;
|
|
assert.strictEqual(drainState, true);
|
|
writer.endSync();
|
|
}
|
|
|
|
// Consumer throw causes subsequent writes to reject with consumer's error
|
|
async function testConsumerThrowRejectsWrites() {
|
|
const kChunk = new Uint8Array(16384);
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
writer.writeSync(kChunk);
|
|
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const err = new Error('consumer boom');
|
|
await assert.rejects(
|
|
() => iter.throw(err),
|
|
(e) => e === err,
|
|
);
|
|
|
|
// Subsequent async writes should reject with the consumer's error
|
|
await assert.rejects(
|
|
() => writer.write('x'),
|
|
{ message: 'consumer boom' },
|
|
);
|
|
}
|
|
|
|
async function testConsumerThrowRejectsWithThrownError() {
|
|
const { readable } = push();
|
|
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const err = new Error('boom');
|
|
|
|
await assert.rejects(
|
|
() => iter.throw(err),
|
|
(e) => e === err,
|
|
);
|
|
}
|
|
|
|
// end() resolves a pending read as done:true
|
|
async function testEndResolvesPendingRead() {
|
|
const { writer, readable } = push();
|
|
|
|
// Consumer starts reading — blocks because buffer is empty
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const readPromise = iter.next();
|
|
|
|
// Give the read a tick to enter the pending state
|
|
await setImmediate();
|
|
|
|
// End the writer — should resolve the pending read with done:true
|
|
writer.endSync();
|
|
const result = await readPromise;
|
|
assert.strictEqual(result.done, true);
|
|
}
|
|
|
|
// fail() rejects a pending read with the error
|
|
async function testFailRejectsPendingRead() {
|
|
const { writer, readable } = push();
|
|
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const readPromise = iter.next();
|
|
|
|
await setImmediate();
|
|
|
|
writer.fail(new Error('fail during read'));
|
|
await assert.rejects(
|
|
() => readPromise,
|
|
{ message: 'fail during read' },
|
|
);
|
|
}
|
|
|
|
// iterator.return() resolves a pending read with done:true
|
|
async function testConsumerReturnResolvesPendingRead() {
|
|
const { readable } = push();
|
|
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const readPromise = iter.next();
|
|
|
|
await setImmediate();
|
|
|
|
const returnResult = await iter.return();
|
|
assert.strictEqual(returnResult.value, undefined);
|
|
assert.strictEqual(returnResult.done, true);
|
|
|
|
const readResult = await readPromise;
|
|
assert.strictEqual(readResult.value, undefined);
|
|
assert.strictEqual(readResult.done, true);
|
|
}
|
|
|
|
async function testEndRejectsAfterConsumerReturn() {
|
|
const { writer, readable } = push();
|
|
writer.writeSync('data');
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
|
|
await iter.return();
|
|
|
|
await assert.rejects(
|
|
writer.end({ signal: AbortSignal.timeout(common.platformTimeout(100)) }),
|
|
{ code: 'ERR_INVALID_STATE' },
|
|
);
|
|
assert.strictEqual((await iter.next()).done, true);
|
|
}
|
|
|
|
// iterator.throw() rejects a pending read with the thrown error
|
|
async function testConsumerThrowRejectsPendingRead() {
|
|
const { readable } = push();
|
|
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const readPromise = iter.next();
|
|
|
|
await setImmediate();
|
|
|
|
const err = new Error('consumer read boom');
|
|
const readRejects = assert.rejects(
|
|
() => readPromise,
|
|
(e) => e === err,
|
|
);
|
|
await assert.rejects(
|
|
() => iter.throw(err),
|
|
(e) => e === err,
|
|
);
|
|
|
|
await readRejects;
|
|
}
|
|
|
|
// end() drains writes that were already pending, then waits for EOF to be read.
|
|
async function testEndDrainsPendingWrites() {
|
|
const kChunk = new Uint8Array(16384);
|
|
const { writer, readable } = push({ budget: 16384, backpressure: 'unbounded' });
|
|
writer.writeSync(kChunk); // fill budget
|
|
|
|
// This write blocks on backpressure
|
|
const writePromise = writer.write(kChunk);
|
|
const endPromise = writer.end();
|
|
await assert.rejects(writer.write(kChunk), { code: 'ERR_INVALID_STATE' });
|
|
|
|
let ended = false;
|
|
endPromise.then(common.mustCall(() => { ended = true; }));
|
|
const iterator = readable[Symbol.asyncIterator]();
|
|
|
|
assert.strictEqual((await iterator.next()).done, false);
|
|
await writePromise;
|
|
assert.strictEqual((await iterator.next()).done, false);
|
|
await Promise.resolve();
|
|
assert.strictEqual(ended, false);
|
|
|
|
assert.strictEqual((await iterator.next()).done, true);
|
|
assert.strictEqual(await endPromise, kChunk.byteLength * 2);
|
|
assert.strictEqual(ended, true);
|
|
}
|
|
|
|
async function testEndWaitsForEofPull() {
|
|
const { writer, readable } = push();
|
|
writer.writeSync('hello');
|
|
const endPromise = writer.end();
|
|
let ended = false;
|
|
endPromise.then(common.mustCall(() => { ended = true; }));
|
|
const iterator = readable[Symbol.asyncIterator]();
|
|
|
|
const data = await iterator.next();
|
|
assert.strictEqual(data.done, false);
|
|
await Promise.resolve();
|
|
assert.strictEqual(ended, false);
|
|
|
|
assert.strictEqual((await iterator.next()).done, true);
|
|
await endPromise;
|
|
assert.strictEqual(ended, true);
|
|
}
|
|
|
|
async function testEndIdempotentWhenClosed() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
await writer.write('hello');
|
|
// Start consuming concurrently (end() waits for drain)
|
|
const consume = (async () => {
|
|
await dump(readable);
|
|
})();
|
|
const first = await writer.end();
|
|
assert.strictEqual(first, 5);
|
|
// Second end() should resolve with same byte count (idempotent)
|
|
const second = await writer.end();
|
|
assert.strictEqual(second, 5);
|
|
await consume;
|
|
}
|
|
|
|
async function testAsyncDispose() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
writer.writeSync('hello');
|
|
// Symbol.asyncDispose calls fail() with no argument
|
|
await writer[Symbol.asyncDispose]();
|
|
// Writer is now errored, writes should fail
|
|
assert.strictEqual(writer.writeSync('fail'), false);
|
|
// Drain readable
|
|
try {
|
|
await dump(readable);
|
|
} catch {
|
|
// Expected - reader sees the error
|
|
}
|
|
}
|
|
|
|
async function testAsyncDisposeWaitsAfterEndSync() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
writer.writeSync('hello');
|
|
assert.strictEqual(writer.endSync(), -1);
|
|
|
|
let disposed = false;
|
|
const disposal = writer[Symbol.asyncDispose]().then(() => {
|
|
disposed = true;
|
|
});
|
|
await Promise.resolve();
|
|
assert.strictEqual(disposed, false);
|
|
|
|
assert.strictEqual(await text(readable), 'hello');
|
|
await disposal;
|
|
assert.strictEqual(disposed, true);
|
|
}
|
|
|
|
async function testSyncDispose() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
writer.writeSync('hello');
|
|
// Symbol.dispose calls fail() with no argument
|
|
writer[Symbol.dispose]();
|
|
// Writer is now errored, writes should fail
|
|
assert.strictEqual(writer.writeSync('fail'), false);
|
|
// Drain readable
|
|
try {
|
|
await dump(readable);
|
|
} catch {
|
|
// Expected
|
|
}
|
|
}
|
|
|
|
async function testEndRejectsWhenErrored() {
|
|
const { writer, readable } = push({ budget: 16384 });
|
|
await writer.write('hello');
|
|
const err = new Error('boom');
|
|
await writer.fail(err);
|
|
// end() after fail should reject with the stored error
|
|
await assert.rejects(
|
|
() => writer.end(),
|
|
(e) => e === err,
|
|
);
|
|
// Drain readable
|
|
try {
|
|
// eslint-disable-next-line no-unused-vars
|
|
for await (const _ of readable) { break; }
|
|
} catch {
|
|
// Expected - reader may see the error
|
|
}
|
|
}
|
|
|
|
async function testFailRejectsFutureReadWithFalsyReason() {
|
|
for (const reason of [0, null]) {
|
|
const { writer, readable } = push();
|
|
|
|
writer.fail(reason);
|
|
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
await iter.next().then(
|
|
common.mustNotCall(),
|
|
common.mustCall((rejection) => {
|
|
assert.strictEqual(rejection, reason);
|
|
}),
|
|
);
|
|
}
|
|
}
|
|
|
|
async function testFailRejectsPendingReadWithFalsyReason() {
|
|
const { writer, readable } = push();
|
|
|
|
const iter = readable[Symbol.asyncIterator]();
|
|
const readPromise = iter.next();
|
|
|
|
await setImmediate();
|
|
|
|
writer.fail(false);
|
|
await readPromise.then(
|
|
common.mustNotCall(),
|
|
common.mustCall((reason) => {
|
|
assert.strictEqual(reason, false);
|
|
}),
|
|
);
|
|
}
|
|
|
|
Promise.all([
|
|
testOndrain(),
|
|
testDropPoliciesReportPhysicalCapacity(),
|
|
testOndrainNonDrainable(),
|
|
testWriteWithSignalRejects(),
|
|
testWriteWithPreAbortedSignal(),
|
|
testCancelledWriteRemovedFromQueue(),
|
|
testOndrainResolvesFalseOnConsumerBreak(),
|
|
testOndrainRejectsOnConsumerThrow(),
|
|
testWritev(),
|
|
testWritevSync(),
|
|
testWritevSyncInvalidChunkDoesNotQueue(),
|
|
testWritevMixedTypes(),
|
|
testWriteAfterEnd(),
|
|
testWriteAfterFail(),
|
|
testOndrainProtocolErrorPropagates(),
|
|
testFail(),
|
|
testEndAsyncReturnValue(),
|
|
testEndWithPreAbortedSignal(),
|
|
testEndSignalAbortWhileDraining(),
|
|
testFactorySignalAbortWhileDraining(),
|
|
testEndAfterEndSyncWaitsForDrain(),
|
|
testWriteUint8Array(),
|
|
testOndrainWaitsForDrain(),
|
|
testConsumerThrowRejectsWrites(),
|
|
testConsumerThrowRejectsWithThrownError(),
|
|
testEndResolvesPendingRead(),
|
|
testFailRejectsPendingRead(),
|
|
testFailRejectsFutureReadWithFalsyReason(),
|
|
testFailRejectsPendingReadWithFalsyReason(),
|
|
testConsumerReturnResolvesPendingRead(),
|
|
testEndRejectsAfterConsumerReturn(),
|
|
testConsumerThrowRejectsPendingRead(),
|
|
testEndDrainsPendingWrites(),
|
|
testEndWaitsForEofPull(),
|
|
testEndIdempotentWhenClosed(),
|
|
testEndRejectsWhenErrored(),
|
|
testAsyncDispose(),
|
|
testAsyncDisposeWaitsAfterEndSync(),
|
|
testSyncDispose(),
|
|
]).then(common.mustCall());
|