diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js index 105eebbd1..e03c6bf5f 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -1,3 +1,4 @@ -'use strict' // Keep this file as an alias for the full stream module. +'use strict' +// Keep this file as an alias for the full stream module. module.exports = require('./stream').Duplex diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js index 31358e6d1..1206dc455 100644 --- a/lib/_stream_passthrough.js +++ b/lib/_stream_passthrough.js @@ -1,3 +1,4 @@ -'use strict' // Keep this file as an alias for the full stream module. +'use strict' +// Keep this file as an alias for the full stream module. module.exports = require('./stream').PassThrough diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index abd53db4c..49416586f 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -1,3 +1,4 @@ -'use strict' // Keep this file as an alias for the full stream module. +'use strict' +// Keep this file as an alias for the full stream module. module.exports = require('./stream').Readable diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js index 98ea33824..ef227b12c 100644 --- a/lib/_stream_transform.js +++ b/lib/_stream_transform.js @@ -1,3 +1,4 @@ -'use strict' // Keep this file as an alias for the full stream module. +'use strict' +// Keep this file as an alias for the full stream module. module.exports = require('./stream').Transform diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 07204c429..00c7b037c 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -1,3 +1,4 @@ -'use strict' // Keep this file as an alias for the full stream module. +'use strict' +// Keep this file as an alias for the full stream module. module.exports = require('./stream').Writable diff --git a/lib/internal/streams/add-abort-signal.js b/lib/internal/streams/add-abort-signal.js index 8d5a840f7..c6ba8b9c2 100644 --- a/lib/internal/streams/add-abort-signal.js +++ b/lib/internal/streams/add-abort-signal.js @@ -1,38 +1,31 @@ 'use strict' const { AbortError, codes } = require('../../ours/errors') - const eos = require('./end-of-stream') +const { ERR_INVALID_ARG_TYPE } = codes -const { ERR_INVALID_ARG_TYPE } = codes // This method is inlined here for readable-stream +// This method is inlined here for readable-stream // It also does not allow for signal to not exist on the stream // https://github.com/nodejs/node/pull/36061#discussion_r533718029 - const validateAbortSignal = (signal, name) => { if (typeof signal !== 'object' || !('aborted' in signal)) { throw new ERR_INVALID_ARG_TYPE(name, 'AbortSignal', signal) } } - function isNodeStream(obj) { return !!(obj && typeof obj.pipe === 'function') } - module.exports.addAbortSignal = function addAbortSignal(signal, stream) { validateAbortSignal(signal, 'signal') - if (!isNodeStream(stream)) { throw new ERR_INVALID_ARG_TYPE('stream', 'stream.Stream', stream) } - return module.exports.addAbortSignalNoValidate(signal, stream) } - module.exports.addAbortSignalNoValidate = function (signal, stream) { if (typeof signal !== 'object' || !('aborted' in signal)) { return stream } - const onAbort = () => { stream.destroy( new AbortError(undefined, { @@ -40,13 +33,11 @@ module.exports.addAbortSignalNoValidate = function (signal, stream) { }) ) } - if (signal.aborted) { onAbort() } else { signal.addEventListener('abort', onAbort) eos(stream, () => signal.removeEventListener('abort', onAbort)) } - return stream } diff --git a/lib/internal/streams/buffer_list.js b/lib/internal/streams/buffer_list.js index e22914f0e..b55e35cf9 100644 --- a/lib/internal/streams/buffer_list.js +++ b/lib/internal/streams/buffer_list.js @@ -1,18 +1,14 @@ 'use strict' const { StringPrototypeSlice, SymbolIterator, TypedArrayPrototypeSet, Uint8Array } = require('../../ours/primordials') - const { Buffer } = require('buffer') - const { inspect } = require('../../ours/util') - module.exports = class BufferList { constructor() { this.head = null this.tail = null this.length = 0 } - push(v) { const entry = { data: v, @@ -23,7 +19,6 @@ module.exports = class BufferList { this.tail = entry ++this.length } - unshift(v) { const entry = { data: v, @@ -33,7 +28,6 @@ module.exports = class BufferList { this.head = entry ++this.length } - shift() { if (this.length === 0) return const ret = this.head.data @@ -42,73 +36,62 @@ module.exports = class BufferList { --this.length return ret } - clear() { this.head = this.tail = null this.length = 0 } - join(s) { if (this.length === 0) return '' let p = this.head let ret = '' + p.data - while ((p = p.next) !== null) ret += s + p.data - return ret } - concat(n) { if (this.length === 0) return Buffer.alloc(0) const ret = Buffer.allocUnsafe(n >>> 0) let p = this.head let i = 0 - while (p) { TypedArrayPrototypeSet(ret, p.data, i) i += p.data.length p = p.next } - return ret - } // Consumes a specified amount of bytes or characters from the buffered data. + } + // Consumes a specified amount of bytes or characters from the buffered data. consume(n, hasStrings) { const data = this.head.data - if (n < data.length) { // `slice` is the same for buffers and strings. const slice = data.slice(0, n) this.head.data = data.slice(n) return slice } - if (n === data.length) { // First chunk is a perfect match. return this.shift() - } // Result spans more than one buffer. - + } + // Result spans more than one buffer. return hasStrings ? this._getString(n) : this._getBuffer(n) } - first() { return this.head.data } - *[SymbolIterator]() { for (let p = this.head; p; p = p.next) { yield p.data } - } // Consumes a specified amount of characters from the buffered data. + } + // Consumes a specified amount of characters from the buffered data. _getString(n) { let ret = '' let p = this.head let c = 0 - do { const str = p.data - if (n > str.length) { ret += str n -= str.length @@ -123,26 +106,22 @@ module.exports = class BufferList { this.head = p p.data = StringPrototypeSlice(str, n) } - break } - ++c } while ((p = p.next) !== null) - this.length -= c return ret - } // Consumes a specified amount of bytes from the buffered data. + } + // Consumes a specified amount of bytes from the buffered data. _getBuffer(n) { const ret = Buffer.allocUnsafe(n) const retLen = n let p = this.head let c = 0 - do { const buf = p.data - if (n > buf.length) { TypedArrayPrototypeSet(ret, buf, retLen - n) n -= buf.length @@ -157,17 +136,15 @@ module.exports = class BufferList { this.head = p p.data = buf.slice(n) } - break } - ++c } while ((p = p.next) !== null) - this.length -= c return ret - } // Make sure the linked list only shows the minimal necessary information. + } + // Make sure the linked list only shows the minimal necessary information. [Symbol.for('nodejs.util.inspect.custom')](_, options) { return inspect(this, { ...options, diff --git a/lib/internal/streams/compose.js b/lib/internal/streams/compose.js index 0a2e810a3..4a00aead8 100644 --- a/lib/internal/streams/compose.js +++ b/lib/internal/streams/compose.js @@ -1,63 +1,48 @@ 'use strict' const { pipeline } = require('./pipeline') - const Duplex = require('./duplex') - const { destroyer } = require('./destroy') - const { isNodeStream, isReadable, isWritable } = require('./utils') - const { AbortError, codes: { ERR_INVALID_ARG_VALUE, ERR_MISSING_ARGS } } = require('../../ours/errors') - module.exports = function compose(...streams) { if (streams.length === 0) { throw new ERR_MISSING_ARGS('streams') } - if (streams.length === 1) { return Duplex.from(streams[0]) } - const orgStreams = [...streams] - if (typeof streams[0] === 'function') { streams[0] = Duplex.from(streams[0]) } - if (typeof streams[streams.length - 1] === 'function') { const idx = streams.length - 1 streams[idx] = Duplex.from(streams[idx]) } - for (let n = 0; n < streams.length; ++n) { if (!isNodeStream(streams[n])) { // TODO(ronag): Add checks for non streams. continue } - if (n < streams.length - 1 && !isReadable(streams[n])) { throw new ERR_INVALID_ARG_VALUE(`streams[${n}]`, orgStreams[n], 'must be readable') } - if (n > 0 && !isWritable(streams[n])) { throw new ERR_INVALID_ARG_VALUE(`streams[${n}]`, orgStreams[n], 'must be writable') } } - let ondrain let onfinish let onreadable let onclose let d - function onfinished(err) { const cb = onclose onclose = null - if (cb) { cb(err) } else if (err) { @@ -66,14 +51,14 @@ module.exports = function compose(...streams) { d.destroy() } } - const head = streams[0] const tail = pipeline(streams, onfinished) const writable = !!isWritable(head) - const readable = !!isReadable(tail) // TODO(ronag): Avoid double buffering. + const readable = !!isReadable(tail) + + // TODO(ronag): Avoid double buffering. // Implement Writable/Readable/Duplex traits. // See, https://github.com/nodejs/node/pull/33515. - d = new Duplex({ // TODO (ronag): highWaterMark? writableObjectMode: !!(head !== null && head !== undefined && head.writableObjectMode), @@ -81,7 +66,6 @@ module.exports = function compose(...streams) { writable, readable }) - if (writable) { d._write = function (chunk, encoding, callback) { if (head.write(chunk, encoding)) { @@ -90,12 +74,10 @@ module.exports = function compose(...streams) { ondrain = callback } } - d._final = function (callback) { head.end() onfinish = callback } - head.on('drain', function () { if (ondrain) { const cb = ondrain @@ -111,7 +93,6 @@ module.exports = function compose(...streams) { } }) } - if (readable) { tail.on('readable', function () { if (onreadable) { @@ -123,32 +104,26 @@ module.exports = function compose(...streams) { tail.on('end', function () { d.push(null) }) - d._read = function () { while (true) { const buf = tail.read() - if (buf === null) { onreadable = d._read return } - if (!d.push(buf)) { return } } } } - d._destroy = function (err, callback) { if (!err && onclose !== null) { err = new AbortError() } - onreadable = null ondrain = null onfinish = null - if (onclose === null) { callback(err) } else { @@ -156,6 +131,5 @@ module.exports = function compose(...streams) { destroyer(tail, err) } } - return d } diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index e04306f0b..dfcbddf12 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -3,6 +3,7 @@ /* replacement start */ const process = require('process') + /* replacement end */ const { @@ -10,14 +11,10 @@ const { codes: { ERR_MULTIPLE_CALLBACK }, AbortError } = require('../../ours/errors') - const { Symbol } = require('../../ours/primordials') - const { kDestroyed, isDestroyed, isFinished, isServerRequest } = require('./utils') - const kDestroy = Symbol('kDestroy') const kConstruct = Symbol('kConstruct') - function checkError(err, w, r) { if (err) { // Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364 @@ -26,39 +23,37 @@ function checkError(err, w, r) { if (w && !w.errored) { w.errored = err } - if (r && !r.errored) { r.errored = err } } -} // Backwards compat. cb() is undocumented and unused in core but -// unfortunately might be used by modules. +} +// Backwards compat. cb() is undocumented and unused in core but +// unfortunately might be used by modules. function destroy(err, cb) { const r = this._readableState - const w = this._writableState // With duplex streams we use the writable side for state. - + const w = this._writableState + // With duplex streams we use the writable side for state. const s = w || r - if ((w && w.destroyed) || (r && r.destroyed)) { if (typeof cb === 'function') { cb() } - return this - } // We set destroyed to true before firing error callbacks in order - // to make it re-entrance safe in case destroy() is called within callbacks + } + // We set destroyed to true before firing error callbacks in order + // to make it re-entrance safe in case destroy() is called within callbacks checkError(err, w, r) - if (w) { w.destroyed = true } - if (r) { r.destroyed = true - } // If still constructing then defer calling _destroy. + } + // If still constructing then defer calling _destroy. if (!s.constructed) { this.once(kDestroy, function (er) { _destroy(this, aggregateTwoErrors(er, err), cb) @@ -66,94 +61,73 @@ function destroy(err, cb) { } else { _destroy(this, err, cb) } - return this } - function _destroy(self, err, cb) { let called = false - function onDestroy(err) { if (called) { return } - called = true const r = self._readableState const w = self._writableState checkError(err, w, r) - if (w) { w.closed = true } - if (r) { r.closed = true } - if (typeof cb === 'function') { cb(err) } - if (err) { process.nextTick(emitErrorCloseNT, self, err) } else { process.nextTick(emitCloseNT, self) } } - try { self._destroy(err || null, onDestroy) } catch (err) { onDestroy(err) } } - function emitErrorCloseNT(self, err) { emitErrorNT(self, err) emitCloseNT(self) } - function emitCloseNT(self) { const r = self._readableState const w = self._writableState - if (w) { w.closeEmitted = true } - if (r) { r.closeEmitted = true } - if ((w && w.emitClose) || (r && r.emitClose)) { self.emit('close') } } - function emitErrorNT(self, err) { const r = self._readableState const w = self._writableState - if ((w && w.errorEmitted) || (r && r.errorEmitted)) { return } - if (w) { w.errorEmitted = true } - if (r) { r.errorEmitted = true } - self.emit('error', err) } - function undestroy() { const r = this._readableState const w = this._writableState - if (r) { r.constructed = true r.closed = false @@ -165,7 +139,6 @@ function undestroy() { r.ended = r.readable === false r.endEmitted = r.readable === false } - if (w) { w.constructed = true w.destroyed = false @@ -180,20 +153,18 @@ function undestroy() { w.finished = w.writable === false } } - function errorOrDestroy(stream, err, sync) { // We have tests that rely on errors being emitted // in the same tick, so changing this is semver major. // For now when you opt-in to autoDestroy we allow // the error to be emitted nextTick. In a future // semver major update we should change the default to this. + const r = stream._readableState const w = stream._writableState - if ((w && w.destroyed) || (r && r.destroyed)) { return this } - if ((r && r.autoDestroy) || (w && w.autoDestroy)) stream.destroy(err) else if (err) { // Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364 @@ -202,11 +173,9 @@ function errorOrDestroy(stream, err, sync) { if (w && !w.errored) { w.errored = err } - if (r && !r.errored) { r.errored = err } - if (sync) { process.nextTick(emitErrorNT, stream, err) } else { @@ -214,55 +183,42 @@ function errorOrDestroy(stream, err, sync) { } } } - function construct(stream, cb) { if (typeof stream._construct !== 'function') { return } - const r = stream._readableState const w = stream._writableState - if (r) { r.constructed = false } - if (w) { w.constructed = false } - stream.once(kConstruct, cb) - if (stream.listenerCount(kConstruct) > 1) { // Duplex return } - process.nextTick(constructNT, stream) } - function constructNT(stream) { let called = false - function onConstruct(err) { if (called) { errorOrDestroy(stream, err !== null && err !== undefined ? err : new ERR_MULTIPLE_CALLBACK()) return } - called = true const r = stream._readableState const w = stream._writableState const s = w || r - if (r) { r.constructed = true } - if (w) { w.constructed = true } - if (s.destroyed) { stream.emit(kDestroy, err) } else if (err) { @@ -271,40 +227,36 @@ function constructNT(stream) { process.nextTick(emitConstructNT, stream) } } - try { stream._construct(onConstruct) } catch (err) { onConstruct(err) } } - function emitConstructNT(stream) { stream.emit(kConstruct) } - function isRequest(stream) { return stream && stream.setHeader && typeof stream.abort === 'function' } - function emitCloseLegacy(stream) { stream.emit('close') } - function emitErrorCloseLegacy(stream, err) { stream.emit('error', err) process.nextTick(emitCloseLegacy, stream) -} // Normalize destroy for legacy. +} +// Normalize destroy for legacy. function destroyer(stream, err) { if (!stream || isDestroyed(stream)) { return } - if (!err && !isFinished(stream)) { err = new AbortError() - } // TODO: Remove isRequest branches. + } + // TODO: Remove isRequest branches. if (isServerRequest(stream)) { stream.socket = null stream.destroy(err) @@ -322,12 +274,10 @@ function destroyer(stream, err) { } else { process.nextTick(emitCloseLegacy, stream) } - if (!stream.destroyed) { stream[kDestroyed] = true } } - module.exports = { construct, destroyer, diff --git a/lib/internal/streams/duplex.js b/lib/internal/streams/duplex.js index 24e5be6ff..dd0839673 100644 --- a/lib/internal/streams/duplex.js +++ b/lib/internal/streams/duplex.js @@ -18,10 +18,12 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + // a duplex stream is just a stream that is both readable and writable. // Since JS doesn't have multiple prototype inheritance, this class // prototypically inherits from Readable, and then parasitically from // Writable. + 'use strict' const { @@ -30,38 +32,30 @@ const { ObjectKeys, ObjectSetPrototypeOf } = require('../../ours/primordials') - module.exports = Duplex - const Readable = require('./readable') - const Writable = require('./writable') - ObjectSetPrototypeOf(Duplex.prototype, Readable.prototype) ObjectSetPrototypeOf(Duplex, Readable) { - const keys = ObjectKeys(Writable.prototype) // Allow the keys array to be GC'ed. - + const keys = ObjectKeys(Writable.prototype) + // Allow the keys array to be GC'ed. for (let i = 0; i < keys.length; i++) { const method = keys[i] if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method] } } - function Duplex(options) { if (!(this instanceof Duplex)) return new Duplex(options) Readable.call(this, options) Writable.call(this, options) - if (options) { this.allowHalfOpen = options.allowHalfOpen !== false - if (options.readable === false) { this._readableState.readable = false this._readableState.ended = true this._readableState.endEmitted = true } - if (options.writable === false) { this._writableState.writable = false this._writableState.ending = true @@ -72,7 +66,6 @@ function Duplex(options) { this.allowHalfOpen = true } } - ObjectDefineProperties(Duplex.prototype, { writable: { __proto__: null, @@ -112,15 +105,12 @@ ObjectDefineProperties(Duplex.prototype, { }, destroyed: { __proto__: null, - get() { if (this._readableState === undefined || this._writableState === undefined) { return false } - return this._readableState.destroyed && this._writableState.destroyed }, - set(value) { // Backward compatibility, the user is explicitly // managing destroyed. @@ -131,27 +121,23 @@ ObjectDefineProperties(Duplex.prototype, { } } }) -let webStreamsAdapters // Lazy to avoid circular references +let webStreamsAdapters +// Lazy to avoid circular references function lazyWebStreams() { if (webStreamsAdapters === undefined) webStreamsAdapters = {} return webStreamsAdapters } - Duplex.fromWeb = function (pair, options) { return lazyWebStreams().newStreamDuplexFromReadableWritablePair(pair, options) } - Duplex.toWeb = function (duplex) { return lazyWebStreams().newReadableWritablePairFromDuplex(duplex) } - let duplexify - Duplex.from = function (body) { if (!duplexify) { duplexify = require('./duplexify') } - return duplexify(body, 'body') } diff --git a/lib/internal/streams/duplexify.js b/lib/internal/streams/duplexify.js index 9ff4df964..4d74b18e0 100644 --- a/lib/internal/streams/duplexify.js +++ b/lib/internal/streams/duplexify.js @@ -1,11 +1,11 @@ /* replacement start */ + const process = require('process') + /* replacement end */ ;('use strict') - const bufferModule = require('buffer') - const { isReadable, isWritable, @@ -15,24 +15,16 @@ const { isWritableNodeStream, isDuplexNodeStream } = require('./utils') - const eos = require('./end-of-stream') - const { AbortError, codes: { ERR_INVALID_ARG_TYPE, ERR_INVALID_RETURN_VALUE } } = require('../../ours/errors') - const { destroyer } = require('./destroy') - const Duplex = require('./duplex') - const Readable = require('./readable') - const { createDeferredPromise } = require('../../ours/util') - const from = require('./from') - const Blob = globalThis.Blob || bufferModule.Blob const isBlob = typeof Blob !== 'undefined' @@ -42,21 +34,21 @@ const isBlob = : function isBlob(b) { return false } - const AbortController = globalThis.AbortController || require('abort-controller').AbortController +const { FunctionPrototypeCall } = require('../../ours/primordials') -const { FunctionPrototypeCall } = require('../../ours/primordials') // This is needed for pre node 17. - +// This is needed for pre node 17. class Duplexify extends Duplex { constructor(options) { - super(options) // https://github.com/nodejs/node/pull/34385 + super(options) + + // https://github.com/nodejs/node/pull/34385 if ((options === null || options === undefined ? undefined : options.readable) === false) { this._readableState.readable = false this._readableState.ended = true this._readableState.endEmitted = true } - if ((options === null || options === undefined ? undefined : options.writable) === false) { this._writableState.writable = false this._writableState.ending = true @@ -65,33 +57,32 @@ class Duplexify extends Duplex { } } } - module.exports = function duplexify(body, name) { if (isDuplexNodeStream(body)) { return body } - if (isReadableNodeStream(body)) { return _duplexify({ readable: body }) } - if (isWritableNodeStream(body)) { return _duplexify({ writable: body }) } - if (isNodeStream(body)) { return _duplexify({ writable: false, readable: false }) - } // TODO: Webstreams + } + + // TODO: Webstreams // if (isReadableStream(body)) { // return _duplexify({ readable: Readable.fromWeb(body) }); // } + // TODO: Webstreams // if (isWritableStream(body)) { // return _duplexify({ writable: Writable.fromWeb(body) }); @@ -99,7 +90,6 @@ module.exports = function duplexify(body, name) { if (typeof body === 'function') { const { value, write, final, destroy } = fromAsyncGen(body) - if (isIterable(value)) { return from(Duplexify, value, { // TODO (ronag): highWaterMark? @@ -109,9 +99,7 @@ module.exports = function duplexify(body, name) { destroy }) } - const then = value === null || value === undefined ? undefined : value.then - if (typeof then === 'function') { let d const promise = FunctionPrototypeCall( @@ -131,7 +119,6 @@ module.exports = function duplexify(body, name) { objectMode: true, readable: false, write, - final(cb) { final(async () => { try { @@ -142,25 +129,23 @@ module.exports = function duplexify(body, name) { } }) }, - destroy })) } - throw new ERR_INVALID_RETURN_VALUE('Iterable, AsyncIterable or AsyncFunction', name, value) } - if (isBlob(body)) { return duplexify(body.arrayBuffer()) } - if (isIterable(body)) { return from(Duplexify, body, { // TODO (ronag): highWaterMark? objectMode: true, writable: false }) - } // TODO: Webstreams. + } + + // TODO: Webstreams. // if ( // isReadableStream(body?.readable) && // isWritableStream(body?.writable) @@ -193,9 +178,7 @@ module.exports = function duplexify(body, name) { writable }) } - const then = body === null || body === undefined ? undefined : body.then - if (typeof then === 'function') { let d FunctionPrototypeCall( @@ -205,7 +188,6 @@ module.exports = function duplexify(body, name) { if (val != null) { d.push(val) } - d.push(null) }, (err) => { @@ -215,11 +197,9 @@ module.exports = function duplexify(body, name) { return (d = new Duplexify({ objectMode: true, writable: false, - read() {} })) } - throw new ERR_INVALID_ARG_TYPE( name, [ @@ -236,7 +216,6 @@ module.exports = function duplexify(body, name) { body ) } - function fromAsyncGen(fn) { let { promise, resolve } = createDeferredPromise() const ac = new AbortController() @@ -263,35 +242,29 @@ function fromAsyncGen(fn) { ) return { value, - write(chunk, encoding, cb) { const _resolve = resolve resolve = null - _resolve({ chunk, done: false, cb }) }, - final(cb) { const _resolve = resolve resolve = null - _resolve({ done: true, cb }) }, - destroy(err, cb) { ac.abort() cb(err) } } } - function _duplexify(pair) { const r = pair.readable && typeof pair.readable.read !== 'function' ? Readable.wrap(pair.readable) : pair.readable const w = pair.writable @@ -302,11 +275,9 @@ function _duplexify(pair) { let onreadable let onclose let d - function onfinished(err) { const cb = onclose onclose = null - if (cb) { cb(err) } else if (err) { @@ -314,10 +285,11 @@ function _duplexify(pair) { } else if (!readable && !writable) { d.destroy() } - } // TODO(ronag): Avoid double buffering. + } + + // TODO(ronag): Avoid double buffering. // Implement Writable/Readable/Duplex traits. // See, https://github.com/nodejs/node/pull/33515. - d = new Duplexify({ // TODO (ronag): highWaterMark? readableObjectMode: !!(r !== null && r !== undefined && r.readableObjectMode), @@ -325,18 +297,14 @@ function _duplexify(pair) { readable, writable }) - if (writable) { eos(w, (err) => { writable = false - if (err) { destroyer(r, err) } - onfinished(err) }) - d._write = function (chunk, encoding, callback) { if (w.write(chunk, encoding)) { callback() @@ -344,12 +312,10 @@ function _duplexify(pair) { ondrain = callback } } - d._final = function (callback) { w.end() onfinish = callback } - w.on('drain', function () { if (ondrain) { const cb = ondrain @@ -365,15 +331,12 @@ function _duplexify(pair) { } }) } - if (readable) { eos(r, (err) => { readable = false - if (err) { destroyer(r, err) } - onfinished(err) }) r.on('readable', function () { @@ -386,32 +349,26 @@ function _duplexify(pair) { r.on('end', function () { d.push(null) }) - d._read = function () { while (true) { const buf = r.read() - if (buf === null) { onreadable = d._read return } - if (!d.push(buf)) { return } } } } - d._destroy = function (err, callback) { if (!err && onclose !== null) { err = new AbortError() } - onreadable = null ondrain = null onfinish = null - if (onclose === null) { callback(err) } else { @@ -420,6 +377,5 @@ function _duplexify(pair) { destroyer(r, err) } } - return d } diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index acc13be7d..b8456988a 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -1,21 +1,17 @@ /* replacement start */ + const process = require('process') + /* replacement end */ // Ported from https://github.com/mafintosh/end-of-stream with // permission from the author, Mathias Buus (@mafintosh). ;('use strict') - const { AbortError, codes } = require('../../ours/errors') - const { ERR_INVALID_ARG_TYPE, ERR_STREAM_PREMATURE_CLOSE } = codes - const { kEmptyObject, once } = require('../../ours/util') - const { validateAbortSignal, validateFunction, validateObject } = require('../validators') - const { Promise } = require('../../ours/primordials') - const { isClosed, isReadable, @@ -29,16 +25,12 @@ const { isNodeStream, willEmitClose: _willEmitClose } = require('./utils') - function isRequest(stream) { return stream.setHeader && typeof stream.abort === 'function' } - const nop = () => {} - function eos(stream, options, callback) { var _options$readable, _options$writable - if (arguments.length === 2) { callback = options options = kEmptyObject @@ -47,7 +39,6 @@ function eos(stream, options, callback) { } else { validateObject(options, 'options') } - validateFunction(callback, 'callback') validateAbortSignal(options.signal, 'options.signal') callback = once(callback) @@ -59,101 +50,81 @@ function eos(stream, options, callback) { (_options$writable = options.writable) !== null && _options$writable !== undefined ? _options$writable : isWritableNodeStream(stream) - if (!isNodeStream(stream)) { // TODO: Webstreams. throw new ERR_INVALID_ARG_TYPE('stream', 'Stream', stream) } - const wState = stream._writableState const rState = stream._readableState - const onlegacyfinish = () => { if (!stream.writable) { onfinish() } - } // TODO (ronag): Improve soft detection to include core modules and + } + + // TODO (ronag): Improve soft detection to include core modules and // common ecosystem modules that do properly emit 'close' but fail // this generic check. - let willEmitClose = _willEmitClose(stream) && isReadableNodeStream(stream) === readable && isWritableNodeStream(stream) === writable let writableFinished = isWritableFinished(stream, false) - const onfinish = () => { - writableFinished = true // Stream should not be destroyed here. If it is that + writableFinished = true + // Stream should not be destroyed here. If it is that // means that user space is doing something differently and // we cannot trust willEmitClose. - if (stream.destroyed) { willEmitClose = false } - if (willEmitClose && (!stream.readable || readable)) { return } - if (!readable || readableFinished) { callback.call(stream) } } - let readableFinished = isReadableFinished(stream, false) - const onend = () => { - readableFinished = true // Stream should not be destroyed here. If it is that + readableFinished = true + // Stream should not be destroyed here. If it is that // means that user space is doing something differently and // we cannot trust willEmitClose. - if (stream.destroyed) { willEmitClose = false } - if (willEmitClose && (!stream.writable || writable)) { return } - if (!writable || writableFinished) { callback.call(stream) } } - const onerror = (err) => { callback.call(stream, err) } - let closed = isClosed(stream) - const onclose = () => { closed = true const errored = isWritableErrored(stream) || isReadableErrored(stream) - if (errored && typeof errored !== 'boolean') { return callback.call(stream, errored) } - if (readable && !readableFinished && isReadableNodeStream(stream, true)) { if (!isReadableFinished(stream, false)) return callback.call(stream, new ERR_STREAM_PREMATURE_CLOSE()) } - if (writable && !writableFinished) { if (!isWritableFinished(stream, false)) return callback.call(stream, new ERR_STREAM_PREMATURE_CLOSE()) } - callback.call(stream) } - const onrequest = () => { stream.req.on('finish', onfinish) } - if (isRequest(stream)) { stream.on('complete', onfinish) - if (!willEmitClose) { stream.on('abort', onclose) } - if (stream.req) { onrequest() } else { @@ -163,21 +134,18 @@ function eos(stream, options, callback) { // legacy streams stream.on('end', onlegacyfinish) stream.on('close', onlegacyfinish) - } // Not all streams will emit 'close' after 'aborted'. + } + // Not all streams will emit 'close' after 'aborted'. if (!willEmitClose && typeof stream.aborted === 'boolean') { stream.on('aborted', onclose) } - stream.on('end', onend) stream.on('finish', onfinish) - if (options.error !== false) { stream.on('error', onerror) } - stream.on('close', onclose) - if (closed) { process.nextTick(onclose) } else if ( @@ -202,7 +170,6 @@ function eos(stream, options, callback) { } else if (rState && stream.req && stream.aborted) { process.nextTick(onclose) } - const cleanup = () => { callback = nop stream.removeListener('aborted', onclose) @@ -217,7 +184,6 @@ function eos(stream, options, callback) { stream.removeListener('error', onerror) stream.removeListener('close', onclose) } - if (options.signal && !closed) { const abort = () => { // Keep it because cleanup removes it. @@ -230,7 +196,6 @@ function eos(stream, options, callback) { }) ) } - if (options.signal.aborted) { process.nextTick(abort) } else { @@ -242,10 +207,8 @@ function eos(stream, options, callback) { options.signal.addEventListener('abort', abort) } } - return cleanup } - function finished(stream, opts) { return new Promise((resolve, reject) => { eos(stream, opts, (err) => { @@ -257,6 +220,5 @@ function finished(stream, opts) { }) }) } - module.exports = eos module.exports.finished = finished diff --git a/lib/internal/streams/from.js b/lib/internal/streams/from.js index 89ce1a8be..2b3a8411b 100644 --- a/lib/internal/streams/from.js +++ b/lib/internal/streams/from.js @@ -3,31 +3,25 @@ /* replacement start */ const process = require('process') + /* replacement end */ const { PromisePrototypeThen, SymbolAsyncIterator, SymbolIterator } = require('../../ours/primordials') - const { Buffer } = require('buffer') - const { ERR_INVALID_ARG_TYPE, ERR_STREAM_NULL_VALUES } = require('../../ours/errors').codes - function from(Readable, iterable, opts) { let iterator - if (typeof iterable === 'string' || iterable instanceof Buffer) { return new Readable({ objectMode: true, ...opts, - read() { this.push(iterable) this.push(null) } }) } - let isAsync - if (iterable && iterable[SymbolAsyncIterator]) { isAsync = true iterator = iterable[SymbolAsyncIterator]() @@ -37,61 +31,53 @@ function from(Readable, iterable, opts) { } else { throw new ERR_INVALID_ARG_TYPE('iterable', ['Iterable'], iterable) } - const readable = new Readable({ objectMode: true, highWaterMark: 1, // TODO(ronag): What options should be allowed? ...opts - }) // Flag to protect against _read - // being called before last iteration completion. + }) + // Flag to protect against _read + // being called before last iteration completion. let reading = false - readable._read = function () { if (!reading) { reading = true next() } } - readable._destroy = function (error, cb) { PromisePrototypeThen( close(error), - () => process.nextTick(cb, error), // nextTick is here in case cb throws + () => process.nextTick(cb, error), + // nextTick is here in case cb throws (e) => process.nextTick(cb, e || error) ) } - async function close(error) { const hadError = error !== undefined && error !== null const hasThrow = typeof iterator.throw === 'function' - if (hadError && hasThrow) { const { value, done } = await iterator.throw(error) await value - if (done) { return } } - if (typeof iterator.return === 'function') { const { value } = await iterator.return() await value } } - async function next() { for (;;) { try { const { value, done } = isAsync ? await iterator.next() : iterator.next() - if (done) { readable.push(null) } else { const res = value && typeof value.then === 'function' ? await value : value - if (res === null) { reading = false throw new ERR_STREAM_NULL_VALUES() @@ -104,12 +90,9 @@ function from(Readable, iterable, opts) { } catch (err) { readable.destroy(err) } - break } } - return readable } - module.exports = from diff --git a/lib/internal/streams/lazy_transform.js b/lib/internal/streams/lazy_transform.js index 466aa0354..439461a12 100644 --- a/lib/internal/streams/lazy_transform.js +++ b/lib/internal/streams/lazy_transform.js @@ -4,33 +4,24 @@ 'use strict' const { ObjectDefineProperties, ObjectDefineProperty, ObjectSetPrototypeOf } = require('../../ours/primordials') - const stream = require('../../stream') - const { getDefaultEncoding } = require('../crypto/util') - module.exports = LazyTransform - function LazyTransform(options) { this._options = options } - ObjectSetPrototypeOf(LazyTransform.prototype, stream.Transform.prototype) ObjectSetPrototypeOf(LazyTransform, stream.Transform) - function makeGetter(name) { return function () { stream.Transform.call(this, this._options) this._writableState.decodeStrings = false - if (!this._options || !this._options.defaultEncoding) { this._writableState.defaultEncoding = getDefaultEncoding() } - return this[name] } } - function makeSetter(name) { return function (val) { ObjectDefineProperty(this, name, { @@ -42,7 +33,6 @@ function makeSetter(name) { }) } } - ObjectDefineProperties(LazyTransform.prototype, { _readableState: { __proto__: null, diff --git a/lib/internal/streams/legacy.js b/lib/internal/streams/legacy.js index 09c3b7201..d492f7ff4 100644 --- a/lib/internal/streams/legacy.js +++ b/lib/internal/streams/legacy.js @@ -1,66 +1,56 @@ 'use strict' const { ArrayIsArray, ObjectSetPrototypeOf } = require('../../ours/primordials') - const { EventEmitter: EE } = require('events') - function Stream(opts) { EE.call(this, opts) } - ObjectSetPrototypeOf(Stream.prototype, EE.prototype) ObjectSetPrototypeOf(Stream, EE) - Stream.prototype.pipe = function (dest, options) { const source = this - function ondata(chunk) { if (dest.writable && dest.write(chunk) === false && source.pause) { source.pause() } } - source.on('data', ondata) - function ondrain() { if (source.readable && source.resume) { source.resume() } } + dest.on('drain', ondrain) - dest.on('drain', ondrain) // If the 'end' option is not supplied, dest.end() will be called when + // If the 'end' option is not supplied, dest.end() will be called when // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { source.on('end', onend) source.on('close', onclose) } - let didOnEnd = false - function onend() { if (didOnEnd) return didOnEnd = true dest.end() } - function onclose() { if (didOnEnd) return didOnEnd = true if (typeof dest.destroy === 'function') dest.destroy() - } // Don't leave dangling pipes when there are errors. + } + // Don't leave dangling pipes when there are errors. function onerror(er) { cleanup() - if (EE.listenerCount(this, 'error') === 0) { this.emit('error', er) } } - prependListener(source, 'error', onerror) - prependListener(dest, 'error', onerror) // Remove all the event listeners that were added. + prependListener(dest, 'error', onerror) + // Remove all the event listeners that were added. function cleanup() { source.removeListener('data', ondata) dest.removeListener('drain', ondrain) @@ -72,28 +62,27 @@ Stream.prototype.pipe = function (dest, options) { source.removeListener('close', cleanup) dest.removeListener('close', cleanup) } - source.on('end', cleanup) source.on('close', cleanup) dest.on('close', cleanup) - dest.emit('pipe', source) // Allow for unix-like usage: A.pipe(B).pipe(C) + dest.emit('pipe', source) + // Allow for unix-like usage: A.pipe(B).pipe(C) return dest } - function prependListener(emitter, event, fn) { // Sadly this is not cacheable as some libraries bundle their own // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn) // This is a hack to make sure that our error handler is attached before any + if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn) + + // This is a hack to make sure that our error handler is attached before any // userland ones. NEVER DO THIS. This is here only because this code needs // to continue to work with older versions of Node.js that do not include // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn) else if (ArrayIsArray(emitter._events[event])) emitter._events[event].unshift(fn) else emitter._events[event] = [fn, emitter._events[event]] } - module.exports = { Stream, prependListener diff --git a/lib/internal/streams/operators.js b/lib/internal/streams/operators.js index 11778e50f..323a74a17 100644 --- a/lib/internal/streams/operators.js +++ b/lib/internal/streams/operators.js @@ -1,18 +1,13 @@ 'use strict' const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const { codes: { ERR_INVALID_ARG_TYPE, ERR_MISSING_ARGS, ERR_OUT_OF_RANGE }, AbortError } = require('../../ours/errors') - const { validateAbortSignal, validateInteger, validateObject } = require('../validators') - const kWeakHandler = require('../../ours/primordials').Symbol('kWeak') - const { finished } = require('./end-of-stream') - const { ArrayPrototypePush, MathFloor, @@ -23,33 +18,25 @@ const { PromisePrototypeThen, Symbol } = require('../../ours/primordials') - const kEmpty = Symbol('kEmpty') const kEof = Symbol('kEof') - function map(fn, options) { if (typeof fn !== 'function') { throw new ERR_INVALID_ARG_TYPE('fn', ['Function', 'AsyncFunction'], fn) } - if (options != null) { validateObject(options, 'options') } - if ((options === null || options === undefined ? undefined : options.signal) != null) { validateAbortSignal(options.signal, 'options.signal') } - let concurrency = 1 - if ((options === null || options === undefined ? undefined : options.concurrency) != null) { concurrency = MathFloor(options.concurrency) } - validateInteger(concurrency, 'concurrency', 1) return async function* map() { var _options$signal, _options$signal2 - const ac = new AbortController() const stream = this const queue = [] @@ -57,9 +44,7 @@ function map(fn, options) { const signalOpt = { signal } - const abort = () => ac.abort() - if ( options !== null && options !== undefined && @@ -69,7 +54,6 @@ function map(fn, options) { ) { abort() } - options === null || options === undefined ? undefined : (_options$signal2 = options.signal) === null || _options$signal2 === undefined @@ -78,52 +62,41 @@ function map(fn, options) { let next let resume let done = false - function onDone() { done = true } - async function pump() { try { for await (let val of stream) { var _val - if (done) { return } - if (signal.aborted) { throw new AbortError() } - try { val = fn(val, signalOpt) } catch (err) { val = PromiseReject(err) } - if (val === kEmpty) { continue } - if (typeof ((_val = val) === null || _val === undefined ? undefined : _val.catch) === 'function') { val.catch(onDone) } - queue.push(val) - if (next) { next() next = null } - if (!done && queue.length && queue.length >= concurrency) { await new Promise((resolve) => { resume = resolve }) } } - queue.push(kEof) } catch (err) { const val = PromiseReject(err) @@ -131,14 +104,11 @@ function map(fn, options) { queue.push(val) } finally { var _options$signal3 - done = true - if (next) { next() next = null } - options === null || options === undefined ? undefined : (_options$signal3 = options.signal) === null || _options$signal3 === undefined @@ -146,34 +116,26 @@ function map(fn, options) { : _options$signal3.removeEventListener('abort', abort) } } - pump() - try { while (true) { while (queue.length > 0) { const val = await queue[0] - if (val === kEof) { return } - if (signal.aborted) { throw new AbortError() } - if (val !== kEmpty) { yield val } - queue.shift() - if (resume) { resume() resume = null } } - await new Promise((resolve) => { next = resolve }) @@ -181,7 +143,6 @@ function map(fn, options) { } finally { ac.abort() done = true - if (resume) { resume() resume = null @@ -189,22 +150,17 @@ function map(fn, options) { } }.call(this) } - function asIndexedPairs(options = undefined) { if (options != null) { validateObject(options, 'options') } - if ((options === null || options === undefined ? undefined : options.signal) != null) { validateAbortSignal(options.signal, 'options.signal') } - return async function* asIndexedPairs() { let index = 0 - for await (const val of this) { var _options$signal4 - if ( options !== null && options !== undefined && @@ -216,25 +172,21 @@ function asIndexedPairs(options = undefined) { cause: options.signal.reason }) } - yield [index++, val] } }.call(this) } - async function some(fn, options = undefined) { for await (const unused of filter.call(this, fn, options)) { return true } - return false } - async function every(fn, options = undefined) { if (typeof fn !== 'function') { throw new ERR_INVALID_ARG_TYPE('fn', ['Function', 'AsyncFunction'], fn) - } // https://en.wikipedia.org/wiki/De_Morgan%27s_laws - + } + // https://en.wikipedia.org/wiki/De_Morgan%27s_laws return !(await some.call( this, async (...args) => { @@ -243,69 +195,56 @@ async function every(fn, options = undefined) { options )) } - async function find(fn, options) { for await (const result of filter.call(this, fn, options)) { return result } - return undefined } - async function forEach(fn, options) { if (typeof fn !== 'function') { throw new ERR_INVALID_ARG_TYPE('fn', ['Function', 'AsyncFunction'], fn) } - async function forEachFn(value, options) { await fn(value, options) return kEmpty - } // eslint-disable-next-line no-unused-vars - + } + // eslint-disable-next-line no-unused-vars for await (const unused of map.call(this, forEachFn, options)); } - function filter(fn, options) { if (typeof fn !== 'function') { throw new ERR_INVALID_ARG_TYPE('fn', ['Function', 'AsyncFunction'], fn) } - async function filterFn(value, options) { if (await fn(value, options)) { return value } - return kEmpty } - return map.call(this, filterFn, options) -} // Specific to provide better error to reduce since the argument is only -// missing if the stream has no items in it - but the code is still appropriate +} +// Specific to provide better error to reduce since the argument is only +// missing if the stream has no items in it - but the code is still appropriate class ReduceAwareErrMissingArgs extends ERR_MISSING_ARGS { constructor() { super('reduce') this.message = 'Reduce of an empty stream requires an initial value' } } - async function reduce(reducer, initialValue, options) { var _options$signal5 - if (typeof reducer !== 'function') { throw new ERR_INVALID_ARG_TYPE('reducer', ['Function', 'AsyncFunction'], reducer) } - if (options != null) { validateObject(options, 'options') } - if ((options === null || options === undefined ? undefined : options.signal) != null) { validateAbortSignal(options.signal, 'options.signal') } - let hasInitialValue = arguments.length > 1 - if ( options !== null && options !== undefined && @@ -317,14 +256,11 @@ async function reduce(reducer, initialValue, options) { cause: options.signal.reason }) this.once('error', () => {}) // The error is already propagated - await finished(this.destroy(err)) throw err } - const ac = new AbortController() const signal = ac.signal - if (options !== null && options !== undefined && options.signal) { const opts = { once: true, @@ -332,15 +268,11 @@ async function reduce(reducer, initialValue, options) { } options.signal.addEventListener('abort', () => ac.abort(), opts) } - let gotAnyItemFromStream = false - try { for await (const value of this) { var _options$signal6 - gotAnyItemFromStream = true - if ( options !== null && options !== undefined && @@ -350,7 +282,6 @@ async function reduce(reducer, initialValue, options) { ) { throw new AbortError() } - if (!hasInitialValue) { initialValue = value hasInitialValue = true @@ -360,31 +291,24 @@ async function reduce(reducer, initialValue, options) { }) } } - if (!gotAnyItemFromStream && !hasInitialValue) { throw new ReduceAwareErrMissingArgs() } } finally { ac.abort() } - return initialValue } - async function toArray(options) { if (options != null) { validateObject(options, 'options') } - if ((options === null || options === undefined ? undefined : options.signal) != null) { validateAbortSignal(options.signal, 'options.signal') } - const result = [] - for await (const val of this) { var _options$signal7 - if ( options !== null && options !== undefined && @@ -396,13 +320,10 @@ async function toArray(options) { cause: options.signal.reason }) } - ArrayPrototypePush(result, val) } - return result } - function flatMap(fn, options) { const values = map.call(this, fn, options) return async function* flatMap() { @@ -411,36 +332,28 @@ function flatMap(fn, options) { } }.call(this) } - function toIntegerOrInfinity(number) { // We coerce here to align with the spec // https://github.com/tc39/proposal-iterator-helpers/issues/169 number = Number(number) - if (NumberIsNaN(number)) { return 0 } - if (number < 0) { throw new ERR_OUT_OF_RANGE('number', '>= 0', number) } - return number } - function drop(number, options = undefined) { if (options != null) { validateObject(options, 'options') } - if ((options === null || options === undefined ? undefined : options.signal) != null) { validateAbortSignal(options.signal, 'options.signal') } - number = toIntegerOrInfinity(number) return async function* drop() { var _options$signal8 - if ( options !== null && options !== undefined && @@ -450,10 +363,8 @@ function drop(number, options = undefined) { ) { throw new AbortError() } - for await (const val of this) { var _options$signal9 - if ( options !== null && options !== undefined && @@ -463,27 +374,22 @@ function drop(number, options = undefined) { ) { throw new AbortError() } - if (number-- <= 0) { yield val } } }.call(this) } - function take(number, options = undefined) { if (options != null) { validateObject(options, 'options') } - if ((options === null || options === undefined ? undefined : options.signal) != null) { validateAbortSignal(options.signal, 'options.signal') } - number = toIntegerOrInfinity(number) return async function* take() { var _options$signal10 - if ( options !== null && options !== undefined && @@ -493,10 +399,8 @@ function take(number, options = undefined) { ) { throw new AbortError() } - for await (const val of this) { var _options$signal11 - if ( options !== null && options !== undefined && @@ -506,7 +410,6 @@ function take(number, options = undefined) { ) { throw new AbortError() } - if (number-- > 0) { yield val } else { @@ -515,7 +418,6 @@ function take(number, options = undefined) { } }.call(this) } - module.exports.streamReturningOperators = { asIndexedPairs, drop, diff --git a/lib/internal/streams/passthrough.js b/lib/internal/streams/passthrough.js index 55c551723..ed4f486c3 100644 --- a/lib/internal/streams/passthrough.js +++ b/lib/internal/streams/passthrough.js @@ -18,25 +18,22 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + // a passthrough stream. // basically just the most minimal sort of Transform stream. // Every written chunk gets output as-is. + 'use strict' const { ObjectSetPrototypeOf } = require('../../ours/primordials') - module.exports = PassThrough - const Transform = require('./transform') - ObjectSetPrototypeOf(PassThrough.prototype, Transform.prototype) ObjectSetPrototypeOf(PassThrough, Transform) - function PassThrough(options) { if (!(this instanceof PassThrough)) return new PassThrough(options) Transform.call(this, options) } - PassThrough.prototype._transform = function (chunk, encoding, cb) { cb(null, chunk) } diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js index c170b4832..d5392fa59 100644 --- a/lib/internal/streams/pipeline.js +++ b/lib/internal/streams/pipeline.js @@ -1,21 +1,17 @@ /* replacement start */ + const process = require('process') + /* replacement end */ // Ported from https://github.com/mafintosh/pump with // permission from the author, Mathias Buus (@mafintosh). ;('use strict') - const { ArrayIsArray, Promise, SymbolAsyncIterator } = require('../../ours/primordials') - const eos = require('./end-of-stream') - const { once } = require('../../ours/util') - const destroyImpl = require('./destroy') - const Duplex = require('./duplex') - const { aggregateTwoErrors, codes: { @@ -27,16 +23,11 @@ const { }, AbortError } = require('../../ours/errors') - const { validateFunction, validateAbortSignal } = require('../validators') - const { isIterable, isReadable, isReadableNodeStream, isNodeStream } = require('./utils') - const AbortController = globalThis.AbortController || require('abort-controller').AbortController - let PassThrough let Readable - function destroyer(stream, reading, writing) { let finished = false stream.on('close', () => { @@ -61,7 +52,6 @@ function destroyer(stream, reading, writing) { cleanup } } - function popCallback(streams) { // Streams should never be an empty array. It should always contain at least // a single stream. Therefore optimize for the average case instead of @@ -69,7 +59,6 @@ function popCallback(streams) { validateFunction(streams[streams.length - 1], 'streams[stream.length - 1]') return streams.pop() } - function makeAsyncIterable(val) { if (isIterable(val)) { return val @@ -77,34 +66,27 @@ function makeAsyncIterable(val) { // Legacy streams are not Iterable. return fromReadable(val) } - throw new ERR_INVALID_ARG_TYPE('val', ['Readable', 'Iterable', 'AsyncIterable'], val) } - async function* fromReadable(val) { if (!Readable) { Readable = require('./readable') } - yield* Readable.prototype[SymbolAsyncIterator].call(val) } - async function pump(iterable, writable, finish, { end }) { let error let onresolve = null - const resume = (err) => { if (err) { error = err } - if (onresolve) { const callback = onresolve onresolve = null callback() } } - const wait = () => new Promise((resolve, reject) => { if (error) { @@ -119,7 +101,6 @@ async function pump(iterable, writable, finish, { end }) { } } }) - writable.on('drain', resume) const cleanup = eos( writable, @@ -128,22 +109,18 @@ async function pump(iterable, writable, finish, { end }) { }, resume ) - try { if (writable.writableNeedDrain) { await wait() } - for await (const chunk of iterable) { if (!writable.write(chunk)) { await wait() } } - if (end) { writable.end() } - await wait() finish() } catch (err) { @@ -153,107 +130,88 @@ async function pump(iterable, writable, finish, { end }) { writable.off('drain', resume) } } - function pipeline(...streams) { return pipelineImpl(streams, once(popCallback(streams))) } - function pipelineImpl(streams, callback, opts) { if (streams.length === 1 && ArrayIsArray(streams[0])) { streams = streams[0] } - if (streams.length < 2) { throw new ERR_MISSING_ARGS('streams') } - const ac = new AbortController() const signal = ac.signal - const outerSignal = opts === null || opts === undefined ? undefined : opts.signal // Need to cleanup event listeners if last stream is readable - // https://github.com/nodejs/node/issues/35452 + const outerSignal = opts === null || opts === undefined ? undefined : opts.signal + // Need to cleanup event listeners if last stream is readable + // https://github.com/nodejs/node/issues/35452 const lastStreamCleanup = [] validateAbortSignal(outerSignal, 'options.signal') - function abort() { finishImpl(new AbortError()) } - outerSignal === null || outerSignal === undefined ? undefined : outerSignal.addEventListener('abort', abort) let error let value const destroys = [] let finishCount = 0 - function finish(err) { finishImpl(err, --finishCount === 0) } - function finishImpl(err, final) { if (err && (!error || error.code === 'ERR_STREAM_PREMATURE_CLOSE')) { error = err } - if (!error && !final) { return } - while (destroys.length) { destroys.shift()(error) } - outerSignal === null || outerSignal === undefined ? undefined : outerSignal.removeEventListener('abort', abort) ac.abort() - if (final) { if (!error) { lastStreamCleanup.forEach((fn) => fn()) } - process.nextTick(callback, error, value) } } - let ret - for (let i = 0; i < streams.length; i++) { const stream = streams[i] const reading = i < streams.length - 1 const writing = i > 0 const end = reading || (opts === null || opts === undefined ? undefined : opts.end) !== false const isLastStream = i === streams.length - 1 - if (isNodeStream(stream)) { if (end) { const { destroy, cleanup } = destroyer(stream, reading, writing) destroys.push(destroy) - if (isReadable(stream) && isLastStream) { lastStreamCleanup.push(cleanup) } - } // Catch stream errors that occur after pipe/pump has completed. + } + // Catch stream errors that occur after pipe/pump has completed. function onError(err) { if (err && err.name !== 'AbortError' && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') { finish(err) } } - stream.on('error', onError) - if (isReadable(stream) && isLastStream) { lastStreamCleanup.push(() => { stream.removeListener('error', onError) }) } } - if (i === 0) { if (typeof stream === 'function') { ret = stream({ signal }) - if (!isIterable(ret)) { throw new ERR_INVALID_RETURN_VALUE('Iterable, AsyncIterable or Stream', 'source', ret) } @@ -267,43 +225,40 @@ function pipelineImpl(streams, callback, opts) { ret = stream(ret, { signal }) - if (reading) { if (!isIterable(ret, true)) { throw new ERR_INVALID_RETURN_VALUE('AsyncIterable', `transform[${i - 1}]`, ret) } } else { var _ret - if (!PassThrough) { PassThrough = require('./passthrough') - } // If the last argument to pipeline is not a stream + } + + // If the last argument to pipeline is not a stream // we must create a proxy stream so that pipeline(...) // always returns a stream which can be further // composed through `.pipe(stream)`. const pt = new PassThrough({ objectMode: true - }) // Handle Promises/A+ spec, `then` could be a getter that throws on - // second use. + }) + // Handle Promises/A+ spec, `then` could be a getter that throws on + // second use. const then = (_ret = ret) === null || _ret === undefined ? undefined : _ret.then - if (typeof then === 'function') { finishCount++ then.call( ret, (val) => { value = val - if (val != null) { pt.write(val) } - if (end) { pt.end() } - process.nextTick(finish) }, (err) => { @@ -319,11 +274,9 @@ function pipelineImpl(streams, callback, opts) { } else { throw new ERR_INVALID_RETURN_VALUE('AsyncIterable or Promise', 'destination', ret) } - ret = pt const { destroy, cleanup } = destroyer(ret, false, true) destroys.push(destroy) - if (isLastStream) { lastStreamCleanup.push(cleanup) } @@ -334,7 +287,6 @@ function pipelineImpl(streams, callback, opts) { const cleanup = pipe(ret, stream, finish, { end }) - if (isReadable(stream) && isLastStream) { lastStreamCleanup.push(cleanup) } @@ -346,23 +298,19 @@ function pipelineImpl(streams, callback, opts) { } else { throw new ERR_INVALID_ARG_TYPE('val', ['Readable', 'Iterable', 'AsyncIterable'], ret) } - ret = stream } else { ret = Duplex.from(stream) } } - if ( (signal !== null && signal !== undefined && signal.aborted) || (outerSignal !== null && outerSignal !== undefined && outerSignal.aborted) ) { process.nextTick(abort) } - return ret } - function pipe(src, dst, finish, { end }) { let ended = false dst.on('close', () => { @@ -374,7 +322,6 @@ function pipe(src, dst, finish, { end }) { src.pipe(dst, { end }) - if (end) { // Compat. Before node v10.12.0 stdio used to throw an error so // pipe() did/does not end() stdio destinations. @@ -386,7 +333,6 @@ function pipe(src, dst, finish, { end }) { } else { finish() } - eos( src, { @@ -395,7 +341,6 @@ function pipe(src, dst, finish, { end }) { }, (err) => { const rState = src._readableState - if ( err && err.code === 'ERR_STREAM_PREMATURE_CLOSE' && @@ -427,7 +372,6 @@ function pipe(src, dst, finish, { end }) { finish ) } - module.exports = { pipelineImpl, pipeline diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js index 299299d24..b800ee3c2 100644 --- a/lib/internal/streams/readable.js +++ b/lib/internal/streams/readable.js @@ -1,5 +1,7 @@ /* replacement start */ + const process = require('process') + /* replacement end */ // Copyright Joyent, Inc. and other Node contributors. // @@ -23,7 +25,6 @@ const process = require('process') // USE OR OTHER DEALINGS IN THE SOFTWARE. ;('use strict') - const { ArrayPrototypeIndexOf, NumberIsInteger, @@ -37,30 +38,19 @@ const { SymbolAsyncIterator, Symbol } = require('../../ours/primordials') - module.exports = Readable Readable.ReadableState = ReadableState - const { EventEmitter: EE } = require('events') - const { Stream, prependListener } = require('./legacy') - const { Buffer } = require('buffer') - const { addAbortSignal } = require('./add-abort-signal') - const eos = require('./end-of-stream') - let debug = require('../../ours/util').debuglog('stream', (fn) => { debug = fn }) - const BufferList = require('./buffer_list') - const destroyImpl = require('./destroy') - const { getHighWaterMark, getDefaultHighWaterMark } = require('./state') - const { aggregateTwoErrors, codes: { @@ -71,118 +61,122 @@ const { ERR_STREAM_UNSHIFT_AFTER_END_EVENT } } = require('../../ours/errors') - const { validateObject } = require('../validators') - const kPaused = Symbol('kPaused') - const { StringDecoder } = require('string_decoder') - const from = require('./from') - ObjectSetPrototypeOf(Readable.prototype, Stream.prototype) ObjectSetPrototypeOf(Readable, Stream) - const nop = () => {} - const { errorOrDestroy } = destroyImpl - function ReadableState(options, stream, isDuplex) { // Duplex streams are both readable and writable, but share // the same options object. // However, some cases require setting options to different // values for the readable and the writable sides of the duplex stream. // These options can be provided separately as readableXXX and writableXXX. - if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof require('./duplex') // Object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away. + if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof require('./duplex') + // Object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away. this.objectMode = !!(options && options.objectMode) - if (isDuplex) this.objectMode = this.objectMode || !!(options && options.readableObjectMode) // The point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" + if (isDuplex) this.objectMode = this.objectMode || !!(options && options.readableObjectMode) + // The point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" this.highWaterMark = options ? getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex) - : getDefaultHighWaterMark(false) // A linked list is used to store data chunks instead of an array because the + : getDefaultHighWaterMark(false) + + // A linked list is used to store data chunks instead of an array because the // linked list can remove elements from the beginning faster than // array.shift(). - this.buffer = new BufferList() this.length = 0 this.pipes = [] this.flowing = null this.ended = false this.endEmitted = false - this.reading = false // Stream is still being constructed and cannot be + this.reading = false + + // Stream is still being constructed and cannot be // destroyed until construction finished or failed. // Async construction is opt in, therefore we start as // constructed. + this.constructed = true - this.constructed = true // A flag to be able to tell if the event 'readable'/'data' is emitted + // A flag to be able to tell if the event 'readable'/'data' is emitted // immediately, or on a later tick. We set this to true at first, because // any actions that shouldn't happen until "later" should generally also // not happen before the first read call. + this.sync = true - this.sync = true // Whenever we return null, then we set a flag to say + // Whenever we return null, then we set a flag to say // that we're awaiting a 'readable' event emission. - this.needReadable = false this.emittedReadable = false this.readableListening = false this.resumeScheduled = false - this[kPaused] = null // True if the error was already emitted and should not be thrown again. + this[kPaused] = null - this.errorEmitted = false // Should close be emitted on destroy. Defaults to true. + // True if the error was already emitted and should not be thrown again. + this.errorEmitted = false - this.emitClose = !options || options.emitClose !== false // Should .destroy() be called after 'end' (and potentially 'finish'). + // Should close be emitted on destroy. Defaults to true. + this.emitClose = !options || options.emitClose !== false - this.autoDestroy = !options || options.autoDestroy !== false // Has it been destroyed. + // Should .destroy() be called after 'end' (and potentially 'finish'). + this.autoDestroy = !options || options.autoDestroy !== false - this.destroyed = false // Indicates whether the stream has errored. When true no further + // Has it been destroyed. + this.destroyed = false + + // Indicates whether the stream has errored. When true no further // _read calls, 'data' or 'readable' events should occur. This is needed // since when autoDestroy is disabled we need a way to tell whether the // stream has failed. + this.errored = null - this.errored = null // Indicates whether the stream has finished destroying. + // Indicates whether the stream has finished destroying. + this.closed = false - this.closed = false // True if close has been emitted or would have been emitted + // True if close has been emitted or would have been emitted // depending on emitClose. + this.closeEmitted = false - this.closeEmitted = false // Crypto is kind of old and crusty. Historically, its default string + // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = (options && options.defaultEncoding) || 'utf8' - this.defaultEncoding = (options && options.defaultEncoding) || 'utf8' // Ref the piped dest which we need a drain event on it + // Ref the piped dest which we need a drain event on it // type: null | Writable | Set. - this.awaitDrainWriters = null - this.multiAwaitDrain = false // If true, a maybeReadMore has been scheduled. + this.multiAwaitDrain = false + // If true, a maybeReadMore has been scheduled. this.readingMore = false this.dataEmitted = false this.decoder = null this.encoding = null - if (options && options.encoding) { this.decoder = new StringDecoder(options.encoding) this.encoding = options.encoding } } - function Readable(options) { - if (!(this instanceof Readable)) return new Readable(options) // Checking for a Stream.Duplex instance is faster here instead of inside - // the ReadableState constructor, at least with V8 6.5. + if (!(this instanceof Readable)) return new Readable(options) + // Checking for a Stream.Duplex instance is faster here instead of inside + // the ReadableState constructor, at least with V8 6.5. const isDuplex = this instanceof require('./duplex') - this._readableState = new ReadableState(options, this, isDuplex) - if (options) { if (typeof options.read === 'function') this._read = options.read if (typeof options.destroy === 'function') this._destroy = options.destroy if (typeof options.construct === 'function') this._construct = options.construct if (options.signal && !isDuplex) addAbortSignal(options.signal, this) } - Stream.call(this, options) destroyImpl.construct(this, () => { if (this._readableState.needReadable) { @@ -190,38 +184,34 @@ function Readable(options) { } }) } - Readable.prototype.destroy = destroyImpl.destroy Readable.prototype._undestroy = destroyImpl.undestroy - Readable.prototype._destroy = function (err, cb) { cb(err) } - Readable.prototype[EE.captureRejectionSymbol] = function (err) { this.destroy(err) -} // Manually shove something into the read() buffer. +} + +// Manually shove something into the read() buffer. // This returns true if the highWaterMark has not been hit yet, // similar to how Writable.write() returns true if you should // write() some more. - Readable.prototype.push = function (chunk, encoding) { return readableAddChunk(this, chunk, encoding, false) -} // Unshift should *always* be something directly out of read(). +} +// Unshift should *always* be something directly out of read(). Readable.prototype.unshift = function (chunk, encoding) { return readableAddChunk(this, chunk, encoding, true) } - function readableAddChunk(stream, chunk, encoding, addToFront) { debug('readableAddChunk', chunk) const state = stream._readableState let err - if (!state.objectMode) { if (typeof chunk === 'string') { encoding = encoding || state.defaultEncoding - if (state.encoding !== encoding) { if (addToFront && state.encoding) { // When unshifting, if state.encoding is set, we have to save @@ -241,7 +231,6 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { err = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk) } } - if (err) { errorOrDestroy(stream, err) } else if (chunk === null) { @@ -258,7 +247,6 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { return false } else { state.reading = false - if (state.decoder && !encoding) { chunk = state.decoder.write(chunk) if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false) @@ -270,13 +258,13 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { } else if (!addToFront) { state.reading = false maybeReadMore(stream, state) - } // We can push more data if we are below the highWaterMark. + } + + // We can push more data if we are below the highWaterMark. // Also, if we have no data yet, we can stand some more bytes. // This is to work around cases where hwm=0, such as the repl. - return !state.ended && (state.length < state.highWaterMark || state.length === 0) } - function addChunk(stream, state, chunk, addToFront) { if (state.flowing && state.length === 0 && !state.sync && stream.listenerCount('data') > 0) { // Use the guard to avoid creating `Set()` repeatedly @@ -286,7 +274,6 @@ function addChunk(stream, state, chunk, addToFront) { } else { state.awaitDrainWriters = null } - state.dataEmitted = true stream.emit('data', chunk) } else { @@ -296,36 +283,33 @@ function addChunk(stream, state, chunk, addToFront) { else state.buffer.push(chunk) if (state.needReadable) emitReadable(stream) } - maybeReadMore(stream, state) } - Readable.prototype.isPaused = function () { const state = this._readableState return state[kPaused] === true || state.flowing === false -} // Backwards compatibility. +} +// Backwards compatibility. Readable.prototype.setEncoding = function (enc) { const decoder = new StringDecoder(enc) - this._readableState.decoder = decoder // If setEncoding(null), decoder.encoding equals utf8. - + this._readableState.decoder = decoder + // If setEncoding(null), decoder.encoding equals utf8. this._readableState.encoding = this._readableState.decoder.encoding - const buffer = this._readableState.buffer // Iterate over current buffer to convert already stored Buffers: - + const buffer = this._readableState.buffer + // Iterate over current buffer to convert already stored Buffers: let content = '' - for (const data of buffer) { content += decoder.write(data) } - buffer.clear() if (content !== '') buffer.push(content) this._readableState.length = content.length return this -} // Don't raise the hwm > 1GB. +} +// Don't raise the hwm > 1GB. const MAX_HWM = 0x40000000 - function computeNewHighWaterMark(n) { if (n > MAX_HWM) { throw new ERR_OUT_OF_RANGE('size', '<= 1GiB', n) @@ -340,43 +324,43 @@ function computeNewHighWaterMark(n) { n |= n >>> 16 n++ } - return n -} // This function is designed to be inlinable, so please take care when making -// changes to the function body. +} +// This function is designed to be inlinable, so please take care when making +// changes to the function body. function howMuchToRead(n, state) { if (n <= 0 || (state.length === 0 && state.ended)) return 0 if (state.objectMode) return 1 - if (NumberIsNaN(n)) { // Only flow one buffer at a time. if (state.flowing && state.length) return state.buffer.first().length return state.length } - if (n <= state.length) return n return state.ended ? state.length : 0 -} // You can override either this method, or the async _read(n) below. +} +// You can override either this method, or the async _read(n) below. Readable.prototype.read = function (n) { - debug('read', n) // Same as parseInt(undefined, 10), however V8 7.3 performance regressed + debug('read', n) + // Same as parseInt(undefined, 10), however V8 7.3 performance regressed // in this scenario, so we are doing it manually. - if (n === undefined) { n = NaN } else if (!NumberIsInteger(n)) { n = NumberParseInt(n, 10) } - const state = this._readableState - const nOrig = n // If we're asking for more than the current hwm, then raise the hwm. + const nOrig = n + // If we're asking for more than the current hwm, then raise the hwm. if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n) - if (n !== 0) state.emittedReadable = false // If we're doing read(0) to trigger a readable event, but we + if (n !== 0) state.emittedReadable = false + + // If we're doing read(0) to trigger a readable event, but we // already have a bunch of data in the buffer, then just trigger // the 'readable' event and move on. - if ( n === 0 && state.needReadable && @@ -387,13 +371,15 @@ Readable.prototype.read = function (n) { else emitReadable(this) return null } + n = howMuchToRead(n, state) - n = howMuchToRead(n, state) // If we've ended, and we're now clear, then finish it up. - + // If we've ended, and we're now clear, then finish it up. if (n === 0 && state.ended) { if (state.length === 0) endReadable(this) return null - } // All the actual chunk generation logic needs to be + } + + // All the actual chunk generation logic needs to be // *below* the call to _read. The reason is that in certain // synthetic stream cases, such as passthrough streams, _read // may be a completely synchronous operation which may change @@ -414,88 +400,80 @@ Readable.prototype.read = function (n) { // 'readable' etc. // // 3. Actually pull the requested chunks out of the buffer and return. - // if we need a readable event, then we need to do some reading. + // if we need a readable event, then we need to do some reading. let doRead = state.needReadable - debug('need readable', doRead) // If we currently have less than the highWaterMark, then also read some. + debug('need readable', doRead) + // If we currently have less than the highWaterMark, then also read some. if (state.length === 0 || state.length - n < state.highWaterMark) { doRead = true debug('length less than watermark', doRead) - } // However, if we've ended, then there's no point, if we're already + } + + // However, if we've ended, then there's no point, if we're already // reading, then it's unnecessary, if we're constructing we have to wait, // and if we're destroyed or errored, then it's not allowed, - if (state.ended || state.reading || state.destroyed || state.errored || !state.constructed) { doRead = false debug('reading, ended or constructing', doRead) } else if (doRead) { debug('do read') state.reading = true - state.sync = true // If the length is currently zero, then we *need* a readable event. - - if (state.length === 0) state.needReadable = true // Call internal read method + state.sync = true + // If the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true + // Call internal read method try { this._read(state.highWaterMark) } catch (err) { errorOrDestroy(this, err) } - - state.sync = false // If _read pushed data synchronously, then `reading` will be false, + state.sync = false + // If _read pushed data synchronously, then `reading` will be false, // and we need to re-evaluate how much data we can return to the user. - if (!state.reading) n = howMuchToRead(nOrig, state) } - let ret if (n > 0) ret = fromList(n, state) else ret = null - if (ret === null) { state.needReadable = state.length <= state.highWaterMark n = 0 } else { state.length -= n - if (state.multiAwaitDrain) { state.awaitDrainWriters.clear() } else { state.awaitDrainWriters = null } } - if (state.length === 0) { // If we have nothing in the buffer, then we want to know // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true // If we tried to read() past the EOF, then emit end on the next tick. + if (!state.ended) state.needReadable = true + // If we tried to read() past the EOF, then emit end on the next tick. if (nOrig !== n && state.ended) endReadable(this) } - if (ret !== null && !state.errorEmitted && !state.closeEmitted) { state.dataEmitted = true this.emit('data', ret) } - return ret } - function onEofChunk(stream, state) { debug('onEofChunk') if (state.ended) return - if (state.decoder) { const chunk = state.decoder.end() - if (chunk && chunk.length) { state.buffer.push(chunk) state.length += state.objectMode ? 1 : chunk.length } } - state.ended = true - if (state.sync) { // If we are sync, wait until next tick to emit the data. // Otherwise we risk emitting data in the flow() @@ -504,57 +482,56 @@ function onEofChunk(stream, state) { } else { // Emit 'readable' now to make sure it gets picked up. state.needReadable = false - state.emittedReadable = true // We have to emit readable now that we are EOF. Modules + state.emittedReadable = true + // We have to emit readable now that we are EOF. Modules // in the ecosystem (e.g. dicer) rely on this event being sync. - emitReadable_(stream) } -} // Don't emit readable right away in sync mode, because this can trigger +} + +// Don't emit readable right away in sync mode, because this can trigger // another read() call => stack overflow. This way, it might trigger // a nextTick recursion warning, but that's not so bad. - function emitReadable(stream) { const state = stream._readableState debug('emitReadable', state.needReadable, state.emittedReadable) state.needReadable = false - if (!state.emittedReadable) { debug('emitReadable', state.flowing) state.emittedReadable = true process.nextTick(emitReadable_, stream) } } - function emitReadable_(stream) { const state = stream._readableState debug('emitReadable_', state.destroyed, state.length, state.ended) - if (!state.destroyed && !state.errored && (state.length || state.ended)) { stream.emit('readable') state.emittedReadable = false - } // The stream needs another readable event if: + } + + // The stream needs another readable event if: // 1. It is not flowing, as the flow mechanism will take // care of it. // 2. It is not ended. // 3. It is below the highWaterMark, so we can schedule // another readable later. - state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark flow(stream) -} // At this point, the user has presumably seen the 'readable' event, +} + +// At this point, the user has presumably seen the 'readable' event, // and called read() to consume some data. that may have triggered // in turn another _read(n) call, in which case reading = true if // it's in progress. // However, if we're not ended, or reading, and the length < hwm, // then go ahead and try to read some more preemptively. - function maybeReadMore(stream, state) { if (!state.readingMore && state.constructed) { state.readingMore = true process.nextTick(maybeReadMore_, stream, state) } } - function maybeReadMore_(stream, state) { // Attempt to read more data if we should. // @@ -591,28 +568,25 @@ function maybeReadMore_(stream, state) { // Didn't get any data, stop spinning. break } - state.readingMore = false -} // Abstract method. to be overridden in specific implementation classes. +} + +// Abstract method. to be overridden in specific implementation classes. // call cb(er, data) where data is <= n in length. // for virtual (non-string, non-buffer) streams, "length" is somewhat // arbitrary, and perhaps not very meaningful. - Readable.prototype._read = function (n) { throw new ERR_METHOD_NOT_IMPLEMENTED('_read()') } - Readable.prototype.pipe = function (dest, pipeOpts) { const src = this const state = this._readableState - if (state.pipes.length === 1) { if (!state.multiAwaitDrain) { state.multiAwaitDrain = true state.awaitDrainWriters = new SafeSet(state.awaitDrainWriters ? [state.awaitDrainWriters] : []) } } - state.pipes.push(dest) debug('pipe count=%d opts=%j', state.pipes.length, pipeOpts) const doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr @@ -620,10 +594,8 @@ Readable.prototype.pipe = function (dest, pipeOpts) { if (state.endEmitted) process.nextTick(endFn) else src.once('end', endFn) dest.on('unpipe', onunpipe) - function onunpipe(readable, unpipeInfo) { debug('onunpipe') - if (readable === src) { if (unpipeInfo && unpipeInfo.hasUnpiped === false) { unpipeInfo.hasUnpiped = true @@ -631,39 +603,34 @@ Readable.prototype.pipe = function (dest, pipeOpts) { } } } - function onend() { debug('onend') dest.end() } - let ondrain let cleanedUp = false - function cleanup() { - debug('cleanup') // Cleanup event handlers once the pipe is broken. - + debug('cleanup') + // Cleanup event handlers once the pipe is broken. dest.removeListener('close', onclose) dest.removeListener('finish', onfinish) - if (ondrain) { dest.removeListener('drain', ondrain) } - dest.removeListener('error', onerror) dest.removeListener('unpipe', onunpipe) src.removeListener('end', onend) src.removeListener('end', unpipe) src.removeListener('data', ondata) - cleanedUp = true // If the reader is waiting for a drain event from this + cleanedUp = true + + // If the reader is waiting for a drain event from this // specific writer, then it would cause it to never start // flowing again. // So, if this is awaiting a drain, then we just call it now. // If we don't know, then assume that we are waiting for one. - if (ondrain && state.awaitDrainWriters && (!dest._writableState || dest._writableState.needDrain)) ondrain() } - function pause() { // If the user unpiped during `dest.write()`, it is possible // to get stuck in a permanently paused state if that write @@ -678,10 +645,8 @@ Readable.prototype.pipe = function (dest, pipeOpts) { debug('false write response, pause', state.awaitDrainWriters.size) state.awaitDrainWriters.add(dest) } - src.pause() } - if (!ondrain) { // When the dest drains, it reduces the awaitDrain counter // on the source. This would be more elegant with a .once() @@ -691,28 +656,24 @@ Readable.prototype.pipe = function (dest, pipeOpts) { dest.on('drain', ondrain) } } - src.on('data', ondata) - function ondata(chunk) { debug('ondata') const ret = dest.write(chunk) debug('dest.write', ret) - if (ret === false) { pause() } - } // If the dest has an error, then stop piping into it. - // However, don't suppress the throwing behavior for this. + } + // If the dest has an error, then stop piping into it. + // However, don't suppress the throwing behavior for this. function onerror(er) { debug('onerror', er) unpipe() dest.removeListener('error', onerror) - if (dest.listenerCount('error') === 0) { const s = dest._writableState || dest._readableState - if (s && !s.errorEmitted) { // User incorrectly emitted 'error' directly on the stream. errorOrDestroy(dest, er) @@ -720,31 +681,32 @@ Readable.prototype.pipe = function (dest, pipeOpts) { dest.emit('error', er) } } - } // Make sure our error handler is attached before userland ones. + } - prependListener(dest, 'error', onerror) // Both close and finish should trigger unpipe, but only once. + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror) + // Both close and finish should trigger unpipe, but only once. function onclose() { dest.removeListener('finish', onfinish) unpipe() } - dest.once('close', onclose) - function onfinish() { debug('onfinish') dest.removeListener('close', onclose) unpipe() } - dest.once('finish', onfinish) - function unpipe() { debug('unpipe') src.unpipe(dest) - } // Tell the dest that it's being piped to. + } + + // Tell the dest that it's being piped to. + dest.emit('pipe', src) - dest.emit('pipe', src) // Start the flow if it hasn't been started already. + // Start the flow if it hasn't been started already. if (dest.writableNeedDrain === true) { if (state.flowing) { @@ -754,16 +716,15 @@ Readable.prototype.pipe = function (dest, pipeOpts) { debug('pipe resume') src.resume() } - return dest } - function pipeOnDrain(src, dest) { return function pipeOnDrainFunctionResult() { - const state = src._readableState // `ondrain` will call directly, + const state = src._readableState + + // `ondrain` will call directly, // `this` maybe not a reference to dest, // so we use the real dest here. - if (state.awaitDrainWriters === dest) { debug('pipeOnDrain', 1) state.awaitDrainWriters = null @@ -771,53 +732,51 @@ function pipeOnDrain(src, dest) { debug('pipeOnDrain', state.awaitDrainWriters.size) state.awaitDrainWriters.delete(dest) } - if ((!state.awaitDrainWriters || state.awaitDrainWriters.size === 0) && src.listenerCount('data')) { src.resume() } } } - Readable.prototype.unpipe = function (dest) { const state = this._readableState const unpipeInfo = { hasUnpiped: false - } // If we're not piping anywhere, then do nothing. + } + // If we're not piping anywhere, then do nothing. if (state.pipes.length === 0) return this - if (!dest) { // remove all. const dests = state.pipes state.pipes = [] this.pause() - for (let i = 0; i < dests.length; i++) dests[i].emit('unpipe', this, { hasUnpiped: false }) - return this - } // Try to find the right one. + } + // Try to find the right one. const index = ArrayPrototypeIndexOf(state.pipes, dest) if (index === -1) return this state.pipes.splice(index, 1) if (state.pipes.length === 0) this.pause() dest.emit('unpipe', this, unpipeInfo) return this -} // Set up data events if they are asked for -// Ensure readable listeners eventually get something. +} +// Set up data events if they are asked for +// Ensure readable listeners eventually get something. Readable.prototype.on = function (ev, fn) { const res = Stream.prototype.on.call(this, ev, fn) const state = this._readableState - if (ev === 'data') { // Update readableListening so that resume() may be a no-op // a few lines down. This is needed to support once('readable'). - state.readableListening = this.listenerCount('readable') > 0 // Try start flowing on next tick if stream isn't explicitly paused. + state.readableListening = this.listenerCount('readable') > 0 + // Try start flowing on next tick if stream isn't explicitly paused. if (state.flowing !== false) this.resume() } else if (ev === 'readable') { if (!state.endEmitted && !state.readableListening) { @@ -825,7 +784,6 @@ Readable.prototype.on = function (ev, fn) { state.flowing = false state.emittedReadable = false debug('on readable', state.length, state.reading) - if (state.length) { emitReadable(this) } else if (!state.reading) { @@ -833,15 +791,11 @@ Readable.prototype.on = function (ev, fn) { } } } - return res } - Readable.prototype.addListener = Readable.prototype.on - Readable.prototype.removeListener = function (ev, fn) { const res = Stream.prototype.removeListener.call(this, ev, fn) - if (ev === 'readable') { // We need to check if there is someone still listening to // readable and reset the state. However this needs to happen @@ -851,15 +805,11 @@ Readable.prototype.removeListener = function (ev, fn) { // effect. process.nextTick(updateReadableListening, this) } - return res } - Readable.prototype.off = Readable.prototype.removeListener - Readable.prototype.removeAllListeners = function (ev) { const res = Stream.prototype.removeAllListeners.apply(this, arguments) - if (ev === 'readable' || ev === undefined) { // We need to check if there is someone still listening to // readable and reset the state. However this needs to happen @@ -869,91 +819,82 @@ Readable.prototype.removeAllListeners = function (ev) { // effect. process.nextTick(updateReadableListening, this) } - return res } - function updateReadableListening(self) { const state = self._readableState state.readableListening = self.listenerCount('readable') > 0 - if (state.resumeScheduled && state[kPaused] === false) { // Flowing needs to be set to true now, otherwise // the upcoming resume will not flow. - state.flowing = true // Crude way to check if we should resume. + state.flowing = true + + // Crude way to check if we should resume. } else if (self.listenerCount('data') > 0) { self.resume() } else if (!state.readableListening) { state.flowing = null } } - function nReadingNextTick(self) { debug('readable nexttick read 0') self.read(0) -} // pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. +} +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. Readable.prototype.resume = function () { const state = this._readableState - if (!state.flowing) { - debug('resume') // We flow only if there is no one listening + debug('resume') + // We flow only if there is no one listening // for readable, but we still have to call // resume(). - state.flowing = !state.readableListening resume(this, state) } - state[kPaused] = false return this } - function resume(stream, state) { if (!state.resumeScheduled) { state.resumeScheduled = true process.nextTick(resume_, stream, state) } } - function resume_(stream, state) { debug('resume', state.reading) - if (!state.reading) { stream.read(0) } - state.resumeScheduled = false stream.emit('resume') flow(stream) if (state.flowing && !state.reading) stream.read(0) } - Readable.prototype.pause = function () { debug('call pause flowing=%j', this._readableState.flowing) - if (this._readableState.flowing !== false) { debug('pause') this._readableState.flowing = false this.emit('pause') } - this._readableState[kPaused] = true return this } - function flow(stream) { const state = stream._readableState debug('flow', state.flowing) - while (state.flowing && stream.read() !== null); -} // Wrap an old-style stream as the async data source. +} + +// Wrap an old-style stream as the async data source. // This is *not* part of the readable stream interface. // It is an ugly unfortunate mess of history. - Readable.prototype.wrap = function (stream) { - let paused = false // TODO (ronag): Should this.destroy(err) emit + let paused = false + + // TODO (ronag): Should this.destroy(err) emit // 'error' on the wrapped stream? Would require // a static factory method, e.g. Readable.wrap(stream). @@ -975,54 +916,44 @@ Readable.prototype.wrap = function (stream) { stream.on('destroy', () => { this.destroy() }) - this._read = () => { if (paused && stream.resume) { paused = false stream.resume() } - } // Proxy all the other methods. Important when wrapping filters and duplexes. + } + // Proxy all the other methods. Important when wrapping filters and duplexes. const streamKeys = ObjectKeys(stream) - for (let j = 1; j < streamKeys.length; j++) { const i = streamKeys[j] - if (this[i] === undefined && typeof stream[i] === 'function') { this[i] = stream[i].bind(stream) } } - return this } - Readable.prototype[SymbolAsyncIterator] = function () { return streamToAsyncIterator(this) } - Readable.prototype.iterator = function (options) { if (options !== undefined) { validateObject(options, 'options') } - return streamToAsyncIterator(this, options) } - function streamToAsyncIterator(stream, options) { if (typeof stream.read !== 'function') { stream = Readable.wrap(stream, { objectMode: true }) } - const iter = createAsyncIterator(stream, options) iter.stream = stream return iter } - async function* createAsyncIterator(stream, options) { let callback = nop - function next(resolve) { if (this === stream) { callback() @@ -1031,7 +962,6 @@ async function* createAsyncIterator(stream, options) { callback = resolve } } - stream.on('readable', next) let error const cleanup = eos( @@ -1045,11 +975,9 @@ async function* createAsyncIterator(stream, options) { callback = nop } ) - try { while (true) { const chunk = stream.destroyed ? null : stream.read() - if (chunk !== null) { yield chunk } else if (error) { @@ -1074,23 +1002,22 @@ async function* createAsyncIterator(stream, options) { cleanup() } } -} // Making it explicit these properties are not enumerable +} + +// Making it explicit these properties are not enumerable // because otherwise some prototype manipulation in // userland will fail. - ObjectDefineProperties(Readable.prototype, { readable: { __proto__: null, - get() { - const r = this._readableState // r.readable === false means that this is part of a Duplex stream + const r = this._readableState + // r.readable === false means that this is part of a Duplex stream // where the readable side was disabled upon construction. // Compat. The user might manually disable readable side through // deprecated setter. - return !!r && r.readable !== false && !r.destroyed && !r.errorEmitted && !r.endEmitted }, - set(val) { // Backwards compat. if (this._readableState) { @@ -1145,7 +1072,6 @@ ObjectDefineProperties(Readable.prototype, { readableLength: { __proto__: null, enumerable: false, - get() { return this._readableState.length } @@ -1153,7 +1079,6 @@ ObjectDefineProperties(Readable.prototype, { readableObjectMode: { __proto__: null, enumerable: false, - get() { return this._readableState ? this._readableState.objectMode : false } @@ -1161,7 +1086,6 @@ ObjectDefineProperties(Readable.prototype, { readableEncoding: { __proto__: null, enumerable: false, - get() { return this._readableState ? this._readableState.encoding : null } @@ -1169,14 +1093,12 @@ ObjectDefineProperties(Readable.prototype, { errored: { __proto__: null, enumerable: false, - get() { return this._readableState ? this._readableState.errored : null } }, closed: { __proto__: null, - get() { return this._readableState ? this._readableState.closed : false } @@ -1184,26 +1106,24 @@ ObjectDefineProperties(Readable.prototype, { destroyed: { __proto__: null, enumerable: false, - get() { return this._readableState ? this._readableState.destroyed : false }, - set(value) { // We ignore the value if the stream // has not been initialized yet. if (!this._readableState) { return - } // Backward compatibility, the user is explicitly - // managing destroyed. + } + // Backward compatibility, the user is explicitly + // managing destroyed. this._readableState.destroyed = value } }, readableEnded: { __proto__: null, enumerable: false, - get() { return this._readableState ? this._readableState.endEmitted : false } @@ -1213,7 +1133,6 @@ ObjectDefineProperties(ReadableState.prototype, { // Legacy getter for `pipesCount`. pipesCount: { __proto__: null, - get() { return this.pipes.length } @@ -1221,22 +1140,22 @@ ObjectDefineProperties(ReadableState.prototype, { // Legacy property for `paused`. paused: { __proto__: null, - get() { return this[kPaused] !== false }, - set(value) { this[kPaused] = !!value } } -}) // Exposed for testing purposes only. +}) + +// Exposed for testing purposes only. +Readable._fromList = fromList -Readable._fromList = fromList // Pluck off n bytes from an array of buffers. +// Pluck off n bytes from an array of buffers. // Length is the combined lengths of all the buffers in the list. // This function is designed to be inlinable, so please take care when making // changes to the function body. - function fromList(n, state) { // nothing buffered. if (state.length === 0) return null @@ -1254,24 +1173,21 @@ function fromList(n, state) { } return ret } - function endReadable(stream) { const state = stream._readableState debug('endReadable', state.endEmitted) - if (!state.endEmitted) { state.ended = true process.nextTick(endReadableNT, state, stream) } } - function endReadableNT(state, stream) { - debug('endReadableNT', state.endEmitted, state.length) // Check that we didn't get one last unshift. + debug('endReadableNT', state.endEmitted, state.length) + // Check that we didn't get one last unshift. if (!state.errored && !state.closeEmitted && !state.endEmitted && state.length === 0) { state.endEmitted = true stream.emit('end') - if (stream.writable && stream.allowHalfOpen === false) { process.nextTick(endWritableNT, stream) } else if (state.autoDestroy) { @@ -1280,47 +1196,40 @@ function endReadableNT(state, stream) { const wState = stream._writableState const autoDestroy = !wState || - (wState.autoDestroy && // We don't expect the writable to ever 'finish' + (wState.autoDestroy && + // We don't expect the writable to ever 'finish' // if writable is explicitly set to false. (wState.finished || wState.writable === false)) - if (autoDestroy) { stream.destroy() } } } } - function endWritableNT(stream) { const writable = stream.writable && !stream.writableEnded && !stream.destroyed - if (writable) { stream.end() } } - Readable.from = function (iterable, opts) { return from(Readable, iterable, opts) } +let webStreamsAdapters -let webStreamsAdapters // Lazy to avoid circular references - +// Lazy to avoid circular references function lazyWebStreams() { if (webStreamsAdapters === undefined) webStreamsAdapters = {} return webStreamsAdapters } - Readable.fromWeb = function (readableStream, options) { return lazyWebStreams().newStreamReadableFromReadableStream(readableStream, options) } - Readable.toWeb = function (streamReadable, options) { return lazyWebStreams().newReadableStreamFromStreamReadable(streamReadable, options) } - Readable.wrap = function (src, options) { var _ref, _src$readableObjectMo - return new Readable({ objectMode: (_ref = @@ -1330,7 +1239,6 @@ Readable.wrap = function (src, options) { ? _ref : true, ...options, - destroy(err, callback) { destroyImpl.destroyer(src, err) callback(err) diff --git a/lib/internal/streams/state.js b/lib/internal/streams/state.js index e7fcebdde..18c2d845f 100644 --- a/lib/internal/streams/state.js +++ b/lib/internal/streams/state.js @@ -1,32 +1,26 @@ 'use strict' const { MathFloor, NumberIsInteger } = require('../../ours/primordials') - const { ERR_INVALID_ARG_VALUE } = require('../../ours/errors').codes - function highWaterMarkFrom(options, isDuplex, duplexKey) { return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null } - function getDefaultHighWaterMark(objectMode) { return objectMode ? 16 : 16 * 1024 } - function getHighWaterMark(state, options, duplexKey, isDuplex) { const hwm = highWaterMarkFrom(options, isDuplex, duplexKey) - if (hwm != null) { if (!NumberIsInteger(hwm) || hwm < 0) { const name = isDuplex ? `options.${duplexKey}` : 'options.highWaterMark' throw new ERR_INVALID_ARG_VALUE(name, hwm) } - return MathFloor(hwm) - } // Default value + } + // Default value return getDefaultHighWaterMark(state.objectMode) } - module.exports = { getHighWaterMark, getDefaultHighWaterMark diff --git a/lib/internal/streams/transform.js b/lib/internal/streams/transform.js index 18601011e..fa9413a44 100644 --- a/lib/internal/streams/transform.js +++ b/lib/internal/streams/transform.js @@ -18,6 +18,7 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + // a transform stream is a readable/writable stream where you do // something with the data. Sometimes it's called a "filter", // but that's not a great name for it, since that implies a thing where @@ -59,29 +60,24 @@ // However, even in such a pathological case, only a single written chunk // would be consumed, and then the rest would wait (un-transformed) until // the results of the previous transformed chunk were consumed. + 'use strict' const { ObjectSetPrototypeOf, Symbol } = require('../../ours/primordials') - module.exports = Transform - const { ERR_METHOD_NOT_IMPLEMENTED } = require('../../ours/errors').codes - const Duplex = require('./duplex') - const { getHighWaterMark } = require('./state') - ObjectSetPrototypeOf(Transform.prototype, Duplex.prototype) ObjectSetPrototypeOf(Transform, Duplex) const kCallback = Symbol('kCallback') - function Transform(options) { - if (!(this instanceof Transform)) return new Transform(options) // TODO (ronag): This should preferably always be + if (!(this instanceof Transform)) return new Transform(options) + + // TODO (ronag): This should preferably always be // applied but would be semver-major. Or even better; // make Transform a Readable with the Writable interface. - const readableHighWaterMark = options ? getHighWaterMark(this, options, 'readableHighWaterMark', true) : null - if (readableHighWaterMark === 0) { // A Duplex will buffer both on the writable and readable side while // a Transform just wants to buffer hwm number of elements. To avoid @@ -97,25 +93,24 @@ function Transform(options) { writableHighWaterMark: options.writableHighWaterMark || 0 } } + Duplex.call(this, options) - Duplex.call(this, options) // We have implemented the _read method, and done the other things + // We have implemented the _read method, and done the other things // that Readable wants before the first _read call, so unset the // sync guard flag. - this._readableState.sync = false this[kCallback] = null - if (options) { if (typeof options.transform === 'function') this._transform = options.transform if (typeof options.flush === 'function') this._flush = options.flush - } // When the writable side finishes, then flush out anything remaining. + } + + // When the writable side finishes, then flush out anything remaining. // Backwards compat. Some Transform streams incorrectly implement _final // instead of or in addition to _flush. By using 'prefinish' instead of // implementing _final we continue supporting this unfortunate use case. - this.on('prefinish', prefinish) } - function final(cb) { if (typeof this._flush === 'function' && !this.destroyed) { this._flush((er, data) => { @@ -125,59 +120,49 @@ function final(cb) { } else { this.destroy(er) } - return } - if (data != null) { this.push(data) } - this.push(null) - if (cb) { cb() } }) } else { this.push(null) - if (cb) { cb() } } } - function prefinish() { if (this._final !== final) { final.call(this) } } - Transform.prototype._final = final - Transform.prototype._transform = function (chunk, encoding, callback) { throw new ERR_METHOD_NOT_IMPLEMENTED('_transform()') } - Transform.prototype._write = function (chunk, encoding, callback) { const rState = this._readableState const wState = this._writableState const length = rState.length - this._transform(chunk, encoding, (err, val) => { if (err) { callback(err) return } - if (val != null) { this.push(val) } - if ( - wState.ended || // Backwards compat. - length === rState.length || // Backwards compat. + wState.ended || + // Backwards compat. + length === rState.length || + // Backwards compat. rState.length < rState.highWaterMark ) { callback() @@ -186,7 +171,6 @@ Transform.prototype._write = function (chunk, encoding, callback) { } }) } - Transform.prototype._read = function () { if (this[kCallback]) { const callback = this[kCallback] diff --git a/lib/internal/streams/utils.js b/lib/internal/streams/utils.js index b1aa7d817..f87e9fe68 100644 --- a/lib/internal/streams/utils.js +++ b/lib/internal/streams/utils.js @@ -1,15 +1,12 @@ 'use strict' const { Symbol, SymbolAsyncIterator, SymbolIterator } = require('../../ours/primordials') - const kDestroyed = Symbol('kDestroyed') const kIsErrored = Symbol('kIsErrored') const kIsReadable = Symbol('kIsReadable') const kIsDisturbed = Symbol('kIsDisturbed') - function isReadableNodeStream(obj, strict = false) { var _obj$_readableState - return !!( ( obj && @@ -19,7 +16,8 @@ function isReadableNodeStream(obj, strict = false) { (!obj._writableState || ((_obj$_readableState = obj._readableState) === null || _obj$_readableState === undefined ? undefined - : _obj$_readableState.readable) !== false) && // Duplex + : _obj$_readableState.readable) !== false) && + // Duplex (!obj._writableState || obj._readableState) ) // Writable has .pipe. ) @@ -27,7 +25,6 @@ function isReadableNodeStream(obj, strict = false) { function isWritableNodeStream(obj) { var _obj$_writableState - return !!( ( obj && @@ -50,7 +47,6 @@ function isDuplexNodeStream(obj) { typeof obj.write === 'function' ) } - function isNodeStream(obj) { return ( obj && @@ -60,22 +56,21 @@ function isNodeStream(obj) { (typeof obj.pipe === 'function' && typeof obj.on === 'function')) ) } - function isIterable(obj, isAsync) { if (obj == null) return false if (isAsync === true) return typeof obj[SymbolAsyncIterator] === 'function' if (isAsync === false) return typeof obj[SymbolIterator] === 'function' return typeof obj[SymbolAsyncIterator] === 'function' || typeof obj[SymbolIterator] === 'function' } - function isDestroyed(stream) { if (!isNodeStream(stream)) return null const wState = stream._writableState const rState = stream._readableState const state = wState || rState return !!(stream.destroyed || stream[kDestroyed] || (state !== null && state !== undefined && state.destroyed)) -} // Have been end():d. +} +// Have been end():d. function isWritableEnded(stream) { if (!isWritableNodeStream(stream)) return null if (stream.writableEnded === true) return true @@ -83,8 +78,9 @@ function isWritableEnded(stream) { if (wState !== null && wState !== undefined && wState.errored) return false if (typeof (wState === null || wState === undefined ? undefined : wState.ended) !== 'boolean') return null return wState.ended -} // Have emitted 'finish'. +} +// Have emitted 'finish'. function isWritableFinished(stream, strict) { if (!isWritableNodeStream(stream)) return null if (stream.writableFinished === true) return true @@ -92,8 +88,9 @@ function isWritableFinished(stream, strict) { if (wState !== null && wState !== undefined && wState.errored) return false if (typeof (wState === null || wState === undefined ? undefined : wState.finished) !== 'boolean') return null return !!(wState.finished || (strict === false && wState.ended === true && wState.length === 0)) -} // Have been push(null):d. +} +// Have been push(null):d. function isReadableEnded(stream) { if (!isReadableNodeStream(stream)) return null if (stream.readableEnded === true) return true @@ -101,8 +98,9 @@ function isReadableEnded(stream) { if (!rState || rState.errored) return false if (typeof (rState === null || rState === undefined ? undefined : rState.ended) !== 'boolean') return null return rState.ended -} // Have emitted 'end'. +} +// Have emitted 'end'. function isReadableFinished(stream, strict) { if (!isReadableNodeStream(stream)) return null const rState = stream._readableState @@ -110,51 +108,40 @@ function isReadableFinished(stream, strict) { if (typeof (rState === null || rState === undefined ? undefined : rState.endEmitted) !== 'boolean') return null return !!(rState.endEmitted || (strict === false && rState.ended === true && rState.length === 0)) } - function isReadable(stream) { if (stream && stream[kIsReadable] != null) return stream[kIsReadable] if (typeof (stream === null || stream === undefined ? undefined : stream.readable) !== 'boolean') return null if (isDestroyed(stream)) return false return isReadableNodeStream(stream) && stream.readable && !isReadableFinished(stream) } - function isWritable(stream) { if (typeof (stream === null || stream === undefined ? undefined : stream.writable) !== 'boolean') return null if (isDestroyed(stream)) return false return isWritableNodeStream(stream) && stream.writable && !isWritableEnded(stream) } - function isFinished(stream, opts) { if (!isNodeStream(stream)) { return null } - if (isDestroyed(stream)) { return true } - if ((opts === null || opts === undefined ? undefined : opts.readable) !== false && isReadable(stream)) { return false } - if ((opts === null || opts === undefined ? undefined : opts.writable) !== false && isWritable(stream)) { return false } - return true } - function isWritableErrored(stream) { var _stream$_writableStat, _stream$_writableStat2 - if (!isNodeStream(stream)) { return null } - if (stream.writableErrored) { return stream.writableErrored } - return (_stream$_writableStat = (_stream$_writableStat2 = stream._writableState) === null || _stream$_writableStat2 === undefined ? undefined @@ -162,18 +149,14 @@ function isWritableErrored(stream) { ? _stream$_writableStat : null } - function isReadableErrored(stream) { var _stream$_readableStat, _stream$_readableStat2 - if (!isNodeStream(stream)) { return null } - if (stream.readableErrored) { return stream.readableErrored } - return (_stream$_readableStat = (_stream$_readableStat2 = stream._readableState) === null || _stream$_readableStat2 === undefined ? undefined @@ -181,19 +164,15 @@ function isReadableErrored(stream) { ? _stream$_readableStat : null } - function isClosed(stream) { if (!isNodeStream(stream)) { return null } - if (typeof stream.closed === 'boolean') { return stream.closed } - const wState = stream._writableState const rState = stream._readableState - if ( typeof (wState === null || wState === undefined ? undefined : wState.closed) === 'boolean' || typeof (rState === null || rState === undefined ? undefined : rState.closed) === 'boolean' @@ -203,14 +182,11 @@ function isClosed(stream) { (rState === null || rState === undefined ? undefined : rState.closed) ) } - if (typeof stream._closed === 'boolean' && isOutgoingMessage(stream)) { return stream._closed } - return null } - function isOutgoingMessage(stream) { return ( typeof stream._closed === 'boolean' && @@ -219,14 +195,11 @@ function isOutgoingMessage(stream) { typeof stream._removedContLen === 'boolean' ) } - function isServerResponse(stream) { return typeof stream._sent100 === 'boolean' && isOutgoingMessage(stream) } - function isServerRequest(stream) { var _stream$req - return ( typeof stream._consuming === 'boolean' && typeof stream._dumped === 'boolean' && @@ -234,7 +207,6 @@ function isServerRequest(stream) { undefined ) } - function willEmitClose(stream) { if (!isNodeStream(stream)) return null const wState = stream._writableState @@ -244,10 +216,8 @@ function willEmitClose(stream) { (!state && isServerResponse(stream)) || !!(state && state.autoDestroy && state.emitClose && state.closed === false) ) } - function isDisturbed(stream) { var _stream$kIsDisturbed - return !!( stream && ((_stream$kIsDisturbed = stream[kIsDisturbed]) !== null && _stream$kIsDisturbed !== undefined @@ -255,7 +225,6 @@ function isDisturbed(stream) { : stream.readableDidRead || stream.readableAborted) ) } - function isErrored(stream) { var _ref, _ref2, @@ -267,7 +236,6 @@ function isErrored(stream) { _stream$_writableStat3, _stream$_readableStat4, _stream$_writableStat4 - return !!( stream && ((_ref = @@ -298,7 +266,6 @@ function isErrored(stream) { : _stream$_writableStat4.errored) ) } - module.exports = { kDestroyed, isDisturbed, diff --git a/lib/internal/streams/writable.js b/lib/internal/streams/writable.js index 9b792e60d..15136e06d 100644 --- a/lib/internal/streams/writable.js +++ b/lib/internal/streams/writable.js @@ -1,5 +1,7 @@ /* replacement start */ + const process = require('process') + /* replacement end */ // Copyright Joyent, Inc. and other Node contributors. // @@ -21,12 +23,12 @@ const process = require('process') // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + // A bit simpler than readable streams. // Implement an async ._write(chunk, encoding, cb), and it'll handle all // the drain event emission and buffering. ;('use strict') - const { ArrayPrototypeSlice, Error, @@ -38,22 +40,14 @@ const { Symbol, SymbolHasInstance } = require('../../ours/primordials') - module.exports = Writable Writable.WritableState = WritableState - const { EventEmitter: EE } = require('events') - const Stream = require('./legacy').Stream - const { Buffer } = require('buffer') - const destroyImpl = require('./destroy') - const { addAbortSignal } = require('./add-abort-signal') - const { getHighWaterMark, getDefaultHighWaterMark } = require('./state') - const { ERR_INVALID_ARG_TYPE, ERR_METHOD_NOT_IMPLEMENTED, @@ -65,142 +59,158 @@ const { ERR_STREAM_WRITE_AFTER_END, ERR_UNKNOWN_ENCODING } = require('../../ours/errors').codes - const { errorOrDestroy } = destroyImpl ObjectSetPrototypeOf(Writable.prototype, Stream.prototype) ObjectSetPrototypeOf(Writable, Stream) - function nop() {} - const kOnFinished = Symbol('kOnFinished') - function WritableState(options, stream, isDuplex) { // Duplex streams are both readable and writable, but share // the same options object. // However, some cases require setting options to different // values for the readable and the writable sides of the duplex stream, // e.g. options.readableObjectMode vs. options.writableObjectMode, etc. - if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof require('./duplex') // Object stream flag to indicate whether or not this stream - // contains buffers or objects. + if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof require('./duplex') + // Object stream flag to indicate whether or not this stream + // contains buffers or objects. this.objectMode = !!(options && options.objectMode) - if (isDuplex) this.objectMode = this.objectMode || !!(options && options.writableObjectMode) // The point at which write() starts returning false + if (isDuplex) this.objectMode = this.objectMode || !!(options && options.writableObjectMode) + + // The point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write(). - this.highWaterMark = options ? getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex) - : getDefaultHighWaterMark(false) // if _final has been called. + : getDefaultHighWaterMark(false) - this.finalCalled = false // drain event flag. + // if _final has been called. + this.finalCalled = false - this.needDrain = false // At the start of calling end() + // drain event flag. + this.needDrain = false + // At the start of calling end() + this.ending = false + // When end() has been called, and returned. + this.ended = false + // When 'finish' is emitted. + this.finished = false - this.ending = false // When end() has been called, and returned. + // Has it been destroyed + this.destroyed = false - this.ended = false // When 'finish' is emitted. - - this.finished = false // Has it been destroyed - - this.destroyed = false // Should we decode strings into buffers before passing to _write? + // Should we decode strings into buffers before passing to _write? // this is here so that some node-core streams can optimize string // handling at a lower level. - const noDecode = !!(options && options.decodeStrings === false) - this.decodeStrings = !noDecode // Crypto is kind of old and crusty. Historically, its default string + this.decodeStrings = !noDecode + + // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = (options && options.defaultEncoding) || 'utf8' - this.defaultEncoding = (options && options.defaultEncoding) || 'utf8' // Not an actual buffer we keep track of, but a measurement + // Not an actual buffer we keep track of, but a measurement // of how much we're waiting to get pushed to some underlying // socket or file. + this.length = 0 - this.length = 0 // A flag to see when we're in the middle of a write. + // A flag to see when we're in the middle of a write. + this.writing = false - this.writing = false // When true all writes will be buffered until .uncork() call. + // When true all writes will be buffered until .uncork() call. + this.corked = 0 - this.corked = 0 // A flag to be able to tell if the onwrite cb is called immediately, + // A flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. + this.sync = true - this.sync = true // A flag to know if we're processing previously buffered items, which + // A flag to know if we're processing previously buffered items, which // may call the _write() callback in the same tick, so that we don't // end up in an overlapped onwrite situation. + this.bufferProcessing = false - this.bufferProcessing = false // The callback that's passed to _write(chunk, cb). + // The callback that's passed to _write(chunk, cb). + this.onwrite = onwrite.bind(undefined, stream) - this.onwrite = onwrite.bind(undefined, stream) // The callback that the user supplies to write(chunk, encoding, cb). + // The callback that the user supplies to write(chunk, encoding, cb). + this.writecb = null - this.writecb = null // The amount that is being written when _write is called. + // The amount that is being written when _write is called. + this.writelen = 0 - this.writelen = 0 // Storage for data passed to the afterWrite() callback in case of + // Storage for data passed to the afterWrite() callback in case of // synchronous _write() completion. - this.afterWriteTickInfo = null - resetBuffer(this) // Number of pending user-supplied write callbacks + resetBuffer(this) + + // Number of pending user-supplied write callbacks // this must be 0 before 'finish' can be emitted. + this.pendingcb = 0 - this.pendingcb = 0 // Stream is still being constructed and cannot be + // Stream is still being constructed and cannot be // destroyed until construction finished or failed. // Async construction is opt in, therefore we start as // constructed. + this.constructed = true - this.constructed = true // Emit prefinish if the only thing we're waiting for is _write cbs + // Emit prefinish if the only thing we're waiting for is _write cbs // This is relevant for synchronous Transform streams. + this.prefinished = false - this.prefinished = false // True if the error was already emitted and should not be thrown again. + // True if the error was already emitted and should not be thrown again. + this.errorEmitted = false - this.errorEmitted = false // Should close be emitted on destroy. Defaults to true. + // Should close be emitted on destroy. Defaults to true. + this.emitClose = !options || options.emitClose !== false - this.emitClose = !options || options.emitClose !== false // Should .destroy() be called after 'finish' (and potentially 'end'). + // Should .destroy() be called after 'finish' (and potentially 'end'). + this.autoDestroy = !options || options.autoDestroy !== false - this.autoDestroy = !options || options.autoDestroy !== false // Indicates whether the stream has errored. When true all write() calls + // Indicates whether the stream has errored. When true all write() calls // should return false. This is needed since when autoDestroy // is disabled we need a way to tell whether the stream has failed. + this.errored = null - this.errored = null // Indicates whether the stream has finished destroying. + // Indicates whether the stream has finished destroying. + this.closed = false - this.closed = false // True if close has been emitted or would have been emitted + // True if close has been emitted or would have been emitted // depending on emitClose. - this.closeEmitted = false this[kOnFinished] = [] } - function resetBuffer(state) { state.buffered = [] state.bufferedIndex = 0 state.allBuffers = true state.allNoop = true } - WritableState.prototype.getBuffer = function getBuffer() { return ArrayPrototypeSlice(this.buffered, this.bufferedIndex) } - ObjectDefineProperty(WritableState.prototype, 'bufferedRequestCount', { __proto__: null, - get() { return this.buffered.length - this.bufferedIndex } }) - function Writable(options) { // Writable ctor is applied to Duplexes, too. // `realHasInstance` is necessary because using plain `instanceof` // would return false, as no `_writableState` property is attached. + // Trying to use the custom `instanceof` for Writable here will also break the // Node.js LazyTransform implementation, which has a non-trivial getter for // `_writableState` that would lead to infinite recursion. + // Checking for a Stream.Duplex instance is faster here instead of inside // the WritableState constructor, at least with V8 6.5. const isDuplex = this instanceof require('./duplex') - if (!isDuplex && !FunctionPrototypeSymbolHasInstance(Writable, this)) return new Writable(options) this._writableState = new WritableState(options, this, isDuplex) - if (options) { if (typeof options.write === 'function') this._write = options.write if (typeof options.writev === 'function') this._writev = options.writev @@ -209,19 +219,15 @@ function Writable(options) { if (typeof options.construct === 'function') this._construct = options.construct if (options.signal) addAbortSignal(options.signal, this) } - Stream.call(this, options) destroyImpl.construct(this, () => { const state = this._writableState - if (!state.writing) { clearBuffer(this, state) } - finishMaybe(this, state) }) } - ObjectDefineProperty(Writable, SymbolHasInstance, { __proto__: null, value: function (object) { @@ -229,15 +235,14 @@ ObjectDefineProperty(Writable, SymbolHasInstance, { if (this !== Writable) return false return object && object._writableState instanceof WritableState } -}) // Otherwise people can pipe Writable streams, which is just wrong. +}) +// Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function () { errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE()) } - function _write(stream, chunk, encoding, cb) { const state = stream._writableState - if (typeof encoding === 'function') { cb = encoding encoding = state.defaultEncoding @@ -246,7 +251,6 @@ function _write(stream, chunk, encoding, cb) { else if (encoding !== 'buffer' && !Buffer.isEncoding(encoding)) throw new ERR_UNKNOWN_ENCODING(encoding) if (typeof cb !== 'function') cb = nop } - if (chunk === null) { throw new ERR_STREAM_NULL_VALUES() } else if (!state.objectMode) { @@ -264,71 +268,61 @@ function _write(stream, chunk, encoding, cb) { throw new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk) } } - let err - if (state.ending) { err = new ERR_STREAM_WRITE_AFTER_END() } else if (state.destroyed) { err = new ERR_STREAM_DESTROYED('write') } - if (err) { process.nextTick(cb, err) errorOrDestroy(stream, err, true) return err } - state.pendingcb++ return writeOrBuffer(stream, state, chunk, encoding, cb) } - Writable.prototype.write = function (chunk, encoding, cb) { return _write(this, chunk, encoding, cb) === true } - Writable.prototype.cork = function () { this._writableState.corked++ } - Writable.prototype.uncork = function () { const state = this._writableState - if (state.corked) { state.corked-- if (!state.writing) clearBuffer(this, state) } } - Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { // node::ParseEncoding() requires lower case. if (typeof encoding === 'string') encoding = StringPrototypeToLowerCase(encoding) if (!Buffer.isEncoding(encoding)) throw new ERR_UNKNOWN_ENCODING(encoding) this._writableState.defaultEncoding = encoding return this -} // If we're already writing something, then just put this +} + +// If we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. - function writeOrBuffer(stream, state, chunk, encoding, callback) { const len = state.objectMode ? 1 : chunk.length - state.length += len // stream._write resets state.length - - const ret = state.length < state.highWaterMark // We must ensure that previous needDrain will not be reset to false. + state.length += len + // stream._write resets state.length + const ret = state.length < state.highWaterMark + // We must ensure that previous needDrain will not be reset to false. if (!ret) state.needDrain = true - if (state.writing || state.corked || state.errored || !state.constructed) { state.buffered.push({ chunk, encoding, callback }) - if (state.allBuffers && encoding !== 'buffer') { state.allBuffers = false } - if (state.allNoop && callback !== nop) { state.allNoop = false } @@ -337,16 +331,14 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) { state.writecb = callback state.writing = true state.sync = true - stream._write(chunk, encoding, state.onwrite) - state.sync = false - } // Return false if errored or destroyed in order to break - // any synchronous while(stream.write(data)) loops. + } + // Return false if errored or destroyed in order to break + // any synchronous while(stream.write(data)) loops. return ret && !state.errored && !state.destroyed } - function doWrite(stream, state, writev, len, chunk, encoding, cb) { state.writelen = len state.writecb = cb @@ -357,47 +349,42 @@ function doWrite(stream, state, writev, len, chunk, encoding, cb) { else stream._write(chunk, encoding, state.onwrite) state.sync = false } - function onwriteError(stream, state, er, cb) { --state.pendingcb - cb(er) // Ensure callbacks are invoked even when autoDestroy is + cb(er) + // Ensure callbacks are invoked even when autoDestroy is // not enabled. Passing `er` here doesn't make sense since // it's related to one specific write, not to the buffered // writes. - - errorBuffer(state) // This can emit error, but error must always follow cb. - + errorBuffer(state) + // This can emit error, but error must always follow cb. errorOrDestroy(stream, er) } - function onwrite(stream, er) { const state = stream._writableState const sync = state.sync const cb = state.writecb - if (typeof cb !== 'function') { errorOrDestroy(stream, new ERR_MULTIPLE_CALLBACK()) return } - state.writing = false state.writecb = null state.length -= state.writelen state.writelen = 0 - if (er) { // Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364 er.stack // eslint-disable-line no-unused-expressions if (!state.errored) { state.errored = er - } // In case of duplex streams we need to notify the readable side of the - // error. + } + // In case of duplex streams we need to notify the readable side of the + // error. if (stream._readableState && !stream._readableState.errored) { stream._readableState.errored = er } - if (sync) { process.nextTick(onwriteError, stream, state, er, cb) } else { @@ -407,7 +394,6 @@ function onwrite(stream, er) { if (state.buffered.length > state.bufferedIndex) { clearBuffer(stream, state) } - if (sync) { // It is a common case that the callback passed to .write() is always // the same. In that case, we do not schedule a new nextTick(), but @@ -429,40 +415,33 @@ function onwrite(stream, er) { } } } - function afterWriteTick({ stream, state, count, cb }) { state.afterWriteTickInfo = null return afterWrite(stream, state, count, cb) } - function afterWrite(stream, state, count, cb) { const needDrain = !state.ending && !stream.destroyed && state.length === 0 && state.needDrain - if (needDrain) { state.needDrain = false stream.emit('drain') } - while (count-- > 0) { state.pendingcb-- cb() } - if (state.destroyed) { errorBuffer(state) } - finishMaybe(stream, state) -} // If there's something in the buffer waiting, then invoke callbacks. +} +// If there's something in the buffer waiting, then invoke callbacks. function errorBuffer(state) { if (state.writing) { return } - for (let n = state.bufferedIndex; n < state.buffered.length; ++n) { var _state$errored - const { chunk, callback } = state.buffered[n] const len = state.objectMode ? 1 : chunk.length state.length -= len @@ -472,37 +451,30 @@ function errorBuffer(state) { : new ERR_STREAM_DESTROYED('write') ) } - const onfinishCallbacks = state[kOnFinished].splice(0) - for (let i = 0; i < onfinishCallbacks.length; i++) { var _state$errored2 - onfinishCallbacks[i]( (_state$errored2 = state.errored) !== null && _state$errored2 !== undefined ? _state$errored2 : new ERR_STREAM_DESTROYED('end') ) } - resetBuffer(state) -} // If there's something in the buffer waiting, then process it. +} +// If there's something in the buffer waiting, then process it. function clearBuffer(stream, state) { if (state.corked || state.bufferProcessing || state.destroyed || !state.constructed) { return } - const { buffered, bufferedIndex, objectMode } = state const bufferedLength = buffered.length - bufferedIndex - if (!bufferedLength) { return } - let i = bufferedIndex state.bufferProcessing = true - if (bufferedLength > 1 && stream._writev) { state.pendingcb -= bufferedLength - 1 const callback = state.allNoop @@ -511,9 +483,9 @@ function clearBuffer(stream, state) { for (let n = i; n < buffered.length; ++n) { buffered[n].callback(err) } - } // Make a copy of `buffered` if it's going to be used by `callback` above, + } + // Make a copy of `buffered` if it's going to be used by `callback` above, // since `doWrite` will mutate the array. - const chunks = state.allNoop && i === 0 ? buffered : ArrayPrototypeSlice(buffered, i) chunks.allBuffers = state.allBuffers doWrite(stream, state, true, state.length, chunks, '', callback) @@ -525,7 +497,6 @@ function clearBuffer(stream, state) { const len = objectMode ? 1 : chunk.length doWrite(stream, state, false, len, chunk, encoding, callback) } while (i < buffered.length && !state.writing) - if (i === buffered.length) { resetBuffer(state) } else if (i > 256) { @@ -535,10 +506,8 @@ function clearBuffer(stream, state) { state.bufferedIndex = i } } - state.bufferProcessing = false } - Writable.prototype._write = function (chunk, encoding, cb) { if (this._writev) { this._writev( @@ -554,12 +523,9 @@ Writable.prototype._write = function (chunk, encoding, cb) { throw new ERR_METHOD_NOT_IMPLEMENTED('_write()') } } - Writable.prototype._writev = null - Writable.prototype.end = function (chunk, encoding, cb) { const state = this._writableState - if (typeof chunk === 'function') { cb = chunk chunk = null @@ -568,22 +534,19 @@ Writable.prototype.end = function (chunk, encoding, cb) { cb = encoding encoding = null } - let err - if (chunk !== null && chunk !== undefined) { const ret = _write(this, chunk, encoding) - if (ret instanceof Error) { err = ret } - } // .end() fully uncorks. + } + // .end() fully uncorks. if (state.corked) { state.corked = 1 this.uncork() } - if (err) { // Do nothing... } else if (!state.errored && !state.ending) { @@ -592,6 +555,7 @@ Writable.prototype.end = function (chunk, encoding, cb) { // hard error can be disproportionately destructive. It is not always // trivial for the user to determine whether end() needs to be called // or not. + state.ending = true finishMaybe(this, state, true) state.ended = true @@ -600,7 +564,6 @@ Writable.prototype.end = function (chunk, encoding, cb) { } else if (state.destroyed) { err = new ERR_STREAM_DESTROYED('end') } - if (typeof cb === 'function') { if (err || state.finished) { process.nextTick(cb, err) @@ -608,10 +571,8 @@ Writable.prototype.end = function (chunk, encoding, cb) { state[kOnFinished].push(cb) } } - return this } - function needFinish(state) { return ( state.ending && @@ -626,50 +587,40 @@ function needFinish(state) { !state.closeEmitted ) } - function callFinal(stream, state) { let called = false - function onFinish(err) { if (called) { errorOrDestroy(stream, err !== null && err !== undefined ? err : ERR_MULTIPLE_CALLBACK()) return } - called = true state.pendingcb-- - if (err) { const onfinishCallbacks = state[kOnFinished].splice(0) - for (let i = 0; i < onfinishCallbacks.length; i++) { onfinishCallbacks[i](err) } - errorOrDestroy(stream, err, state.sync) } else if (needFinish(state)) { state.prefinished = true - stream.emit('prefinish') // Backwards compat. Don't check state.sync here. + stream.emit('prefinish') + // Backwards compat. Don't check state.sync here. // Some streams assume 'finish' will be emitted // asynchronously relative to _final callback. - state.pendingcb++ process.nextTick(finish, stream, state) } } - state.sync = true state.pendingcb++ - try { stream._final(onFinish) } catch (err) { onFinish(err) } - state.sync = false } - function prefinish(stream, state) { if (!state.prefinished && !state.finalCalled) { if (typeof stream._final === 'function' && !state.destroyed) { @@ -681,11 +632,9 @@ function prefinish(stream, state) { } } } - function finishMaybe(stream, state, sync) { if (needFinish(state)) { prefinish(stream, state) - if (state.pendingcb === 0) { if (sync) { state.pendingcb++ @@ -707,49 +656,41 @@ function finishMaybe(stream, state, sync) { } } } - function finish(stream, state) { state.pendingcb-- state.finished = true const onfinishCallbacks = state[kOnFinished].splice(0) - for (let i = 0; i < onfinishCallbacks.length; i++) { onfinishCallbacks[i]() } - stream.emit('finish') - if (state.autoDestroy) { // In case of duplex streams we need a way to detect // if the readable side is ready for autoDestroy as well. const rState = stream._readableState const autoDestroy = !rState || - (rState.autoDestroy && // We don't expect the readable to ever 'end' + (rState.autoDestroy && + // We don't expect the readable to ever 'end' // if readable is explicitly set to false. (rState.endEmitted || rState.readable === false)) - if (autoDestroy) { stream.destroy() } } } - ObjectDefineProperties(Writable.prototype, { closed: { __proto__: null, - get() { return this._writableState ? this._writableState.closed : false } }, destroyed: { __proto__: null, - get() { return this._writableState ? this._writableState.destroyed : false }, - set(value) { // Backward compatibility, the user is explicitly managing destroyed. if (this._writableState) { @@ -759,16 +700,14 @@ ObjectDefineProperties(Writable.prototype, { }, writable: { __proto__: null, - get() { - const w = this._writableState // w.writable === false means that this is part of a Duplex stream + const w = this._writableState + // w.writable === false means that this is part of a Duplex stream // where the writable side was disabled upon construction. // Compat. The user might manually disable writable side through // deprecated setter. - return !!w && w.writable !== false && !w.destroyed && !w.errored && !w.ending && !w.ended }, - set(val) { // Backwards compatible. if (this._writableState) { @@ -778,35 +717,30 @@ ObjectDefineProperties(Writable.prototype, { }, writableFinished: { __proto__: null, - get() { return this._writableState ? this._writableState.finished : false } }, writableObjectMode: { __proto__: null, - get() { return this._writableState ? this._writableState.objectMode : false } }, writableBuffer: { __proto__: null, - get() { return this._writableState && this._writableState.getBuffer() } }, writableEnded: { __proto__: null, - get() { return this._writableState ? this._writableState.ending : false } }, writableNeedDrain: { __proto__: null, - get() { const wState = this._writableState if (!wState) return false @@ -815,21 +749,18 @@ ObjectDefineProperties(Writable.prototype, { }, writableHighWaterMark: { __proto__: null, - get() { return this._writableState && this._writableState.highWaterMark } }, writableCorked: { __proto__: null, - get() { return this._writableState ? this._writableState.corked : 0 } }, writableLength: { __proto__: null, - get() { return this._writableState && this._writableState.length } @@ -837,7 +768,6 @@ ObjectDefineProperties(Writable.prototype, { errored: { __proto__: null, enumerable: false, - get() { return this._writableState ? this._writableState.errored : null } @@ -855,39 +785,33 @@ ObjectDefineProperties(Writable.prototype, { } }) const destroy = destroyImpl.destroy - Writable.prototype.destroy = function (err, cb) { - const state = this._writableState // Invoke pending callbacks. + const state = this._writableState + // Invoke pending callbacks. if (!state.destroyed && (state.bufferedIndex < state.buffered.length || state[kOnFinished].length)) { process.nextTick(errorBuffer, state) } - destroy.call(this, err, cb) return this } - Writable.prototype._undestroy = destroyImpl.undestroy - Writable.prototype._destroy = function (err, cb) { cb(err) } - Writable.prototype[EE.captureRejectionSymbol] = function (err) { this.destroy(err) } +let webStreamsAdapters -let webStreamsAdapters // Lazy to avoid circular references - +// Lazy to avoid circular references function lazyWebStreams() { if (webStreamsAdapters === undefined) webStreamsAdapters = {} return webStreamsAdapters } - Writable.fromWeb = function (writableStream, options) { return lazyWebStreams().newStreamWritableFromWritableStream(writableStream, options) } - Writable.toWeb = function (streamWritable) { return lazyWebStreams().newWritableStreamFromStreamWritable(streamWritable) } diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 3225949f3..2475fecaf 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -16,36 +16,32 @@ const { StringPrototypeToUpperCase, StringPrototypeTrim } = require('../ours/primordials') - const { hideStackFrames, codes: { ERR_SOCKET_BAD_PORT, ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_OUT_OF_RANGE, ERR_UNKNOWN_SIGNAL } } = require('../ours/errors') - const { normalizeEncoding } = require('../ours/util') - const { isAsyncFunction, isArrayBufferView } = require('../ours/util').types - const signals = {} + /** * @param {*} value * @returns {boolean} */ - function isInt32(value) { return value === (value | 0) } + /** * @param {*} value * @returns {boolean} */ - function isUint32(value) { return value === value >>> 0 } - const octalReg = /^[0-7]+$/ const modeDesc = 'must be a 32-bit unsigned integer or an octal string' + /** * Parse and validate values that will be converted into mode_t (the S_* * constants). Only valid numbers and octal strings are allowed. They could be @@ -58,23 +54,20 @@ const modeDesc = 'must be a 32-bit unsigned integer or an octal string' * @param {number} [def] If specified, will be returned for invalid values * @returns {number} */ - function parseFileMode(value, name, def) { if (typeof value === 'undefined') { value = def } - if (typeof value === 'string') { if (RegExpPrototypeExec(octalReg, value) === null) { throw new ERR_INVALID_ARG_VALUE(name, value, modeDesc) } - value = NumberParseInt(value, 8) } - validateUint32(value, name) return value } + /** * @callback validateInteger * @param {*} value @@ -85,12 +78,12 @@ function parseFileMode(value, name, def) { */ /** @type {validateInteger} */ - const validateInteger = hideStackFrames((value, name, min = NumberMIN_SAFE_INTEGER, max = NumberMAX_SAFE_INTEGER) => { if (typeof value !== 'number') throw new ERR_INVALID_ARG_TYPE(name, 'number', value) if (!NumberIsInteger(value)) throw new ERR_OUT_OF_RANGE(name, 'an integer', value) if (value < min || value > max) throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value) }) + /** * @callback validateInt32 * @param {*} value @@ -101,21 +94,19 @@ const validateInteger = hideStackFrames((value, name, min = NumberMIN_SAFE_INTEG */ /** @type {validateInt32} */ - const validateInt32 = hideStackFrames((value, name, min = -2147483648, max = 2147483647) => { // The defaults for min and max correspond to the limits of 32-bit integers. if (typeof value !== 'number') { throw new ERR_INVALID_ARG_TYPE(name, 'number', value) } - if (!NumberIsInteger(value)) { throw new ERR_OUT_OF_RANGE(name, 'an integer', value) } - if (value < min || value > max) { throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value) } }) + /** * @callback validateUint32 * @param {*} value @@ -125,24 +116,21 @@ const validateInt32 = hideStackFrames((value, name, min = -2147483648, max = 214 */ /** @type {validateUint32} */ - const validateUint32 = hideStackFrames((value, name, positive = false) => { if (typeof value !== 'number') { throw new ERR_INVALID_ARG_TYPE(name, 'number', value) } - if (!NumberIsInteger(value)) { throw new ERR_OUT_OF_RANGE(name, 'an integer', value) } - - const min = positive ? 1 : 0 // 2 ** 32 === 4294967296 - + const min = positive ? 1 : 0 + // 2 ** 32 === 4294967296 const max = 4_294_967_295 - if (value < min || value > max) { throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value) } }) + /** * @callback validateString * @param {*} value @@ -151,10 +139,10 @@ const validateUint32 = hideStackFrames((value, name, positive = false) => { */ /** @type {validateString} */ - function validateString(value, name) { if (typeof value !== 'string') throw new ERR_INVALID_ARG_TYPE(name, 'string', value) } + /** * @callback validateNumber * @param {*} value @@ -165,10 +153,8 @@ function validateString(value, name) { */ /** @type {validateNumber} */ - function validateNumber(value, name, min = undefined, max) { if (typeof value !== 'number') throw new ERR_INVALID_ARG_TYPE(name, 'number', value) - if ( (min != null && value < min) || (max != null && value > max) || @@ -181,6 +167,7 @@ function validateNumber(value, name, min = undefined, max) { ) } } + /** * @callback validateOneOf * @template T @@ -190,7 +177,6 @@ function validateNumber(value, name, min = undefined, max) { */ /** @type {validateOneOf} */ - const validateOneOf = hideStackFrames((value, name, oneOf) => { if (!ArrayPrototypeIncludes(oneOf, value)) { const allowed = ArrayPrototypeJoin( @@ -201,6 +187,7 @@ const validateOneOf = hideStackFrames((value, name, oneOf) => { throw new ERR_INVALID_ARG_VALUE(name, value, reason) } }) + /** * @callback validateBoolean * @param {*} value @@ -209,14 +196,13 @@ const validateOneOf = hideStackFrames((value, name, oneOf) => { */ /** @type {validateBoolean} */ - function validateBoolean(value, name) { if (typeof value !== 'boolean') throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value) } - function getOwnPropertyValueOrDefault(options, key, defaultValue) { return options == null || !ObjectPrototypeHasOwnProperty(options, key) ? defaultValue : options[key] } + /** * @callback validateObject * @param {*} value @@ -229,12 +215,10 @@ function getOwnPropertyValueOrDefault(options, key, defaultValue) { */ /** @type {validateObject} */ - const validateObject = hideStackFrames((value, name, options = null) => { const allowArray = getOwnPropertyValueOrDefault(options, 'allowArray', false) const allowFunction = getOwnPropertyValueOrDefault(options, 'allowFunction', false) const nullable = getOwnPropertyValueOrDefault(options, 'nullable', false) - if ( (!nullable && value === null) || (!allowArray && ArrayIsArray(value)) || @@ -243,6 +227,7 @@ const validateObject = hideStackFrames((value, name, options = null) => { throw new ERR_INVALID_ARG_TYPE(name, 'Object', value) } }) + /** * @callback validateArray * @param {*} value @@ -252,35 +237,32 @@ const validateObject = hideStackFrames((value, name, options = null) => { */ /** @type {validateArray} */ - const validateArray = hideStackFrames((value, name, minLength = 0) => { if (!ArrayIsArray(value)) { throw new ERR_INVALID_ARG_TYPE(name, 'Array', value) } - if (value.length < minLength) { const reason = `must be longer than ${minLength}` throw new ERR_INVALID_ARG_VALUE(name, value, reason) } -}) // eslint-disable-next-line jsdoc/require-returns-check +}) +// eslint-disable-next-line jsdoc/require-returns-check /** * @param {*} signal * @param {string} [name='signal'] * @returns {asserts signal is keyof signals} */ - function validateSignalName(signal, name = 'signal') { validateString(signal, name) - if (signals[signal] === undefined) { if (signals[StringPrototypeToUpperCase(signal)] !== undefined) { throw new ERR_UNKNOWN_SIGNAL(signal + ' (signals must use all capital letters)') } - throw new ERR_UNKNOWN_SIGNAL(signal) } } + /** * @callback validateBuffer * @param {*} buffer @@ -289,25 +271,24 @@ function validateSignalName(signal, name = 'signal') { */ /** @type {validateBuffer} */ - const validateBuffer = hideStackFrames((buffer, name = 'buffer') => { if (!isArrayBufferView(buffer)) { throw new ERR_INVALID_ARG_TYPE(name, ['Buffer', 'TypedArray', 'DataView'], buffer) } }) + /** * @param {string} data * @param {string} encoding */ - function validateEncoding(data, encoding) { const normalizedEncoding = normalizeEncoding(encoding) const length = data.length - if (normalizedEncoding === 'hex' && length % 2 !== 0) { throw new ERR_INVALID_ARG_VALUE('encoding', encoding, `is invalid for data of length ${length}`) } } + /** * Check that the port number is not NaN when coerced to a number, * is an integer and that it falls within the legal range of port numbers. @@ -316,7 +297,6 @@ function validateEncoding(data, encoding) { * @param {boolean} [allowZero=true] * @returns {number} */ - function validatePort(port, name = 'Port', allowZero = true) { if ( (typeof port !== 'number' && typeof port !== 'string') || @@ -327,9 +307,9 @@ function validatePort(port, name = 'Port', allowZero = true) { ) { throw new ERR_SOCKET_BAD_PORT(name, port, allowZero) } - return port | 0 } + /** * @callback validateAbortSignal * @param {*} signal @@ -337,12 +317,12 @@ function validatePort(port, name = 'Port', allowZero = true) { */ /** @type {validateAbortSignal} */ - const validateAbortSignal = hideStackFrames((signal, name) => { if (signal !== undefined && (signal === null || typeof signal !== 'object' || !('aborted' in signal))) { throw new ERR_INVALID_ARG_TYPE(name, 'AbortSignal', signal) } }) + /** * @callback validateFunction * @param {*} value @@ -351,10 +331,10 @@ const validateAbortSignal = hideStackFrames((signal, name) => { */ /** @type {validateFunction} */ - const validateFunction = hideStackFrames((value, name) => { if (typeof value !== 'function') throw new ERR_INVALID_ARG_TYPE(name, 'Function', value) }) + /** * @callback validatePlainFunction * @param {*} value @@ -363,10 +343,10 @@ const validateFunction = hideStackFrames((value, name) => { */ /** @type {validatePlainFunction} */ - const validatePlainFunction = hideStackFrames((value, name) => { if (typeof value !== 'function' || isAsyncFunction(value)) throw new ERR_INVALID_ARG_TYPE(name, 'Function', value) }) + /** * @callback validateUndefined * @param {*} value @@ -375,23 +355,21 @@ const validatePlainFunction = hideStackFrames((value, name) => { */ /** @type {validateUndefined} */ - const validateUndefined = hideStackFrames((value, name) => { if (value !== undefined) throw new ERR_INVALID_ARG_TYPE(name, 'undefined', value) }) + /** * @template T * @param {T} value * @param {string} name * @param {T[]} union */ - function validateUnion(value, name, union) { if (!ArrayPrototypeIncludes(union, value)) { throw new ERR_INVALID_ARG_TYPE(name, `('${ArrayPrototypeJoin(union, '|')}')`, value) } } - module.exports = { isInt32, isUint32, diff --git a/lib/ours/browser.js b/lib/ours/browser.js index 7083fb31e..39acef3d7 100644 --- a/lib/ours/browser.js +++ b/lib/ours/browser.js @@ -1,12 +1,11 @@ 'use strict' const CustomStream = require('../stream') - const promises = require('../stream/promises') - const originalDestroy = CustomStream.Readable.destroy -module.exports = CustomStream.Readable // Explicit export naming is needed for ESM +module.exports = CustomStream.Readable +// Explicit export naming is needed for ESM module.exports._uint8ArrayToBuffer = CustomStream._uint8ArrayToBuffer module.exports._isUint8Array = CustomStream._isUint8Array module.exports.isDisturbed = CustomStream.isDisturbed @@ -26,11 +25,11 @@ module.exports.compose = CustomStream.compose Object.defineProperty(CustomStream, 'promises', { configurable: true, enumerable: true, - get() { return promises } }) -module.exports.Stream = CustomStream.Stream // Allow default importing +module.exports.Stream = CustomStream.Stream +// Allow default importing module.exports.default = module.exports diff --git a/lib/ours/errors.js b/lib/ours/errors.js index 7fd9a97c9..97866d14f 100644 --- a/lib/ours/errors.js +++ b/lib/ours/errors.js @@ -1,6 +1,7 @@ 'use strict' const { format, inspect, AggregateError: CustomAggregateError } = require('./util') + /* This file is a reduced and adapted version of the main lib/internal/errors.js file defined at @@ -16,7 +17,8 @@ const kTypes = [ 'string', 'function', 'number', - 'object', // Accept 'Function' and 'Object' as alternative to the lower cased version. + 'object', + // Accept 'Function' and 'Object' as alternative to the lower cased version. 'Function', 'Object', 'boolean', @@ -26,62 +28,53 @@ const kTypes = [ const classRegExp = /^([A-Z][a-z0-9]*)+$/ const nodeInternalPrefix = '__node_internal_' const codes = {} - function assert(value, message) { if (!value) { throw new codes.ERR_INTERNAL_ASSERTION(message) } -} // Only use this for integers! Decimal numbers do not work with this function. +} +// Only use this for integers! Decimal numbers do not work with this function. function addNumericalSeparator(val) { let res = '' let i = val.length const start = val[0] === '-' ? 1 : 0 - for (; i >= start + 4; i -= 3) { res = `_${val.slice(i - 3, i)}${res}` } - return `${val.slice(0, i)}${res}` } - function getMessage(key, msg, args) { if (typeof msg === 'function') { assert( - msg.length <= args.length, // Default options do not count. + msg.length <= args.length, + // Default options do not count. `Code: ${key}; The provided arguments length (${args.length}) does not match the required ones (${msg.length}).` ) return msg(...args) } - const expectedLength = (msg.match(/%[dfijoOs]/g) || []).length assert( expectedLength === args.length, `Code: ${key}; The provided arguments length (${args.length}) does not match the required ones (${expectedLength}).` ) - if (args.length === 0) { return msg } - return format(msg, ...args) } - function E(code, message, Base) { if (!Base) { Base = Error } - class NodeError extends Base { constructor(...args) { super(getMessage(code, message, args)) } - toString() { return `${this.name} [${code}]: ${this.message}` } } - Object.defineProperties(NodeError.prototype, { name: { value: Base.name, @@ -93,7 +86,6 @@ function E(code, message, Base) { value() { return `${this.name} [${code}]: ${this.message}` }, - writable: true, enumerable: false, configurable: true @@ -103,7 +95,6 @@ function E(code, message, Base) { NodeError.prototype[kIsNodeError] = true codes[code] = NodeError } - function hideStackFrames(fn) { // We rename the functions that will be hidden to cut off the stacktrace // at the outermost one @@ -113,7 +104,6 @@ function hideStackFrames(fn) { }) return fn } - function aggregateTwoErrors(innerError, outerError) { if (innerError && outerError && innerError !== outerError) { if (Array.isArray(outerError.errors)) { @@ -121,54 +111,43 @@ function aggregateTwoErrors(innerError, outerError) { outerError.errors.push(innerError) return outerError } - const err = new AggregateError([outerError, innerError], outerError.message) err.code = outerError.code return err } - return innerError || outerError } - class AbortError extends Error { constructor(message = 'The operation was aborted', options = undefined) { if (options !== undefined && typeof options !== 'object') { throw new codes.ERR_INVALID_ARG_TYPE('options', 'Object', options) } - super(message, options) this.code = 'ABORT_ERR' this.name = 'AbortError' } } - E('ERR_ASSERTION', '%s', Error) E( 'ERR_INVALID_ARG_TYPE', (name, expected, actual) => { assert(typeof name === 'string', "'name' must be a string") - if (!Array.isArray(expected)) { expected = [expected] } - let msg = 'The ' - if (name.endsWith(' argument')) { // For cases like 'first argument' msg += `${name} ` } else { msg += `"${name}" ${name.includes('.') ? 'property' : 'argument'} ` } - msg += 'must be ' const types = [] const instances = [] const other = [] - for (const value of expected) { assert(typeof value === 'string', 'All expected entries have to be of type string') - if (kTypes.includes(value)) { types.push(value.toLowerCase()) } else if (classRegExp.test(value)) { @@ -177,89 +156,74 @@ E( assert(value !== 'object', 'The value "object" should be written as "Object"') other.push(value) } - } // Special handle `object` in case other instances are allowed to outline - // the differences between each other. + } + // Special handle `object` in case other instances are allowed to outline + // the differences between each other. if (instances.length > 0) { const pos = types.indexOf('object') - if (pos !== -1) { types.splice(types, pos, 1) instances.push('Object') } } - if (types.length > 0) { switch (types.length) { case 1: msg += `of type ${types[0]}` break - case 2: msg += `one of type ${types[0]} or ${types[1]}` break - default: { const last = types.pop() msg += `one of type ${types.join(', ')}, or ${last}` } } - if (instances.length > 0 || other.length > 0) { msg += ' or ' } } - if (instances.length > 0) { switch (instances.length) { case 1: msg += `an instance of ${instances[0]}` break - case 2: msg += `an instance of ${instances[0]} or ${instances[1]}` break - default: { const last = instances.pop() msg += `an instance of ${instances.join(', ')}, or ${last}` } } - if (other.length > 0) { msg += ' or ' } } - switch (other.length) { case 0: break - case 1: if (other[0].toLowerCase() !== other[0]) { msg += 'an ' } - msg += `${other[0]}` break - case 2: msg += `one of ${other[0]} or ${other[1]}` break - default: { const last = other.pop() msg += `one of ${other.join(', ')}, or ${last}` } } - if (actual == null) { msg += `. Received ${actual}` } else if (typeof actual === 'function' && actual.name) { msg += `. Received function ${actual.name}` } else if (typeof actual === 'object') { var _actual$constructor - if ( (_actual$constructor = actual.constructor) !== null && _actual$constructor !== undefined && @@ -276,14 +240,11 @@ E( let inspected = inspect(actual, { colors: false }) - if (inspected.length > 25) { inspected = `${inspected.slice(0, 25)}...` } - msg += `. Received type ${typeof actual} (${inspected})` } - return msg }, TypeError @@ -292,11 +253,9 @@ E( 'ERR_INVALID_ARG_VALUE', (name, value, reason = 'is invalid') => { let inspected = inspect(value) - if (inspected.length > 128) { inspected = inspected.slice(0, 128) + '...' } - const type = name.includes('.') ? 'property' : 'argument' return `The ${type} '${name}' ${reason}. Received ${inspected}` }, @@ -306,7 +265,6 @@ E( 'ERR_INVALID_RETURN_VALUE', (input, name, value) => { var _value$constructor - const type = value !== null && value !== undefined && @@ -326,16 +284,13 @@ E( let msg const len = args.length args = (Array.isArray(args) ? args : [args]).map((a) => `"${a}"`).join(' or ') - switch (len) { case 1: msg += `The ${args[0]} argument` break - case 2: msg += `The ${args[0]} and ${args[1]} arguments` break - default: { const last = args.pop() @@ -343,7 +298,6 @@ E( } break } - return `${msg} must be specified` }, TypeError @@ -353,21 +307,17 @@ E( (str, range, input) => { assert(range, 'Missing "range" argument') let received - if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) { received = addNumericalSeparator(String(input)) } else if (typeof input === 'bigint') { received = String(input) - if (input > 2n ** 32n || input < -(2n ** 32n)) { received = addNumericalSeparator(received) } - received += 'n' } else { received = inspect(input) } - return `The value of "${str}" is out of range. It must be ${range}. Received ${received}` }, RangeError diff --git a/lib/ours/index.js b/lib/ours/index.js index 1a6af8ad8..6cdd2d785 100644 --- a/lib/ours/index.js +++ b/lib/ours/index.js @@ -1,10 +1,10 @@ 'use strict' const Stream = require('stream') - if (Stream && process.env.READABLE_STREAM === 'disable') { - const promises = Stream.promises // Explicit export naming is needed for ESM + const promises = Stream.promises + // Explicit export naming is needed for ESM module.exports._uint8ArrayToBuffer = Stream._uint8ArrayToBuffer module.exports._isUint8Array = Stream._isUint8Array module.exports.isDisturbed = Stream.isDisturbed @@ -23,7 +23,6 @@ if (Stream && process.env.READABLE_STREAM === 'disable') { Object.defineProperty(Stream, 'promises', { configurable: true, enumerable: true, - get() { return promises } @@ -31,12 +30,11 @@ if (Stream && process.env.READABLE_STREAM === 'disable') { module.exports.Stream = Stream.Stream } else { const CustomStream = require('../stream') - const promises = require('../stream/promises') - const originalDestroy = CustomStream.Readable.destroy - module.exports = CustomStream.Readable // Explicit export naming is needed for ESM + module.exports = CustomStream.Readable + // Explicit export naming is needed for ESM module.exports._uint8ArrayToBuffer = CustomStream._uint8ArrayToBuffer module.exports._isUint8Array = CustomStream._isUint8Array module.exports.isDisturbed = CustomStream.isDisturbed @@ -56,12 +54,12 @@ if (Stream && process.env.READABLE_STREAM === 'disable') { Object.defineProperty(CustomStream, 'promises', { configurable: true, enumerable: true, - get() { return promises } }) module.exports.Stream = CustomStream.Stream -} // Allow default importing +} +// Allow default importing module.exports.default = module.exports diff --git a/lib/ours/primordials.js b/lib/ours/primordials.js index fab7a28e4..6a98b0168 100644 --- a/lib/ours/primordials.js +++ b/lib/ours/primordials.js @@ -1,4 +1,5 @@ 'use strict' + /* This file is a reduced and adapted version of the main lib/internal/per_context/primordials.js file defined at @@ -6,50 +7,38 @@ Don't try to replace with the original file and keep it up to date with the upstream file. */ - module.exports = { ArrayIsArray(self) { return Array.isArray(self) }, - ArrayPrototypeIncludes(self, el) { return self.includes(el) }, - ArrayPrototypeIndexOf(self, el) { return self.indexOf(el) }, - ArrayPrototypeJoin(self, sep) { return self.join(sep) }, - ArrayPrototypeMap(self, fn) { return self.map(fn) }, - ArrayPrototypePop(self, el) { return self.pop(el) }, - ArrayPrototypePush(self, el) { return self.push(el) }, - ArrayPrototypeSlice(self, start, end) { return self.slice(start, end) }, - Error, - FunctionPrototypeCall(fn, thisArgs, ...args) { return fn.call(thisArgs, ...args) }, - FunctionPrototypeSymbolHasInstance(self, instance) { return Function.prototype[Symbol.hasInstance].call(self, instance) }, - MathFloor: Math.floor, Number, NumberIsInteger: Number.isInteger, @@ -57,74 +46,55 @@ module.exports = { NumberMAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER, NumberMIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER, NumberParseInt: Number.parseInt, - ObjectDefineProperties(self, props) { return Object.defineProperties(self, props) }, - ObjectDefineProperty(self, name, prop) { return Object.defineProperty(self, name, prop) }, - ObjectGetOwnPropertyDescriptor(self, name) { return Object.getOwnPropertyDescriptor(self, name) }, - ObjectKeys(obj) { return Object.keys(obj) }, - ObjectSetPrototypeOf(target, proto) { return Object.setPrototypeOf(target, proto) }, - Promise, - PromisePrototypeCatch(self, fn) { return self.catch(fn) }, - PromisePrototypeThen(self, thenFn, catchFn) { return self.then(thenFn, catchFn) }, - PromiseReject(err) { return Promise.reject(err) }, - ReflectApply: Reflect.apply, - RegExpPrototypeTest(self, value) { return self.test(value) }, - SafeSet: Set, String, - StringPrototypeSlice(self, start, end) { return self.slice(start, end) }, - StringPrototypeToLowerCase(self) { return self.toLowerCase() }, - StringPrototypeToUpperCase(self) { return self.toUpperCase() }, - StringPrototypeTrim(self) { return self.trim() }, - Symbol, SymbolAsyncIterator: Symbol.asyncIterator, SymbolHasInstance: Symbol.hasInstance, SymbolIterator: Symbol.iterator, - TypedArrayPrototypeSet(self, buf, len) { return self.set(buf, len) }, - Uint8Array } diff --git a/lib/ours/util.js b/lib/ours/util.js index fdaaacd67..e125ce17a 100644 --- a/lib/ours/util.js +++ b/lib/ours/util.js @@ -1,11 +1,9 @@ 'use strict' const bufferModule = require('buffer') - const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor const Blob = globalThis.Blob || bufferModule.Blob /* eslint-disable indent */ - const isBlob = typeof Blob !== 'undefined' ? function isBlob(b) { @@ -16,46 +14,40 @@ const isBlob = return false } /* eslint-enable indent */ -// This is a simplified version of AggregateError +// This is a simplified version of AggregateError class AggregateError extends Error { constructor(errors) { if (!Array.isArray(errors)) { throw new TypeError(`Expected input to be an Array, got ${typeof errors}`) } - let message = '' - for (let i = 0; i < errors.length; i++) { message += ` ${errors[i].stack}\n` } - super(message) this.name = 'AggregateError' this.errors = errors } } - module.exports = { AggregateError, kEmptyObject: Object.freeze({}), - once(callback) { let called = false return function (...args) { if (called) { return } - called = true callback.apply(this, args) } }, - createDeferredPromise: function () { let resolve - let reject // eslint-disable-next-line promise/param-names + let reject + // eslint-disable-next-line promise/param-names const promise = new Promise((res, rej) => { resolve = res reject = rej @@ -66,28 +58,23 @@ module.exports = { reject } }, - promisify(fn) { return new Promise((resolve, reject) => { fn((err, ...args) => { if (err) { return reject(err) } - return resolve(...args) }) }) }, - debuglog() { return function () {} }, - format(format, ...args) { // Simplified version of https://nodejs.org/api/util.html#utilformatformat-args return format.replace(/%([sdifj])/g, function (...[_unused, type]) { const replacement = args.shift() - if (type === 'f') { return replacement.toFixed(6) } else if (type === 'j') { @@ -100,7 +87,6 @@ module.exports = { } }) }, - inspect(value) { // Vastly simplified version of https://nodejs.org/api/util.html#utilinspectobject-options switch (typeof value) { @@ -112,35 +98,27 @@ module.exports = { return `\`${value}\`` } } - return `'${value}'` - case 'number': if (isNaN(value)) { return 'NaN' } else if (Object.is(value, -0)) { return String(value) } - return value - case 'bigint': return `${String(value)}n` - case 'boolean': case 'undefined': return String(value) - case 'object': return '{}' } }, - types: { isAsyncFunction(fn) { return fn instanceof AsyncFunction }, - isArrayBufferView(arr) { return ArrayBuffer.isView(arr) } diff --git a/lib/stream.js b/lib/stream.js index f52681714..e9bb6ba90 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -1,5 +1,7 @@ /* replacement start */ + const { Buffer } = require('buffer') + /* replacement end */ // Copyright Joyent, Inc. and other Node contributors. // @@ -23,51 +25,34 @@ const { Buffer } = require('buffer') // USE OR OTHER DEALINGS IN THE SOFTWARE. ;('use strict') - const { ObjectDefineProperty, ObjectKeys, ReflectApply } = require('./ours/primordials') - const { promisify: { custom: customPromisify } } = require('./ours/util') - const { streamReturningOperators, promiseReturningOperators } = require('./internal/streams/operators') - const { codes: { ERR_ILLEGAL_CONSTRUCTOR } } = require('./ours/errors') - const compose = require('./internal/streams/compose') - const { pipeline } = require('./internal/streams/pipeline') - const { destroyer } = require('./internal/streams/destroy') - const eos = require('./internal/streams/end-of-stream') - const internalBuffer = {} - const promises = require('./stream/promises') - const utils = require('./internal/streams/utils') - const Stream = (module.exports = require('./internal/streams/legacy').Stream) - Stream.isDisturbed = utils.isDisturbed Stream.isErrored = utils.isErrored Stream.isReadable = utils.isReadable Stream.Readable = require('./internal/streams/readable') - for (const key of ObjectKeys(streamReturningOperators)) { const op = streamReturningOperators[key] - function fn(...args) { if (new.target) { throw ERR_ILLEGAL_CONSTRUCTOR() } - return Stream.Readable.from(ReflectApply(op, this, args)) } - ObjectDefineProperty(fn, 'name', { __proto__: null, value: op.name @@ -84,18 +69,14 @@ for (const key of ObjectKeys(streamReturningOperators)) { writable: true }) } - for (const key of ObjectKeys(promiseReturningOperators)) { const op = promiseReturningOperators[key] - function fn(...args) { if (new.target) { throw ERR_ILLEGAL_CONSTRUCTOR() } - return ReflectApply(op, this, args) } - ObjectDefineProperty(fn, 'name', { __proto__: null, value: op.name @@ -112,15 +93,12 @@ for (const key of ObjectKeys(promiseReturningOperators)) { writable: true }) } - Stream.Writable = require('./internal/streams/writable') Stream.Duplex = require('./internal/streams/duplex') Stream.Transform = require('./internal/streams/transform') Stream.PassThrough = require('./internal/streams/passthrough') Stream.pipeline = pipeline - const { addAbortSignal } = require('./internal/streams/add-abort-signal') - Stream.addAbortSignal = addAbortSignal Stream.finished = eos Stream.destroy = destroyer @@ -129,7 +107,6 @@ ObjectDefineProperty(Stream, 'promises', { __proto__: null, configurable: true, enumerable: true, - get() { return promises } @@ -137,7 +114,6 @@ ObjectDefineProperty(Stream, 'promises', { ObjectDefineProperty(pipeline, customPromisify, { __proto__: null, enumerable: true, - get() { return promises.pipeline } @@ -145,18 +121,16 @@ ObjectDefineProperty(pipeline, customPromisify, { ObjectDefineProperty(eos, customPromisify, { __proto__: null, enumerable: true, - get() { return promises.finished } -}) // Backwards-compat with node 0.4.x +}) +// Backwards-compat with node 0.4.x Stream.Stream = Stream - Stream._isUint8Array = function isUint8Array(value) { return value instanceof Uint8Array } - Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) } diff --git a/lib/stream/promises.js b/lib/stream/promises.js index 5e7972ee8..d44dd8ad0 100644 --- a/lib/stream/promises.js +++ b/lib/stream/promises.js @@ -1,25 +1,19 @@ 'use strict' const { ArrayPrototypePop, Promise } = require('../ours/primordials') - const { isIterable, isNodeStream } = require('../internal/streams/utils') - const { pipelineImpl: pl } = require('../internal/streams/pipeline') - const { finished } = require('../internal/streams/end-of-stream') - function pipeline(...streams) { return new Promise((resolve, reject) => { let signal let end const lastArg = streams[streams.length - 1] - if (lastArg && typeof lastArg === 'object' && !isNodeStream(lastArg) && !isIterable(lastArg)) { const options = ArrayPrototypePop(streams) signal = options.signal end = options.end } - pl( streams, (err, value) => { @@ -36,7 +30,6 @@ function pipeline(...streams) { ) }) } - module.exports = { finished, pipeline diff --git a/test/browser/test-browser.js b/test/browser/test-browser.js index b4a22f9c0..bbf8ce69e 100644 --- a/test/browser/test-browser.js +++ b/test/browser/test-browser.js @@ -1,31 +1,25 @@ 'use strict' const logger = globalThis.logger || console.log - const tape = require('tape') - const { createDeferredPromise } = require('../../lib/ours/util') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - let totalTests = 0 let completed = 0 let failed = 0 - async function test(rootName, fn) { // Gather all tests in the file const tests = {} - function addTests(name, fn) { tests[`${rootName} - ${name}`] = fn } - if (fn[kReadableStreamSuiteHasMultipleTests]) { fn(addTests) } else { tests[rootName] = fn - } // Execute each test in a separate harness and then output overall results + } + // Execute each test in a separate harness and then output overall results for (const [name, subtest] of Object.entries(tests)) { const currentIndex = ++totalTests const harness = tape.createHarness() @@ -35,7 +29,6 @@ async function test(rootName, fn) { if (row.startsWith('TAP version') || row.match(new RegExp(`^# (?:${name})`))) { return } - messages.push(row.trim().replace(/^/gm, ' ')) }) harness.onFinish(() => { @@ -43,40 +36,39 @@ async function test(rootName, fn) { messages.push(`${success ? 'ok' : 'not ok'} ${currentIndex} - ${name}`) logger(messages.join('\n')) completed++ - if (!success) { failed++ } - resolve() }) harness(name, subtest) await promise } } - async function runTests(suites) { // Setup an interval const interval = setInterval(() => { if (completed < totalTests) { return } - clearInterval(interval) logger(`1..${totalTests}`) logger(`# tests ${totalTests}`) logger(`# pass ${completed - failed}`) logger(`# fail ${failed}`) - logger(`# ${failed === 0 ? 'ok' : 'not ok'}`) // This line is used by the playwright script to detect we're done + logger(`# ${failed === 0 ? 'ok' : 'not ok'}`) + // This line is used by the playwright script to detect we're done logger('# readable-stream-finished') - }, 100) // Execute each test serially, to avoid side-effects errors when dealing with global error handling + }, 100) + // Execute each test serially, to avoid side-effects errors when dealing with global error handling for (const suite of suites) { await test(suite[kReadableStreamSuiteName], suite) } -} // Important: Do not try to make the require dynamic because bundlers will not like it +} +// Important: Do not try to make the require dynamic because bundlers will not like it runTests([ require('./test-stream-big-packet'), require('./test-stream-big-push'), diff --git a/test/browser/test-stream-big-packet.js b/test/browser/test-stream-big-packet.js index 180419dc6..58cd37cb9 100644 --- a/test/browser/test-stream-big-packet.js +++ b/test/browser/test-stream-big-packet.js @@ -1,77 +1,67 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const inherits = require('inherits') - const { Transform } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(3) let passed = false - function PassThrough() { Transform.call(this) } - inherits(PassThrough, Transform) - PassThrough.prototype._transform = function (chunk, encoding, done) { this.push(chunk) done() } - function TestStream() { Transform.call(this) } - inherits(TestStream, Transform) - TestStream.prototype._transform = function (chunk, encoding, done) { if (!passed) { // Char 'a' only exists in the last write passed = indexOf(chunk.toString(), 'a') >= 0 } - if (passed) { t.ok(passed) } - done() } - const s1 = new PassThrough() const s2 = new PassThrough() const s3 = new TestStream() - s1.pipe(s3) // Don't let s2 auto close which may close s3 - + s1.pipe(s3) + // Don't let s2 auto close which may close s3 s2.pipe(s3, { end: false - }) // We must write a buffer larger than highWaterMark + }) + // We must write a buffer larger than highWaterMark const big = Buffer.alloc(s1._writableState.highWaterMark + 1) - big.fill('x') // Since big is larger than highWaterMark, it will be buffered internally. + big.fill('x') - t.notOk(s1.write(big)) // 'tiny' is small enough to pass through internal buffer. + // Since big is larger than highWaterMark, it will be buffered internally. + t.notOk(s1.write(big)) - t.ok(s2.write('tiny')) // Write some small data in next IO loop, which will never be written to s3 - // Because 'drain' event is not emitted from s1 and s1 is still paused + // 'tiny' is small enough to pass through internal buffer. + t.ok(s2.write('tiny')) + // Write some small data in next IO loop, which will never be written to s3 + // Because 'drain' event is not emitted from s1 and s1 is still paused setImmediate(s1.write.bind(s1), 'later') - function indexOf(xs, x) { for (let i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) { return i } } - return -1 } } - module.exports[kReadableStreamSuiteName] = 'stream-big-packet' diff --git a/test/browser/test-stream-big-push.js b/test/browser/test-stream-big-push.js index 01398e63e..03abceac3 100644 --- a/test/browser/test-stream-big-push.js +++ b/test/browser/test-stream-big-push.js @@ -1,9 +1,7 @@ 'use strict' const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(10) const str = 'asdfasdfasdfasdfasdf' @@ -14,7 +12,6 @@ module.exports = function (t) { let reads = 0 let eofed = false let ended = false - r._read = function (n) { if (reads === 0) { setTimeout(function () { @@ -31,14 +28,15 @@ module.exports = function (t) { r.push(null) } } - r.on('end', function () { ended = true - }) // push some data in to start. - // we've never gotten any read event at this point. + }) - const ret = r.push(str) // should be false. > hwm + // push some data in to start. + // we've never gotten any read event at this point. + const ret = r.push(str) + // should be false. > hwm t.notOk(ret) let chunk = r.read() t.equal(chunk, str) @@ -60,5 +58,4 @@ module.exports = function (t) { t.equal(reads, 2) }) } - module.exports[kReadableStreamSuiteName] = 'stream-big-push' diff --git a/test/browser/test-stream-duplex.js b/test/browser/test-stream-duplex.js index 1d768bb39..e594458c8 100644 --- a/test/browser/test-stream-duplex.js +++ b/test/browser/test-stream-duplex.js @@ -1,9 +1,7 @@ 'use strict' const { Duplex } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(4) const stream = new Duplex({ @@ -13,14 +11,11 @@ module.exports = function (t) { t.ok(stream._writableState.objectMode) let written let read - stream._write = function (obj, _, cb) { written = obj cb() } - stream._read = function () {} - stream.on('data', function (obj) { read = obj }) @@ -36,5 +31,4 @@ module.exports = function (t) { }) stream.push(null) } - module.exports[kReadableStreamSuiteName] = 'stream-duplex' diff --git a/test/browser/test-stream-end-paused.js b/test/browser/test-stream-end-paused.js index 722db644b..9aa637e31 100644 --- a/test/browser/test-stream-end-paused.js +++ b/test/browser/test-stream-end-paused.js @@ -1,20 +1,16 @@ 'use strict' const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(2) const stream = new Readable() let calledRead = false - stream._read = function () { t.notOk(calledRead) calledRead = true this.push(null) } - stream.on('data', function () { throw new Error('should not ever get data') }) @@ -26,5 +22,4 @@ module.exports = function (t) { stream.resume() }) } - module.exports[kReadableStreamSuiteName] = 'stream-end-paused' diff --git a/test/browser/test-stream-finished.js b/test/browser/test-stream-finished.js index cec12616e..541e8ea62 100644 --- a/test/browser/test-stream-finished.js +++ b/test/browser/test-stream-finished.js @@ -1,9 +1,7 @@ 'use strict' const { Writable, Readable, Transform, finished } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - module.exports = function (test) { test('readable finished', function (t) { t.plan(1) @@ -52,6 +50,5 @@ module.exports = function (test) { tr.resume() }) } - module.exports[kReadableStreamSuiteName] = 'stream-finished' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream-ispaused.js b/test/browser/test-stream-ispaused.js index 3cc378e90..778676073 100644 --- a/test/browser/test-stream-ispaused.js +++ b/test/browser/test-stream-ispaused.js @@ -1,24 +1,25 @@ 'use strict' const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(4) - const readable = new stream.Readable() // _read is a noop, here. + const readable = new stream.Readable() - readable._read = () => {} // default state of a stream is not "paused" + // _read is a noop, here. + readable._read = () => {} - t.notOk(readable.isPaused()) // make the stream start flowing... + // default state of a stream is not "paused" + t.notOk(readable.isPaused()) - readable.on('data', () => {}) // still not paused. + // make the stream start flowing... + readable.on('data', () => {}) + // still not paused. t.notOk(readable.isPaused()) readable.pause() t.ok(readable.isPaused()) readable.resume() t.notOk(readable.isPaused()) } - module.exports[kReadableStreamSuiteName] = 'stream-ispaused' diff --git a/test/browser/test-stream-pipe-after-end.js b/test/browser/test-stream-pipe-after-end.js index ba65ee54a..f7fa5cfd6 100644 --- a/test/browser/test-stream-pipe-after-end.js +++ b/test/browser/test-stream-pipe-after-end.js @@ -1,56 +1,45 @@ 'use strict' const inherits = require('inherits') - const { Readable, Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(4) - function TestReadable(opt) { if (!(this instanceof TestReadable)) { return new TestReadable(opt) } - Readable.call(this, opt) this._ended = false } - inherits(TestReadable, Readable) - TestReadable.prototype._read = function (n) { if (this._ended) { this.emit('error', new Error('_read called twice')) } - this._ended = true this.push(null) } - function TestWritable(opt) { if (!(this instanceof TestWritable)) { return new TestWritable(opt) } - Writable.call(this, opt) this._written = [] } - inherits(TestWritable, Writable) - TestWritable.prototype._write = function (chunk, encoding, cb) { this._written.push(chunk) - cb() - } // this one should not emit 'end' until we read() from it later. + } + // this one should not emit 'end' until we read() from it later. const ender = new TestReadable() - let enderEnded = false // what happens when you pipe() a Readable that's already ended? - - const piper = new TestReadable() // pushes EOF null, and length=0, so this will trigger 'end' + let enderEnded = false + // what happens when you pipe() a Readable that's already ended? + const piper = new TestReadable() + // pushes EOF null, and length=0, so this will trigger 'end' piper.read() setTimeout(function () { ender.on('end', function () { @@ -67,5 +56,4 @@ module.exports = function (t) { piper.pipe(w) }) } - module.exports[kReadableStreamSuiteName] = 'stream-pipe-after-end' diff --git a/test/browser/test-stream-pipe-cleanup-pause.js b/test/browser/test-stream-pipe-cleanup-pause.js index c01dc8c41..dd0ea0ba9 100644 --- a/test/browser/test-stream-pipe-cleanup-pause.js +++ b/test/browser/test-stream-pipe-cleanup-pause.js @@ -1,30 +1,27 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(3) const reader = new stream.Readable() const writer1 = new stream.Writable() - const writer2 = new stream.Writable() // 560000 is chosen here because it is larger than the (default) highWaterMark + const writer2 = new stream.Writable() + + // 560000 is chosen here because it is larger than the (default) highWaterMark // and will cause `.write()` to return false // See: https://github.com/nodejs/node/issues/2323 - const buffer = Buffer.alloc(560000) - reader._read = function () {} - writer1._write = function (chunk, encoding, cb) { this.emit('chunk-received') cb() } - writer1.on('chunk-received', function () { reader.unpipe(writer1) reader.pipe(writer2) @@ -36,14 +33,11 @@ module.exports = function (t) { }) }) }) - writer2._write = function (chunk, encoding, cb) { t.ok(true) cb() } - reader.pipe(writer1) reader.push(buffer) } - module.exports[kReadableStreamSuiteName] = 'stream-pipe-cleanup-pause' diff --git a/test/browser/test-stream-pipe-cleanup.js b/test/browser/test-stream-pipe-cleanup.js index ab8d981f6..ce204334f 100644 --- a/test/browser/test-stream-pipe-cleanup.js +++ b/test/browser/test-stream-pipe-cleanup.js @@ -1,101 +1,75 @@ -'use strict' // This test asserts that Stream.prototype.pipe does not leave listeners -// hanging on the source or dest. +'use strict' +// This test asserts that Stream.prototype.pipe does not leave listeners +// hanging on the source or dest. const inherits = require('inherits') - const { Stream } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(27) - if (/^v0\.8\./.test(process.version)) { return } - function Writable() { this.writable = true this.endCalls = 0 Stream.call(this) } - inherits(Writable, Stream) - Writable.prototype.end = function () { this.endCalls++ } - Writable.prototype.destroy = function () { this.endCalls++ } - function Readable() { this.readable = true Stream.call(this) } - inherits(Readable, Stream) - Readable.prototype._read = function () {} - function Duplex() { this.readable = true Writable.call(this) } - inherits(Duplex, Writable) - Duplex.prototype._read = function () {} - let i = 0 let r let w = new Writable() const limit = 100 - for (i = 0; i < limit; i++) { r = new Readable() r.pipe(w) r.emit('end') } - t.equal(0, r.listeners('end').length) t.equal(limit, w.endCalls) w.endCalls = 0 - for (i = 0; i < limit; i++) { r = new Readable() r.pipe(w) r.emit('close') } - t.equal(0, r.listeners('close').length) t.equal(limit, w.endCalls) w.endCalls = 0 r = new Readable() - for (i = 0; i < limit; i++) { w = new Writable() r.pipe(w) w.emit('close') } - t.equal(0, w.listeners('close').length) r = new Readable() w = new Writable() const d = new Duplex() r.pipe(d) // pipeline A - d.pipe(w) // pipeline B - t.equal(r.listeners('end').length, 2) // A.onend, A.cleanup - t.equal(r.listeners('close').length, 2) // A.onclose, A.cleanup - t.equal(d.listeners('end').length, 2) // B.onend, B.cleanup - t.equal(d.listeners('close').length, 3) // A.cleanup, B.onclose, B.cleanup - t.equal(w.listeners('end').length, 0) t.equal(w.listeners('close').length, 1) // B.cleanup @@ -105,9 +79,7 @@ module.exports = function (t) { t.equal(r.listeners('end').length, 0) t.equal(r.listeners('close').length, 0) t.equal(d.listeners('end').length, 2) // B.onend, B.cleanup - t.equal(d.listeners('close').length, 2) // B.onclose, B.cleanup - t.equal(w.listeners('end').length, 0) t.equal(w.listeners('close').length, 1) // B.cleanup @@ -122,5 +94,4 @@ module.exports = function (t) { t.equal(w.listeners('close').length, 0) d.end() } - module.exports[kReadableStreamSuiteName] = 'stream-pipe-cleanup' diff --git a/test/browser/test-stream-pipe-error-handling.js b/test/browser/test-stream-pipe-error-handling.js index 826ec775a..553712cb3 100644 --- a/test/browser/test-stream-pipe-error-handling.js +++ b/test/browser/test-stream-pipe-error-handling.js @@ -1,17 +1,13 @@ 'use strict' const { Readable, Writable, Stream } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - module.exports = function (test) { test('Error Listener Catches', function (t) { t.plan(1) const source = new Stream() const dest = new Stream() - source._read = function () {} - source.pipe(dest) let gotErr = null source.on('error', function (err) { @@ -25,19 +21,15 @@ module.exports = function (test) { t.plan(1) const source = new Stream() const dest = new Stream() - source._read = function () {} - source.pipe(dest) const err = new Error('This stream turned into bacon.') let gotErr = null - try { source.emit('error', err) } catch (e) { gotErr = e } - t.strictEqual(gotErr, err) }) test('Error With Removed Listener Throws', function (t) { @@ -47,25 +39,21 @@ module.exports = function (test) { const w = new Writable() let removed = false let caught = false - global.onerror = () => { t.notOk(caught) global.onerror = onerror return true } - r._read = function () { setTimeout(function () { t.ok(removed) w.emit('error', new Error('fail')) }) } - w.on('error', myOnError) r.pipe(w) w.removeListener('error', myOnError) removed = true - function myOnError(er) { caught = true } @@ -76,29 +64,23 @@ module.exports = function (test) { const w = new Writable() let removed = false let caught = false - r._read = function () { setTimeout(function () { t.ok(removed) w.emit('error', new Error('fail')) }) } - w.on('error', myOnError) - w._write = function () {} - - r.pipe(w) // Removing some OTHER random listener should not do anything - + r.pipe(w) + // Removing some OTHER random listener should not do anything w.removeListener('error', function () {}) removed = true - function myOnError(er) { t.notOk(caught) caught = true } }) } - module.exports[kReadableStreamSuiteName] = 'stream-pipe-error-handling' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream-pipe-event.js b/test/browser/test-stream-pipe-event.js index 4ec67cecc..573093754 100644 --- a/test/browser/test-stream-pipe-event.js +++ b/test/browser/test-stream-pipe-event.js @@ -1,26 +1,19 @@ 'use strict' const inherits = require('inherits') - const { Stream } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(1) - function Writable() { this.writable = true Stream.call(this) } - inherits(Writable, Stream) - function Readable() { this.readable = true Stream.call(this) } - inherits(Readable, Stream) let passed = false const w = new Writable() @@ -28,11 +21,8 @@ module.exports = function (t) { passed = true }) const r = new Readable() - r._read = function () {} - r.pipe(w) t.ok(passed) } - module.exports[kReadableStreamSuiteName] = 'stream-pipe-event' diff --git a/test/browser/test-stream-pipe-without-listenerCount.js b/test/browser/test-stream-pipe-without-listenerCount.js index ecd414a2f..3b498a09b 100644 --- a/test/browser/test-stream-pipe-without-listenerCount.js +++ b/test/browser/test-stream-pipe-without-listenerCount.js @@ -1,9 +1,7 @@ 'use strict' const { Stream } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(1) const r = new Stream({ @@ -16,5 +14,4 @@ module.exports = function (t) { }) t.throws(() => r.pipe(w), 'TypeError: this.listenerCount is not a function') } - module.exports[kReadableStreamSuiteName] = 'stream-pipe-without-listenerCount' diff --git a/test/browser/test-stream-pipeline.js b/test/browser/test-stream-pipeline.js index 9528eeeeb..949135cd2 100644 --- a/test/browser/test-stream-pipeline.js +++ b/test/browser/test-stream-pipeline.js @@ -1,13 +1,12 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Readable, Writable, pipeline } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - module.exports = function (test) { test('pipeline', function (t) { t.plan(3) @@ -26,11 +25,9 @@ module.exports = function (test) { write.on('finish', function () { finished = true }) - for (let i = 0; i < expected.length; i++) { read.push(expected[i]) } - read.push(null) pipeline(read, write, (err) => { t.ifErr(err) @@ -40,11 +37,9 @@ module.exports = function (test) { }) test('pipeline missing args', function (t) { t.plan(3) - const _read = new Readable({ read: function read() {} }) - t.throws(function () { pipeline(_read, function () {}) }) @@ -57,19 +52,15 @@ module.exports = function (test) { }) test('pipeline error', function (t) { t.plan(1) - const _read2 = new Readable({ read: function read() {} }) - const _write = new Writable({ write: function write(data, enc, cb) { cb() } }) - _read2.push('data') - setImmediate(function () { return _read2.destroy() }) @@ -79,19 +70,15 @@ module.exports = function (test) { }) test('pipeline destroy', function (t) { t.plan(2) - const _read3 = new Readable({ read: function read() {} }) - const _write2 = new Writable({ write: function write(data, enc, cb) { cb() } }) - _read3.push('data') - setImmediate(function () { return _read3.destroy(new Error('kaboom')) }) @@ -101,6 +88,5 @@ module.exports = function (test) { t.equal(dst, _write2) }) } - module.exports[kReadableStreamSuiteName] = 'stream-pipeline' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream-push-order.js b/test/browser/test-stream-push-order.js index 430182c3c..ad821efac 100644 --- a/test/browser/test-stream-push-order.js +++ b/test/browser/test-stream-push-order.js @@ -1,9 +1,7 @@ 'use strict' const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(1) const s = new Readable({ @@ -11,10 +9,8 @@ module.exports = function (t) { encoding: 'ascii' }) const list = ['1', '2', '3', '4', '5', '6'] - s._read = function (n) { const one = list.shift() - if (!one) { s.push(null) } else { @@ -23,11 +19,9 @@ module.exports = function (t) { s.push(two) } } - s.read(0) setTimeout(function () { t.equals(s._readableState.buffer.join(','), '1,2,3,4,5,6') }) } - module.exports[kReadableStreamSuiteName] = 'stream-push-order' diff --git a/test/browser/test-stream-push-strings.js b/test/browser/test-stream-push-strings.js index fb20f3cd3..4c6a8aa83 100644 --- a/test/browser/test-stream-push-strings.js +++ b/test/browser/test-stream-push-strings.js @@ -1,26 +1,19 @@ 'use strict' const inherits = require('inherits') - const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(2) - function MyStream(options) { Readable.call(this, options) this._chunks = 3 } - inherits(MyStream, Readable) - MyStream.prototype._read = function (n) { switch (this._chunks--) { case 0: return this.push(null) - case 1: return setTimeout( function () { @@ -28,28 +21,23 @@ module.exports = function (t) { }.bind(this), 100 ) - case 2: return this.push('second to last chunk') - case 3: return process.nextTick( function () { this.push('first chunk') }.bind(this) ) - default: throw new Error('?') } } - const expect = ['first chunksecond to last chunk', 'last chunk'] const ms = new MyStream() const results = [] ms.on('readable', function () { let chunk - while ((chunk = ms.read()) !== null) { results.push(chunk + '') } @@ -59,5 +47,4 @@ module.exports = function (t) { t.deepEqual(results, expect) }) } - module.exports[kReadableStreamSuiteName] = 'stream-push-strings' diff --git a/test/browser/test-stream-readable-constructor-set-methods.js b/test/browser/test-stream-readable-constructor-set-methods.js index 8461661d9..b9b0ec0e5 100644 --- a/test/browser/test-stream-readable-constructor-set-methods.js +++ b/test/browser/test-stream-readable-constructor-set-methods.js @@ -1,18 +1,14 @@ 'use strict' const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(2) let _readCalled = false - function _read(n) { _readCalled = true this.push(null) } - const r = new Readable({ read: _read }) @@ -22,5 +18,4 @@ module.exports = function (t) { t.ok(_readCalled) }) } - module.exports[kReadableStreamSuiteName] = 'stream-readable-constructor-set-methods' diff --git a/test/browser/test-stream-readable-event.js b/test/browser/test-stream-readable-event.js index 42b6246f7..d6da267c9 100644 --- a/test/browser/test-stream-readable-event.js +++ b/test/browser/test-stream-readable-event.js @@ -1,27 +1,27 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - module.exports = function (test) { test('readable events - first', (t) => { - t.plan(3) // First test, not reading when the readable is added. - // make sure that on('readable', ...) triggers a readable event. + t.plan(3) + // First test, not reading when the readable is added. + // make sure that on('readable', ...) triggers a readable event. const r = new Readable({ highWaterMark: 3 }) let _readCalled = false - r._read = function (n) { _readCalled = true - } // This triggers a 'readable' event, which is lost. + } + // This triggers a 'readable' event, which is lost. r.push(Buffer.from('blerg')) let caughtReadable = false setTimeout(function () { @@ -38,18 +38,20 @@ module.exports = function (test) { }) }) test('readable events - second', (t) => { - t.plan(3) // second test, make sure that readable is re-emitted if there's + t.plan(3) + + // second test, make sure that readable is re-emitted if there's // already a length, while it IS reading. const r = new Readable({ highWaterMark: 3 }) let _readCalled = false - r._read = function (n) { _readCalled = true - } // This triggers a 'readable' event, which is lost. + } + // This triggers a 'readable' event, which is lost. r.push(Buffer.from('bl')) let caughtReadable = false setTimeout(function () { @@ -66,18 +68,19 @@ module.exports = function (test) { }) }) test('readable events - third', (t) => { - t.plan(3) // Third test, not reading when the stream has not passed - // the highWaterMark but *has* reached EOF. + t.plan(3) + // Third test, not reading when the stream has not passed + // the highWaterMark but *has* reached EOF. const r = new Readable({ highWaterMark: 30 }) let _readCalled = false - r._read = function (n) { _readCalled = true - } // This triggers a 'readable' event, which is lost. + } + // This triggers a 'readable' event, which is lost. r.push(Buffer.from('blerg')) r.push(null) let caughtReadable = false @@ -95,6 +98,5 @@ module.exports = function (test) { }) }) } - module.exports[kReadableStreamSuiteName] = 'stream-readable-event' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream-sync-write.js b/test/browser/test-stream-sync-write.js index 2ab9b4e51..50b0615bb 100644 --- a/test/browser/test-stream-sync-write.js +++ b/test/browser/test-stream-sync-write.js @@ -1,52 +1,37 @@ 'use strict' const inherits = require('inherits') - const { Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(2) let internalCalls = 0 let externalCalls = 0 - const InternalStream = function () { Writable.call(this) } - inherits(InternalStream, Writable) - InternalStream.prototype._write = function (chunk, encoding, callback) { internalCalls++ callback() } - const internalStream = new InternalStream() - const ExternalStream = function (writable) { this._writable = writable Writable.call(this) } - inherits(ExternalStream, Writable) - ExternalStream.prototype._write = function (chunk, encoding, callback) { externalCalls++ - this._writable.write(chunk, encoding, callback) } - const externalStream = new ExternalStream(internalStream) - for (let i = 0; i < 2000; i++) { externalStream.write(i.toString()) } - externalStream.end(() => { t.equal(internalCalls, 2000) t.equal(externalCalls, 2000) }) } - module.exports[kReadableStreamSuiteName] = 'stream-sync-write' diff --git a/test/browser/test-stream-transform-constructor-set-methods.js b/test/browser/test-stream-transform-constructor-set-methods.js index 44609a0a5..13edd24e9 100644 --- a/test/browser/test-stream-transform-constructor-set-methods.js +++ b/test/browser/test-stream-transform-constructor-set-methods.js @@ -1,29 +1,24 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Transform } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(4) let _transformCalled = false - function _transform(d, e, n) { _transformCalled = true n() } - let _flushCalled = false - function _flush(n) { _flushCalled = true n() } - const tr = new Transform({ transform: _transform, flush: _flush @@ -37,5 +32,4 @@ module.exports = function (t) { t.ok(_flushCalled) }) } - module.exports[kReadableStreamSuiteName] = 'stream-transform-constructor-set-methods' diff --git a/test/browser/test-stream-transform-objectmode-falsey-value.js b/test/browser/test-stream-transform-objectmode-falsey-value.js index 69a987649..1240dfa9b 100644 --- a/test/browser/test-stream-transform-objectmode-falsey-value.js +++ b/test/browser/test-stream-transform-objectmode-falsey-value.js @@ -1,9 +1,7 @@ 'use strict' const { PassThrough } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(13) const src = new PassThrough({ @@ -35,5 +33,4 @@ module.exports = function (t) { } }, 10) } - module.exports[kReadableStreamSuiteName] = 'stream-transform-objectmode-falsey-value' diff --git a/test/browser/test-stream-transform-split-objectmode.js b/test/browser/test-stream-transform-split-objectmode.js index 6c6a41cd4..aacd36338 100644 --- a/test/browser/test-stream-transform-split-objectmode.js +++ b/test/browser/test-stream-transform-split-objectmode.js @@ -1,13 +1,12 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Transform } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(10) const parser = new Transform({ @@ -17,13 +16,11 @@ module.exports = function (t) { t.notOk(parser._writableState.objectMode, 'parser 2') t.equals(parser._readableState.highWaterMark, 16, 'parser 3') t.equals(parser._writableState.highWaterMark, 16 * 1024, 'parser 4') - parser._transform = function (chunk, enc, callback) { callback(null, { val: chunk[0] }) } - let parsed parser.on('data', function (obj) { parsed = obj @@ -39,11 +36,9 @@ module.exports = function (t) { t.ok(serializer._writableState.objectMode, 'serializer 2') t.equals(serializer._readableState.highWaterMark, 16 * 1024, 'serializer 3') t.equals(serializer._writableState.highWaterMark, 16, 'serializer 4') - serializer._transform = function (obj, _, callback) { callback(null, Buffer.from([obj.val])) } - let serialized serializer.on('data', function (chunk) { serialized = chunk @@ -58,5 +53,4 @@ module.exports = function (t) { serializer.end() }) } - module.exports[kReadableStreamSuiteName] = 'stream-transform-split-objectmode' diff --git a/test/browser/test-stream-unshift-empty-chunk.js b/test/browser/test-stream-unshift-empty-chunk.js index b1f2ff263..d707c3940 100644 --- a/test/browser/test-stream-unshift-empty-chunk.js +++ b/test/browser/test-stream-unshift-empty-chunk.js @@ -1,38 +1,34 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(1) const r = new Readable() let nChunks = 10 const chunk = Buffer.alloc(10) chunk.fill('x') - r._read = function (n) { setTimeout(function () { r.push(--nChunks === 0 ? null : chunk) }) } - let readAll = false const seen = [] r.on('readable', function () { let chunk - while ((chunk = r.read())) { - seen.push(chunk.toString()) // simulate only reading a certain amount of the data, + seen.push(chunk.toString()) + // simulate only reading a certain amount of the data, // and then putting the rest of the chunk back into the // stream, like a parser might do. We just fill it with // 'y' so that it's easy to see which bits were touched, // and which were not. - const putBack = Buffer.alloc(readAll ? 0 : 5) putBack.fill('y') readAll = !readAll @@ -63,5 +59,4 @@ module.exports = function (t) { t.deepEqual(seen, expect) }) } - module.exports[kReadableStreamSuiteName] = 'stream-unshift-empty-chunk' diff --git a/test/browser/test-stream-unshift-read-race.js b/test/browser/test-stream-unshift-read-race.js index a58b15878..6cc346632 100644 --- a/test/browser/test-stream-unshift-read-race.js +++ b/test/browser/test-stream-unshift-read-race.js @@ -1,8 +1,10 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ + // This test verifies that: // 1. unshift() does not cause colliding _read() calls. // 2. unshift() after the 'end' event is an error, but after the EOF @@ -11,9 +13,7 @@ const { Buffer } = require('buffer') // 4. _read() is not called after pushing the EOF null chunk. const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(139) const hwm = 10 @@ -22,29 +22,24 @@ module.exports = function (t) { }) const chunks = 10 const data = Buffer.alloc(chunks * hwm + Math.ceil(hwm / 2)) - for (let i = 0; i < data.length; i++) { const c = 'asdf'.charCodeAt(i % 4) data[i] = c } - let pos = 0 let pushedNull = false - r._read = function (n) { - t.notOk(pushedNull, '_read after null push') // every third chunk is fast + t.notOk(pushedNull, '_read after null push') + // every third chunk is fast push(!(chunks % 3)) - function push(fast) { t.notOk(pushedNull, 'push() after null push') const c = pos >= data.length ? null : data.slice(pos, pos + n) pushedNull = c === null - if (fast) { pos += n r.push(c) - if (c === null) { pushError() } @@ -52,7 +47,6 @@ module.exports = function (t) { setTimeout(function () { pos += n r.push(c) - if (c === null) { pushError() } @@ -60,36 +54,28 @@ module.exports = function (t) { } } } - function pushError() { r.unshift(Buffer.allocUnsafe(1)) w.end() const onerror = global.onerror - global.onerror = () => { t.ok(true) global.onerror = onerror return true } - r.push(Buffer.allocUnsafe(1)) } - const w = stream.Writable() const written = [] - w._write = function (chunk, encoding, cb) { written.push(chunk.toString()) cb() } - r.on('end', t.fail) r.on('readable', function () { let chunk - while ((chunk = r.read(10)) !== null) { w.write(chunk) - if (chunk.length > 4) { r.unshift(Buffer.from('1234')) } @@ -100,38 +86,32 @@ module.exports = function (t) { // The first got pulled out before the first unshift('1234'), so it's // lacking that piece. t.equal(written[0], 'asdfasdfas') - let asdf = 'd' // console.error('0: %s', written[0]); + let asdf = 'd' + // console.error('0: %s', written[0]); for (let i = 1; i < written.length; i++) { // console.error('%s: %s', i.toString(32), written[i]); t.equal(written[i].slice(0, 4), '1234') - for (let j = 4; j < written[i].length; j++) { const c = written[i].charAt(j) t.equal(c, asdf) - switch (asdf) { case 'a': asdf = 's' break - case 's': asdf = 'd' break - case 'd': asdf = 'f' break - case 'f': asdf = 'a' break } } } - t.equal(written.length, 18) }) } - module.exports[kReadableStreamSuiteName] = 'stream-unshift-read-race' diff --git a/test/browser/test-stream-writable-change-default-encoding.js b/test/browser/test-stream-writable-change-default-encoding.js index 4d8ee37be..615c60e46 100644 --- a/test/browser/test-stream-writable-change-default-encoding.js +++ b/test/browser/test-stream-writable-change-default-encoding.js @@ -1,27 +1,22 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const inherits = require('inherits') - const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - inherits(MyWritable, stream.Writable) - MyWritable.prototype._write = function (chunk, encoding, callback) { this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding) callback() } - function MyWritable(fn, options) { stream.Writable.call(this, options) this.fn = fn } - module.exports = function (test) { test('defaultCondingIsUtf8', (t) => { t.plan(1) @@ -76,6 +71,5 @@ module.exports = function (test) { m.end() }) } - module.exports[kReadableStreamSuiteName] = 'stream-writable-change-default-encoding' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream-writable-constructor-set-methods.js b/test/browser/test-stream-writable-constructor-set-methods.js index 8065d938a..520d41dd3 100644 --- a/test/browser/test-stream-writable-constructor-set-methods.js +++ b/test/browser/test-stream-writable-constructor-set-methods.js @@ -1,33 +1,28 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(5) let _writeCalled = false - function _write(d, e, n) { _writeCalled = true } - const w = new Writable({ write: _write }) w.end(Buffer.from('blerg')) let _writevCalled = false let dLength = 0 - function _writev(d, n) { dLength = d.length _writevCalled = true } - const w2 = new Writable({ writev: _writev }) @@ -43,5 +38,4 @@ module.exports = function (t) { t.ok(_writevCalled) }) } - module.exports[kReadableStreamSuiteName] = 'stream-writable-constructor-set-methods' diff --git a/test/browser/test-stream-writable-decoded-encoding.js b/test/browser/test-stream-writable-decoded-encoding.js index 36d3219d8..44654a7f5 100644 --- a/test/browser/test-stream-writable-decoded-encoding.js +++ b/test/browser/test-stream-writable-decoded-encoding.js @@ -1,27 +1,22 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const inherits = require('inherits') - const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - function MyWritable(fn, options) { stream.Writable.call(this, options) this.fn = fn } - inherits(MyWritable, stream.Writable) - MyWritable.prototype._write = function (chunk, encoding, callback) { this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding) callback() } - module.exports = function (test) { test('decodeStringsTrue', (t) => { t.plan(3) @@ -29,7 +24,8 @@ module.exports = function (test) { function (isBuffer, type, enc) { t.ok(isBuffer) t.equal(type, 'object') - t.equal(enc, 'buffer') // console.log('ok - decoded string is decoded'); + t.equal(enc, 'buffer') + // console.log('ok - decoded string is decoded'); }, { decodeStrings: true @@ -44,7 +40,8 @@ module.exports = function (test) { function (isBuffer, type, enc) { t.notOk(isBuffer) t.equal(type, 'string') - t.equal(enc, 'utf8') // console.log('ok - un-decoded string is not decoded'); + t.equal(enc, 'utf8') + // console.log('ok - un-decoded string is not decoded'); }, { decodeStrings: false @@ -54,6 +51,5 @@ module.exports = function (test) { m.end() }) } - module.exports[kReadableStreamSuiteName] = 'stream-writable-decoded-encoding' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream-writev.js b/test/browser/test-stream-writev.js index 619369d7d..df9bab6f4 100644 --- a/test/browser/test-stream-writev.js +++ b/test/browser/test-stream-writev.js @@ -1,15 +1,13 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - const queue = [] - for (let decode = 0; decode < 2; decode++) { for (let uncork = 0; uncork < 2; uncork++) { for (let multi = 0; multi < 2; multi++) { @@ -17,14 +15,13 @@ for (let decode = 0; decode < 2; decode++) { } } } - function runTest(decode, uncork, multi) { return function (t) { - t.plan(8) // console.log('# decode=%j uncork=%j multi=%j', decode, uncork, multi); + t.plan(8) + // console.log('# decode=%j uncork=%j multi=%j', decode, uncork, multi); let counter = 0 let expectCount = 0 - function cnt(msg) { expectCount++ const expect = expectCount @@ -32,20 +29,16 @@ function runTest(decode, uncork, multi) { if (er) { throw er } - counter++ t.equal(counter, expect) } } - const w = new stream.Writable({ decodeStrings: decode }) - w._write = function (chunk, e, cb) { t.ok(false, 'Should not call _write') } - const expectChunks = decode ? [ { @@ -92,7 +85,6 @@ function runTest(decode, uncork, multi) { } ] let actualChunks - w._writev = function (chunks, cb) { actualChunks = chunks.map(function (chunk) { return { @@ -102,28 +94,21 @@ function runTest(decode, uncork, multi) { }) cb() } - w.cork() w.write('hello, ', 'ascii', cnt('hello')) w.write('world', 'utf8', cnt('world')) - if (multi) { w.cork() } - w.write(Buffer.from('!'), 'buffer', cnt('!')) w.write('\nand then...', 'binary', cnt('and then')) - if (multi) { w.uncork() } - w.write('facebea7deadbeefdecafbad', 'hex', cnt('hex')) - if (uncork) { w.uncork() } - w.end(cnt('end')) w.on('finish', function () { // make sure finish comes after all the write cb @@ -132,13 +117,11 @@ function runTest(decode, uncork, multi) { }) } } - module.exports = function (test) { for (let i = 0; i < queue.length; i++) { const tr = queue[i] test('round ' + i, runTest(tr[0], tr[1], tr[2])) } } - module.exports[kReadableStreamSuiteName] = 'stream-writev' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream2-base64-single-char-read-end.js b/test/browser/test-stream2-base64-single-char-read-end.js index ce8a0ac0b..c0534c903 100644 --- a/test/browser/test-stream2-base64-single-char-read-end.js +++ b/test/browser/test-stream2-base64-single-char-read-end.js @@ -1,13 +1,12 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Readable, Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(1) const src = new Readable({ @@ -16,7 +15,6 @@ module.exports = function (t) { const dst = new Writable() let hasRead = false const accum = [] - src._read = function (n) { if (!hasRead) { hasRead = true @@ -26,12 +24,10 @@ module.exports = function (t) { }) } } - dst._write = function (chunk, enc, cb) { accum.push(chunk) cb() } - src.on('end', function () { t.equal(Buffer.concat(accum) + '', 'MQ==') clearTimeout(timeout) @@ -41,5 +37,4 @@ module.exports = function (t) { t.fail('timed out waiting for _write') }, 100) } - module.exports[kReadableStreamSuiteName] = 'stream2-base64-single-char-read-end' diff --git a/test/browser/test-stream2-compatibility.js b/test/browser/test-stream2-compatibility.js index cbe76b1fb..c41d6912f 100644 --- a/test/browser/test-stream2-compatibility.js +++ b/test/browser/test-stream2-compatibility.js @@ -1,41 +1,32 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const inherits = require('inherits') - const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(1) let ondataCalled = 0 - function TestReader() { Readable.apply(this) this._buffer = Buffer.alloc(100) - this._buffer.fill('x') - this.on('data', function () { ondataCalled++ }) } - inherits(TestReader, Readable) - TestReader.prototype._read = function (n) { this.push(this._buffer) this._buffer = Buffer.alloc(0) } - setTimeout(function () { t.equal(ondataCalled, 1) }) new TestReader().read() } - module.exports[kReadableStreamSuiteName] = 'stream2-compatibility' diff --git a/test/browser/test-stream2-large-read-stall.js b/test/browser/test-stream2-large-read-stall.js index 590da1308..ffcd73881 100644 --- a/test/browser/test-stream2-large-read-stall.js +++ b/test/browser/test-stream2-large-read-stall.js @@ -1,15 +1,16 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { - t.plan(1) // If everything aligns so that you do a read(n) of exactly the + t.plan(1) + + // If everything aligns so that you do a read(n) of exactly the // remaining buffer, then make sure that 'end' still emits. const READSIZE = 100 @@ -24,13 +25,11 @@ module.exports = function (t) { r.on('readable', function () { false && console.error('>> readable') let ret - do { false && console.error(' > read(%d)', READSIZE) ret = r.read(READSIZE) false && console.error(' < %j (%d remain)', ret && ret.length, rs.length) } while (ret && ret.length === READSIZE) - false && console.error('<< after read()', ret && ret.length, rs.needReadable, rs.length) }) r.on('end', function () { @@ -38,25 +37,21 @@ module.exports = function (t) { false && console.error('end') }) let pushes = 0 - function push() { if (pushes > PUSHCOUNT) { return } - if (pushes++ === PUSHCOUNT) { false && console.error(' push(EOF)') return r.push(null) } - false && console.error(' push #%d', pushes) - if (r.push(Buffer.alloc(PUSHSIZE))) { setTimeout(push) } - } // start the flow + } + // start the flow r.read(0) } - module.exports[kReadableStreamSuiteName] = 'stream2-large-read-stall' diff --git a/test/browser/test-stream2-objects.js b/test/browser/test-stream2-objects.js index 679636a6a..07be218fb 100644 --- a/test/browser/test-stream2-objects.js +++ b/test/browser/test-stream2-objects.js @@ -1,32 +1,25 @@ 'use strict' const { Readable, Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - function forEach(xs, f) { for (let i = 0, l = xs.length; i < l; i++) { f(xs[i], i) } } - function toArray(callback) { const stream = new Writable({ objectMode: true }) const list = [] - stream.write = function (chunk) { list.push(chunk) } - stream.end = function () { callback(list) } - return stream } - function fromArray(list) { const r = new Readable({ objectMode: true @@ -38,9 +31,7 @@ function fromArray(list) { r.push(null) return r } - function noop() {} - module.exports = function (test) { test('can read objects from stream', function (t) { t.plan(3) @@ -114,12 +105,10 @@ module.exports = function (test) { two: '2' } ] - r._read = function (n) { const item = list.shift() r.push(item || null) } - r.pipe( toArray(function (list) { t.deepEqual(list, [ @@ -146,14 +135,12 @@ module.exports = function (test) { two: '2' } ] - r._read = function (n) { const item = list.shift() process.nextTick(function () { r.push(item || null) }) } - r.pipe( toArray(function (list) { t.deepEqual(list, [ @@ -223,11 +210,9 @@ module.exports = function (test) { }) let calls = 0 const list = ['1', '2', '3', '4', '5', '6', '7', '8'] - r._read = function (n) { calls++ } - forEach(list, function (c) { r.push(c) }) @@ -246,9 +231,7 @@ module.exports = function (test) { highWaterMark: 6, objectMode: true }) - r._read = function (n) {} - for (let i = 0; i < 6; i++) { const bool = r.push(i) t.equal(bool, i !== 5) @@ -259,14 +242,12 @@ module.exports = function (test) { const w = new Writable({ objectMode: true }) - w._write = function (chunk, encoding, cb) { t.deepEqual(chunk, { foo: 'bar' }) cb() } - w.on('finish', function () {}) w.write({ foo: 'bar' @@ -279,12 +260,10 @@ module.exports = function (test) { objectMode: true }) const list = [] - w._write = function (chunk, encoding, cb) { list.push(chunk) cb() } - w.on('finish', function () { t.deepEqual(list, [0, 1, 2, 3, 4]) }) @@ -301,12 +280,10 @@ module.exports = function (test) { objectMode: true }) const list = [] - w._write = function (chunk, encoding, cb) { list.push(chunk) process.nextTick(cb) } - w.on('finish', function () { t.deepEqual(list, ['0', '1', '2', '3', '4']) }) @@ -323,7 +300,6 @@ module.exports = function (test) { objectMode: true }) let called = false - w._write = function (chunk, encoding, cb) { t.equal(chunk, 'foo') process.nextTick(function () { @@ -331,7 +307,6 @@ module.exports = function (test) { cb() }) } - w.on('finish', function () { t.equal(called, true) }) @@ -339,6 +314,5 @@ module.exports = function (test) { w.end() }) } - module.exports[kReadableStreamSuiteName] = 'stream2-objects' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream2-pipe-error-handling.js b/test/browser/test-stream2-pipe-error-handling.js index cc30fab7d..df0afb614 100644 --- a/test/browser/test-stream2-pipe-error-handling.js +++ b/test/browser/test-stream2-pipe-error-handling.js @@ -1,38 +1,31 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - module.exports = function (test) { test('Error Listener Catches', function (t) { t.plan(3) let count = 1000 const source = new stream.Readable() - source._read = function (n) { n = Math.min(count, n) count -= n source.push(Buffer.alloc(n)) } - let unpipedDest - source.unpipe = function (dest) { unpipedDest = dest stream.Readable.prototype.unpipe.call(this, dest) } - const dest = new stream.Writable() - dest._write = function (chunk, encoding, cb) { cb() } - source.pipe(dest) let gotErr = null dest.on('error', function (err) { @@ -52,26 +45,20 @@ module.exports = function (test) { t.plan(3) let count = 1000 const source = new stream.Readable() - source._read = function (n) { n = Math.min(count, n) count -= n source.push(Buffer.alloc(n)) } - let unpipedDest - source.unpipe = function (dest) { unpipedDest = dest stream.Readable.prototype.unpipe.call(this, dest) } - const dest = new stream.Writable() - dest._write = function (chunk, encoding, cb) { cb() } - source.pipe(dest) let unpipedSource dest.on('unpipe', function (src) { @@ -80,7 +67,6 @@ module.exports = function (test) { const err = new Error('This stream turned into bacon.') const onerror = global.onerror dest.emit('error', err) - global.onerror = () => { t.ok(true) t.strictEqual(unpipedSource, source) @@ -90,6 +76,5 @@ module.exports = function (test) { } }) } - module.exports[kReadableStreamSuiteName] = 'stream2-pipe-error-handling' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream2-pipe-error-once-listener.js b/test/browser/test-stream2-pipe-error-once-listener.js index c5696778a..a9c8c6706 100644 --- a/test/browser/test-stream2-pipe-error-once-listener.js +++ b/test/browser/test-stream2-pipe-error-once-listener.js @@ -1,36 +1,26 @@ 'use strict' const inherits = require('inherits') - const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(1) - const Read = function () { stream.Readable.call(this) } - inherits(Read, stream.Readable) - Read.prototype._read = function (size) { this.push('x') this.push(null) } - const Write = function () { stream.Writable.call(this) } - inherits(Write, stream.Writable) - Write.prototype._write = function (buffer, encoding, cb) { this.emit('error', new Error('boom')) this.emit('alldone') } - const read = new Read() const write = new Write() write.once('error', () => {}) @@ -39,5 +29,4 @@ module.exports = function (t) { }) read.pipe(write) } - module.exports[kReadableStreamSuiteName] = 'stream2-pipe-error-once-listener' diff --git a/test/browser/test-stream2-push.js b/test/browser/test-stream2-push.js index 0c3307f51..e2b4b0e0d 100644 --- a/test/browser/test-stream2-push.js +++ b/test/browser/test-stream2-push.js @@ -1,11 +1,8 @@ 'use strict' const { EventEmitter: EE } = require('events') - const { Readable, Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(33) const stream = new Readable({ @@ -13,19 +10,17 @@ module.exports = function (t) { encoding: 'utf8' }) const source = new EE() - stream._read = function () { // console.error('stream._read'); readStart() } - let ended = false stream.on('end', function () { ended = true }) source.on('data', function (chunk) { - const ret = stream.push(chunk) // console.error('data', stream._readableState.length); - + const ret = stream.push(chunk) + // console.error('data', stream._readableState.length); if (!ret) { readStop() } @@ -34,24 +29,20 @@ module.exports = function (t) { stream.push(null) }) let reading = false - function readStart() { // console.error('readStart'); reading = true } - function readStop() { // console.error('readStop'); reading = false process.nextTick(function () { const r = stream.read() - if (r !== null) { writer.write(r) } }) } - const writer = new Writable({ decodeStrings: false }) @@ -64,20 +55,19 @@ module.exports = function (t) { 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg' ] - writer._write = function (chunk, encoding, cb) { // console.error('WRITE %s', chunk); written.push(chunk) process.nextTick(cb) } + writer.on('finish', finish) - writer.on('finish', finish) // now emit some chunks. + // now emit some chunks. const chunk = 'asdfg' let set = 0 readStart() data() - function data() { t.ok(reading) source.emit('data', chunk) @@ -88,19 +78,16 @@ module.exports = function (t) { t.ok(reading) source.emit('data', chunk) t.notOk(reading) - if (set++ < 5) { setTimeout(data, 10) } else { end() } } - function finish() { // console.error('finish'); t.deepEqual(written, expectWritten) } - function end() { source.emit('end') t.notOk(reading) @@ -110,5 +97,4 @@ module.exports = function (t) { }) } } - module.exports[kReadableStreamSuiteName] = 'stream2-push' diff --git a/test/browser/test-stream2-readable-empty-buffer-no-eof.js b/test/browser/test-stream2-readable-empty-buffer-no-eof.js index f65a77f77..576aeb7da 100644 --- a/test/browser/test-stream2-readable-empty-buffer-no-eof.js +++ b/test/browser/test-stream2-readable-empty-buffer-no-eof.js @@ -1,17 +1,18 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - module.exports = function (test) { test('readable empty buffer no eof 1', function (t) { t.plan(1) - const r = new Readable() // should not end when we get a Buffer(0) or '' as the _read result + const r = new Readable() + + // should not end when we get a Buffer(0) or '' as the _read result // that just means that there is *temporarily* no data, but to go // ahead and try again later. // @@ -24,53 +25,42 @@ module.exports = function (test) { const buf = Buffer.alloc(5) buf.fill('x') let reads = 5 - r._read = function (n) { switch (reads--) { case 0: return r.push(null) // EOF - case 1: return r.push(buf) - case 2: setTimeout(r.read.bind(r, 0), 50) return r.push(Buffer.alloc(0)) // Not-EOF! - case 3: setTimeout(r.read.bind(r, 0), 50) return process.nextTick(function () { return r.push(Buffer.alloc(0)) }) - case 4: setTimeout(r.read.bind(r, 0), 50) return setTimeout(function () { return r.push(Buffer.alloc(0)) }) - case 5: return setTimeout(function () { return r.push(buf) }) - default: throw new Error('unreachable') } } - const results = [] - function flow() { let chunk - while ((chunk = r.read()) !== null) { results.push(chunk + '') } } - r.on('readable', flow) r.on('end', function () { results.push('EOF') @@ -84,7 +74,6 @@ module.exports = function (test) { encoding: 'base64' }) let reads = 5 - r._read = function (n) { if (!reads--) { return r.push(null) // EOF @@ -92,17 +81,13 @@ module.exports = function (test) { return r.push(Buffer.from('x')) } } - const results = [] - function flow() { let chunk - while ((chunk = r.read()) !== null) { results.push(chunk + '') } } - r.on('readable', flow) r.on('end', function () { results.push('EOF') @@ -111,6 +96,5 @@ module.exports = function (test) { flow() }) } - module.exports[kReadableStreamSuiteName] = 'stream2-readable-empty-buffer-no-eof' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream2-readable-from-list.js b/test/browser/test-stream2-readable-from-list.js index a34430825..9d3ad502c 100644 --- a/test/browser/test-stream2-readable-from-list.js +++ b/test/browser/test-stream2-readable-from-list.js @@ -1,93 +1,97 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { _fromList: fromList } = require('../../lib/_stream_readable') - const BufferList = require('../../lib/internal/streams/buffer_list') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - function bufferListFromArray(arr) { const bl = new BufferList() - for (let i = 0; i < arr.length; ++i) { bl.push(arr[i]) } - return bl } - module.exports = function (test) { test('buffers', function (t) { t.plan(5) let list = [Buffer.from('foog'), Buffer.from('bark'), Buffer.from('bazy'), Buffer.from('kuel')] - list = bufferListFromArray(list) // read more than the first element. + list = bufferListFromArray(list) + // read more than the first element. let ret = fromList(6, { buffer: list, length: 16 }) - t.equal(ret.toString(), 'foogba') // read exactly the first element. + t.equal(ret.toString(), 'foogba') + // read exactly the first element. ret = fromList(2, { buffer: list, length: 10 }) - t.equal(ret.toString(), 'rk') // read less than the first element. + t.equal(ret.toString(), 'rk') + // read less than the first element. ret = fromList(2, { buffer: list, length: 8 }) - t.equal(ret.toString(), 'ba') // read more than we have. + t.equal(ret.toString(), 'ba') + // read more than we have. ret = fromList(100, { buffer: list, length: 6 }) - t.equal(ret.toString(), 'zykuel') // all consumed. + t.equal(ret.toString(), 'zykuel') + // all consumed. t.same(list, new BufferList()) }) test('strings', function (t) { t.plan(5) let list = ['foog', 'bark', 'bazy', 'kuel'] - list = bufferListFromArray(list) // read more than the first element. + list = bufferListFromArray(list) + // read more than the first element. let ret = fromList(6, { buffer: list, length: 16, decoder: true }) - t.equal(ret, 'foogba') // read exactly the first element. + t.equal(ret, 'foogba') + // read exactly the first element. ret = fromList(2, { buffer: list, length: 10, decoder: true }) - t.equal(ret, 'rk') // read less than the first element. + t.equal(ret, 'rk') + // read less than the first element. ret = fromList(2, { buffer: list, length: 8, decoder: true }) - t.equal(ret, 'ba') // read more than we have. + t.equal(ret, 'ba') + // read more than we have. ret = fromList(100, { buffer: list, length: 6, decoder: true }) - t.equal(ret, 'zykuel') // all consumed. + t.equal(ret, 'zykuel') + // all consumed. t.same(list, new BufferList()) }) } - module.exports[kReadableStreamSuiteName] = 'stream2-readable-from-list' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream2-readable-legacy-drain.js b/test/browser/test-stream2-readable-legacy-drain.js index f2faf8307..8aa867054 100644 --- a/test/browser/test-stream2-readable-legacy-drain.js +++ b/test/browser/test-stream2-readable-legacy-drain.js @@ -1,23 +1,20 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Stream, Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(3) const r = new Readable() const N = 256 let reads = 0 - r._read = function (n) { return r.push(++reads === N ? null : Buffer.alloc(1)) } - r.on('end', function () { t.ok(true, 'rended') }) @@ -25,29 +22,23 @@ module.exports = function (t) { w.writable = true let writes = 0 let buffered = 0 - w.write = function (c) { writes += c.length buffered += c.length process.nextTick(drain) return false } - function drain() { if (buffered > 3) { t.ok(false, 'to much buffer') } - buffered = 0 w.emit('drain') } - w.end = function () { t.equal(writes, 255) t.ok(true, 'wended') } - r.pipe(w) } - module.exports[kReadableStreamSuiteName] = 'stream2-readable-legacy-drain' diff --git a/test/browser/test-stream2-readable-non-empty-end.js b/test/browser/test-stream2-readable-non-empty-end.js index 6040d14cc..b8e23851d 100644 --- a/test/browser/test-stream2-readable-non-empty-end.js +++ b/test/browser/test-stream2-readable-non-empty-end.js @@ -1,61 +1,52 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(4) let len = 0 const chunks = new Array(10) - for (let i = 1; i <= 10; i++) { chunks[i - 1] = Buffer.alloc(i) len += i } - const test = new Readable() let n = 0 - test._read = function (size) { const chunk = chunks[n++] setTimeout(function () { test.push(chunk === undefined ? null : chunk) }) } - test.on('end', thrower) - function thrower() { throw new Error('this should not happen!') } - let bytesread = 0 test.on('readable', function () { const b = len - bytesread - 1 const res = test.read(b) - if (res) { - bytesread += res.length // console.error('br=%d len=%d', bytesread, len); - + bytesread += res.length + // console.error('br=%d len=%d', bytesread, len); setTimeout(next) } - test.read(0) }) test.read(0) - function next() { // now let's make 'end' happen test.removeListener('end', thrower) test.on('end', function () { t.ok(true, 'end emitted') - }) // one to get the last byte + }) + // one to get the last byte let r = test.read() t.ok(r) t.equal(r.length, 1) @@ -63,5 +54,4 @@ module.exports = function (t) { t.equal(r, null) } } - module.exports[kReadableStreamSuiteName] = 'stream2-readable-non-empty-end' diff --git a/test/browser/test-stream2-readable-wrap-empty.js b/test/browser/test-stream2-readable-wrap-empty.js index 40b4b8db8..2dd97b0cb 100644 --- a/test/browser/test-stream2-readable-wrap-empty.js +++ b/test/browser/test-stream2-readable-wrap-empty.js @@ -1,19 +1,13 @@ 'use strict' const { EventEmitter: EE } = require('events') - const Readable = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(1) const oldStream = new EE() - oldStream.pause = function () {} - oldStream.resume = function () {} - const newStream = new Readable().wrap(oldStream) newStream .on('readable', function () {}) @@ -22,5 +16,4 @@ module.exports = function (t) { }) oldStream.emit('end') } - module.exports[kReadableStreamSuiteName] = 'stream2-readable-wrap-empty' diff --git a/test/browser/test-stream2-readable-wrap.js b/test/browser/test-stream2-readable-wrap.js index 2b453a215..82fef9927 100644 --- a/test/browser/test-stream2-readable-wrap.js +++ b/test/browser/test-stream2-readable-wrap.js @@ -1,17 +1,14 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { EventEmitter: EE } = require('events') - const { Readable, Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - let run = 0 - module.exports = function (test) { function runTest(highWaterMark, objectMode, produce) { test('run #' + ++run, (t) => { @@ -26,59 +23,52 @@ module.exports = function (test) { r.on('end', function () { ended = true }) - old.pause = function () { // console.error('old.pause()'); old.emit('pause') flowing = false } - old.resume = function () { // console.error('old.resume()'); old.emit('resume') flow() } - let flowing let chunks = 10 let oldEnded = false const expected = [] - function flow() { - flowing = true // eslint-disable-next-line no-unmodified-loop-condition - + flowing = true + // eslint-disable-next-line no-unmodified-loop-condition while (flowing && chunks-- > 0) { const item = produce() - expected.push(item) // console.log('old.emit', chunks, flowing); - - old.emit('data', item) // console.log('after emit', chunks, flowing); + expected.push(item) + // console.log('old.emit', chunks, flowing); + old.emit('data', item) + // console.log('after emit', chunks, flowing); } if (chunks <= 0) { - oldEnded = true // console.log('old end', chunks, flowing); - + oldEnded = true + // console.log('old end', chunks, flowing); old.emit('end') } } - const w = new Writable({ highWaterMark: highWaterMark * 2, objectMode }) const written = [] - w._write = function (chunk, encoding, cb) { // console.log('_write', chunk); written.push(chunk) setTimeout(cb) } - w.on('finish', function () { performAsserts() }) r.pipe(w) flow() - function performAsserts() { t.ok(ended) t.ok(oldEnded) @@ -86,7 +76,6 @@ module.exports = function (test) { } }) } - runTest(100, false, function () { return Buffer.alloc(100) }) @@ -116,6 +105,5 @@ module.exports = function (test) { return objectChunks.shift() }) } - module.exports[kReadableStreamSuiteName] = 'stream2-readable-wrap' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream2-set-encoding.js b/test/browser/test-stream2-set-encoding.js index cb697e07f..4af1c989f 100644 --- a/test/browser/test-stream2-set-encoding.js +++ b/test/browser/test-stream2-set-encoding.js @@ -1,23 +1,19 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const inherits = require('inherits') - const { Readable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - inherits(TestReader, Readable) - function TestReader(n, opts) { Readable.call(this, opts) this.pos = 0 this.len = n || 100 } - TestReader.prototype._read = function (n) { setTimeout( function () { @@ -26,25 +22,23 @@ TestReader.prototype._read = function (n) { this.push(null) return this.push(null) } - n = Math.min(n, this.len - this.pos) - if (n <= 0) { // double push(null) to test eos handling this.push(null) return this.push(null) } - this.pos += n const ret = Buffer.alloc(n) - ret.fill('a') // console.log('this.push(ret)', ret); + ret.fill('a') + + // console.log('this.push(ret)', ret); return this.push(ret) }.bind(this), 1 ) } - module.exports = function (test) { test('setEncoding utf8', function (t) { t.plan(1) @@ -65,7 +59,6 @@ module.exports = function (test) { ] tr.on('readable', function flow() { let chunk - while ((chunk = tr.read(10)) !== null) { out.push(chunk) } @@ -103,7 +96,6 @@ module.exports = function (test) { ] tr.on('readable', function flow() { let chunk - while ((chunk = tr.read(10)) !== null) { out.push(chunk) } @@ -138,7 +130,6 @@ module.exports = function (test) { tr.on('readable', function flow() { // console.log('readable once'); let chunk - while ((chunk = tr.read(13)) !== null) { out.push(chunk) } @@ -171,7 +162,6 @@ module.exports = function (test) { ] tr.on('readable', function flow() { let chunk - while ((chunk = tr.read(10)) !== null) { out.push(chunk) } @@ -200,7 +190,6 @@ module.exports = function (test) { ] tr.on('readable', function flow() { let chunk - while ((chunk = tr.read(10)) !== null) { out.push(chunk) } @@ -239,7 +228,6 @@ module.exports = function (test) { ] tr.on('readable', function flow() { let chunk - while ((chunk = tr.read(10)) !== null) { out.push(chunk) } @@ -274,7 +262,6 @@ module.exports = function (test) { ] tr.on('readable', function flow() { let chunk - while ((chunk = tr.read(13)) !== null) { out.push(chunk) } @@ -307,7 +294,6 @@ module.exports = function (test) { ] tr.on('readable', function flow() { let chunk - while ((chunk = tr.read(10)) !== null) { out.push(chunk) } @@ -322,6 +308,5 @@ module.exports = function (test) { t.equal(tr.setEncoding('utf8'), tr) }) } - module.exports[kReadableStreamSuiteName] = 'stream2-set-encoding' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream2-transform.js b/test/browser/test-stream2-transform.js index a78cf02f7..27a95c98d 100644 --- a/test/browser/test-stream2-transform.js +++ b/test/browser/test-stream2-transform.js @@ -1,13 +1,12 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { PassThrough, Transform } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - module.exports = function (test) { test('writable side consumption', function (t) { t.plan(3) @@ -15,17 +14,14 @@ module.exports = function (test) { highWaterMark: 10 }) let transformed = 0 - tx._transform = function (chunk, encoding, cb) { transformed += chunk.length tx.push(chunk) cb() } - for (let i = 1; i <= 10; i++) { tx.write(Buffer.alloc(i)) } - tx.end() t.equal(tx._readableState.length, 10) t.equal(transformed, 10) @@ -77,14 +73,12 @@ module.exports = function (test) { test('simple transform', function (t) { t.plan(4) const pt = new Transform() - pt._transform = function (c, e, cb) { const ret = Buffer.alloc(c.length) ret.fill('x') pt.push(ret) cb() } - pt.write(Buffer.from('foog')) pt.write(Buffer.from('bark')) pt.write(Buffer.from('bazy')) @@ -100,12 +94,10 @@ module.exports = function (test) { const pt = new Transform({ objectMode: true }) - pt._transform = function (c, e, cb) { pt.push(JSON.stringify(c)) cb() } - pt.write(1) pt.write(true) pt.write(false) @@ -127,14 +119,12 @@ module.exports = function (test) { test('async passthrough', function (t) { t.plan(4) const pt = new Transform() - pt._transform = function (chunk, encoding, cb) { setTimeout(function () { pt.push(chunk) cb() }, 10) } - pt.write(Buffer.from('foog')) pt.write(Buffer.from('bark')) pt.write(Buffer.from('bazy')) @@ -149,8 +139,9 @@ module.exports = function (test) { }) test('assymetric transform (expand)', function (t) { t.plan(7) - const pt = new Transform() // emit each chunk 2 times. + const pt = new Transform() + // emit each chunk 2 times. pt._transform = function (chunk, encoding, cb) { setTimeout(function () { pt.push(chunk) @@ -160,7 +151,6 @@ module.exports = function (test) { }, 10) }, 10) } - pt.write(Buffer.from('foog')) pt.write(Buffer.from('bark')) pt.write(Buffer.from('bazy')) @@ -178,39 +168,34 @@ module.exports = function (test) { }) test('assymetric transform (compress)', function (t) { t.plan(3) - const pt = new Transform() // each output is the first char of 3 consecutive chunks, - // or whatever's left. + const pt = new Transform() + // each output is the first char of 3 consecutive chunks, + // or whatever's left. pt.state = '' - pt._transform = function (chunk, encoding, cb) { if (!chunk) { chunk = '' } - const s = chunk.toString() setTimeout( function () { this.state += s.charAt(0) - if (this.state.length === 3) { pt.push(Buffer.from(this.state)) this.state = '' } - cb() }.bind(this), 10 ) } - pt._flush = function (cb) { // just output whatever we have. pt.push(Buffer.from(this.state)) this.state = '' cb() } - pt.write(Buffer.from('aaaa')) pt.write(Buffer.from('bbbb')) pt.write(Buffer.from('cccc')) @@ -225,16 +210,18 @@ module.exports = function (test) { pt.write(Buffer.from('bbbb')) pt.write(Buffer.from('cccc')) pt.write(Buffer.from('dddd')) - pt.end() // 'abcdeabcdeabcd' + pt.end() + // 'abcdeabcdeabcd' pt.on('finish', function () { t.equal(pt.read(5).toString(), 'abcde') t.equal(pt.read(5).toString(), 'abcde') t.equal(pt.read(5).toString(), 'abcd') }) - }) // this tests for a stall when data is written to a full stream - // that has empty transforms. + }) + // this tests for a stall when data is written to a full stream + // that has empty transforms. test('complex transform', function (t) { t.plan(2) let count = 0 @@ -242,7 +229,6 @@ module.exports = function (test) { const pt = new Transform({ highWaterMark: 3 }) - pt._transform = function (c, e, cb) { if (count++ === 1) { saved = c @@ -251,13 +237,10 @@ module.exports = function (test) { pt.push(saved) saved = null } - pt.push(c) } - cb() } - pt.once('readable', function () { process.nextTick(function () { pt.write(Buffer.from('d')) @@ -278,31 +261,38 @@ module.exports = function (test) { // console.error('>>> emit readable %d', emits); emits++ }) - pt.write(Buffer.from('foog')) // console.error('need emit 0'); + pt.write(Buffer.from('foog')) + // console.error('need emit 0'); pt.write(Buffer.from('bark')) setTimeout(() => { // console.error('should have emitted readable now 1 === %d', emits) t.equal(emits, 1) t.equal(pt.read(5).toString(), 'foogb') - t.equal(pt.read(5) + '', 'null') // console.error('need emit 1'); + t.equal(pt.read(5) + '', 'null') - pt.write(Buffer.from('bazy')) // console.error('should have emitted, but not again'); + // console.error('need emit 1'); - pt.write(Buffer.from('kuel')) // console.error('should have emitted readable now 2 === %d', emits); + pt.write(Buffer.from('bazy')) + // console.error('should have emitted, but not again'); + pt.write(Buffer.from('kuel')) + // console.error('should have emitted readable now 2 === %d', emits); setTimeout(() => { t.equal(emits, 2) t.equal(pt.read(5).toString(), 'arkba') t.equal(pt.read(5).toString(), 'zykue') - t.equal(pt.read(5), null) // console.error('need emit 2'); + t.equal(pt.read(5), null) + + // console.error('need emit 2'); pt.end() setTimeout(() => { t.equal(emits, 3) t.equal(pt.read(5).toString(), 'l') - t.equal(pt.read(5), null) // console.error('should not have emitted again'); + t.equal(pt.read(5), null) + // console.error('should not have emitted again'); t.equal(emits, 3) }) }) @@ -316,19 +306,21 @@ module.exports = function (test) { // console.error('emit readable', emits); emits++ }) - pt.write(Buffer.from('foog')) // console.error('need emit 0'); - + pt.write(Buffer.from('foog')) + // console.error('need emit 0'); pt.write(Buffer.from('bark')) setTimeout(() => { // console.error('should have emitted readable now 1 === %d', emits); t.equal(emits, 1) t.equal(pt.read(5).toString(), 'foogb') - t.equal(pt.read(5), null) // console.error('need emit 1'); + t.equal(pt.read(5), null) + // console.error('need emit 1'); pt.once('readable', function () { t.equal(pt.read(5).toString(), 'arkba') - t.equal(pt.read(5), null) // console.error('need emit 2'); + t.equal(pt.read(5), null) + // console.error('need emit 2'); pt.once('readable', function () { t.equal(pt.read(5).toString(), 'zykue') t.equal(pt.read(5), null) @@ -345,8 +337,9 @@ module.exports = function (test) { }) }) test('passthrough facaded', function (t) { - t.plan(1) // console.error('passthrough facaded'); + t.plan(1) + // console.error('passthrough facaded'); const pt = new PassThrough() const datas = [] pt.on('data', function (chunk) { @@ -370,12 +363,12 @@ module.exports = function (test) { }, 10) }) test('object transform (json parse)', function (t) { - t.plan(5) // console.error('json parse stream'); + t.plan(5) + // console.error('json parse stream'); const jp = new Transform({ objectMode: true }) - jp._transform = function (data, encoding, cb) { try { jp.push(JSON.parse(data)) @@ -383,9 +376,10 @@ module.exports = function (test) { } catch (er) { cb(er) } - } // anything except null/undefined is fine. - // those are "magic" in the stream API, because they signal EOF. + } + // anything except null/undefined is fine. + // those are "magic" in the stream API, because they signal EOF. const objects = [ { foo: 'bar' @@ -413,20 +407,20 @@ module.exports = function (test) { const res = jp.read() t.same(res, obj) }) - jp.end() // read one more time to get the 'end' event - + jp.end() + // read one more time to get the 'end' event jp.read() process.nextTick(function () { t.ok(ended) }) }) test('object transform (json stringify)', function (t) { - t.plan(5) // console.error('json parse stream'); + t.plan(5) + // console.error('json parse stream'); const js = new Transform({ objectMode: true }) - js._transform = function (data, encoding, cb) { try { js.push(JSON.stringify(data)) @@ -434,9 +428,10 @@ module.exports = function (test) { } catch (er) { cb(er) } - } // anything except null/undefined is fine. - // those are "magic" in the stream API, because they signal EOF. + } + // anything except null/undefined is fine. + // those are "magic" in the stream API, because they signal EOF. const objects = [ { foo: 'bar' @@ -464,20 +459,18 @@ module.exports = function (test) { const res = js.read() t.equal(res, JSON.stringify(obj)) }) - js.end() // read one more time to get the 'end' event - + js.end() + // read one more time to get the 'end' event js.read() process.nextTick(function () { t.ok(ended) }) }) - function forEach(xs, f) { for (let i = 0, l = xs.length; i < l; i++) { f(xs[i], i) } } } - module.exports[kReadableStreamSuiteName] = 'stream2-transform' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream2-unpipe-drain.js b/test/browser/test-stream2-unpipe-drain.js index 52742520a..5b20ee530 100644 --- a/test/browser/test-stream2-unpipe-drain.js +++ b/test/browser/test-stream2-unpipe-drain.js @@ -1,13 +1,9 @@ 'use strict' const crypto = require('crypto') - const inherits = require('inherits') - const stream = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { try { crypto.randomBytes(9) @@ -16,34 +12,25 @@ module.exports = function (t) { t.ok(true, 'does not suport random, skipping') return } - t.plan(2) - function TestWriter() { stream.Writable.call(this) } - inherits(TestWriter, stream.Writable) - TestWriter.prototype._write = function (buffer, encoding, callback) { // console.log('write called'); // super slow write stream (callback never called) } - const dest = new TestWriter() - function TestReader(id) { stream.Readable.call(this) this.reads = 0 } - inherits(TestReader, stream.Readable) - TestReader.prototype._read = function (size) { this.reads += 1 this.push(crypto.randomBytes(size)) } - const src1 = new TestReader() const src2 = new TestReader() src1.pipe(dest) @@ -62,5 +49,4 @@ module.exports = function (t) { t.equal(src2.reads, 1) }) } - module.exports[kReadableStreamSuiteName] = 'stream2-unpipe-drain' diff --git a/test/browser/test-stream2-writable.js b/test/browser/test-stream2-writable.js index 3cd3dd207..4a917f26e 100644 --- a/test/browser/test-stream2-writable.js +++ b/test/browser/test-stream2-writable.js @@ -1,23 +1,19 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const inherits = require('inherits') - const { Duplex, Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols') - inherits(TestWriter, Writable) - function TestWriter() { Writable.apply(this, arguments) this.buffer = [] this.written = 0 } - TestWriter.prototype._write = function (chunk, encoding, cb) { // simulate a small unpredictable latency setTimeout( @@ -29,30 +25,23 @@ TestWriter.prototype._write = function (chunk, encoding, cb) { Math.floor(Math.random() * 10) ) } - inherits(Processstdout, Writable) - function Processstdout() { Writable.apply(this, arguments) this.buffer = [] this.written = 0 } - Processstdout.prototype._write = function (chunk, encoding, cb) { // console.log(chunk.toString()); cb() } - const chunks = new Array(50) - for (let i = 0; i < chunks.length; i++) { chunks[i] = new Array(i + 1).join('x') } - if (!process.stdout) { process.stdout = new Processstdout() } - module.exports = function (test) { test('write fast', function (t) { t.plan(1) @@ -77,10 +66,8 @@ module.exports = function (test) { t.same(tw.buffer, chunks, 'got chunks in the right order') }) let i = 0 - ;(function W() { tw.write(chunks[i++]) - if (i < chunks.length) { setTimeout(W, 10) } else { @@ -102,14 +89,11 @@ module.exports = function (test) { drains++ }) let i = 0 - ;(function W() { let ret - do { ret = tw.write(chunks[i++]) } while (ret !== false && i < chunks.length) - if (i < chunks.length) { t.ok(tw._writableState.length >= 50) tw.once('drain', W) @@ -139,16 +123,17 @@ module.exports = function (test) { tw.on('finish', function () { forEach(chunks, function (chunk, i) { const actual = Buffer.from(tw.buffer[i]) - chunk = Buffer.from(chunk) // Some combination of encoding and length result in the last byte replaced by two extra null bytes + chunk = Buffer.from(chunk) + // Some combination of encoding and length result in the last byte replaced by two extra null bytes if (actual[actual.length - 1] === 0) { chunk = Buffer.concat([chunk.slice(0, chunk.length - 1), Buffer.from([0, 0])]) - } // In some cases instead there is one byte less + } + // In some cases instead there is one byte less if (actual.length === chunk.length - 1) { chunk = chunk.slice(0, chunk.length - 1) } - t.same(actual, chunk, 'got the expected chunks ' + i) }) }) @@ -165,13 +150,11 @@ module.exports = function (test) { highWaterMark: 100, decodeStrings: false }) - tw._write = function (chunk, encoding, cb) { t.equals(typeof chunk, 'string') chunk = Buffer.from(chunk, encoding) return TestWriter.prototype._write.call(this, chunk, encoding, cb) } - const encodings = [ 'hex', 'utf8', @@ -188,16 +171,17 @@ module.exports = function (test) { tw.on('finish', function () { forEach(chunks, function (chunk, i) { const actual = Buffer.from(tw.buffer[i]) - chunk = Buffer.from(chunk) // Some combination of encoding and length result in the last byte replaced by two extra null bytes + chunk = Buffer.from(chunk) + // Some combination of encoding and length result in the last byte replaced by two extra null bytes if (actual[actual.length - 1] === 0) { chunk = Buffer.concat([chunk.slice(0, chunk.length - 1), Buffer.from([0, 0])]) - } // In some cases instead there is one byte less + } + // In some cases instead there is one byte less if (actual.length === chunk.length - 1) { chunk = chunk.slice(0, chunk.length - 1) } - t.same(actual, chunk, 'got the expected chunks ' + i) }) }) @@ -282,11 +266,9 @@ module.exports = function (test) { t.plan(1) const tw = new Writable() const hex = '018b5e9a8f6236ffe30e31baf80d2cf6eb' - tw._write = function (chunk, encoding, cb) { t.equal(chunk.toString('hex'), hex) } - const buf = Buffer.from(hex, 'hex') tw.write(buf, 'binary') }) @@ -295,9 +277,7 @@ module.exports = function (test) { const w = new Writable({ autoDestroy: false }) - w._write = function () {} - let gotError = false w.on('error', function (er) { gotError = true @@ -308,11 +288,8 @@ module.exports = function (test) { test('duplexes are pipable', function (t) { t.plan(1) const d = new Duplex() - d._read = function () {} - d._write = function () {} - let gotError = false d.on('error', function (er) { gotError = true @@ -323,9 +300,7 @@ module.exports = function (test) { test('end(chunk) two times is an error', function (t) { t.plan(2) const w = new Writable() - w._write = function () {} - let gotError = false w.on('error', function (er) { gotError = true @@ -341,7 +316,6 @@ module.exports = function (test) { t.plan(2) const w = new Writable() let wrote = false - w._write = function (chunk, e, cb) { t.notOk(this.writing) wrote = true @@ -351,7 +325,6 @@ module.exports = function (test) { cb() }) } - w.on('finish', function () { t.ok(wrote) }) @@ -362,14 +335,12 @@ module.exports = function (test) { t.plan(1) const w = new Writable() let writeCb = false - w._write = function (chunk, e, cb) { setTimeout(function () { writeCb = true cb() }, 10) } - w.on('finish', function () { t.ok(writeCb) }) @@ -380,11 +351,9 @@ module.exports = function (test) { t.plan(1) const w = new Writable() let writeCb = false - w._write = function (chunk, e, cb) { cb() } - w.on('finish', function () { t.ok(writeCb) }) @@ -396,24 +365,20 @@ module.exports = function (test) { test('finish is emitted if last chunk is empty', function (t) { t.plan(1) const w = new Writable() - w._write = function (chunk, e, cb) { process.nextTick(cb) } - w.on('finish', () => { t.ok(true) }) w.write(Buffer.alloc(1)) w.end(Buffer.alloc(0)) }) - function forEach(xs, f) { for (let i = 0, l = xs.length; i < l; i++) { f(xs[i], i) } } } - module.exports[kReadableStreamSuiteName] = 'stream2-writable' module.exports[kReadableStreamSuiteHasMultipleTests] = true diff --git a/test/browser/test-stream3-pause-then-read.js b/test/browser/test-stream3-pause-then-read.js index 4603cb22b..cced00a5c 100644 --- a/test/browser/test-stream3-pause-then-read.js +++ b/test/browser/test-stream3-pause-then-read.js @@ -1,13 +1,12 @@ 'use strict' -/* replacement start */ +/* replacement start */ const { Buffer } = require('buffer') + /* replacement end */ const { Readable, Writable } = require('../../lib/ours/index') - const { kReadableStreamSuiteName } = require('./symbols') - module.exports = function (t) { t.plan(7) const totalChunks = 100 @@ -18,7 +17,6 @@ module.exports = function (t) { highWaterMark: 1000 }) let chunks = totalChunks - r._read = function (n) { if (!(chunks % 2)) { setImmediate(push) @@ -28,33 +26,26 @@ module.exports = function (t) { push() } } - let totalPushed = 0 - function push() { const chunk = chunks-- > 0 ? Buffer.alloc(chunkSize) : null - if (chunk) { totalPushed += chunk.length chunk.fill('x') } - r.push(chunk) } + read100() - read100() // first we read 100 bytes - + // first we read 100 bytes function read100() { readn(100, onData) } - function readn(n, then) { // console.error('read %d', n); expectEndingData -= n - ;(function read() { const c = r.read(n) - if (!c) { r.once('readable', read) } else { @@ -63,50 +54,49 @@ module.exports = function (t) { then() } })() - } // then we listen to some data events + } + // then we listen to some data events function onData() { - expectEndingData -= 100 // console.error('onData'); - + expectEndingData -= 100 + // console.error('onData'); let seen = 0 r.on('data', function od(c) { seen += c.length - if (seen >= 100) { // seen enough r.removeListener('data', od) r.pause() - if (seen > 100) { // oh no, seen too much! // put the extra back. const diff = seen - 100 - r.unshift(c.slice(c.length - diff)) // console.error('seen too much', seen, diff) - } // Nothing should be lost in between + r.unshift(c.slice(c.length - diff)) + // console.error('seen too much', seen, diff) + } + // Nothing should be lost in between setImmediate(pipeLittle) } }) - } // Just pipe 200 bytes, then unshift the extra and unpipe + } + // Just pipe 200 bytes, then unshift the extra and unpipe function pipeLittle() { - expectEndingData -= 200 // console.error('pipe a little'); - + expectEndingData -= 200 + // console.error('pipe a little'); const w = new Writable() let written = 0 w.on('finish', function () { t.equal(written, 200) setImmediate(read1234) }) - w._write = function (chunk, encoding, cb) { written += chunk.length - if (written >= 200) { r.unpipe(w) w.end() cb() - if (written > 200) { const diff = written - 200 written -= diff @@ -116,14 +106,13 @@ module.exports = function (t) { setImmediate(cb) } } - r.pipe(w) - } // now read 1234 more bytes + } + // now read 1234 more bytes function read1234() { readn(1234, resumePause) } - function resumePause() { // console.error('resumePause'); // don't read anything, just resume and re-pause a whole bunch @@ -139,17 +128,14 @@ module.exports = function (t) { r.pause() setImmediate(pipe) } - function pipe() { // console.error('pipe the rest'); const w = new Writable() let written = 0 - w._write = function (chunk, encoding, cb) { written += chunk.length cb() } - w.on('finish', function () { // console.error('written', written, totalPushed); t.equal(written, expectEndingData) @@ -158,5 +144,4 @@ module.exports = function (t) { r.pipe(w) } } - module.exports[kReadableStreamSuiteName] = 'stream3-pause-then-read' diff --git a/test/common/fixtures.js b/test/common/fixtures.js index d6fcd811b..d69561bc7 100644 --- a/test/common/fixtures.js +++ b/test/common/fixtures.js @@ -1,34 +1,25 @@ 'use strict' const path = require('path') - const fs = require('fs') - const { pathToFileURL } = require('url') - const fixturesDir = path.join(__dirname, '..', 'fixtures') - function fixturesPath(...args) { return path.join(fixturesDir, ...args) } - function fixturesFileURL(...args) { return pathToFileURL(fixturesPath(...args)) } - function readFixtureSync(args, enc) { if (Array.isArray(args)) return fs.readFileSync(fixturesPath(...args), enc) return fs.readFileSync(fixturesPath(args), enc) } - function readFixtureKey(name, enc) { return fs.readFileSync(fixturesPath('keys', name), enc) } - function readFixtureKeys(enc, ...names) { return names.map((name) => readFixtureKey(name, enc)) } - module.exports = { fixturesDir, path: fixturesPath, diff --git a/test/common/fixtures.mjs b/test/common/fixtures.mjs index d6f7f6c09..372fabf88 100644 --- a/test/common/fixtures.mjs +++ b/test/common/fixtures.mjs @@ -1,17 +1,5 @@ -import fixtures from './fixtures.js'; +import fixtures from './fixtures.js' -const { - fixturesDir, - path, - fileURL, - readSync, - readKey, -} = fixtures; +const { fixturesDir, path, fileURL, readSync, readKey } = fixtures -export { - fixturesDir, - path, - fileURL, - readSync, - readKey, -}; +export { fixturesDir, path, fileURL, readSync, readKey } diff --git a/test/common/index.js b/test/common/index.js index b9b07d980..5491b5666 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -25,40 +25,33 @@ const process = global.process // Some tests tamper with the process global. const assert = require('assert') - const { exec, execSync, spawn, spawnSync } = require('child_process') - -const fs = require('fs') // Do not require 'os' until needed so that test-os-checked-function can +const fs = require('fs') +// Do not require 'os' until needed so that test-os-checked-function can // monkey patch it. If 'os' is required here, that test will fail. - const path = require('path') - const { inspect } = require('util') - const { isMainThread } = require('worker_threads') - const tmpdir = require('./tmpdir') - const bits = ['arm64', 'mips', 'mipsel', 'ppc64', 'riscv64', 's390x', 'x64'].includes(process.arch) ? 64 : 32 const hasIntl = !!process.config.variables.v8_enable_i18n_support +const { atob, btoa } = require('buffer') -const { atob, btoa } = require('buffer') // Some tests assume a umask of 0o022 so set that up front. Tests that need a +// Some tests assume a umask of 0o022 so set that up front. Tests that need a // different umask will set it themselves. // // Workers can read, but not set the umask, so check that this is the main // thread. - if (isMainThread) process.umask(0o022) - const noop = () => {} - const hasCrypto = Boolean(process.versions.openssl) && !process.env.NODE_SKIP_CRYPTO const hasOpenSSL3 = hasCrypto && require('crypto').constants.OPENSSL_VERSION_NUMBER >= 805306368 -const hasQuic = hasCrypto && !!process.config.variables.openssl_quic // Check for flags. Skip this for workers (both, the `cluster` module and +const hasQuic = hasCrypto && !!process.config.variables.openssl_quic + +// Check for flags. Skip this for workers (both, the `cluster` module and // `worker_threads`) and child processes. // If the binary was built without-ssl then the crypto flags are // invalid (bad option). The test itself should handle this case. - if ( process.argv.length === 2 && !process.env.NODE_SKIP_FLAG_CHECK && @@ -75,20 +68,18 @@ if ( fs.closeSync(fd) const source = buffer.toString('utf8', 0, bytesRead) const flagStart = source.indexOf('// Flags: --') + 10 - if (flagStart !== 9) { - let flagEnd = source.indexOf('\n', flagStart) // Normalize different EOL. - + let flagEnd = source.indexOf('\n', flagStart) + // Normalize different EOL. if (source[flagEnd - 1] === '\r') { flagEnd-- } - const flags = source.substring(flagStart, flagEnd).replace(/_/g, '-').split(' ') const args = process.execArgv.map((arg) => arg.replace(/_/g, '-')) - for (const flag of flags) { if ( - !args.includes(flag) && // If the binary is build without `intl` the inspect option is + !args.includes(flag) && + // If the binary is build without `intl` the inspect option is // invalid. The test itself should handle this case. (process.features.inspector || !flag.startsWith('--inspect')) ) { @@ -103,7 +94,6 @@ if ( stdio: 'inherit' } const result = spawnSync(process.execPath, args, options) - if (result.signal) { process.kill(0, result.signal) } else { @@ -113,7 +103,6 @@ if ( } } } - const isWindows = process.platform === 'win32' const isAIX = process.platform === 'aix' const isSunOS = process.platform === 'sunos' @@ -121,11 +110,9 @@ const isFreeBSD = process.platform === 'freebsd' const isOpenBSD = process.platform === 'openbsd' const isLinux = process.platform === 'linux' const isOSX = process.platform === 'darwin' - const isPi = (() => { try { - var _$exec - + var _exec // Normal Raspberry Pi detection is to find the `Raspberry Pi` string in // the contents of `/sys/firmware/devicetree/base/model` but that doesn't // work inside a container. Match the chipset model number instead. @@ -133,81 +120,63 @@ const isPi = (() => { encoding: 'utf8' }) return ( - ((_$exec = /^Hardware\s*:\s*(.*)$/im.exec(cpuinfo)) === null || _$exec === undefined ? undefined : _$exec[1]) === + ((_exec = /^Hardware\s*:\s*(.*)$/im.exec(cpuinfo)) === null || _exec === undefined ? undefined : _exec[1]) === 'BCM2835' ) } catch { return false } })() - const isDumbTerminal = process.env.TERM === 'dumb' -const buildType = process.config.target_defaults ? process.config.target_defaults.default_configuration : 'Release' // If env var is set then enable async_hook hooks for all tests. +const buildType = process.config.target_defaults ? process.config.target_defaults.default_configuration : 'Release' +// If env var is set then enable async_hook hooks for all tests. if (process.env.NODE_TEST_WITH_ASYNC_HOOKS) { const destroydIdsList = {} const destroyListList = {} const initHandles = {} - const { internalBinding } = require('internal/test/binding') - const async_wrap = internalBinding('async_wrap') process.on('exit', () => { // Iterate through handles to make sure nothing crashes for (const k in initHandles) inspect(initHandles[k]) }) const _queueDestroyAsyncId = async_wrap.queueDestroyAsyncId - async_wrap.queueDestroyAsyncId = function queueDestroyAsyncId(id) { if (destroyListList[id] !== undefined) { process._rawDebug(destroyListList[id]) - process._rawDebug() - throw new Error(`same id added to destroy list twice (${id})`) } - destroyListList[id] = inspect(new Error()) - _queueDestroyAsyncId(id) } - require('async_hooks') .createHook({ init(id, ty, tr, resource) { if (initHandles[id]) { process._rawDebug(`Is same resource: ${resource === initHandles[id].resource}`) - process._rawDebug(`Previous stack:\n${initHandles[id].stack}\n`) - throw new Error(`init called twice for same id (${id})`) } - initHandles[id] = { resource, stack: inspect(new Error()).substr(6) } }, - before() {}, - after() {}, - destroy(id) { if (destroydIdsList[id] !== undefined) { process._rawDebug(destroydIdsList[id]) - process._rawDebug() - throw new Error(`destroy called for same id (${id})`) } - destroydIdsList[id] = inspect(new Error()) } }) .enable() } - let opensslCli = null let inFreeBSDJail = null let localhostIPv4 = null @@ -215,31 +184,31 @@ const localIPv6Hosts = isLinux ? [ // Debian/Ubuntu 'ip6-localhost', - 'ip6-loopback', // SUSE + 'ip6-loopback', + // SUSE 'ipv6-localhost', - 'ipv6-loopback', // Typically universal + 'ipv6-loopback', + // Typically universal 'localhost' ] : ['localhost'] - const PIPE = (() => { const localRelative = path.relative(process.cwd(), `${tmpdir.path}/`) const pipePrefix = isWindows ? '\\\\.\\pipe\\' : localRelative const pipeName = `node-test.${process.pid}.sock` return path.join(pipePrefix, pipeName) -})() // Check that when running a test with +})() + +// Check that when running a test with // `$node --abort-on-uncaught-exception $file child` // the process aborts. - function childShouldThrowAndAbort() { let testCmd = '' - if (!isWindows) { // Do not create core files, as it can take a lot of disk space on // continuous testing and developers' machines testCmd += 'ulimit -c 0 && ' } - testCmd += `"${process.argv[0]}" --abort-on-uncaught-exception ` testCmd += `"${process.argv[1]}" child` const child = exec(testCmd) @@ -249,15 +218,12 @@ function childShouldThrowAndAbort() { assert(nodeProcessAborted(exitCode, signal), errMsg) }) } - function createZeroFilledFile(filename) { const fd = fs.openSync(filename, 'w') fs.ftruncateSync(fd, 10 * 1024 * 1024) fs.closeSync(fd) } - const pwdCommand = isWindows ? ['cmd.exe', ['/d', '/c', 'cd']] : ['pwd', []] - function platformTimeout(ms) { const multipliers = typeof ms === 'bigint' @@ -278,7 +244,6 @@ function platformTimeout(ms) { return ms } - let knownGlobals = [ typeof AggregateError !== 'undefined' ? AggregateError : require('../../lib/ours/util').AggregateError, typeof AbortController !== 'undefined' ? AbortController : require('abort-controller').AbortController, @@ -294,56 +259,49 @@ let knownGlobals = [ setInterval, setTimeout, queueMicrotask -] // TODO(@jasnell): This check can be temporary. AbortController is +] + +// TODO(@jasnell): This check can be temporary. AbortController is // not currently supported in either Node.js 12 or 10, making it // difficult to run tests comparatively on those versions. Once // all supported versions have AbortController as a global, this // check can be removed and AbortController can be added to the // knownGlobals list above. - if (global.AbortController) knownGlobals.push(global.AbortController) - if (global.gc) { knownGlobals.push(global.gc) } - if (global.Performance) { knownGlobals.push(global.Performance) } - if (global.performance) { knownGlobals.push(global.performance) } - if (global.PerformanceMark) { knownGlobals.push(global.PerformanceMark) } - if (global.PerformanceMeasure) { knownGlobals.push(global.PerformanceMeasure) -} // TODO(@ethan-arrowood): Similar to previous checks, this can be temporary +} + +// TODO(@ethan-arrowood): Similar to previous checks, this can be temporary // until v16.x is EOL. Once all supported versions have structuredClone we // can add this to the list above instead. - if (global.structuredClone) { knownGlobals.push(global.structuredClone) } - if (global.fetch) { knownGlobals.push(fetch) } - if (hasCrypto && global.crypto) { knownGlobals.push(global.crypto) knownGlobals.push(global.Crypto) knownGlobals.push(global.CryptoKey) knownGlobals.push(global.SubtleCrypto) } - if (global.CustomEvent) { knownGlobals.push(global.CustomEvent) } - if (global.ReadableStream) { knownGlobals.push( global.ReadableStream, @@ -365,40 +323,31 @@ if (global.ReadableStream) { global.DecompressionStream ) } - function allowGlobals(...allowlist) { knownGlobals = knownGlobals.concat(allowlist) } - if (process.env.NODE_TEST_KNOWN_GLOBALS !== '0') { if (process.env.NODE_TEST_KNOWN_GLOBALS) { const knownFromEnv = process.env.NODE_TEST_KNOWN_GLOBALS.split(',') allowGlobals(...knownFromEnv) } - function leakedGlobals() { const leaked = [] - for (const val in global) { if (!knownGlobals.includes(global[val])) { leaked.push(val) } } - return leaked } - process.on('exit', function () { const leaked = leakedGlobals() - if (leaked.length > 0) { assert.fail(`Unexpected global(s) found: ${leaked.join(', ')}`) } }) } - const mustCallChecks = [] - function runCallChecks(exitCode) { if (exitCode !== 0) return const failed = mustCallChecks.filter(function (context) { @@ -406,7 +355,6 @@ function runCallChecks(exitCode) { context.messageSegment = `at least ${context.minimum}` return context.actual < context.minimum } - context.messageSegment = `exactly ${context.exact}` return context.actual !== context.exact }) @@ -421,51 +369,45 @@ function runCallChecks(exitCode) { }) if (failed.length) process.exit(1) } - function mustCall(fn, exact) { return _mustCallInner(fn, exact, 'exact') } - function mustSucceed(fn, exact) { return mustCall(function (err, ...args) { assert.ifError(err) if (typeof fn === 'function') return fn.apply(this, args) }, exact) } - function mustCallAtLeast(fn, minimum) { return _mustCallInner(fn, minimum, 'minimum') } - function _mustCallInner(fn, criteria = 1, field) { if (process._exiting) throw new Error('Cannot use common.mustCall*() in process exit handler') - if (typeof fn === 'number') { criteria = fn fn = noop } else if (fn === undefined) { fn = noop } - if (typeof criteria !== 'number') throw new TypeError(`Invalid ${field} value: ${criteria}`) const context = { [field]: criteria, actual: 0, stack: inspect(new Error()), name: fn.name || '' - } // Add the exit listener only once to avoid listener leak warnings + } + // Add the exit listener only once to avoid listener leak warnings if (mustCallChecks.length === 0) process.on('exit', runCallChecks) mustCallChecks.push(context) - const _return = function () { // eslint-disable-line func-style context.actual++ return fn.apply(this, arguments) - } // Function instances have own properties that may be relevant. + } + // Function instances have own properties that may be relevant. // Let's replicate those properties to the returned function. // Refs: https://tc39.es/ecma262/#sec-function-instances - Object.defineProperties(_return, { name: { value: fn.name, @@ -482,23 +424,19 @@ function _mustCallInner(fn, criteria = 1, field) { }) return _return } - function hasMultiLocalhost() { const { internalBinding } = require('internal/test/binding') - const { TCP, constants: TCPConstants } = internalBinding('tcp_wrap') const t = new TCP(TCPConstants.SOCKET) const ret = t.bind('127.0.0.2', 0) t.close() return ret === 0 } - function skipIfEslintMissing() { if (!fs.existsSync(path.join(__dirname, '..', '..', 'tools', 'node_modules', 'eslint'))) { skip('missing ESLint') } } - function canCreateSymLink() { // On Windows, creating symlinks requires admin privileges. // We'll only try to run symlink test if we have enough privileges. @@ -508,7 +446,6 @@ function canCreateSymLink() { // If unix tools are in the path, they can shadow the one we want, // so use the full path while executing whoami const whoamiPath = path.join(process.env.SystemRoot, 'System32', 'whoami.exe') - try { const output = execSync(`${whoamiPath} /priv`, { timeout: 1000 @@ -517,25 +454,20 @@ function canCreateSymLink() { } catch { return false } - } // On non-Windows platforms, this always returns `true` - + } + // On non-Windows platforms, this always returns `true` return true } - function getCallSite(top) { const originalStackFormatter = Error.prepareStackTrace - Error.prepareStackTrace = (err, stack) => `${stack[0].getFileName()}:${stack[0].getLineNumber()}` - const err = new Error() - Error.captureStackTrace(err, top) // With the V8 Error API, the stack is not formatted until it is accessed - + Error.captureStackTrace(err, top) + // With the V8 Error API, the stack is not formatted until it is accessed err.stack // eslint-disable-line no-unused-expressions - Error.prepareStackTrace = originalStackFormatter return err.stack } - function mustNotCall(msg) { const callSite = getCallSite(mustNotCall) return function mustNotCall(...args) { @@ -543,9 +475,7 @@ function mustNotCall(msg) { assert.fail(`${msg || 'function should not have been called'} at ${callSite}` + argsInfo) } } - const _mustNotMutateObjectDeepProxies = new WeakMap() - function mustNotMutateObjectDeep(original) { // Return primitives and functions directly. Primitives are immutable, and // proxied functions are impossible to compare against originals, e.g. with @@ -553,88 +483,77 @@ function mustNotMutateObjectDeep(original) { if (original === null || typeof original !== 'object') { return original } - const cachedProxy = _mustNotMutateObjectDeepProxies.get(original) - if (cachedProxy) { return cachedProxy } - const _mustNotMutateObjectDeepHandler = { __proto__: null, - defineProperty(target, property, descriptor) { assert.fail(`Expected no side effects, got ${inspect(property)} ` + 'defined') }, - deleteProperty(target, property) { assert.fail(`Expected no side effects, got ${inspect(property)} ` + 'deleted') }, - get(target, prop, receiver) { return mustNotMutateObjectDeep(Reflect.get(target, prop, receiver)) }, - preventExtensions(target) { assert.fail('Expected no side effects, got extensions prevented on ' + inspect(target)) }, - set(target, property, value, receiver) { assert.fail(`Expected no side effects, got ${inspect(value)} ` + `assigned to ${inspect(property)}`) }, - setPrototypeOf(target, prototype) { assert.fail(`Expected no side effects, got set prototype to ${prototype}`) } } const proxy = new Proxy(original, _mustNotMutateObjectDeepHandler) - _mustNotMutateObjectDeepProxies.set(original, proxy) - return proxy } - function printSkipMessage(msg) { console.log(`1..0 # Skipped: ${msg}`) } - function skip(msg) { printSkipMessage(msg) process.exit(0) -} // Returns true if the exit code "exitCode" and/or signal name "signal" +} + +// Returns true if the exit code "exitCode" and/or signal name "signal" // represent the exit code and/or signal name of a node process that aborted, // false otherwise. - function nodeProcessAborted(exitCode, signal) { // Depending on the compiler used, node will exit with either // exit code 132 (SIGILL), 133 (SIGTRAP) or 134 (SIGABRT). - let expectedExitCodes = [132, 133, 134] // On platforms using KSH as the default shell (like SmartOS), + let expectedExitCodes = [132, 133, 134] + + // On platforms using KSH as the default shell (like SmartOS), // when a process aborts, KSH exits with an exit code that is // greater than 256, and thus the exit code emitted with the 'exit' // event is null and the signal is set to either SIGILL, SIGTRAP, // or SIGABRT (depending on the compiler). + const expectedSignals = ['SIGILL', 'SIGTRAP', 'SIGABRT'] - const expectedSignals = ['SIGILL', 'SIGTRAP', 'SIGABRT'] // On Windows, 'aborts' are of 2 types, depending on the context: + // On Windows, 'aborts' are of 2 types, depending on the context: // (i) Exception breakpoint, if --abort-on-uncaught-exception is on // which corresponds to exit code 2147483651 (0x80000003) // (ii) Otherwise, _exit(134) which is called in place of abort() due to // raising SIGABRT exiting with ambiguous exit code '3' by default + if (isWindows) expectedExitCodes = [0x80000003, 134] - if (isWindows) expectedExitCodes = [0x80000003, 134] // When using --abort-on-uncaught-exception, V8 will use + // When using --abort-on-uncaught-exception, V8 will use // base::OS::Abort to terminate the process. // Depending on the compiler used, the shell or other aspects of // the platform used to build the node binary, this will actually // make V8 exit by aborting or by raising a signal. In any case, // one of them (exit code or signal) needs to be set to one of // the expected exit codes or signals. - if (signal !== null) { return expectedSignals.includes(signal) } - return expectedExitCodes.includes(exitCode) } - function isAlive(pid) { try { process.kill(pid, 'SIGCONT') @@ -643,7 +562,6 @@ function isAlive(pid) { return false } } - function _expectWarning(name, expected, code) { if (typeof expected === 'string') { expected = [[expected, code]] @@ -651,37 +569,32 @@ function _expectWarning(name, expected, code) { expected = Object.entries(expected).map(([a, b]) => [b, a]) } else if (!Array.isArray(expected[0])) { expected = [[expected[0], expected[1]]] - } // Deprecation codes are mandatory, everything else is not. - + } + // Deprecation codes are mandatory, everything else is not. if (name === 'DeprecationWarning') { expected.forEach(([_, code]) => assert(code, expected)) } - return mustCall((warning) => { const expectedProperties = expected.shift() - if (!expectedProperties) { assert.fail(`Unexpected extra warning received: ${warning}`) } - const [message, code] = expectedProperties assert.strictEqual(warning.name, name) - if (typeof message === 'string') { assert.strictEqual(warning.message, message) } else { assert.match(warning.message, message) } - assert.strictEqual(warning.code, code) }, expected.length) } +let catchWarning -let catchWarning // Accepts a warning name and description or array of descriptions or a map of +// Accepts a warning name and description or array of descriptions or a map of // warning names to description(s) ensures a warning is generated for each // name/description pair. // The expected messages have to be unique per `expectWarning()` call. - function expectWarning(nameOrMap, expected, code) { if (catchWarning === undefined) { catchWarning = {} @@ -689,11 +602,9 @@ function expectWarning(nameOrMap, expected, code) { if (!catchWarning[warning.name]) { throw new TypeError(`"${warning.name}" was triggered without being expected.\n` + inspect(warning)) } - catchWarning[warning.name](warning) }) } - if (typeof nameOrMap === 'string') { catchWarning[nameOrMap] = _expectWarning(nameOrMap, expected, code) } else { @@ -701,8 +612,9 @@ function expectWarning(nameOrMap, expected, code) { catchWarning[name] = _expectWarning(name, nameOrMap[name]) }) } -} // Useful for testing expected internal/error objects +} +// Useful for testing expected internal/error objects function expectsError(validator, exact) { return mustCall((...args) => { if (args.length !== 1) { @@ -710,10 +622,9 @@ function expectsError(validator, exact) { // always being called. assert.fail(`Expected one argument, got ${inspect(args)}`) } - const error = args.pop() - const descriptor = Object.getOwnPropertyDescriptor(error, 'message') // The error message should be non-enumerable - + const descriptor = Object.getOwnPropertyDescriptor(error, 'message') + // The error message should be non-enumerable assert.strictEqual(descriptor.enumerable, false) assert.throws(() => { throw error @@ -721,25 +632,21 @@ function expectsError(validator, exact) { return true }, exact) } - function skipIfInspectorDisabled() { if (!process.features.inspector) { skip('V8 inspector is disabled') } } - function skipIf32Bits() { if (bits < 64) { skip('The tested feature is not available in 32bit builds') } } - function skipIfWorker() { if (!isMainThread) { skip('This test only works on a main thread') } } - function getArrayBufferViews(buf) { const { buffer, byteOffset, byteLength } = buf const out = [] @@ -757,29 +664,23 @@ function getArrayBufferViews(buf) { BigUint64Array, DataView ] - for (const type of arrayBufferViews) { const { BYTES_PER_ELEMENT = 1 } = type - if (byteLength % BYTES_PER_ELEMENT === 0) { out.push(new type(buffer, byteOffset, byteLength / BYTES_PER_ELEMENT)) } } - return out } - function getBufferSources(buf) { return [...getArrayBufferViews(buf), new Uint8Array(buf).buffer] } - function getTTYfd() { // Do our best to grab a tty fd. - const tty = require('tty') // Don't attempt fd 0 as it is not writable on Windows. + const tty = require('tty') + // Don't attempt fd 0 as it is not writable on Windows. // Ref: ef2861961c3d9e9ed6972e1e84d969683b25cf95 - const ttyFd = [1, 2, 4, 5].find(tty.isatty) - if (ttyFd === undefined) { try { return fs.openSync('/dev/tty') @@ -788,35 +689,30 @@ function getTTYfd() { return -1 } } - return ttyFd } - function runWithInvalidFD(func) { - let fd = 1 << 30 // Get first known bad file descriptor. 1 << 30 is usually unlikely to + let fd = 1 << 30 + // Get first known bad file descriptor. 1 << 30 is usually unlikely to // be an valid one. - try { while (fs.fstatSync(fd--) && fd > 0); } catch { return func(fd) } - printSkipMessage('Could not generate an invalid fd') -} // A helper function to simplify checking for ERR_INVALID_ARG_TYPE output. +} +// A helper function to simplify checking for ERR_INVALID_ARG_TYPE output. function invalidArgTypeHelper(input) { if (input == null) { return ` Received ${input}` } - if (typeof input === 'function' && input.name) { return ` Received function ${input.name}` } - if (typeof input === 'object') { var _input$constructor - if ( (_input$constructor = input.constructor) !== null && _input$constructor !== undefined && @@ -824,43 +720,34 @@ function invalidArgTypeHelper(input) { ) { return ` Received an instance of ${input.constructor.name}` } - return ` Received ${inspect(input, { depth: -1 })}` } - let inspected = inspect(input, { colors: false }) - if (inspected.length > 28) { inspected = `${inspected.slice(inspected, 0, 25)}...` } - return ` Received type ${typeof input} (${inspected})` } - function skipIfDumbTerminal() { if (isDumbTerminal) { skip('skipping - dumb terminal') } } - function gcUntil(name, condition) { if (typeof name === 'function') { condition = name name = undefined } - return new Promise((resolve, reject) => { let count = 0 - function gcAndCheck() { setImmediate(() => { count++ global.gc() - if (condition()) { resolve() } else if (count < 10) { @@ -870,15 +757,12 @@ function gcUntil(name, condition) { } }) } - gcAndCheck() }) } - function requireNoPackageJSONAbove(dir = __dirname) { let possiblePackage = path.join(dir, '..', 'package.json') let lastPackage = null - while (possiblePackage !== lastPackage) { if (fs.existsSync(possiblePackage)) { assert.fail( @@ -886,12 +770,10 @@ function requireNoPackageJSONAbove(dir = __dirname) { `its file location. Found package.json at ${possiblePackage}.` ) } - lastPackage = possiblePackage possiblePackage = path.join(possiblePackage, '..', '..', 'package.json') } } - function spawnPromisified(...args) { let stderr = '' let stdout = '' @@ -923,7 +805,6 @@ function spawnPromisified(...args) { }) }) } - const common = { allowGlobals, buildType, @@ -974,50 +855,39 @@ const common = { skipIfInspectorDisabled, skipIfWorker, spawnPromisified, - get enoughTestMem() { - return require('os').totalmem() > 0x70000000 - /* 1.75 Gb */ + return require('os').totalmem() > 0x70000000 /* 1.75 Gb */ }, get hasFipsCrypto() { return hasCrypto && require('crypto').getFips() }, - get hasIPv6() { const iFaces = require('os').networkInterfaces() - const re = isWindows ? /Loopback Pseudo-Interface/ : /lo/ return Object.keys(iFaces).some((name) => { return re.test(name) && iFaces[name].some(({ family }) => family === 'IPv6') }) }, - get inFreeBSDJail() { if (inFreeBSDJail !== null) return inFreeBSDJail - if (exports.isFreeBSD && execSync('sysctl -n security.jail.jailed').toString() === '1\n') { inFreeBSDJail = true } else { inFreeBSDJail = false } - return inFreeBSDJail }, - // On IBMi, process.platform and os.platform() both return 'aix', // It is not enough to differentiate between IBMi and real AIX system. get isIBMi() { return require('os').type() === 'OS400' }, - get isLinuxPPCBE() { return process.platform === 'linux' && process.arch === 'ppc64' && require('os').endianness() === 'BE' }, - get localhostIPv4() { if (localhostIPv4 !== null) return localhostIPv4 - if (this.inFreeBSDJail) { // Jailed network interfaces are a bit special - since we need to jump // through loops, as well as this being an exception case, assume the @@ -1032,15 +902,12 @@ const common = { ) } } - if (localhostIPv4 === null) localhostIPv4 = '127.0.0.1' return localhostIPv4 }, - // opensslCli defined lazily to reduce overhead of spawnSync get opensslCli() { if (opensslCli !== null) return opensslCli - if (process.config.variables.node_shared_openssl) { // Use external command opensslCli = 'openssl' @@ -1048,26 +915,20 @@ const common = { // Use command built from sources included in Node.js repository opensslCli = path.join(path.dirname(process.execPath), 'openssl-cli') } - if (exports.isWindows) opensslCli += '.exe' const opensslCmd = spawnSync(opensslCli, ['version']) - if (opensslCmd.status !== 0 || opensslCmd.error !== undefined) { // OpenSSL command cannot be executed opensslCli = false } - return opensslCli }, - get PORT() { if (+process.env.TEST_PARALLEL) { throw new Error('common.PORT cannot be used in a parallelized test') } - return +process.env.NODE_COMMON_PORT || 12346 }, - /** * Returns the EOL character used by this Git checkout. */ diff --git a/test/common/index.mjs b/test/common/index.mjs index 2b30f4993..41a63bce2 100644 --- a/test/common/index.mjs +++ b/test/common/index.mjs @@ -1,7 +1,7 @@ -import { createRequire } from 'module'; +import { createRequire } from 'module' -const require = createRequire(import.meta.url); -const common = require('./index.js'); +const require = createRequire(import.meta.url) +const common = require('./index.js') const { isMainThread, @@ -49,8 +49,8 @@ const { getBufferSources, getTTYfd, runWithInvalidFD, - spawnPromisified, -} = common; + spawnPromisified +} = common export { isMainThread, @@ -99,5 +99,5 @@ export { getTTYfd, runWithInvalidFD, createRequire, - spawnPromisified, -}; + spawnPromisified +} diff --git a/test/common/tmpdir.js b/test/common/tmpdir.js index 5773c5554..641d65e01 100644 --- a/test/common/tmpdir.js +++ b/test/common/tmpdir.js @@ -1,11 +1,8 @@ 'use strict' const fs = require('fs') - const path = require('path') - const { isMainThread } = require('worker_threads') - function rmSync(pathname) { fs.rmSync(pathname, { maxRetries: 3, @@ -13,48 +10,41 @@ function rmSync(pathname) { force: true }) } +const testRoot = process.env.NODE_TEST_DIR ? fs.realpathSync(process.env.NODE_TEST_DIR) : path.resolve(__dirname, '..') -const testRoot = process.env.NODE_TEST_DIR ? fs.realpathSync(process.env.NODE_TEST_DIR) : path.resolve(__dirname, '..') // Using a `.` prefixed name, which is the convention for "hidden" on POSIX, +// Using a `.` prefixed name, which is the convention for "hidden" on POSIX, // gets tools to ignore it by default or by simple rules, especially eslint. - const tmpdirName = '.tmp.' + (process.env.TEST_SERIAL_ID || process.env.TEST_THREAD_ID || '0') const tmpPath = path.join(testRoot, tmpdirName) let firstRefresh = true - function refresh() { rmSync(tmpPath) fs.mkdirSync(tmpPath) - if (firstRefresh) { - firstRefresh = false // Clean only when a test uses refresh. This allows for child processes to + firstRefresh = false + // Clean only when a test uses refresh. This allows for child processes to // use the tmpdir and only the parent will clean on exit. - process.on('exit', onexit) } } - function onexit() { // Change directory to avoid possible EBUSY if (isMainThread) process.chdir(testRoot) - try { rmSync(tmpPath) } catch (e) { console.error("Can't clean tmpdir:", tmpPath) const files = fs.readdirSync(tmpPath) console.error('Files blocking:', files) - if (files.some((f) => f.startsWith('.nfs'))) { // Warn about NFS "silly rename" console.error('Note: ".nfs*" might be files that were open and ' + 'unlinked but not closed.') console.error('See http://nfs.sourceforge.net/#faq_d2 for details.') } - console.error() throw e } } - module.exports = { path: tmpPath, refresh diff --git a/test/ours/test-errors.js b/test/ours/test-errors.js index 84a34a574..4e0f898fc 100644 --- a/test/ours/test-errors.js +++ b/test/ours/test-errors.js @@ -1,16 +1,15 @@ 'use strict' const t = require('tap') - const { codes: errors } = require('../../lib/ours/errors') - function checkError(err, Base, name, code, message) { t.ok(err instanceof Base) t.equal(err.name, name) t.equal(err.code, code) t.equal(err.message, message) -} // Update this numbers based on the number of checkError below multiplied by the assertions within checkError +} +// Update this numbers based on the number of checkError below multiplied by the assertions within checkError t.plan(17 * 4) checkError( new errors.ERR_INVALID_ARG_VALUE('name', 0), diff --git a/test/ours/test-fake-timers.js b/test/ours/test-fake-timers.js index b4cc966b1..98871f304 100644 --- a/test/ours/test-fake-timers.js +++ b/test/ours/test-fake-timers.js @@ -1,21 +1,14 @@ 'use strict' require('../common') - const t = require('tap') - const util = require('util') - const fakeTimers = require('@sinonjs/fake-timers') - const Transform = require('../../lib/ours/index').Transform - t.plan(1) - function MyTransform() { Transform.call(this) } - util.inherits(MyTransform, Transform) const clock = fakeTimers.install({ toFake: ['setImmediate', 'nextTick'] diff --git a/test/ours/test-stream-sync-write.js b/test/ours/test-stream-sync-write.js index 7fa0e4678..ed6d01ee6 100644 --- a/test/ours/test-stream-sync-write.js +++ b/test/ours/test-stream-sync-write.js @@ -1,48 +1,34 @@ 'use strict' require('../common') - const t = require('tap') - const util = require('util') - const stream = require('../../lib/ours/index') - const WritableStream = stream.Writable t.plan(1) - const InternalStream = function () { WritableStream.call(this) } - util.inherits(InternalStream, WritableStream) let invocations = 0 - InternalStream.prototype._write = function (chunk, encoding, callback) { callback() } - const internalStream = new InternalStream() - const ExternalStream = function (writable) { this._writable = writable WritableStream.call(this) } - util.inherits(ExternalStream, WritableStream) - ExternalStream.prototype._write = function (chunk, encoding, callback) { this._writable.write(chunk, encoding, callback) } - const externalStream = new ExternalStream(internalStream) - for (let i = 0; i < 2000; i++) { externalStream.write(i.toString(), () => { invocations++ }) } - externalStream.end() externalStream.on('finish', () => { t.equal(invocations, 2000) diff --git a/test/parallel/test-readable-from-iterator-closing.js b/test/parallel/test-readable-from-iterator-closing.js index 109ab7e34..fee1a5a71 100644 --- a/test/parallel/test-readable-from-iterator-closing.js +++ b/test/parallel/test-readable-from-iterator-closing.js @@ -1,22 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const { mustCall, mustNotCall } = require('../common') - const { Readable } = require('../../lib/ours/index') - const { strictEqual } = require('assert') - async function asyncSupport() { const finallyMustCall = mustCall() const bodyMustCall = mustCall() - async function* infiniteGenerate() { try { while (true) yield 'a' @@ -24,20 +18,16 @@ async function asyncSupport() { finallyMustCall() } } - const stream = Readable.from(infiniteGenerate()) - for await (const chunk of stream) { bodyMustCall() strictEqual(chunk, 'a') break } } - async function syncSupport() { const finallyMustCall = mustCall() const bodyMustCall = mustCall() - function* infiniteGenerate() { try { while (true) yield 'a' @@ -45,20 +35,16 @@ async function syncSupport() { finallyMustCall() } } - const stream = Readable.from(infiniteGenerate()) - for await (const chunk of stream) { bodyMustCall() strictEqual(chunk, 'a') break } } - async function syncPromiseSupport() { const returnMustBeAwaited = mustCall() const bodyMustCall = mustCall() - function* infiniteGenerate() { try { while (true) yield Promise.resolve('a') @@ -72,22 +58,18 @@ async function syncPromiseSupport() { } } } - const stream = Readable.from(infiniteGenerate()) - for await (const chunk of stream) { bodyMustCall() strictEqual(chunk, 'a') break } } - async function syncRejectedSupport() { const returnMustBeAwaited = mustCall() const bodyMustNotCall = mustNotCall() const catchMustCall = mustCall() const secondNextMustNotCall = mustNotCall() - function* generate() { try { yield Promise.reject('a') @@ -102,9 +84,7 @@ async function syncRejectedSupport() { } } } - const stream = Readable.from(generate()) - try { for await (const chunk of stream) { bodyMustNotCall(chunk) @@ -113,7 +93,6 @@ async function syncRejectedSupport() { catchMustCall() } } - async function noReturnAfterThrow() { const returnMustNotCall = mustNotCall() const bodyMustNotCall = mustNotCall() @@ -123,12 +102,10 @@ async function noReturnAfterThrow() { [Symbol.asyncIterator]() { return this }, - async next() { nextMustCall() throw new Error('a') }, - async return() { returnMustNotCall() return { @@ -136,7 +113,6 @@ async function noReturnAfterThrow() { } } }) - try { for await (const chunk of stream) { bodyMustNotCall(chunk) @@ -145,7 +121,6 @@ async function noReturnAfterThrow() { catchMustCall() } } - async function closeStreamWhileNextIsPending() { const finallyMustCall = mustCall() const dataMustCall = mustCall() @@ -157,7 +132,6 @@ async function closeStreamWhileNextIsPending() { const yielded = new Promise((resolve) => { resolveYielded = mustCall(resolve) }) - async function* infiniteGenerate() { try { while (true) { @@ -169,7 +143,6 @@ async function closeStreamWhileNextIsPending() { finallyMustCall() } } - const stream = Readable.from(infiniteGenerate()) stream.on('data', (data) => { dataMustCall() @@ -180,11 +153,9 @@ async function closeStreamWhileNextIsPending() { resolveDestroy() }) } - async function closeAfterNullYielded() { const finallyMustCall = mustCall() const dataMustCall = mustCall(3) - function* generate() { try { yield 'a' @@ -194,14 +165,12 @@ async function closeAfterNullYielded() { finallyMustCall() } } - const stream = Readable.from(generate()) stream.on('data', (chunk) => { dataMustCall() strictEqual(chunk, 'a') }) } - Promise.all([ asyncSupport(), syncSupport(), @@ -211,8 +180,8 @@ Promise.all([ closeStreamWhileNextIsPending(), closeAfterNullYielded() ]).then(mustCall()) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-readable-from.js b/test/parallel/test-readable-from.js index 60ce376eb..886a7634c 100644 --- a/test/parallel/test-readable-from.js +++ b/test/parallel/test-readable-from.js @@ -1,93 +1,72 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const { mustCall } = require('../common') - const { once } = require('events') - const { Readable } = require('../../lib/ours/index') - const { strictEqual, throws } = require('assert') - const common = require('../common') - { throws(() => { Readable.from(null) }, /ERR_INVALID_ARG_TYPE/) } - async function toReadableBasicSupport() { async function* generate() { yield 'a' yield 'b' yield 'c' } - const stream = Readable.from(generate()) const expected = ['a', 'b', 'c'] - for await (const chunk of stream) { strictEqual(chunk, expected.shift()) } } - async function toReadableSyncIterator() { function* generate() { yield 'a' yield 'b' yield 'c' } - const stream = Readable.from(generate()) const expected = ['a', 'b', 'c'] - for await (const chunk of stream) { strictEqual(chunk, expected.shift()) } } - async function toReadablePromises() { const promises = [Promise.resolve('a'), Promise.resolve('b'), Promise.resolve('c')] const stream = Readable.from(promises) const expected = ['a', 'b', 'c'] - for await (const chunk of stream) { strictEqual(chunk, expected.shift()) } } - async function toReadableString() { const stream = Readable.from('abc') const expected = ['abc'] - for await (const chunk of stream) { strictEqual(chunk, expected.shift()) } } - async function toReadableBuffer() { const stream = Readable.from(Buffer.from('abc')) const expected = ['abc'] - for await (const chunk of stream) { strictEqual(chunk.toString(), expected.shift()) } } - async function toReadableOnData() { async function* generate() { yield 'a' yield 'b' yield 'c' } - const stream = Readable.from(generate()) let iterations = 0 const expected = ['a', 'b', 'c'] @@ -98,14 +77,12 @@ async function toReadableOnData() { await once(stream, 'end') strictEqual(iterations, 3) } - async function toReadableOnDataNonObject() { async function* generate() { yield 'a' yield 'b' yield 'c' } - const stream = Readable.from(generate(), { objectMode: false }) @@ -119,30 +96,25 @@ async function toReadableOnDataNonObject() { await once(stream, 'end') strictEqual(iterations, 3) } - async function destroysTheStreamWhenThrowing() { async function* generate() { // eslint-disable-line require-yield throw new Error('kaboom') } - const stream = Readable.from(generate()) stream.read() const [err] = await once(stream, 'error') strictEqual(err.message, 'kaboom') strictEqual(stream.destroyed, true) } - async function asTransformStream() { async function* generate(stream) { for await (const chunk of stream) { yield chunk.toUpperCase() } } - const source = new Readable({ objectMode: true, - read() { this.push('a') this.push('b') @@ -152,39 +124,32 @@ async function asTransformStream() { }) const stream = Readable.from(generate(source)) const expected = ['A', 'B', 'C'] - for await (const chunk of stream) { strictEqual(chunk, expected.shift()) } } - async function endWithError() { async function* generate() { yield 1 yield 2 yield Promise.reject('Boum') } - const stream = Readable.from(generate()) const expected = [1, 2] - try { for await (const chunk of stream) { strictEqual(chunk, expected.shift()) } - throw new Error() } catch (err) { strictEqual(expected.length, 0) strictEqual(err, 'Boum') } } - async function destroyingStreamWithErrorThrowsInGenerator() { const validateError = common.mustCall((e) => { strictEqual(e, 'Boum') }) - async function* generate() { try { yield 1 @@ -195,13 +160,11 @@ async function destroyingStreamWithErrorThrowsInGenerator() { validateError(e) } } - const stream = Readable.from(generate()) stream.read() stream.once('error', common.mustCall()) stream.destroy('Boum') } - Promise.all([ toReadableBasicSupport(), toReadableSyncIterator(), @@ -215,8 +178,8 @@ Promise.all([ endWithError(), destroyingStreamWithErrorThrowsInGenerator() ]).then(mustCall()) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-readable-large-hwm.js b/test/parallel/test-readable-large-hwm.js index 53251d6ec..23c30b894 100644 --- a/test/parallel/test-readable-large-hwm.js +++ b/test/parallel/test-readable-large-hwm.js @@ -1,24 +1,21 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const { Readable } = require('../../lib/ours/index') -const { Readable } = require('../../lib/ours/index') // Make sure that readable completes +// Make sure that readable completes // even when reading larger buffer. - const bufferSize = 10 * 1024 * 1024 let n = 0 const r = new Readable({ read() { // Try to fill readable buffer piece by piece. r.push(Buffer.alloc(bufferSize / 10)) - if (n++ > 10) { r.push(null) } @@ -31,8 +28,8 @@ r.on('readable', () => { } }) r.on('end', common.mustCall()) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-readable-single-end.js b/test/parallel/test-readable-single-end.js index df4cced65..7827276dd 100644 --- a/test/parallel/test-readable-single-end.js +++ b/test/parallel/test-readable-single-end.js @@ -1,15 +1,14 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const { Readable } = require('../../lib/ours/index') -const { Readable } = require('../../lib/ours/index') // This test ensures that there will not be an additional empty 'readable' +// This test ensures that there will not be an additional empty 'readable' // event when stream has ended (only 1 event signalling about end) const r = new Readable({ @@ -18,8 +17,8 @@ const r = new Readable({ r.push(null) r.on('readable', common.mustCall()) r.on('end', common.mustCall()) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-add-abort-signal.js b/test/parallel/test-stream-add-abort-signal.js index 976c72b20..c72fc45ca 100644 --- a/test/parallel/test-stream-add-abort-signal.js +++ b/test/parallel/test-stream-add-abort-signal.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -16,22 +13,15 @@ if (typeof AbortSignal.abort !== 'function') { // Flags: --expose-internals ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { addAbortSignal, Readable } = require('../../lib/ours/index') - const { addAbortSignalNoValidate } = require('../../lib/internal/streams/add-abort-signal') - { assert.throws(() => { addAbortSignal('INVALID_SIGNAL') @@ -47,8 +37,8 @@ const { addAbortSignalNoValidate } = require('../../lib/internal/streams/add-abo }) assert.deepStrictEqual(r, addAbortSignalNoValidate('INVALID_SIGNAL', r)) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-aliases-legacy.js b/test/parallel/test-stream-aliases-legacy.js index 759665ef0..a3c5d96b5 100644 --- a/test/parallel/test-stream-aliases-legacy.js +++ b/test/parallel/test-stream-aliases-legacy.js @@ -1,25 +1,23 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') +const stream = require('../../lib/ours/index') -const stream = require('../../lib/ours/index') // Verify that all individual aliases are left in place. +// Verify that all individual aliases are left in place. assert.strictEqual(stream.Readable, require('../../lib/_stream_readable')) assert.strictEqual(stream.Writable, require('../../lib/_stream_writable')) assert.strictEqual(stream.Duplex, require('../../lib/_stream_duplex')) assert.strictEqual(stream.Transform, require('../../lib/_stream_transform')) assert.strictEqual(stream.PassThrough, require('../../lib/_stream_passthrough')) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-asIndexedPairs.mjs b/test/parallel/test-stream-asIndexedPairs.mjs index a103920ee..35919114a 100644 --- a/test/parallel/test-stream-asIndexedPairs.mjs +++ b/test/parallel/test-stream-asIndexedPairs.mjs @@ -1,64 +1,82 @@ -import '../common/index.mjs'; -import { Readable }from '../../lib/ours/index.js'; -import { deepStrictEqual, rejects, throws } from 'assert'; -import tap from 'tap'; +import '../common/index.mjs' +import { Readable } from '../../lib/ours/index.js' +import { deepStrictEqual, rejects, throws } from 'assert' +import tap from 'tap' { // asIndexedPairs with a synchronous stream - const pairs = await Readable.from([1, 2, 3]).asIndexedPairs().toArray(); - deepStrictEqual(pairs, [[0, 1], [1, 2], [2, 3]]); - const empty = await Readable.from([]).asIndexedPairs().toArray(); - deepStrictEqual(empty, []); + const pairs = await Readable.from([1, 2, 3]).asIndexedPairs().toArray() + deepStrictEqual(pairs, [ + [0, 1], + [1, 2], + [2, 3] + ]) + const empty = await Readable.from([]).asIndexedPairs().toArray() + deepStrictEqual(empty, []) } { // asIndexedPairs works an asynchronous streams - const asyncFrom = (...args) => Readable.from(...args).map(async (x) => x); - const pairs = await asyncFrom([1, 2, 3]).asIndexedPairs().toArray(); - deepStrictEqual(pairs, [[0, 1], [1, 2], [2, 3]]); - const empty = await asyncFrom([]).asIndexedPairs().toArray(); - deepStrictEqual(empty, []); + const asyncFrom = (...args) => Readable.from(...args).map(async (x) => x) + const pairs = await asyncFrom([1, 2, 3]).asIndexedPairs().toArray() + deepStrictEqual(pairs, [ + [0, 1], + [1, 2], + [2, 3] + ]) + const empty = await asyncFrom([]).asIndexedPairs().toArray() + deepStrictEqual(empty, []) } { // Does not enumerate an infinite stream - const infinite = () => Readable.from(async function* () { - while (true) yield 1; - }()); - const pairs = await infinite().asIndexedPairs().take(3).toArray(); - deepStrictEqual(pairs, [[0, 1], [1, 1], [2, 1]]); - const empty = await infinite().asIndexedPairs().take(0).toArray(); - deepStrictEqual(empty, []); + const infinite = () => + Readable.from( + (async function* () { + while (true) yield 1 + })() + ) + const pairs = await infinite().asIndexedPairs().take(3).toArray() + deepStrictEqual(pairs, [ + [0, 1], + [1, 1], + [2, 1] + ]) + const empty = await infinite().asIndexedPairs().take(0).toArray() + deepStrictEqual(empty, []) } { // AbortSignal - await rejects(async () => { - const ac = new AbortController(); - const { signal } = ac; - const p = Readable.from([1, 2, 3]).asIndexedPairs({ signal }).toArray(); - ac.abort(); - await p; - }, { name: 'AbortError' }); + await rejects( + async () => { + const ac = new AbortController() + const { signal } = ac + const p = Readable.from([1, 2, 3]).asIndexedPairs({ signal }).toArray() + ac.abort() + await p + }, + { name: 'AbortError' } + ) await rejects(async () => { - const signal = AbortSignal.abort(); - await Readable.from([1, 2, 3]).asIndexedPairs({ signal }).toArray(); - }, /AbortError/); + const signal = AbortSignal.abort() + await Readable.from([1, 2, 3]).asIndexedPairs({ signal }).toArray() + }, /AbortError/) } { // Error cases - throws(() => Readable.from([1]).asIndexedPairs(1), /ERR_INVALID_ARG_TYPE/); - throws(() => Readable.from([1]).asIndexedPairs({ signal: true }), /ERR_INVALID_ARG_TYPE/); + throws(() => Readable.from([1]).asIndexedPairs(1), /ERR_INVALID_ARG_TYPE/) + throws(() => Readable.from([1]).asIndexedPairs({ signal: true }), /ERR_INVALID_ARG_TYPE/) } - /* replacement start */ - process.on('beforeExit', (code) => { - if(code === 0) { - tap.pass('test succeeded'); - } else { - tap.fail(`test failed - exited code ${code}`); - } - }); - /* replacement end */ +/* replacement start */ +process.on('beforeExit', (code) => { + if (code === 0) { + tap.pass('test succeeded') + } else { + tap.fail(`test failed - exited code ${code}`) + } +}) +/* replacement end */ diff --git a/test/parallel/test-stream-auto-destroy.js b/test/parallel/test-stream-auto-destroy.js index 77454f414..4163e84ba 100644 --- a/test/parallel/test-stream-auto-destroy.js +++ b/test/parallel/test-stream-auto-destroy.js @@ -1,28 +1,21 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - { const r = new stream.Readable({ autoDestroy: true, - read() { this.push('hello') this.push('world') this.push(null) }, - destroy: common.mustCall((err, cb) => cb()) }) let ended = false @@ -43,11 +36,9 @@ const assert = require('assert') { const w = new stream.Writable({ autoDestroy: true, - write(data, enc, cb) { cb(null) }, - destroy: common.mustCall((err, cb) => cb()) }) let finished = false @@ -70,11 +61,9 @@ const assert = require('assert') { const t = new stream.Transform({ autoDestroy: true, - transform(data, enc, cb) { cb(null, data) }, - destroy: common.mustCall((err, cb) => cb()) }) let ended = false @@ -127,8 +116,8 @@ const assert = require('assert') }) r.pipe(w) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js b/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js index 7a6f7d683..ef8d5a93e 100644 --- a/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js +++ b/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { PassThrough } = require('../../lib/ours/index') - const encode = new PassThrough({ highWaterMark: 1 }) @@ -30,8 +26,8 @@ const onData = common.mustCall(() => { encode.pipe(decode).on('data', onData) send(Buffer.from([0x1])) send(Buffer.from([0x2])) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-backpressure.js b/test/parallel/test-stream-backpressure.js index d9072aec5..3f73d84b9 100644 --- a/test/parallel/test-stream-backpressure.js +++ b/test/parallel/test-stream-backpressure.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - let pushes = 0 const total = 65500 + 40 * 1024 const rs = new stream.Readable({ @@ -21,17 +16,18 @@ const rs = new stream.Readable({ this.push(null) return } + const length = this._readableState.length - const length = this._readableState.length // We are at most doing two full runs of _reads + // We are at most doing two full runs of _reads // before stopping, because Readable is greedy // to keep its buffer full - assert(length <= total) this.push(Buffer.alloc(65500)) - for (let i = 0; i < 40; i++) { this.push(Buffer.alloc(1024)) - } // We will be over highWaterMark at this point + } + + // We will be over highWaterMark at this point // but a new call to _read is scheduled anyway. }, 11) }) @@ -41,8 +37,8 @@ const ws = stream.Writable({ }, 41 * 10) }) rs.pipe(ws) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-base-prototype-accessors-enumerability.js b/test/parallel/test-stream-base-prototype-accessors-enumerability.js index c58a0f817..e593d3303 100644 --- a/test/parallel/test-stream-base-prototype-accessors-enumerability.js +++ b/test/parallel/test-stream-base-prototype-accessors-enumerability.js @@ -1,19 +1,21 @@ // Flags: --expose-internals + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } -require('../common') // This tests that the prototype accessors added by StreamBase::AddMethods +require('../common') + +// This tests that the prototype accessors added by StreamBase::AddMethods // are not enumerable. They could be enumerated when inspecting the prototype // with util.inspect or the inspector protocol. -const assert = require('assert') // Or anything that calls StreamBase::AddMethods when setting up its prototype +const assert = require('assert') +// Or anything that calls StreamBase::AddMethods when setting up its prototype const internalBinding = process.binding const TTY = internalBinding('tty_wrap').TTY { @@ -22,8 +24,8 @@ const TTY = internalBinding('tty_wrap').TTY assert.strictEqual(ttyIsEnumerable('fd'), false) assert.strictEqual(ttyIsEnumerable('_externalStream'), false) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-base-typechecking.js b/test/parallel/test-stream-base-typechecking.js index fdf895dfb..070e7563f 100644 --- a/test/parallel/test-stream-base-typechecking.js +++ b/test/parallel/test-stream-base-typechecking.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const net = require('net') - const server = net.createServer().listen( 0, common.mustCall(() => { @@ -35,8 +30,8 @@ const server = net.createServer().listen( ) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-big-packet.js b/test/parallel/test-stream-big-packet.js index f6591a7b5..9a7a2b92a 100644 --- a/test/parallel/test-stream-big-packet.js +++ b/test/parallel/test-stream-big-packet.js @@ -18,34 +18,27 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - let passed = false - class TestStream extends stream.Transform { _transform(chunk, encoding, done) { if (!passed) { // Char 'a' only exists in the last write passed = chunk.toString().includes('a') } - done() } } - const s1 = new stream.Transform({ transform(chunk, encoding, cb) { process.nextTick(cb, null, chunk) @@ -53,26 +46,30 @@ const s1 = new stream.Transform({ }) const s2 = new stream.PassThrough() const s3 = new TestStream() -s1.pipe(s3) // Don't let s2 auto close which may close s3 - +s1.pipe(s3) +// Don't let s2 auto close which may close s3 s2.pipe(s3, { end: false -}) // We must write a buffer larger than highWaterMark +}) -const big = Buffer.alloc(s1.writableHighWaterMark + 1, 'x') // Since big is larger than highWaterMark, it will be buffered internally. +// We must write a buffer larger than highWaterMark +const big = Buffer.alloc(s1.writableHighWaterMark + 1, 'x') -assert(!s1.write(big)) // 'tiny' is small enough to pass through internal buffer. +// Since big is larger than highWaterMark, it will be buffered internally. +assert(!s1.write(big)) +// 'tiny' is small enough to pass through internal buffer. +assert(s2.write('tiny')) -assert(s2.write('tiny')) // Write some small data in next IO loop, which will never be written to s3 +// Write some small data in next IO loop, which will never be written to s3 // Because 'drain' event is not emitted from s1 and s1 is still paused +setImmediate(s1.write.bind(s1), 'later') -setImmediate(s1.write.bind(s1), 'later') // Assert after two IO loops when all operations have been done. - +// Assert after two IO loops when all operations have been done. process.on('exit', function () { assert(passed, 'Large buffer is not handled properly by Writable Stream') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-big-push.js b/test/parallel/test-stream-big-push.js index b48eb437b..c4171023d 100644 --- a/test/parallel/test-stream-big-push.js +++ b/test/parallel/test-stream-big-push.js @@ -18,28 +18,23 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const str = 'asdfasdfasdfasdfasdf' const r = new stream.Readable({ highWaterMark: 5, encoding: 'utf8' }) let reads = 0 - function _read() { if (reads === 0) { setTimeout(() => { @@ -54,13 +49,13 @@ function _read() { r.push(null) } } - r._read = common.mustCall(_read, 3) -r.on('end', common.mustCall()) // Push some data in to start. -// We've never gotten any read event at this point. - -const ret = r.push(str) // Should be false. > hwm +r.on('end', common.mustCall()) +// Push some data in to start. +// We've never gotten any read event at this point. +const ret = r.push(str) +// Should be false. > hwm assert(!ret) let chunk = r.read() assert.strictEqual(chunk, str) @@ -76,8 +71,8 @@ r.once('readable', () => { chunk = r.read() assert.strictEqual(chunk, null) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-buffer-list.js b/test/parallel/test-stream-buffer-list.js index adcd14310..f134cca0b 100644 --- a/test/parallel/test-stream-buffer-list.js +++ b/test/parallel/test-stream-buffer-list.js @@ -1,46 +1,41 @@ // Flags: --expose-internals + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') +const BufferList = require('../../lib/internal/streams/buffer_list') -const BufferList = require('../../lib/internal/streams/buffer_list') // Test empty buffer list. - +// Test empty buffer list. const emptyList = new BufferList() emptyList.shift() assert.deepStrictEqual(emptyList, new BufferList()) assert.strictEqual(emptyList.join(','), '') assert.deepStrictEqual(emptyList.concat(0), Buffer.alloc(0)) const buf = Buffer.from('foo') - function testIterator(list, count) { // test iterator - let len = 0 // eslint-disable-next-line no-unused-vars - + let len = 0 + // eslint-disable-next-line no-unused-vars for (const x of list) { len++ } - assert.strictEqual(len, count) -} // Test buffer list with one element. +} +// Test buffer list with one element. const list = new BufferList() testIterator(list, 0) list.push(buf) testIterator(list, 1) - for (const x of list) { assert.strictEqual(x, buf) } - const copy = list.concat(3) testIterator(copy, 3) assert.notStrictEqual(copy, buf) @@ -80,8 +75,8 @@ assert.deepStrictEqual(list, new BufferList()) list.push(buf) assert.strictEqual(list.consume(5).toString(), 'foofo') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-catch-rejections.js b/test/parallel/test-stream-catch-rejections.js index 9a39c0870..b4f9efc69 100644 --- a/test/parallel/test-stream-catch-rejections.js +++ b/test/parallel/test-stream-catch-rejections.js @@ -1,22 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - { const r = new stream.Readable({ captureRejections: true, - read() {} }) r.push('hello') @@ -37,7 +31,6 @@ const assert = require('assert') const w = new stream.Writable({ captureRejections: true, highWaterMark: 1, - write(chunk, enc, cb) { process.nextTick(cb) } @@ -60,8 +53,8 @@ const assert = require('assert') }, 2) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-compose.js b/test/parallel/test-stream-compose.js index 2cf56da13..b6b739ac7 100644 --- a/test/parallel/test-stream-compose.js +++ b/test/parallel/test-stream-compose.js @@ -1,21 +1,16 @@ // Flags: --expose-internals + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable, Transform, Writable, finished, PassThrough } = require('../../lib/ours/index') - const compose = require('../../lib/internal/streams/compose') - const assert = require('assert') - { let res = '' compose( @@ -237,7 +232,6 @@ const assert = require('assert') } { const _err = new Error('asd') - compose( new Transform({ objectMode: true, @@ -268,7 +262,6 @@ const assert = require('assert') } { const _err = new Error('asd') - compose( new Transform({ objectMode: true, @@ -279,12 +272,10 @@ const assert = require('assert') async function* (source) { // eslint-disable-line require-yield let tmp = '' - for await (const chunk of source) { tmp += chunk throw _err } - return tmp }, new Transform({ @@ -304,8 +295,9 @@ const assert = require('assert') }) } { - let buf = '' // Convert into readable Duplex. + let buf = '' + // Convert into readable Duplex. const s1 = compose( (async function* () { yield 'Hello' @@ -333,8 +325,8 @@ const assert = require('assert') ) } { - let buf = '' // Convert into transform duplex. - + let buf = '' + // Convert into transform duplex. const s2 = compose(async function* (source) { for await (const chunk of source) { yield String(chunk).toUpperCase() @@ -354,21 +346,24 @@ const assert = require('assert') ) } { - let buf = '' // Convert into readable Duplex. + let buf = '' + // Convert into readable Duplex. const s1 = compose( (async function* () { yield 'Hello' yield 'World' })() - ) // Convert into transform duplex. + ) + // Convert into transform duplex. const s2 = compose(async function* (source) { for await (const chunk of source) { yield String(chunk).toUpperCase() } - }) // Convert into writable duplex. + }) + // Convert into writable duplex. const s3 = compose(async function (source) { for await (const chunk of source) { buf += chunk @@ -384,8 +379,9 @@ const assert = require('assert') ) } { - let buf = '' // Convert into readable Duplex. + let buf = '' + // Convert into readable Duplex. const s1 = compose( (async function* () { yield 'Hello' @@ -438,8 +434,9 @@ const assert = require('assert') } } { - let buf = '' // Convert into readable Duplex. + let buf = '' + // Convert into readable Duplex. const s1 = compose( (async function* () { yield 'Hello' @@ -454,7 +451,6 @@ const assert = require('assert') for await (const chunk of source) { buf += chunk } - return buf } ) @@ -466,8 +462,9 @@ const assert = require('assert') ) } { - let buf = '' // Convert into readable Duplex. + let buf = '' + // Convert into readable Duplex. const s1 = compose( 'HelloWorld', async function* (source) { @@ -489,8 +486,8 @@ const assert = require('assert') }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-construct.js b/test/parallel/test-stream-construct.js index 03aa33f86..0a46a5a0b 100644 --- a/test/parallel/test-stream-construct.js +++ b/test/parallel/test-stream-construct.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable, Readable, Duplex } = require('../../lib/ours/index') - const assert = require('assert') - { // Multiple callback. new Writable({ @@ -45,6 +40,7 @@ const assert = require('assert') } { // Synchronous error. + new Writable({ construct: common.mustCall((callback) => { callback(new Error('test')) @@ -59,6 +55,7 @@ const assert = require('assert') } { // Synchronous error. + new Readable({ construct: common.mustCall((callback) => { callback(new Error('test')) @@ -73,6 +70,7 @@ const assert = require('assert') } { // Asynchronous error. + new Writable({ construct: common.mustCall((callback) => { process.nextTick(callback, new Error('test')) @@ -87,6 +85,7 @@ const assert = require('assert') } { // Asynchronous error. + new Readable({ construct: common.mustCall((callback) => { process.nextTick(callback, new Error('test')) @@ -99,7 +98,6 @@ const assert = require('assert') }) ) } - function testDestroy(factory) { { let constructed = false @@ -199,7 +197,6 @@ function testDestroy(factory) { s.destroy(new Error()) } } - testDestroy( (opts) => new Readable({ @@ -290,6 +287,7 @@ testDestroy( } { // https://github.com/nodejs/node/issues/34448 + let constructed = false const d = new Duplex({ readable: false, @@ -301,11 +299,9 @@ testDestroy( }) ) }), - write(chunk, encoding, callback) { callback() }, - read() { this.push(null) } @@ -328,8 +324,8 @@ testDestroy( read: common.mustNotCall() }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-decoder-objectmode.js b/test/parallel/test-stream-decoder-objectmode.js index 32a5839a8..e282caeed 100644 --- a/test/parallel/test-stream-decoder-objectmode.js +++ b/test/parallel/test-stream-decoder-objectmode.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - const readable = new stream.Readable({ read: () => {}, encoding: 'utf16le', @@ -20,13 +15,14 @@ const readable = new stream.Readable({ }) readable.push(Buffer.from('abc', 'utf16le')) readable.push(Buffer.from('def', 'utf16le')) -readable.push(null) // Without object mode, these would be concatenated into a single chunk. +readable.push(null) +// Without object mode, these would be concatenated into a single chunk. assert.strictEqual(readable.read(), 'abc') assert.strictEqual(readable.read(), 'def') assert.strictEqual(readable.read(), null) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-destroy-event-order.js b/test/parallel/test-stream-destroy-event-order.js index 8086a1733..a52a13ed2 100644 --- a/test/parallel/test-stream-destroy-event-order.js +++ b/test/parallel/test-stream-destroy-event-order.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - const rs = new Readable({ read() {} }) @@ -33,8 +28,8 @@ rs.on( }) ) rs.destroy(new Error('kaboom')) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-drop-take.js b/test/parallel/test-stream-drop-take.js index a80d54b8e..49622b690 100644 --- a/test/parallel/test-stream-drop-take.js +++ b/test/parallel/test-stream-drop-take.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,35 +12,25 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const { deepStrictEqual, rejects, throws } = require('assert') - const { from } = Readable - const fromAsync = (...args) => from(...args).map(async (x) => x) - const naturals = () => from( (async function* () { let i = 1 - while (true) { yield i++ } })() ) - { // Synchronous streams ;(async () => { @@ -54,8 +41,8 @@ const naturals = () => deepStrictEqual(await from([1, 2, 3]).drop(1).take(1).toArray(), [2]) deepStrictEqual(await from([1, 2]).drop(0).toArray(), [1, 2]) deepStrictEqual(await from([1, 2]).take(0).toArray(), []) - })().then(common.mustCall()) // Asynchronous streams - + })().then(common.mustCall()) + // Asynchronous streams ;(async () => { deepStrictEqual(await fromAsync([1, 2, 3]).drop(2).toArray(), [3]) deepStrictEqual(await fromAsync([1, 2, 3]).take(1).toArray(), [1]) @@ -64,9 +51,9 @@ const naturals = () => deepStrictEqual(await fromAsync([1, 2, 3]).drop(1).take(1).toArray(), [2]) deepStrictEqual(await fromAsync([1, 2]).drop(0).toArray(), [1, 2]) deepStrictEqual(await fromAsync([1, 2]).take(0).toArray(), []) - })().then(common.mustCall()) // Infinite streams + })().then(common.mustCall()) + // Infinite streams // Asynchronous streams - ;(async () => { deepStrictEqual(await naturals().take(1).toArray(), [1]) deepStrictEqual(await naturals().drop(1).take(1).toArray(), [2]) @@ -126,11 +113,9 @@ const naturals = () => { // Error cases const invalidArgs = [-1, -Infinity, -40] - for (const example of invalidArgs) { throws(() => from([]).take(example).toArray(), /ERR_OUT_OF_RANGE/) } - throws(() => Readable.from([1]).drop(1, 1), /ERR_INVALID_ARG_TYPE/) throws( () => @@ -148,8 +133,8 @@ const naturals = () => /ERR_INVALID_ARG_TYPE/ ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-duplex-destroy.js b/test/parallel/test-stream-duplex-destroy.js index 52a4f3a03..950686ccb 100644 --- a/test/parallel/test-stream-duplex-destroy.js +++ b/test/parallel/test-stream-duplex-destroy.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,26 +12,19 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Duplex } = require('../../lib/ours/index') - const assert = require('assert') - { const duplex = new Duplex({ write(chunk, enc, cb) { cb() }, - read() {} }) duplex.resume() @@ -49,7 +39,6 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {} }) duplex.resume() @@ -70,7 +59,6 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {} }) duplex._destroy = common.mustCall(function (err, cb) { @@ -94,9 +82,7 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {}, - destroy: common.mustCall(function (err, cb) { assert.strictEqual(err, expected) cb() @@ -104,8 +90,9 @@ const assert = require('assert') }) duplex.resume() duplex.on('end', common.mustNotCall('no end event')) - duplex.on('finish', common.mustNotCall('no finish event')) // Error is swallowed by the custom _destroy + duplex.on('finish', common.mustNotCall('no finish event')) + // Error is swallowed by the custom _destroy duplex.on('error', common.mustNotCall('no error event')) duplex.on('close', common.mustCall()) duplex.destroy(expected) @@ -116,7 +103,6 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {} }) duplex._destroy = common.mustCall(function (err, cb) { @@ -131,7 +117,6 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {} }) duplex.resume() @@ -158,7 +143,6 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {} }) const expected = new Error('kaboom') @@ -182,9 +166,7 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {}, - allowHalfOpen: true }) duplex.resume() @@ -198,12 +180,12 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {} }) duplex.destroyed = true - assert.strictEqual(duplex.destroyed, true) // The internal destroy() mechanism should not be triggered + assert.strictEqual(duplex.destroyed, true) + // The internal destroy() mechanism should not be triggered duplex.on('finish', common.mustNotCall()) duplex.on('end', common.mustNotCall()) duplex.destroy() @@ -214,7 +196,6 @@ const assert = require('assert') this.destroyed = false Duplex.call(this) } - Object.setPrototypeOf(MyDuplex.prototype, Duplex.prototype) Object.setPrototypeOf(MyDuplex, Duplex) new MyDuplex() @@ -223,11 +204,9 @@ const assert = require('assert') const duplex = new Duplex({ writable: false, autoDestroy: true, - write(chunk, enc, cb) { cb() }, - read() {} }) duplex.push(null) @@ -238,11 +217,9 @@ const assert = require('assert') const duplex = new Duplex({ readable: false, autoDestroy: true, - write(chunk, enc, cb) { cb() }, - read() {} }) duplex.end() @@ -252,11 +229,9 @@ const assert = require('assert') const duplex = new Duplex({ allowHalfOpen: false, autoDestroy: true, - write(chunk, enc, cb) { cb() }, - read() {} }) duplex.push(null) @@ -280,9 +255,7 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - read() {}, - signal }) let count = 0 @@ -290,15 +263,14 @@ const assert = require('assert') 'error', common.mustCall((e) => { assert.strictEqual(count++, 0) // Ensure not called twice - assert.strictEqual(e.name, 'AbortError') }) ) duplex.on('close', common.mustCall()) controller.abort() } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-duplex-end.js b/test/parallel/test-stream-duplex-end.js index 743caed87..39c2a0458 100644 --- a/test/parallel/test-stream-duplex-end.js +++ b/test/parallel/test-stream-duplex-end.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const Duplex = require('../../lib/ours/index').Duplex - { const stream = new Duplex({ read() {} @@ -26,7 +21,6 @@ const Duplex = require('../../lib/ours/index').Duplex { const stream = new Duplex({ read() {}, - allowHalfOpen: false }) assert.strictEqual(stream.allowHalfOpen, false) @@ -38,7 +32,6 @@ const Duplex = require('../../lib/ours/index').Duplex { const stream = new Duplex({ read() {}, - allowHalfOpen: false }) assert.strictEqual(stream.allowHalfOpen, false) @@ -48,8 +41,8 @@ const Duplex = require('../../lib/ours/index').Duplex stream.resume() stream.push(null) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-duplex-from.js b/test/parallel/test-stream-duplex-from.js index 6c1010804..b527bd9c0 100644 --- a/test/parallel/test-stream-duplex-from.js +++ b/test/parallel/test-stream-duplex-from.js @@ -1,20 +1,14 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Duplex, Readable, Writable, pipeline } = require('../../lib/ours/index') - const Blob = globalThis.Blob || require('buffer').Blob - { const d = Duplex.from({ readable: new Readable({ @@ -167,37 +161,34 @@ const Blob = globalThis.Blob || require('buffer').Blob ['abc\ndef\nghi'], Duplex.from(async function* (source) { let rest = '' - for await (const chunk of source) { const lines = (rest + chunk.toString()).split('\n') rest = lines.pop() - for (const line of lines) { yield line } } - yield rest }), async function* (source) { // eslint-disable-line require-yield let ret = '' - for await (const x of source) { ret += x } - assert.strictEqual(ret, 'abcdefghi') }, common.mustCall(() => {}) ) -} // Ensure that isDuplexNodeStream was called +} +// Ensure that isDuplexNodeStream was called { const duplex = new Duplex() assert.strictEqual(Duplex.from(duplex), duplex) -} // Ensure that Duplex.from works for blobs +} +// Ensure that Duplex.from works for blobs if (typeof Blob !== 'undefined') { const blob = new Blob(['blob']) const expectedByteLength = blob.size @@ -208,8 +199,9 @@ if (typeof Blob !== 'undefined') { assert.strictEqual(arrayBuffer.byteLength, expectedByteLength) }) ) -} // Ensure that given a promise rejection it emits an error +} +// Ensure that given a promise rejection it emits an error { const myErrorMessage = 'myCustomError' Duplex.from(Promise.reject(myErrorMessage)).on( @@ -218,29 +210,30 @@ if (typeof Blob !== 'undefined') { assert.strictEqual(error, myErrorMessage) }) ) -} // Ensure that given a promise rejection on an async function it emits an error +} +// Ensure that given a promise rejection on an async function it emits an error { const myErrorMessage = 'myCustomError' - async function asyncFn() { return Promise.reject(myErrorMessage) } - Duplex.from(asyncFn).on( 'error', common.mustCall((error) => { assert.strictEqual(error, myErrorMessage) }) ) -} // Ensure that Duplex.from throws an Invalid return value when function is void +} +// Ensure that Duplex.from throws an Invalid return value when function is void { assert.throws(() => Duplex.from(() => {}), { code: 'ERR_INVALID_RETURN_VALUE' }) -} // Ensure data if a sub object has a readable stream it's duplexified +} +// Ensure data if a sub object has a readable stream it's duplexified { const msg = Buffer.from('hello') const duplex = Duplex.from({ @@ -257,8 +250,9 @@ if (typeof Blob !== 'undefined') { }) ) assert.strictEqual(duplex.writable, false) -} // Ensure data if a sub object has a writable stream it's duplexified +} +// Ensure data if a sub object has a writable stream it's duplexified { const msg = Buffer.from('hello') const duplex = Duplex.from({ @@ -270,8 +264,9 @@ if (typeof Blob !== 'undefined') { }) duplex.write(msg) assert.strictEqual(duplex.readable, false) -} // Ensure data if a sub object has a writable and readable stream it's duplexified +} +// Ensure data if a sub object has a writable and readable stream it's duplexified { const msg = Buffer.from('hello') const duplex = Duplex.from({ @@ -298,8 +293,9 @@ if (typeof Blob !== 'undefined') { }) ) .on('end', common.mustCall()) -} // Ensure that given readable stream that throws an error it calls destroy +} +// Ensure that given readable stream that throws an error it calls destroy { const myErrorMessage = 'error!' const duplex = Duplex.from( @@ -315,8 +311,9 @@ if (typeof Blob !== 'undefined') { assert.strictEqual(msg.message, myErrorMessage) }) ) -} // Ensure that given writable stream that throws an error it calls destroy +} +// Ensure that given writable stream that throws an error it calls destroy { const myErrorMessage = 'error!' const duplex = Duplex.from( @@ -334,8 +331,8 @@ if (typeof Blob !== 'undefined') { ) duplex.write('test') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-duplex-props.js b/test/parallel/test-stream-duplex-props.js index ed2528204..1a976f668 100644 --- a/test/parallel/test-stream-duplex-props.js +++ b/test/parallel/test-stream-duplex-props.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { Duplex } = require('../../lib/ours/index') - { const d = new Duplex({ objectMode: true, @@ -35,8 +30,8 @@ const { Duplex } = require('../../lib/ours/index') assert.strictEqual(d.readableObjectMode, false) assert.strictEqual(d.readableHighWaterMark, 10) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-duplex-readable-end.js b/test/parallel/test-stream-duplex-readable-end.js index 1fd1e8966..ecb15381f 100644 --- a/test/parallel/test-stream-duplex-readable-end.js +++ b/test/parallel/test-stream-duplex-readable-end.js @@ -1,18 +1,14 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} -} // https://github.com/nodejs/node/issues/35926 +} +// https://github.com/nodejs/node/issues/35926 const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - let loops = 5 const src = new stream.Readable({ read() { @@ -34,8 +30,8 @@ dst.on( assert.ok(src.isPaused()) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-duplex-readable-writable.js b/test/parallel/test-stream-duplex-readable-writable.js index ba752d929..90425acbd 100644 --- a/test/parallel/test-stream-duplex-readable-writable.js +++ b/test/parallel/test-stream-duplex-readable-writable.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Duplex } = require('../../lib/ours/index') - const assert = require('assert') - { const duplex = new Duplex({ readable: false @@ -50,17 +45,15 @@ const assert = require('assert') assert.strictEqual(duplex.readable, false) duplex.on('data', common.mustNotCall()) duplex.on('end', common.mustNotCall()) - async function run() { for await (const chunk of duplex) { assert(false, chunk) } } - run().then(common.mustCall()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-duplex-writable-finished.js b/test/parallel/test-stream-duplex-writable-finished.js index e84abe9cf..b78ba2393 100644 --- a/test/parallel/test-stream-duplex-writable-finished.js +++ b/test/parallel/test-stream-duplex-writable-finished.js @@ -1,32 +1,28 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Duplex } = require('../../lib/ours/index') +const assert = require('assert') -const assert = require('assert') // basic - +// basic { // Find it on Duplex.prototype assert(Reflect.has(Duplex.prototype, 'writableFinished')) -} // event +} +// event { const duplex = new Duplex() - duplex._write = (chunk, encoding, cb) => { // The state finished should start in false. assert.strictEqual(duplex.writableFinished, false) cb() } - duplex.on( 'finish', common.mustCall(() => { @@ -40,8 +36,8 @@ const assert = require('assert') // basic }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-end-of-streams.js b/test/parallel/test-stream-end-of-streams.js index f731a4d0e..e2af91b8e 100644 --- a/test/parallel/test-stream-end-of-streams.js +++ b/test/parallel/test-stream-end-of-streams.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { Duplex, finished } = require('../../lib/ours/index') - assert.throws( () => { // Passing empty object to mock invalid stream @@ -24,12 +19,12 @@ assert.throws( } ) const streamObj = new Duplex() -streamObj.end() // Below code should not throw any errors as the +streamObj.end() +// Below code should not throw any errors as the // streamObj is `Stream` - finished(streamObj, () => {}) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-end-paused.js b/test/parallel/test-stream-end-paused.js index f1478d685..5ca5d84f7 100644 --- a/test/parallel/test-stream-end-paused.js +++ b/test/parallel/test-stream-end-paused.js @@ -18,30 +18,27 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const assert = require('assert') -const assert = require('assert') // Make sure we don't miss the end event for paused 0-length streams +// Make sure we don't miss the end event for paused 0-length streams const Readable = require('../../lib/ours/index').Readable - const stream = new Readable() let calledRead = false - stream._read = function () { assert(!calledRead) calledRead = true this.push(null) } - stream.on('data', function () { throw new Error('should not ever get data') }) @@ -57,8 +54,8 @@ process.on('exit', function () { assert(calledRead) silentConsole.log('ok') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-error-once.js b/test/parallel/test-stream-error-once.js index 435f9b0b9..dadfc2d67 100644 --- a/test/parallel/test-stream-error-once.js +++ b/test/parallel/test-stream-error-once.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable, Readable } = require('../../lib/ours/index') - { const writable = new Writable() writable.on('error', common.mustCall()) @@ -25,8 +21,8 @@ const { Writable, Readable } = require('../../lib/ours/index') readable.push('h') readable.push('h') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-events-prepend.js b/test/parallel/test-stream-events-prepend.js index 861887c7d..4ad0c24c2 100644 --- a/test/parallel/test-stream-events-prepend.js +++ b/test/parallel/test-stream-events-prepend.js @@ -1,39 +1,32 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - class Writable extends stream.Writable { constructor() { super() this.prependListener = undefined } - _write(chunk, end, cb) { cb() } } - class Readable extends stream.Readable { _read() { this.push(null) } } - const w = new Writable() w.on('pipe', common.mustCall()) const r = new Readable() r.pipe(w) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-filter.js b/test/parallel/test-stream-filter.js index 73571bf4e..277cc38a0 100644 --- a/test/parallel/test-stream-filter.js +++ b/test/parallel/test-stream-filter.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,30 +12,21 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const assert = require('assert') - const { once } = require('events') - const st = require('timers').setTimeout - function setTimeout(ms) { return new Promise((resolve) => { st(resolve, ms) }) } - { // Filter works on synchronous streams with a synchronous predicate const stream = Readable.from([1, 2, 3, 4, 5]).filter((x) => x < 3) @@ -90,7 +78,6 @@ function setTimeout(ms) { ) ;(async () => { let i = 1 - for await (const item of stream) { assert.strictEqual(item, 1) if (++i === 5) break @@ -106,11 +93,9 @@ function setTimeout(ms) { this.push(null) return } - this.push(Uint8Array.from([i])) i++ }, - highWaterMark: 0 }).filter( common.mustCall(async ([x]) => { @@ -129,7 +114,6 @@ function setTimeout(ms) { if (x === 3) { throw new Error('boom') } - return true }) assert.rejects(stream.map((x) => x + x).toArray(), /boom/).then(common.mustCall()) @@ -140,7 +124,6 @@ function setTimeout(ms) { if (x === 3) { throw new Error('boom') } - return true }) assert.rejects(stream.filter(() => true).toArray(), /boom/).then(common.mustCall()) @@ -158,8 +141,8 @@ function setTimeout(ms) { signal: ac.signal, concurrency: 2 } - ) // pump - + ) + // pump assert .rejects( async () => { @@ -193,7 +176,6 @@ function setTimeout(ms) { ) ;(async () => { const expected = [1, 2] - for await (const item of stream) { assert.strictEqual(item, expected.shift()) } @@ -220,12 +202,12 @@ function setTimeout(ms) { const stream = Readable.from([1, 2, 3, 4, 5]) Object.defineProperty(stream, 'map', { value: common.mustNotCall(() => {}) - }) // Check that map isn't getting called. - + }) + // Check that map isn't getting called. stream.filter(() => true) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-finished.js b/test/parallel/test-stream-finished.js index ecd60ffed..3ee5d328c 100644 --- a/test/parallel/test-stream-finished.js +++ b/test/parallel/test-stream-finished.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,28 +12,18 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable, Readable, Transform, finished, Duplex, PassThrough, Stream } = require('../../lib/ours/index') - const assert = require('assert') - const EE = require('events') - const fs = require('fs') - const { promisify } = require('util') - const http = require('http') - { const rs = new Readable({ read() {} @@ -85,7 +72,6 @@ const http = require('http') } { const finishedPromise = promisify(finished) - async function run() { const rs = fs.createReadStream(__filename) const done = common.mustCall() @@ -98,7 +84,6 @@ const http = require('http') assert(ended) done() } - run() } { @@ -170,7 +155,6 @@ const http = require('http') { // Promisified abort works const finishedPromise = promisify(finished) - async function run() { const ac = new AbortController() const { signal } = ac @@ -180,7 +164,6 @@ const http = require('http') signal }) } - assert .rejects(run, { name: 'AbortError' @@ -190,7 +173,6 @@ const http = require('http') { // Promisified pre-aborted works const finishedPromise = promisify(finished) - async function run() { const signal = new EventTarget() signal.aborted = true @@ -199,7 +181,6 @@ const http = require('http') signal }) } - assert .rejects(run, { name: 'AbortError' @@ -220,7 +201,6 @@ const http = require('http') finished(rs, common.mustSucceed()) rs.push(null) rs.emit('close') // Should not trigger an error - rs.resume() } { @@ -232,11 +212,11 @@ const http = require('http') }) ) rs.emit('close') // Should trigger error - rs.push(null) rs.resume() -} // Test faulty input values and options. +} +// Test faulty input values and options. { const rs = new Readable({ read() {} @@ -256,8 +236,9 @@ const http = require('http') finished(rs, null, common.mustCall()) rs.push(null) rs.resume() -} // Test that calling returned function removes listeners +} +// Test that calling returned function removes listeners { const ws = new Writable({ write(data, env, cb) { @@ -329,11 +310,11 @@ const http = require('http') w.end('asd') w.destroy() } - function testClosed(factory) { { // If already destroyed but finished is cancelled in same tick // don't invoke the callback, + const s = factory() s.destroy() const dispose = finished(s, common.mustNotCall()) @@ -341,12 +322,14 @@ function testClosed(factory) { } { // If already destroyed invoked callback. + const s = factory() s.destroy() finished(s, common.mustCall()) } { // Don't invoke until destroy has completed. + let destroyed = false const s = factory({ destroy(err, cb) { @@ -366,9 +349,9 @@ function testClosed(factory) { } { // Invoke callback even if close is inhibited. + const s = factory({ emitClose: false, - destroy(err, cb) { cb() finished(s, common.mustCall()) @@ -378,6 +361,7 @@ function testClosed(factory) { } { // Invoke with deep async. + const s = factory({ destroy(err, cb) { setImmediate(() => { @@ -391,13 +375,16 @@ function testClosed(factory) { s.destroy() } } - -testClosed((opts) => new Readable({ ...opts })) +testClosed( + (opts) => + new Readable({ + ...opts + }) +) testClosed( (opts) => new Writable({ write() {}, - ...opts }) ) @@ -406,7 +393,6 @@ testClosed( write(chunk, encoding, cb) { cb() }, - autoDestroy: false }) w.end('asd') @@ -419,7 +405,6 @@ testClosed( write(chunk, encoding, cb) { cb(new Error()) }, - autoDestroy: false }) w.write('asd') @@ -488,7 +473,6 @@ testClosed( { const d = new Duplex({ final(cb) {}, - // Never close writable side for test purpose read() { this.push(null) @@ -509,7 +493,6 @@ testClosed( { const d = new Duplex({ final(cb) {}, - // Never close writable side for test purpose read() { this.push(null) @@ -541,7 +524,6 @@ testClosed( { // Regression https://github.com/nodejs/node/issues/33130 const response = new PassThrough() - class HelloWorld extends Duplex { constructor(response) { super({ @@ -558,23 +540,18 @@ testClosed( } }) } - _read() { const { response } = this this.readMore = true - if (response.readableLength) { this.readMore = false } - let data - while ((data = response.read()) !== null) { this.push(data) } } } - const instance = new HelloWorld(response) instance.setEncoding('utf8') instance.end() @@ -587,11 +564,9 @@ testClosed( response.end() }) let res = '' - for await (const data of instance) { res += data } - assert.strictEqual(res, 'chunk 1chunk 2chunk 3') })().then(common.mustCall()) } @@ -694,9 +669,7 @@ testClosed( } { const w = new Writable() - const _err = new Error() - w.destroy(_err) assert.strictEqual(w.errored, _err) finished( @@ -771,8 +744,8 @@ testClosed( .end() }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-flatMap.js b/test/parallel/test-stream-flatMap.js index af775d1ba..f4e778712 100644 --- a/test/parallel/test-stream-flatMap.js +++ b/test/parallel/test-stream-flatMap.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,36 +12,25 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const fixtures = require('../common/fixtures') - const { Readable } = require('../../lib/ours/index') - const assert = require('assert') - const st = require('timers').setTimeout - function setTimeout(ms) { return new Promise((resolve) => { st(resolve, ms) }) } - const { createReadStream } = require('fs') - function oneTo5() { return Readable.from([1, 2, 3, 4, 5]) } - { // flatMap works on synchronous streams with a synchronous mapper ;(async () => { @@ -90,15 +76,15 @@ function oneTo5() { }) .toArray() assert.deepStrictEqual(result, [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]) - })().then(common.mustCall()) // flatMap works on an objectMode stream where mappign returns a stream - + })().then(common.mustCall()) + // flatMap works on an objectMode stream where mappign returns a stream ;(async () => { const result = await oneTo5() .flatMap(() => { return createReadStream(fixtures.path('x.txt')) }) - .toArray() // The resultant stream is in object mode so toArray shouldn't flatten - + .toArray() + // The resultant stream is in object mode so toArray shouldn't flatten assert.strictEqual(result.length, 5) assert.deepStrictEqual( Buffer.concat(result).toString(), @@ -119,8 +105,8 @@ function oneTo5() { signal: ac.signal, concurrency: 2 } - ) // pump - + ) + // pump assert .rejects( async () => { @@ -149,8 +135,8 @@ function oneTo5() { { signal: AbortSignal.abort() } - ) // pump - + ) + // pump assert .rejects( async () => { @@ -193,12 +179,12 @@ function oneTo5() { const stream = oneTo5() Object.defineProperty(stream, 'map', { value: common.mustNotCall(() => {}) - }) // Check that map isn't getting called. - + }) + // Check that map isn't getting called. stream.flatMap(() => true) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-forEach.js b/test/parallel/test-stream-forEach.js index 726327a51..784078a9f 100644 --- a/test/parallel/test-stream-forEach.js +++ b/test/parallel/test-stream-forEach.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,22 +12,15 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const assert = require('assert') - const { once } = require('events') - { // forEach works on synchronous streams with a synchronous predicate const stream = Readable.from([1, 2, 3]) @@ -147,8 +137,8 @@ const { once } = require('events') signal: ac.signal, concurrency: 2 } - ) // pump - + ) + // pump assert .rejects( async () => { @@ -193,12 +183,12 @@ const { once } = require('events') const stream = Readable.from([1, 2, 3, 4, 5]) Object.defineProperty(stream, 'map', { value: common.mustNotCall(() => {}) - }) // Check that map isn't getting called. - + }) + // Check that map isn't getting called. stream.forEach(() => true) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-inheritance.js b/test/parallel/test-stream-inheritance.js index 730d9a632..150a43a74 100644 --- a/test/parallel/test-stream-inheritance.js +++ b/test/parallel/test-stream-inheritance.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { Readable, Writable, Duplex, Transform } = require('../../lib/ours/index') - const readable = new Readable({ read() {} }) @@ -21,7 +16,6 @@ const writable = new Writable({ }) const duplex = new Duplex({ read() {}, - write() {} }) const transform = new Transform({ @@ -44,13 +38,13 @@ assert.ok(!(writable instanceof Transform)) assert.ok(!(duplex instanceof Transform)) assert.ok(transform instanceof Transform) assert.ok(!(null instanceof Writable)) -assert.ok(!(undefined instanceof Writable)) // Simple inheritance check for `Writable` works fine in a subclass constructor. +assert.ok(!(undefined instanceof Writable)) +// Simple inheritance check for `Writable` works fine in a subclass constructor. function CustomWritable() { assert.ok(this instanceof CustomWritable, `${this} does not inherit from CustomWritable`) assert.ok(this instanceof Writable, `${this} does not inherit from Writable`) } - Object.setPrototypeOf(CustomWritable, Writable) Object.setPrototypeOf(CustomWritable.prototype, Writable.prototype) new CustomWritable() @@ -59,13 +53,11 @@ assert.throws(CustomWritable, { constructor: assert.AssertionError, message: 'undefined does not inherit from CustomWritable' }) - class OtherCustomWritable extends Writable {} - assert(!(new OtherCustomWritable() instanceof CustomWritable)) assert(!(new CustomWritable() instanceof OtherCustomWritable)) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-ispaused.js b/test/parallel/test-stream-ispaused.js index 7ec86d125..32a8711c3 100644 --- a/test/parallel/test-stream-ispaused.js +++ b/test/parallel/test-stream-ispaused.js @@ -18,36 +18,36 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') +const readable = new stream.Readable() -const readable = new stream.Readable() // _read is a noop, here. +// _read is a noop, here. +readable._read = Function() -readable._read = Function() // Default state of a stream is not "paused" - -assert.ok(!readable.isPaused()) // Make the stream start flowing... +// Default state of a stream is not "paused" +assert.ok(!readable.isPaused()) -readable.on('data', Function()) // still not paused. +// Make the stream start flowing... +readable.on('data', Function()) +// still not paused. assert.ok(!readable.isPaused()) readable.pause() assert.ok(readable.isPaused()) readable.resume() assert.ok(!readable.isPaused()) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-iterator-helpers-test262-tests.mjs b/test/parallel/test-stream-iterator-helpers-test262-tests.mjs index 9f09abeab..8231f80ce 100644 --- a/test/parallel/test-stream-iterator-helpers-test262-tests.mjs +++ b/test/parallel/test-stream-iterator-helpers-test262-tests.mjs @@ -1,7 +1,7 @@ -import { mustCall } from '../common/index.mjs'; -import { Readable }from '../../lib/ours/index.js'; -import assert from 'assert'; -import tap from 'tap'; +import { mustCall } from '../common/index.mjs' +import { Readable } from '../../lib/ours/index.js' +import assert from 'assert' +import tap from 'tap' // These tests are manually ported from the draft PR for the test262 test suite // Authored by Rick Waldron in https://github.com/tc39/test262/pull/2818/files @@ -46,134 +46,131 @@ import tap from 'tap'; // * Ecma International Standards hereafter means Ecma International Standards // as well as Ecma Technical Reports - // Note all the tests that check AsyncIterator's prototype itself and things // that happen before stream conversion were not ported. { // asIndexedPairs/is-function - assert.strictEqual(typeof Readable.prototype.asIndexedPairs, 'function'); + assert.strictEqual(typeof Readable.prototype.asIndexedPairs, 'function') // asIndexedPairs/indexed-pairs.js - const iterator = Readable.from([0, 1]); - const indexedPairs = iterator.asIndexedPairs(); + const iterator = Readable.from([0, 1]) + const indexedPairs = iterator.asIndexedPairs() for await (const [i, v] of indexedPairs) { - assert.strictEqual(i, v); + assert.strictEqual(i, v) } // asIndexedPairs/length.js - assert.strictEqual(Readable.prototype.asIndexedPairs.length, 0); + assert.strictEqual(Readable.prototype.asIndexedPairs.length, 0) // asIndexedPairs/name.js - assert.strictEqual(Readable.prototype.asIndexedPairs.name, 'asIndexedPairs'); - const descriptor = Object.getOwnPropertyDescriptor( - Readable.prototype, - 'asIndexedPairs' - ); - assert.strictEqual(descriptor.enumerable, false); - assert.strictEqual(descriptor.configurable, true); - assert.strictEqual(descriptor.writable, true); + assert.strictEqual(Readable.prototype.asIndexedPairs.name, 'asIndexedPairs') + const descriptor = Object.getOwnPropertyDescriptor(Readable.prototype, 'asIndexedPairs') + assert.strictEqual(descriptor.enumerable, false) + assert.strictEqual(descriptor.configurable, true) + assert.strictEqual(descriptor.writable, true) } { // drop/length - assert.strictEqual(Readable.prototype.drop.length, 1); - const descriptor = Object.getOwnPropertyDescriptor( - Readable.prototype, - 'drop' - ); - assert.strictEqual(descriptor.enumerable, false); - assert.strictEqual(descriptor.configurable, true); - assert.strictEqual(descriptor.writable, true); + assert.strictEqual(Readable.prototype.drop.length, 1) + const descriptor = Object.getOwnPropertyDescriptor(Readable.prototype, 'drop') + assert.strictEqual(descriptor.enumerable, false) + assert.strictEqual(descriptor.configurable, true) + assert.strictEqual(descriptor.writable, true) // drop/limit-equals-total - const iterator = Readable.from([1, 2]).drop(2); - const result = await iterator[Symbol.asyncIterator]().next(); - assert.deepStrictEqual(result, { done: true, value: undefined }); + const iterator = Readable.from([1, 2]).drop(2) + const result = await iterator[Symbol.asyncIterator]().next() + assert.deepStrictEqual(result, { done: true, value: undefined }) // drop/limit-greater-than-total.js - const iterator2 = Readable.from([1, 2]).drop(3); - const result2 = await iterator2[Symbol.asyncIterator]().next(); - assert.deepStrictEqual(result2, { done: true, value: undefined }); + const iterator2 = Readable.from([1, 2]).drop(3) + const result2 = await iterator2[Symbol.asyncIterator]().next() + assert.deepStrictEqual(result2, { done: true, value: undefined }) // drop/limit-less-than-total.js - const iterator3 = Readable.from([1, 2]).drop(1); - const result3 = await iterator3[Symbol.asyncIterator]().next(); - assert.deepStrictEqual(result3, { done: false, value: 2 }); + const iterator3 = Readable.from([1, 2]).drop(1) + const result3 = await iterator3[Symbol.asyncIterator]().next() + assert.deepStrictEqual(result3, { done: false, value: 2 }) // drop/limit-rangeerror - assert.throws(() => Readable.from([1]).drop(-1), RangeError); + assert.throws(() => Readable.from([1]).drop(-1), RangeError) assert.throws(() => { Readable.from([1]).drop({ valueOf() { - throw new Error('boom'); + throw new Error('boom') } - }); - }, /boom/); + }) + }, /boom/) // drop/limit-tointeger - const two = await Readable.from([1, 2]).drop({ valueOf: () => 1 }).toArray(); - assert.deepStrictEqual(two, [2]); + const two = await Readable.from([1, 2]) + .drop({ valueOf: () => 1 }) + .toArray() + assert.deepStrictEqual(two, [2]) // drop/name - assert.strictEqual(Readable.prototype.drop.name, 'drop'); + assert.strictEqual(Readable.prototype.drop.name, 'drop') // drop/non-constructible - assert.throws(() => new Readable.prototype.drop(1), TypeError); + assert.throws(() => new Readable.prototype.drop(1), TypeError) // drop/proto - const proto = Object.getPrototypeOf(Readable.prototype.drop); - assert.strictEqual(proto, Function.prototype); + const proto = Object.getPrototypeOf(Readable.prototype.drop) + assert.strictEqual(proto, Function.prototype) } { // every/abrupt-iterator-close - const stream = Readable.from([1, 2, 3]); - const e = new Error(); - await assert.rejects(stream.every(mustCall(() => { - throw e; - }, 1)), e); + const stream = Readable.from([1, 2, 3]) + const e = new Error() + await assert.rejects( + stream.every( + mustCall(() => { + throw e + }, 1) + ), + e + ) } { // every/callable-fn - await assert.rejects(Readable.from([1, 2]).every({}), TypeError); + await assert.rejects(Readable.from([1, 2]).every({}), TypeError) } { // every/callable - Readable.prototype.every.call(Readable.from([]), () => {}); + Readable.prototype.every.call(Readable.from([]), () => {}) // eslint-disable-next-line array-callback-return - Readable.from([]).every(() => {}); + Readable.from([]).every(() => {}) assert.throws(() => { - const r = Readable.from([]); - new r.every(() => {}); - }, TypeError); + const r = Readable.from([]) + new r.every(() => {}) + }, TypeError) } { // every/false - const iterator = Readable.from([1, 2, 3]); - const result = await iterator.every((v) => v === 1); - assert.strictEqual(result, false); + const iterator = Readable.from([1, 2, 3]) + const result = await iterator.every((v) => v === 1) + assert.strictEqual(result, false) } { // every/every - const iterator = Readable.from([1, 2, 3]); - const result = await iterator.every((v) => true); - assert.strictEqual(result, true); + const iterator = Readable.from([1, 2, 3]) + const result = await iterator.every((v) => true) + assert.strictEqual(result, true) } { // every/is-function - assert.strictEqual(typeof Readable.prototype.every, 'function'); + assert.strictEqual(typeof Readable.prototype.every, 'function') } { // every/length - assert.strictEqual(Readable.prototype.every.length, 1); + assert.strictEqual(Readable.prototype.every.length, 1) // every/name - assert.strictEqual(Readable.prototype.every.name, 'every'); + assert.strictEqual(Readable.prototype.every.name, 'every') // every/propdesc - const descriptor = Object.getOwnPropertyDescriptor( - Readable.prototype, - 'every' - ); - assert.strictEqual(descriptor.enumerable, false); - assert.strictEqual(descriptor.configurable, true); - assert.strictEqual(descriptor.writable, true); + const descriptor = Object.getOwnPropertyDescriptor(Readable.prototype, 'every') + assert.strictEqual(descriptor.enumerable, false) + assert.strictEqual(descriptor.configurable, true) + assert.strictEqual(descriptor.writable, true) } - /* replacement start */ - process.on('beforeExit', (code) => { - if(code === 0) { - tap.pass('test succeeded'); - } else { - tap.fail(`test failed - exited code ${code}`); - } - }); - /* replacement end */ +/* replacement start */ +process.on('beforeExit', (code) => { + if (code === 0) { + tap.pass('test succeeded') + } else { + tap.fail(`test failed - exited code ${code}`) + } +}) +/* replacement end */ diff --git a/test/parallel/test-stream-objectmode-undefined.js b/test/parallel/test-stream-objectmode-undefined.js index 9dac7a397..7e3b28b83 100644 --- a/test/parallel/test-stream-objectmode-undefined.js +++ b/test/parallel/test-stream-objectmode-undefined.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable, Writable, Transform } = require('../../lib/ours/index') - { const stream = new Readable({ objectMode: true, @@ -52,8 +47,8 @@ const { Readable, Writable, Transform } = require('../../lib/ours/index') ) stream.write(undefined) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-once-readable-pipe.js b/test/parallel/test-stream-once-readable-pipe.js index 1f80f3455..097bcae05 100644 --- a/test/parallel/test-stream-once-readable-pipe.js +++ b/test/parallel/test-stream-once-readable-pipe.js @@ -1,17 +1,15 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') +const { Readable, Writable } = require('../../lib/ours/index') -const { Readable, Writable } = require('../../lib/ours/index') // This test ensures that if have 'readable' listener +// This test ensures that if have 'readable' listener // on Readable instance it will not disrupt the pipe. { @@ -64,8 +62,8 @@ const { Readable, Writable } = require('../../lib/ours/index') // This test ensu }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-passthrough-drain.js b/test/parallel/test-stream-passthrough-drain.js index cf9b60857..2433cb373 100644 --- a/test/parallel/test-stream-passthrough-drain.js +++ b/test/parallel/test-stream-passthrough-drain.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { PassThrough } = require('../../lib/ours/index') - const pt = new PassThrough({ highWaterMark: 0 }) @@ -20,8 +15,8 @@ pt.on('drain', common.mustCall()) assert(!pt.write('hello1')) pt.read() pt.read() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-after-end.js b/test/parallel/test-stream-pipe-after-end.js index 0825d5a0e..d0df35184 100644 --- a/test/parallel/test-stream-pipe-after-end.js +++ b/test/parallel/test-stream-pipe-after-end.js @@ -18,51 +18,45 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable, Writable } = require('../../lib/ours/index') - class TestReadable extends Readable { constructor(opt) { super(opt) this._ended = false } - _read() { if (this._ended) this.emit('error', new Error('_read called twice')) this._ended = true this.push(null) } } - class TestWritable extends Writable { constructor(opt) { super(opt) this._written = [] } - _write(chunk, encoding, cb) { this._written.push(chunk) - cb() } -} // This one should not emit 'end' until we read() from it later. - -const ender = new TestReadable() // What happens when you pipe() a Readable that's already ended? +} -const piper = new TestReadable() // pushes EOF null, and length=0, so this will trigger 'end' +// This one should not emit 'end' until we read() from it later. +const ender = new TestReadable() +// What happens when you pipe() a Readable that's already ended? +const piper = new TestReadable() +// pushes EOF null, and length=0, so this will trigger 'end' piper.read() setTimeout( common.mustCall(function () { @@ -75,8 +69,8 @@ setTimeout( }), 1 ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-await-drain-manual-resume.js b/test/parallel/test-stream-pipe-await-drain-manual-resume.js index 9546d06a7..18e62b6c9 100644 --- a/test/parallel/test-stream-pipe-await-drain-manual-resume.js +++ b/test/parallel/test-stream-pipe-await-drain-manual-resume.js @@ -1,26 +1,22 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') +const assert = require('assert') -const assert = require('assert') // A consumer stream with a very low highWaterMark, which starts in a state +// A consumer stream with a very low highWaterMark, which starts in a state // where it buffers the chunk it receives rather than indicating that they // have been consumed. - const writable = new stream.Writable({ highWaterMark: 5 }) let isCurrentlyBufferingWrites = true const queue = [] - writable._write = (chunk, encoding, cb) => { if (isCurrentlyBufferingWrites) queue.push({ @@ -29,7 +25,6 @@ writable._write = (chunk, encoding, cb) => { }) else cb() } - const readable = new stream.Readable({ read() {} }) @@ -41,7 +36,8 @@ readable.once( readable._readableState.awaitDrainWriters, writable, 'Expected awaitDrainWriters to be a Writable but instead got ' + `${readable._readableState.awaitDrainWriters}` - ) // First pause, resume manually. The next write() to writable will still + ) + // First pause, resume manually. The next write() to writable will still // return false, because chunks are still being buffered, so it will increase // the awaitDrain counter again. @@ -58,24 +54,20 @@ readable.once( writable, '.resume() should not reset the awaitDrainWriters, but instead got ' + `${readable._readableState.awaitDrainWriters}` - ) // Second pause, handle all chunks from now on. Once all callbacks that + ) + // Second pause, handle all chunks from now on. Once all callbacks that // are currently queued up are handled, the awaitDrain drain counter should // fall back to 0 and all chunks that are pending on the readable side // should be flushed. - isCurrentlyBufferingWrites = false - for (const queued of queue) queued.cb() }) ) }) ) readable.push(Buffer.alloc(100)) // Fill the writable HWM, first 'pause'. - readable.push(Buffer.alloc(100)) // Second 'pause'. - readable.push(Buffer.alloc(100)) // Should get through to the writable. - readable.push(null) writable.on( 'finish', @@ -86,11 +78,12 @@ writable.on( `awaitDrainWriters should be reset to null after all chunks are written but instead got ${readable._readableState.awaitDrainWriters}` - ) // Everything okay, all chunks were written. + ) + // Everything okay, all chunks were written. }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-await-drain-push-while-write.js b/test/parallel/test-stream-pipe-await-drain-push-while-write.js index 85898e2bd..130ae0856 100644 --- a/test/parallel/test-stream-pipe-await-drain-push-while-write.js +++ b/test/parallel/test-stream-pipe-await-drain-push-while-write.js @@ -1,39 +1,31 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - const writable = new stream.Writable({ write: common.mustCall(function (chunk, encoding, cb) { assert.strictEqual(readable._readableState.awaitDrainWriters, null) - if (chunk.length === 32 * 1024) { // first chunk readable.push(Buffer.alloc(34 * 1024)) // above hwm // We should check if awaitDrain counter is increased in the next // tick, because awaitDrain is incremented after this method finished - process.nextTick(() => { assert.strictEqual(readable._readableState.awaitDrainWriters, writable) }) } - process.nextTick(cb) }, 3) -}) // A readable stream which produces two buffers. +}) +// A readable stream which produces two buffers. const bufs = [Buffer.alloc(32 * 1024), Buffer.alloc(33 * 1024)] // above hwm - const readable = new stream.Readable({ read: function () { while (bufs.length > 0) { @@ -42,8 +34,8 @@ const readable = new stream.Readable({ } }) readable.pipe(writable) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-await-drain.js b/test/parallel/test-stream-pipe-await-drain.js index 48945d621..912e37eef 100644 --- a/test/parallel/test-stream-pipe-await-drain.js +++ b/test/parallel/test-stream-pipe-await-drain.js @@ -1,29 +1,26 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') +const assert = require('assert') -const assert = require('assert') // This is very similar to test-stream-pipe-cleanup-pause.js. +// This is very similar to test-stream-pipe-cleanup-pause.js. const reader = new stream.Readable() const writer1 = new stream.Writable() const writer2 = new stream.Writable() -const writer3 = new stream.Writable() // 560000 is chosen here because it is larger than the (default) highWaterMark +const writer3 = new stream.Writable() + +// 560000 is chosen here because it is larger than the (default) highWaterMark // and will cause `.write()` to return false // See: https://github.com/nodejs/node/issues/5820 - const buffer = Buffer.allocUnsafe(560000) - reader._read = () => {} - writer1._write = common.mustCall(function (chunk, encoding, cb) { this.emit('chunk-received') process.nextTick(cb) @@ -39,14 +36,16 @@ writer1.once('chunk-received', () => { // "done" processing. reader.push(buffer) }) -}) // A "slow" consumer: +}) +// A "slow" consumer: writer2._write = common.mustCall((chunk, encoding, cb) => { assert.strictEqual( reader._readableState.awaitDrainWriters.size, 1, 'awaitDrain should be 1 after first push, actual is ' + reader._readableState.awaitDrainWriters.size - ) // Not calling cb here to "simulate" slow stream. + ) + // Not calling cb here to "simulate" slow stream. // This should be called exactly once, since the first .write() call // will return false. }, 1) @@ -55,7 +54,8 @@ writer3._write = common.mustCall((chunk, encoding, cb) => { reader._readableState.awaitDrainWriters.size, 2, 'awaitDrain should be 2 after second push, actual is ' + reader._readableState.awaitDrainWriters.size - ) // Not calling cb here to "simulate" slow stream. + ) + // Not calling cb here to "simulate" slow stream. // This should be called exactly once, since the first .write() call // will return false. }, 1) @@ -63,8 +63,8 @@ reader.pipe(writer1) reader.pipe(writer2) reader.pipe(writer3) reader.push(buffer) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-cleanup-pause.js b/test/parallel/test-stream-pipe-cleanup-pause.js index c92450079..0b7326dd5 100644 --- a/test/parallel/test-stream-pipe-cleanup-pause.js +++ b/test/parallel/test-stream-pipe-cleanup-pause.js @@ -1,26 +1,21 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const reader = new stream.Readable() const writer1 = new stream.Writable() -const writer2 = new stream.Writable() // 560000 is chosen here because it is larger than the (default) highWaterMark +const writer2 = new stream.Writable() + +// 560000 is chosen here because it is larger than the (default) highWaterMark // and will cause `.write()` to return false // See: https://github.com/nodejs/node/issues/2323 - const buffer = Buffer.allocUnsafe(560000) - reader._read = () => {} - writer1._write = common.mustCall(function (chunk, encoding, cb) { this.emit('chunk-received') cb() @@ -41,8 +36,8 @@ writer2._write = common.mustCall(function (chunk, encoding, cb) { }, 3) reader.pipe(writer1) reader.push(buffer) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-cleanup.js b/test/parallel/test-stream-pipe-cleanup.js index 7fa142275..72b3875e7 100644 --- a/test/parallel/test-stream-pipe-cleanup.js +++ b/test/parallel/test-stream-pipe-cleanup.js @@ -18,102 +18,80 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} -} // This test asserts that Stream.prototype.pipe does not leave listeners +} +// This test asserts that Stream.prototype.pipe does not leave listeners // hanging on the source or dest. - require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - function Writable() { this.writable = true this.endCalls = 0 stream.Stream.call(this) } - Object.setPrototypeOf(Writable.prototype, stream.Stream.prototype) Object.setPrototypeOf(Writable, stream.Stream) - Writable.prototype.end = function () { this.endCalls++ } - Writable.prototype.destroy = function () { this.endCalls++ } - function Readable() { this.readable = true stream.Stream.call(this) } - Object.setPrototypeOf(Readable.prototype, stream.Stream.prototype) Object.setPrototypeOf(Readable, stream.Stream) - function Duplex() { this.readable = true Writable.call(this) } - Object.setPrototypeOf(Duplex.prototype, Writable.prototype) Object.setPrototypeOf(Duplex, Writable) let i = 0 const limit = 100 let w = new Writable() let r - for (i = 0; i < limit; i++) { r = new Readable() r.pipe(w) r.emit('end') } - assert.strictEqual(r.listeners('end').length, 0) assert.strictEqual(w.endCalls, limit) w.endCalls = 0 - for (i = 0; i < limit; i++) { r = new Readable() r.pipe(w) r.emit('close') } - assert.strictEqual(r.listeners('close').length, 0) assert.strictEqual(w.endCalls, limit) w.endCalls = 0 r = new Readable() - for (i = 0; i < limit; i++) { w = new Writable() r.pipe(w) w.emit('close') } - assert.strictEqual(w.listeners('close').length, 0) r = new Readable() w = new Writable() const d = new Duplex() r.pipe(d) // pipeline A - d.pipe(w) // pipeline B - assert.strictEqual(r.listeners('end').length, 2) // A.onend, A.cleanup - assert.strictEqual(r.listeners('close').length, 2) // A.onclose, A.cleanup - assert.strictEqual(d.listeners('end').length, 2) // B.onend, B.cleanup // A.cleanup, B.onclose, B.cleanup - assert.strictEqual(d.listeners('close').length, 3) assert.strictEqual(w.listeners('end').length, 0) assert.strictEqual(w.listeners('close').length, 1) // B.cleanup @@ -124,9 +102,7 @@ assert.strictEqual(w.endCalls, 0) assert.strictEqual(r.listeners('end').length, 0) assert.strictEqual(r.listeners('close').length, 0) assert.strictEqual(d.listeners('end').length, 2) // B.onend, B.cleanup - assert.strictEqual(d.listeners('close').length, 2) // B.onclose, B.cleanup - assert.strictEqual(w.listeners('end').length, 0) assert.strictEqual(w.listeners('close').length, 1) // B.cleanup @@ -139,8 +115,8 @@ assert.strictEqual(d.listeners('end').length, 0) assert.strictEqual(d.listeners('close').length, 0) assert.strictEqual(w.listeners('end').length, 0) assert.strictEqual(w.listeners('close').length, 0) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-error-handling.js b/test/parallel/test-stream-pipe-error-handling.js index 3c7b1a2a1..e399a5f74 100644 --- a/test/parallel/test-stream-pipe-error-handling.js +++ b/test/parallel/test-stream-pipe-error-handling.js @@ -18,21 +18,17 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Stream, PassThrough } = require('../../lib/ours/index') - { const source = new Stream() const dest = new Stream() @@ -51,13 +47,11 @@ const { Stream, PassThrough } = require('../../lib/ours/index') source.pipe(dest) const err = new Error('This stream turned into bacon.') let gotErr = null - try { source.emit('error', err) } catch (e) { gotErr = e } - assert.strictEqual(gotErr, err) } { @@ -85,7 +79,6 @@ const { Stream, PassThrough } = require('../../lib/ours/index') r.pipe(w) w.removeListener('error', myOnError) removed = true - function myOnError() { throw new Error('this should not happen') } @@ -106,17 +99,14 @@ const { Stream, PassThrough } = require('../../lib/ours/index') ) }) w.on('error', common.mustCall()) - w._write = () => {} - - r.pipe(w) // Removing some OTHER random listener should not do anything - + r.pipe(w) + // Removing some OTHER random listener should not do anything w.removeListener('error', () => {}) removed = true } { const _err = new Error('this should be handled') - const destination = new PassThrough() destination.once( 'error', @@ -128,8 +118,8 @@ const { Stream, PassThrough } = require('../../lib/ours/index') stream.pipe(destination) destination.destroy(_err) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-error-unhandled.js b/test/parallel/test-stream-pipe-error-unhandled.js index 557ed6b39..76d4b2128 100644 --- a/test/parallel/test-stream-pipe-error-unhandled.js +++ b/test/parallel/test-stream-pipe-error-unhandled.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable, Writable } = require('../../lib/ours/index') - process.on( 'uncaughtException', common.mustCall((err) => { @@ -26,13 +21,12 @@ const r = new Readable({ }) const w = new Writable({ autoDestroy: true, - write() {} }) r.pipe(w) w.destroy(new Error('asd')) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-event.js b/test/parallel/test-stream-pipe-event.js index e997c9df4..19d716d92 100644 --- a/test/parallel/test-stream-pipe-event.js +++ b/test/parallel/test-stream-pipe-event.js @@ -18,34 +18,27 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - function Writable() { this.writable = true stream.Stream.call(this) } - Object.setPrototypeOf(Writable.prototype, stream.Stream.prototype) Object.setPrototypeOf(Writable, stream.Stream) - function Readable() { this.readable = true stream.Stream.call(this) } - Object.setPrototypeOf(Readable.prototype, stream.Stream.prototype) Object.setPrototypeOf(Readable, stream.Stream) let passed = false @@ -56,8 +49,8 @@ w.on('pipe', function (src) { const r = new Readable() r.pipe(w) assert.ok(passed) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-flow-after-unpipe.js b/test/parallel/test-stream-pipe-flow-after-unpipe.js index d598f4821..882e4a823 100644 --- a/test/parallel/test-stream-pipe-flow-after-unpipe.js +++ b/test/parallel/test-stream-pipe-flow-after-unpipe.js @@ -1,15 +1,14 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const { Readable, Writable } = require('../../lib/ours/index') -const { Readable, Writable } = require('../../lib/ours/index') // Tests that calling .unpipe() un-blocks a stream that is paused because +// Tests that calling .unpipe() un-blocks a stream that is paused because // it is waiting on the writable side to finish a write(). const rs = new Readable({ @@ -32,9 +31,10 @@ rs.on( if (chunks >= 20) rs.pause() // Finish this test. }) ) + rs.pipe(ws) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-flow.js b/test/parallel/test-stream-pipe-flow.js index b38571a71..56ccef69f 100644 --- a/test/parallel/test-stream-pipe-flow.js +++ b/test/parallel/test-stream-pipe-flow.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable, Writable, PassThrough } = require('../../lib/ours/index') - { let ticks = 17 const rs = new Readable({ @@ -62,7 +57,6 @@ const { Readable, Writable, PassThrough } = require('../../lib/ours/index') read: () => { process.nextTick(() => { let data = pt.read() - if (data === null) { pt.once('readable', () => { data = pt.read() @@ -101,8 +95,8 @@ const { Readable, Writable, PassThrough } = require('../../lib/ours/index') assert.strictEqual(pt.listenerCount('drain'), 0) }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-manual-resume.js b/test/parallel/test-stream-pipe-manual-resume.js index c95c9d98d..d4f09f7b6 100644 --- a/test/parallel/test-stream-pipe-manual-resume.js +++ b/test/parallel/test-stream-pipe-manual-resume.js @@ -1,19 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - function test(throwCodeInbetween) { // Check that a pipe does not stall if .read() is called unexpectedly // (i.e. the stream is not resumed by the pipe). + const n = 1000 let counter = n const rs = stream.Readable({ @@ -35,12 +32,11 @@ function test(throwCodeInbetween) { setImmediate(() => throwCodeInbetween(rs, ws)) rs.pipe(ws) } - test((rs) => rs.read()) test((rs) => rs.resume()) test(() => 0) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-multiple-pipes.js b/test/parallel/test-stream-pipe-multiple-pipes.js index 2163ea8f3..18a1e5a4b 100644 --- a/test/parallel/test-stream-pipe-multiple-pipes.js +++ b/test/parallel/test-stream-pipe-multiple-pipes.js @@ -1,23 +1,17 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - const readable = new stream.Readable({ read: () => {} }) const writables = [] - for (let i = 0; i < 5; i++) { const target = new stream.Writable({ write: common.mustCall((chunk, encoding, callback) => { @@ -30,11 +24,11 @@ for (let i = 0; i < 5; i++) { readable.pipe(target) writables.push(target) } - const input = Buffer.from([1, 2, 3, 4, 5]) -readable.push(input) // The pipe() calls will postpone emission of the 'resume' event using nextTick, -// so no data will be available to the writable streams until then. +readable.push(input) +// The pipe() calls will postpone emission of the 'resume' event using nextTick, +// so no data will be available to the writable streams until then. process.nextTick( common.mustCall(() => { for (const target of writables) { @@ -42,13 +36,12 @@ process.nextTick( target.on('unpipe', common.mustCall()) readable.unpipe(target) } - readable.push('something else') // This does not get through. - readable.push(null) readable.resume() // Make sure the 'end' event gets emitted. }) ) + readable.on( 'end', common.mustCall(() => { @@ -57,8 +50,8 @@ readable.on( } }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-needDrain.js b/test/parallel/test-stream-pipe-needDrain.js index 09f51bba7..e4c9ee213 100644 --- a/test/parallel/test-stream-pipe-needDrain.js +++ b/test/parallel/test-stream-pipe-needDrain.js @@ -1,29 +1,23 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') +const { Readable, Writable } = require('../../lib/ours/index') -const { Readable, Writable } = require('../../lib/ours/index') // Pipe should pause temporarily if writable needs drain. - +// Pipe should pause temporarily if writable needs drain. { const w = new Writable({ write(buf, encoding, callback) { process.nextTick(callback) }, - highWaterMark: 1 }) - while (w.write('asd')); - assert.strictEqual(w.writableNeedDrain, true) const r = new Readable({ read() { @@ -35,8 +29,8 @@ const { Readable, Writable } = require('../../lib/ours/index') // Pipe should pa r.on('end', common.mustCall()) r.pipe(w) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-same-destination-twice.js b/test/parallel/test-stream-pipe-same-destination-twice.js index 9d69e2701..63c1797d6 100644 --- a/test/parallel/test-stream-pipe-same-destination-twice.js +++ b/test/parallel/test-stream-pipe-same-destination-twice.js @@ -1,20 +1,17 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } -const common = require('../common') // Regression test for https://github.com/nodejs/node/issues/12718. +const common = require('../common') + +// Regression test for https://github.com/nodejs/node/issues/12718. // Tests that piping a source stream twice to the same destination stream // works, and that a subsequent unpipe() call only removes the pipe *once*. - const assert = require('assert') - const { PassThrough, Writable } = require('../../lib/ours/index') - { const passThrough = new PassThrough() const dest = new Writable({ @@ -69,8 +66,8 @@ const { PassThrough, Writable } = require('../../lib/ours/index') assert.strictEqual(passThrough._readableState.pipes.length, 0) passThrough.write('foobar') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-unpipe-streams.js b/test/parallel/test-stream-pipe-unpipe-streams.js index 759bacf50..86b66f67f 100644 --- a/test/parallel/test-stream-pipe-unpipe-streams.js +++ b/test/parallel/test-stream-pipe-unpipe-streams.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable, Writable } = require('../../lib/ours/index') - const source = Readable({ read: () => {} }) @@ -28,7 +23,9 @@ dest1.on('unpipe', common.mustCall()) dest2.on('unpipe', common.mustCall()) assert.strictEqual(source._readableState.pipes[0], dest1) assert.strictEqual(source._readableState.pipes[1], dest2) -assert.strictEqual(source._readableState.pipes.length, 2) // Should be able to unpipe them in the reverse order that they were piped. +assert.strictEqual(source._readableState.pipes.length, 2) + +// Should be able to unpipe them in the reverse order that they were piped. source.unpipe(dest2) assert.deepStrictEqual(source._readableState.pipes, [dest1]) @@ -58,7 +55,6 @@ assert.strictEqual(source._readableState.pipes.length, 0) assert.strictEqual(source.listenerCount(eventName), 0, `source's '${eventName}' event listeners not removed`) }) }) - function checkDestCleanup(dest) { const currentDestId = ++destCount source.pipe(dest) @@ -80,7 +76,6 @@ assert.strictEqual(source._readableState.pipes.length, 0) }) dest.on('unpipe', unpipeChecker) } - checkDestCleanup(dest1) checkDestCleanup(dest2) source.unpipe() @@ -101,8 +96,8 @@ assert.strictEqual(source._readableState.pipes.length, 0) }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipe-without-listenerCount.js b/test/parallel/test-stream-pipe-without-listenerCount.js index 2db82dcb2..3c2c6f4da 100644 --- a/test/parallel/test-stream-pipe-without-listenerCount.js +++ b/test/parallel/test-stream-pipe-without-listenerCount.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const r = new stream.Stream() r.listenerCount = undefined const w = new stream.Stream() @@ -22,8 +18,8 @@ w.on('pipe', function () { r.on('error', common.mustCall()) w.on('error', common.mustCall()) r.pipe(w) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipeline-async-iterator.js b/test/parallel/test-stream-pipeline-async-iterator.js index e45e01e65..dea0bdbf3 100644 --- a/test/parallel/test-stream-pipeline-async-iterator.js +++ b/test/parallel/test-stream-pipeline-async-iterator.js @@ -1,20 +1,14 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable, PassThrough, pipeline } = require('../../lib/ours/index') - const assert = require('assert') - const _err = new Error('kaboom') - async function run() { const source = new Readable({ read() {} @@ -26,15 +20,13 @@ async function run() { }) const iterator = pipeline(source, new PassThrough(), () => {}) iterator.setEncoding('utf8') - for await (const k of iterator) { assert.strictEqual(k, 'helloworld') } } - run().catch(common.mustCall((err) => assert.strictEqual(err, _err))) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipeline-duplex.js b/test/parallel/test-stream-pipeline-duplex.js index 9e2961bba..833848ed0 100644 --- a/test/parallel/test-stream-pipeline-duplex.js +++ b/test/parallel/test-stream-pipeline-duplex.js @@ -1,22 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { pipeline, Duplex, PassThrough } = require('../../lib/ours/index') - const assert = require('assert') - const remote = new PassThrough() const local = new Duplex({ read() {}, - write(chunk, enc, callback) { callback() } @@ -32,8 +26,8 @@ pipeline( setImmediate(() => { remote.end() }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipeline-http2.js b/test/parallel/test-stream-pipeline-http2.js index e494dde27..5cd16d184 100644 --- a/test/parallel/test-stream-pipeline-http2.js +++ b/test/parallel/test-stream-pipeline-http2.js @@ -1,20 +1,14 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - if (!common.hasCrypto) common.skip('missing crypto') - const { Readable, pipeline } = require('../../lib/ours/index') - const http2 = require('http2') - { const server = http2.createServer((req, res) => { pipeline(req, res, common.mustCall()) @@ -45,8 +39,8 @@ const http2 = require('http2') }) }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipeline-listeners.js b/test/parallel/test-stream-pipeline-listeners.js index 214d8f09b..0b40366d3 100644 --- a/test/parallel/test-stream-pipeline-listeners.js +++ b/test/parallel/test-stream-pipeline-listeners.js @@ -1,26 +1,22 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { pipeline, Duplex, PassThrough, Writable } = require('../../lib/ours/index') - const assert = require('assert') - process.on( 'uncaughtException', common.mustCall((err) => { assert.strictEqual(err.message, 'no way') }, 2) -) // Ensure that listeners is removed if last stream is readable -// And other stream's listeners unchanged +) +// Ensure that listeners is removed if last stream is readable +// And other stream's listeners unchanged const a = new PassThrough() a.end('foobar') const b = new Duplex({ @@ -35,7 +31,6 @@ pipeline( if (error) { assert.ifError(error) } - assert(a.listenerCount('error') > 0) assert.strictEqual(b.listenerCount('error'), 0) setTimeout(() => { @@ -43,8 +38,9 @@ pipeline( b.destroy(new Error('no way')) }, 100) }) -) // Async generators +) +// Async generators const c = new PassThrough() c.end('foobar') const d = pipeline( @@ -58,7 +54,6 @@ const d = pipeline( if (error) { assert.ifError(error) } - assert(c.listenerCount('error') > 0) assert.strictEqual(d.listenerCount('error'), 0) setTimeout(() => { @@ -66,8 +61,9 @@ const d = pipeline( d.destroy(new Error('no way')) }, 100) }) -) // If last stream is not readable, will not throw and remove listeners +) +// If last stream is not readable, will not throw and remove listeners const e = new PassThrough() e.end('foobar') const f = new Writable({ @@ -82,7 +78,6 @@ pipeline( if (error) { assert.ifError(error) } - assert(e.listenerCount('error') > 0) assert(f.listenerCount('error') > 0) setTimeout(() => { @@ -91,8 +86,8 @@ pipeline( }, 100) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipeline-process.js b/test/parallel/test-stream-pipeline-process.js index f00759c9d..d047b179e 100644 --- a/test/parallel/test-stream-pipeline-process.js +++ b/test/parallel/test-stream-pipeline-process.js @@ -1,25 +1,18 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const os = require('os') - if (process.argv[2] === 'child') { const { pipeline } = require('../../lib/ours/index') - pipeline(process.stdin, process.stdout, common.mustSucceed()) } else { const cp = require('child_process') - cp.exec( ['echo', 'hello', '|', `"${process.execPath}"`, `"${__filename}"`, 'child'].join(' '), common.mustSucceed((stdout) => { @@ -27,8 +20,8 @@ if (process.argv[2] === 'child') { }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipeline-queued-end-in-destroy.js b/test/parallel/test-stream-pipeline-queued-end-in-destroy.js index dcb7d99b8..8305a75b6 100644 --- a/test/parallel/test-stream-pipeline-queued-end-in-destroy.js +++ b/test/parallel/test-stream-pipeline-queued-end-in-destroy.js @@ -1,17 +1,15 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') +const { Readable, Duplex, pipeline } = require('../../lib/ours/index') -const { Readable, Duplex, pipeline } = require('../../lib/ours/index') // Test that the callback for pipeline() is called even when the ._destroy() +// Test that the callback for pipeline() is called even when the ._destroy() // method of the stream places an .end() request to itself that does not // get processed before the destruction of the stream (i.e. the 'close' event). // Refs: https://github.com/nodejs/node/issues/24456 @@ -23,9 +21,7 @@ const duplex = new Duplex({ write(chunk, enc, cb) { // Simulate messages queueing up. }, - read() {}, - destroy(err, cb) { // Call end() from inside the destroy() method, like HTTP/2 streams // do at the time of writing. @@ -40,15 +36,16 @@ pipeline( common.mustCall((err) => { assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE') }) -) // Write one chunk of data, and destroy the stream later. -// That should trigger the pipeline destruction. +) +// Write one chunk of data, and destroy the stream later. +// That should trigger the pipeline destruction. readable.push('foo') setImmediate(() => { readable.destroy() }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipeline-uncaught.js b/test/parallel/test-stream-pipeline-uncaught.js index 306b7d7bf..5b45eb1fc 100644 --- a/test/parallel/test-stream-pipeline-uncaught.js +++ b/test/parallel/test-stream-pipeline-uncaught.js @@ -1,26 +1,22 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { pipeline, PassThrough } = require('../../lib/ours/index') - const assert = require('assert') - process.on( 'uncaughtException', common.mustCall((err) => { assert.strictEqual(err.message, 'error') }) -) // Ensure that pipeline that ends with Promise -// still propagates error to uncaughtException. +) +// Ensure that pipeline that ends with Promise +// still propagates error to uncaughtException. const s = new PassThrough() s.end('data') pipeline( @@ -33,8 +29,8 @@ pipeline( throw new Error('error') }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-pipeline-with-empty-string.js b/test/parallel/test-stream-pipeline-with-empty-string.js index 4663e9d7c..74cd6dfbd 100644 --- a/test/parallel/test-stream-pipeline-with-empty-string.js +++ b/test/parallel/test-stream-pipeline-with-empty-string.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { pipeline, PassThrough } = require('../../lib/ours/index') - async function runTest() { await pipeline( '', @@ -20,10 +16,9 @@ async function runTest() { common.mustCall(() => {}) ) } - runTest().then(common.mustCall(() => {})) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-preprocess.js b/test/parallel/test-stream-preprocess.js index 0cf027e56..736043131 100644 --- a/test/parallel/test-stream-preprocess.js +++ b/test/parallel/test-stream-preprocess.js @@ -1,31 +1,28 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const fs = require('fs') - const rl = require('readline') - const fixtures = require('../common/fixtures') +const BOM = '\uFEFF' -const BOM = '\uFEFF' // Get the data using a non-stream way to compare with the streamed data. - +// Get the data using a non-stream way to compare with the streamed data. const modelData = fixtures.readSync('file-to-read-without-bom.txt', 'utf8') -const modelDataFirstCharacter = modelData[0] // Detect the number of forthcoming 'line' events for mustCall() 'expected' arg. +const modelDataFirstCharacter = modelData[0] -const lineCount = modelData.match(/\n/g).length // Ensure both without-bom and with-bom test files are textwise equal. +// Detect the number of forthcoming 'line' events for mustCall() 'expected' arg. +const lineCount = modelData.match(/\n/g).length -assert.strictEqual(fixtures.readSync('file-to-read-with-bom.txt', 'utf8'), `${BOM}${modelData}`) // An unjustified BOM stripping with a non-BOM character unshifted to a stream. +// Ensure both without-bom and with-bom test files are textwise equal. +assert.strictEqual(fixtures.readSync('file-to-read-with-bom.txt', 'utf8'), `${BOM}${modelData}`) +// An unjustified BOM stripping with a non-BOM character unshifted to a stream. const inputWithoutBOM = fs.createReadStream(fixtures.path('file-to-read-without-bom.txt'), 'utf8') inputWithoutBOM.once( 'readable', @@ -51,8 +48,9 @@ inputWithoutBOM.once( }) ) }) -) // A justified BOM stripping. +) +// A justified BOM stripping. const inputWithBOM = fs.createReadStream(fixtures.path('file-to-read-with-bom.txt'), 'utf8') inputWithBOM.once( 'readable', @@ -77,8 +75,8 @@ inputWithBOM.once( ) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-promises.js b/test/parallel/test-stream-promises.js index eb050f6a4..240f931a3 100644 --- a/test/parallel/test-stream-promises.js +++ b/test/parallel/test-stream-promises.js @@ -1,31 +1,23 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const { Readable, Writable, promises } = stream - const { finished, pipeline } = require('../../lib/stream/promises') - const fs = require('fs') - const assert = require('assert') - const { promisify } = require('util') - assert.strictEqual(promises.pipeline, pipeline) assert.strictEqual(promises.finished, finished) assert.strictEqual(pipeline, promisify(stream.pipeline)) -assert.strictEqual(finished, promisify(stream.finished)) // pipeline success +assert.strictEqual(finished, promisify(stream.finished)) +// pipeline success { let finished = false const processed = [] @@ -42,11 +34,9 @@ assert.strictEqual(finished, promisify(stream.finished)) // pipeline success write.on('finish', () => { finished = true }) - for (let i = 0; i < expected.length; i++) { read.push(expected[i]) } - read.push(null) pipeline(read, write).then( common.mustCall((value) => { @@ -54,8 +44,9 @@ assert.strictEqual(finished, promisify(stream.finished)) // pipeline success assert.deepStrictEqual(processed, expected) }) ) -} // pipeline error +} +// pipeline error { const read = new Readable({ read() {} @@ -72,8 +63,9 @@ assert.strictEqual(finished, promisify(stream.finished)) // pipeline success assert.ok(err, 'should have an error') }) ) -} // finished success +} +// finished success { async function run() { const rs = fs.createReadStream(__filename) @@ -85,10 +77,10 @@ assert.strictEqual(finished, promisify(stream.finished)) // pipeline success await finished(rs) assert(ended) } - run().then(common.mustCall()) -} // finished error +} +// finished error { const rs = fs.createReadStream('file-does-not-exist') assert @@ -97,8 +89,8 @@ assert.strictEqual(finished, promisify(stream.finished)) // pipeline success }) .then(common.mustCall()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-push-order.js b/test/parallel/test-stream-push-order.js index d50071898..5ed3c5c67 100644 --- a/test/parallel/test-stream-push-order.js +++ b/test/parallel/test-stream-push-order.js @@ -18,30 +18,24 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const Readable = require('../../lib/ours/index').Readable - const assert = require('assert') - const s = new Readable({ highWaterMark: 20, encoding: 'ascii' }) const list = ['1', '2', '3', '4', '5', '6'] - s._read = function (n) { const one = list.shift() - if (!one) { s.push(null) } else { @@ -50,15 +44,16 @@ s._read = function (n) { s.push(two) } } +s.read(0) -s.read(0) // ACTUALLY [1, 3, 5, 6, 4, 2] +// ACTUALLY [1, 3, 5, 6, 4, 2] process.on('exit', function () { assert.strictEqual(s.readableBuffer.join(','), '1,2,3,4,5,6') silentConsole.log('ok') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-push-strings.js b/test/parallel/test-stream-push-strings.js index bb80a8c0f..d2ceafeb0 100644 --- a/test/parallel/test-stream-push-strings.js +++ b/test/parallel/test-stream-push-strings.js @@ -18,56 +18,45 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const Readable = require('../../lib/ours/index').Readable - class MyStream extends Readable { constructor(options) { super(options) this._chunks = 3 } - _read(n) { switch (this._chunks--) { case 0: return this.push(null) - case 1: return setTimeout(() => { this.push('last chunk') }, 100) - case 2: return this.push('second to last chunk') - case 3: return process.nextTick(() => { this.push('first chunk') }) - default: throw new Error('?') } } } - const ms = new MyStream() const results = [] ms.on('readable', function () { let chunk - while (null !== (chunk = ms.read())) results.push(String(chunk)) }) const expect = ['first chunksecond to last chunk', 'last chunk'] @@ -76,8 +65,8 @@ process.on('exit', function () { assert.deepStrictEqual(results, expect) silentConsole.log('ok') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-aborted.js b/test/parallel/test-stream-readable-aborted.js index 4d271d594..84b126df8 100644 --- a/test/parallel/test-stream-readable-aborted.js +++ b/test/parallel/test-stream-readable-aborted.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable, Duplex } = require('../../lib/ours/index') - { const readable = new Readable({ read() {} @@ -63,14 +58,13 @@ const { Readable, Duplex } = require('../../lib/ours/index') { const duplex = new Duplex({ readable: false, - write() {} }) duplex.destroy() assert.strictEqual(duplex.readableAborted, false) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-add-chunk-during-data.js b/test/parallel/test-stream-readable-add-chunk-during-data.js index 672828775..d5c571f04 100644 --- a/test/parallel/test-stream-readable-add-chunk-during-data.js +++ b/test/parallel/test-stream-readable-add-chunk-during-data.js @@ -1,17 +1,15 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') +const { Readable } = require('../../lib/ours/index') -const { Readable } = require('../../lib/ours/index') // Verify that .push() and .unshift() can be called from 'data' listeners. +// Verify that .push() and .unshift() can be called from 'data' listeners. for (const method of ['push', 'unshift']) { const r = new Readable({ @@ -33,8 +31,8 @@ for (const method of ['push', 'unshift']) { ) r.push('Hello, world') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-constructor-set-methods.js b/test/parallel/test-stream-readable-constructor-set-methods.js index cd5bb31fd..3a80f9618 100644 --- a/test/parallel/test-stream-readable-constructor-set-methods.js +++ b/test/parallel/test-stream-readable-constructor-set-methods.js @@ -1,26 +1,21 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const Readable = require('../../lib/ours/index').Readable - const _read = common.mustCall(function _read(n) { this.push(null) }) - const r = new Readable({ read: _read }) r.resume() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-data.js b/test/parallel/test-stream-readable-data.js index 80db4f024..430475d3e 100644 --- a/test/parallel/test-stream-readable-data.js +++ b/test/parallel/test-stream-readable-data.js @@ -1,22 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const readable = new Readable({ read() {} }) - function read() {} - readable.setEncoding('utf8') readable.on('readable', read) readable.removeListener('readable', read) @@ -24,8 +18,8 @@ process.nextTick(function () { readable.on('data', common.mustCall()) readable.push('hello') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-destroy.js b/test/parallel/test-stream-readable-destroy.js index 1823b1e65..4d71f3c44 100644 --- a/test/parallel/test-stream-readable-destroy.js +++ b/test/parallel/test-stream-readable-destroy.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,20 +12,14 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable, addAbortSignal } = require('../../lib/ours/index') - const assert = require('assert') - { const read = new Readable({ read() {} @@ -80,15 +71,15 @@ const assert = require('assert') { const read = new Readable({ read() {}, - destroy: common.mustCall(function (err, cb) { assert.strictEqual(err, expected) cb() }) }) const expected = new Error('kaboom') - read.on('end', common.mustNotCall('no end event')) // Error is swallowed by the custom _destroy + read.on('end', common.mustNotCall('no end event')) + // Error is swallowed by the custom _destroy read.on('error', common.mustNotCall('no error event')) read.on('close', common.mustCall()) read.destroy(expected) @@ -157,8 +148,9 @@ const assert = require('assert') }) read.resume() read.destroyed = true - assert.strictEqual(read.destroyed, true) // The internal destroy() mechanism should not be triggered + assert.strictEqual(read.destroyed, true) + // The internal destroy() mechanism should not be triggered read.on('end', common.mustNotCall()) read.destroy() } @@ -168,7 +160,6 @@ const assert = require('assert') this.destroyed = false Readable.call(this) } - Object.setPrototypeOf(MyReadable.prototype, Readable.prototype) Object.setPrototypeOf(MyReadable, Readable) new MyReadable() @@ -212,7 +203,6 @@ const assert = require('assert') destroy: common.mustCall(function (err, cb) { process.nextTick(cb, new Error('kaboom 1')) }), - read() {} }) let ticked = false @@ -234,9 +224,10 @@ const assert = require('assert') readable.destroy() assert.strictEqual(readable.destroyed, true) assert.strictEqual(readable._readableState.errored, null) - assert.strictEqual(readable._readableState.errorEmitted, false) // Test case where `readable.destroy()` is called again with an error before - // the `_destroy()` callback is called. + assert.strictEqual(readable._readableState.errorEmitted, false) + // Test case where `readable.destroy()` is called again with an error before + // the `_destroy()` callback is called. readable.destroy(new Error('kaboom 2')) assert.strictEqual(readable._readableState.errorEmitted, false) assert.strictEqual(readable._readableState.errored, null) @@ -261,7 +252,6 @@ const assert = require('assert') { const read = new Readable({ autoDestroy: false, - read() { this.push(null) this.push('asd') @@ -298,7 +288,6 @@ const assert = require('assert') const controller = new AbortController() const read = new Readable({ signal: controller.signal, - read() { this.push('asd') } @@ -318,7 +307,6 @@ const assert = require('assert') controller.signal, new Readable({ objectMode: true, - read() { return false } @@ -420,8 +408,8 @@ const assert = require('assert') read.destroy() read.push('asd') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-didRead.js b/test/parallel/test-stream-readable-didRead.js index 96266e1f2..38cbd4804 100644 --- a/test/parallel/test-stream-readable-didRead.js +++ b/test/parallel/test-stream-readable-didRead.js @@ -1,25 +1,18 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { isDisturbed, isErrored, Readable } = require('../../lib/ours/index') - function noop() {} - function check(readable, data, fn) { assert.strictEqual(readable.readableDidRead, false) assert.strictEqual(isDisturbed(readable), false) assert.strictEqual(isErrored(readable), false) - if (data === -1) { readable.on( 'error', @@ -31,31 +24,26 @@ function check(readable, data, fn) { readable.on('end', common.mustNotCall()) } else { readable.on('error', common.mustNotCall()) - if (data === -2) { readable.on('end', common.mustNotCall()) } else { readable.on('end', common.mustCall()) } - if (data > 0) { readable.on('data', common.mustCallAtLeast(data)) } else { readable.on('data', common.mustNotCall()) } } - readable.on('close', common.mustCall()) fn() setImmediate(() => { assert.strictEqual(readable.readableDidRead, data > 0) - if (data > 0) { assert.strictEqual(isDisturbed(readable), true) } }) } - { const readable = new Readable({ read() { @@ -119,8 +107,8 @@ function check(readable, data, fn) { readable.off('data', noop) }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-emit-readable-short-stream.js b/test/parallel/test-stream-readable-emit-readable-short-stream.js index 72834baa0..224023fd7 100644 --- a/test/parallel/test-stream-readable-emit-readable-short-stream.js +++ b/test/parallel/test-stream-readable-emit-readable-short-stream.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - { const r = new stream.Readable({ read: common.mustCall(function () { @@ -145,8 +140,8 @@ const assert = require('assert') t.write('content') t.end() } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-emittedReadable.js b/test/parallel/test-stream-readable-emittedReadable.js index 34970f6e8..61bcd7524 100644 --- a/test/parallel/test-stream-readable-emittedReadable.js +++ b/test/parallel/test-stream-readable-emittedReadable.js @@ -1,22 +1,18 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const Readable = require('../../lib/ours/index').Readable - const readable = new Readable({ read: () => {} -}) // Initialized to false. +}) +// Initialized to false. assert.strictEqual(readable._readableState.emittedReadable, false) const expected = [Buffer.from('foobar'), Buffer.from('quo'), null] readable.on( @@ -24,15 +20,17 @@ readable.on( common.mustCall(() => { // emittedReadable should be true when the readable event is emitted assert.strictEqual(readable._readableState.emittedReadable, true) - assert.deepStrictEqual(readable.read(), expected.shift()) // emittedReadable is reset to false during read() - + assert.deepStrictEqual(readable.read(), expected.shift()) + // emittedReadable is reset to false during read() assert.strictEqual(readable._readableState.emittedReadable, false) }, 3) -) // When the first readable listener is just attached, -// emittedReadable should be false +) -assert.strictEqual(readable._readableState.emittedReadable, false) // These trigger a single 'readable', as things are batched up +// When the first readable listener is just attached, +// emittedReadable should be false +assert.strictEqual(readable._readableState.emittedReadable, false) +// These trigger a single 'readable', as things are batched up process.nextTick( common.mustCall(() => { readable.push('foo') @@ -42,8 +40,9 @@ process.nextTick( common.mustCall(() => { readable.push('bar') }) -) // These triggers two readable events +) +// These triggers two readable events setImmediate( common.mustCall(() => { readable.push('quo') @@ -62,8 +61,8 @@ noRead.on( common.mustCall(() => { // emittedReadable should be true when the readable event is emitted assert.strictEqual(noRead._readableState.emittedReadable, true) - noRead.read(0) // emittedReadable is not reset during read(0) - + noRead.read(0) + // emittedReadable is not reset during read(0) assert.strictEqual(noRead._readableState.emittedReadable, true) }) ) @@ -89,8 +88,8 @@ process.nextTick( flowing.push(null) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-end-destroyed.js b/test/parallel/test-stream-readable-end-destroyed.js index 9946d8db0..a4936e04e 100644 --- a/test/parallel/test-stream-readable-end-destroyed.js +++ b/test/parallel/test-stream-readable-end-destroyed.js @@ -1,18 +1,15 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - { // Don't emit 'end' after 'close'. + const r = new Readable() r.on('end', common.mustNotCall()) r.resume() @@ -24,8 +21,8 @@ const { Readable } = require('../../lib/ours/index') }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-ended.js b/test/parallel/test-stream-readable-ended.js index d9b1c3669..a18cef4bd 100644 --- a/test/parallel/test-stream-readable-ended.js +++ b/test/parallel/test-stream-readable-ended.js @@ -1,26 +1,23 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') +const assert = require('assert') -const assert = require('assert') // basic - +// basic { // Find it on Readable.prototype assert(Reflect.has(Readable.prototype, 'readableEnded')) -} // event +} +// event { const readable = new Readable() - readable._read = () => { // The state ended should start in false. assert.strictEqual(readable.readableEnded, false) @@ -29,7 +26,6 @@ const assert = require('assert') // basic readable.push(null) assert.strictEqual(readable.readableEnded, false) } - readable.on( 'end', common.mustCall(() => { @@ -42,8 +38,9 @@ const assert = require('assert') // basic assert.strictEqual(readable.readableEnded, false) }) ) -} // Verifies no `error` triggered on multiple .push(null) invocations +} +// Verifies no `error` triggered on multiple .push(null) invocations { const readable = new Readable() readable.on('readable', () => { @@ -55,8 +52,8 @@ const assert = require('assert') // basic readable.push(null) readable.push(null) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-error-end.js b/test/parallel/test-stream-readable-error-end.js index a914d8874..a164e9b91 100644 --- a/test/parallel/test-stream-readable-error-end.js +++ b/test/parallel/test-stream-readable-error-end.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - { const r = new Readable({ read() {} @@ -22,8 +18,8 @@ const { Readable } = require('../../lib/ours/index') r.push(null) r.destroy(new Error('kaboom')) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-event.js b/test/parallel/test-stream-readable-event.js index 5e4b402d9..75fbbe840 100644 --- a/test/parallel/test-stream-readable-event.js +++ b/test/parallel/test-stream-readable-event.js @@ -18,29 +18,26 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const Readable = require('../../lib/ours/index').Readable - { // First test, not reading when the readable is added. // make sure that on('readable', ...) triggers a readable event. const r = new Readable({ highWaterMark: 3 }) - r._read = common.mustNotCall() // This triggers a 'readable' event, which is lost. + r._read = common.mustNotCall() + // This triggers a 'readable' event, which is lost. r.push(Buffer.from('blerg')) setTimeout(function () { // We're testing what we think we are @@ -51,11 +48,13 @@ const Readable = require('../../lib/ours/index').Readable { // Second test, make sure that readable is re-emitted if there's // already a length, while it IS reading. + const r = new Readable({ highWaterMark: 3 }) - r._read = common.mustCall() // This triggers a 'readable' event, which is lost. + r._read = common.mustCall() + // This triggers a 'readable' event, which is lost. r.push(Buffer.from('bl')) setTimeout(function () { // Assert we're testing what we think we are @@ -69,8 +68,9 @@ const Readable = require('../../lib/ours/index').Readable const r = new Readable({ highWaterMark: 30 }) - r._read = common.mustNotCall() // This triggers a 'readable' event, which is lost. + r._read = common.mustNotCall() + // This triggers a 'readable' event, which is lost. r.push(Buffer.from('blerg')) r.push(null) setTimeout(function () { @@ -88,7 +88,6 @@ const Readable = require('../../lib/ours/index').Readable const r = new Readable({ encoding: 'utf8' }) - r._read = function () { process.nextTick(() => { if (!underlyingData.length) { @@ -98,7 +97,6 @@ const Readable = require('../../lib/ours/index').Readable } }) } - r.on('readable', () => { const data = r.read() if (data !== null) result.push(data) @@ -113,17 +111,15 @@ const Readable = require('../../lib/ours/index').Readable { // #20923 const r = new Readable() - r._read = function () { // Actually doing thing here } - r.on('data', function () {}) r.removeAllListeners() assert.strictEqual(r.eventNames().length, 0) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-flow-recursion.js b/test/parallel/test-stream-readable-flow-recursion.js index e4658af00..678385266 100644 --- a/test/parallel/test-stream-readable-flow-recursion.js +++ b/test/parallel/test-stream-readable-flow-recursion.js @@ -18,31 +18,31 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') +const assert = require('assert') -const assert = require('assert') // This test verifies that passing a huge number to read(size) +// This test verifies that passing a huge number to read(size) // will push up the highWaterMark, and cause the stream to read // more data continuously, but without triggering a nextTick // warning or RangeError. -const Readable = require('../../lib/ours/index').Readable // Throw an error if we trigger a nextTick warning. +const Readable = require('../../lib/ours/index').Readable +// Throw an error if we trigger a nextTick warning. process.throwDeprecation = true const stream = new Readable({ highWaterMark: 2 }) let reads = 0 let total = 5000 - stream._read = function (size) { reads++ size = Math.min(size, total) @@ -50,9 +50,7 @@ stream._read = function (size) { if (size === 0) stream.push(null) else stream.push(Buffer.allocUnsafe(size)) } - let depth = 0 - function flow(stream, size, callback) { depth += 1 const chunk = stream.read(size) @@ -61,22 +59,21 @@ function flow(stream, size, callback) { depth -= 1 silentConsole.log(`flow(${depth}): exit`) } - flow(stream, 5000, function () { silentConsole.log(`complete (${depth})`) }) process.on('exit', function (code) { - assert.strictEqual(reads, 2) // We pushed up the high water mark - - assert.strictEqual(stream.readableHighWaterMark, 8192) // Length is 0 right now, because we pulled it all out. - + assert.strictEqual(reads, 2) + // We pushed up the high water mark + assert.strictEqual(stream.readableHighWaterMark, 8192) + // Length is 0 right now, because we pulled it all out. assert.strictEqual(stream.readableLength, 0) assert(!code) assert.strictEqual(depth, 0) silentConsole.log('ok') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-hwm-0-async.js b/test/parallel/test-stream-readable-hwm-0-async.js index b683b3b40..859a11329 100644 --- a/test/parallel/test-stream-readable-hwm-0-async.js +++ b/test/parallel/test-stream-readable-hwm-0-async.js @@ -1,18 +1,17 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } -const common = require('../common') // This test ensures that Readable stream will continue to call _read +const common = require('../common') + +// This test ensures that Readable stream will continue to call _read // for streams with highWaterMark === 0 once the stream returns data // by calling push() asynchronously. const { Readable } = require('../../lib/ours/index') - let count = 5 const r = new Readable({ // Called 6 times: First 5 return data, last one signals end of stream. @@ -28,8 +27,8 @@ const r = new Readable({ }) r.on('end', common.mustCall()) r.on('data', common.mustCall(5)) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-hwm-0-no-flow-data.js b/test/parallel/test-stream-readable-hwm-0-no-flow-data.js index c26401b35..9c0cf2f05 100644 --- a/test/parallel/test-stream-readable-hwm-0-no-flow-data.js +++ b/test/parallel/test-stream-readable-hwm-0-no-flow-data.js @@ -1,24 +1,23 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } -const common = require('../common') // Ensure that subscribing the 'data' event will not make the stream flow. +const common = require('../common') + +// Ensure that subscribing the 'data' event will not make the stream flow. // The 'data' event will require calling read() by hand. // // The test is written for the (somewhat rare) highWaterMark: 0 streams to // specifically catch any regressions that might occur with these streams. const assert = require('assert') - const { Readable } = require('../../lib/ours/index') +const streamData = ['a', null] -const streamData = ['a', null] // Track the calls so we can assert their order later. - +// Track the calls so we can assert their order later. const calls = [] const r = new Readable({ read: common.mustCall(() => { @@ -53,20 +52,24 @@ r.on( calls.push('end') }) ) -assert.strictEqual(r.readableFlowing, false) // The stream emits the events asynchronously but that's not guaranteed to +assert.strictEqual(r.readableFlowing, false) + +// The stream emits the events asynchronously but that's not guaranteed to // happen on the next tick (especially since the _read implementation above // uses process.nextTick). // // We use setImmediate here to give the stream enough time to emit all the // events it's about to emit. - setImmediate(() => { // Only the _read, push, readable calls have happened. No data must be // emitted yet. - assert.deepStrictEqual(calls, ['_read:a', 'push:a', 'readable']) // Calling 'r.read()' should trigger the data event. + assert.deepStrictEqual(calls, ['_read:a', 'push:a', 'readable']) + // Calling 'r.read()' should trigger the data event. assert.strictEqual(r.read(), 'a') - assert.deepStrictEqual(calls, ['_read:a', 'push:a', 'readable', 'data:a']) // The next 'read()' will return null because hwm: 0 does not buffer any + assert.deepStrictEqual(calls, ['_read:a', 'push:a', 'readable', 'data:a']) + + // The next 'read()' will return null because hwm: 0 does not buffer any // data and the _read implementation above does the push() asynchronously. // // Note: This 'null' signals "no data available". It isn't the end-of-stream @@ -75,7 +78,6 @@ setImmediate(() => { // // Using setImmediate again to give the stream enough time to emit all the // events it wants to emit. - assert.strictEqual(r.read(), null) setImmediate(() => { // There's a new 'readable' event after the data has been pushed. @@ -85,11 +87,12 @@ setImmediate(() => { // calls 'push' asynchronously. If 'push' was synchronous, the 'end' event // would be emitted here _before_ we call read(). assert.deepStrictEqual(calls, ['_read:a', 'push:a', 'readable', 'data:a', '_read:null', 'push:null', 'readable']) - assert.strictEqual(r.read(), null) // While it isn't really specified whether the 'end' event should happen + assert.strictEqual(r.read(), null) + + // While it isn't really specified whether the 'end' event should happen // synchronously with read() or not, we'll assert the current behavior // ('end' event happening on the next tick after read()) so any changes // to it are noted and acknowledged in the future. - assert.deepStrictEqual(calls, ['_read:a', 'push:a', 'readable', 'data:a', '_read:null', 'push:null', 'readable']) process.nextTick(() => { assert.deepStrictEqual(calls, [ @@ -105,8 +108,8 @@ setImmediate(() => { }) }) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-hwm-0.js b/test/parallel/test-stream-readable-hwm-0.js index 196cfec35..192788e5a 100644 --- a/test/parallel/test-stream-readable-hwm-0.js +++ b/test/parallel/test-stream-readable-hwm-0.js @@ -1,28 +1,26 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } -const common = require('../common') // This test ensures that Readable stream will call _read() for streams +const common = require('../common') + +// This test ensures that Readable stream will call _read() for streams // with highWaterMark === 0 upon .read(0) instead of just trying to // emit 'readable' event. const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - const r = new Readable({ // Must be called only once upon setting 'readable' listener read: common.mustCall(), highWaterMark: 0 }) -let pushedNull = false // This will trigger read(0) but must only be called after push(null) +let pushedNull = false +// This will trigger read(0) but must only be called after push(null) // because the we haven't pushed any data - r.on( 'readable', common.mustCall(() => { @@ -36,8 +34,8 @@ process.nextTick(() => { pushedNull = true r.push(null) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-infinite-read.js b/test/parallel/test-stream-readable-infinite-read.js index 569e8ee31..233168ca7 100644 --- a/test/parallel/test-stream-readable-infinite-read.js +++ b/test/parallel/test-stream-readable-infinite-read.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - const buf = Buffer.alloc(8192) const readable = new Readable({ read: common.mustCall(function () { @@ -28,10 +23,9 @@ readable.on( process.removeAllListeners('readable') return } - - const data = readable.read() // TODO(mcollina): there is something odd in the highWaterMark logic + const data = readable.read() + // TODO(mcollina): there is something odd in the highWaterMark logic // investigate. - if (i === 1) { assert.strictEqual(data.length, 8192 * 2) } else { @@ -39,8 +33,8 @@ readable.on( } }, 11) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-invalid-chunk.js b/test/parallel/test-stream-readable-invalid-chunk.js index a62210543..d93153b22 100644 --- a/test/parallel/test-stream-readable-invalid-chunk.js +++ b/test/parallel/test-stream-readable-invalid-chunk.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - function testPushArg(val) { const readable = new stream.Readable({ read: () => {} @@ -24,11 +20,9 @@ function testPushArg(val) { ) readable.push(val) } - testPushArg([]) testPushArg({}) testPushArg(0) - function testUnshiftArg(val) { const readable = new stream.Readable({ read: () => {} @@ -42,12 +36,11 @@ function testUnshiftArg(val) { ) readable.unshift(val) } - testUnshiftArg([]) testUnshiftArg({}) testUnshiftArg(0) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-needReadable.js b/test/parallel/test-stream-readable-needReadable.js index 0a1fd7ce9..14981a600 100644 --- a/test/parallel/test-stream-readable-needReadable.js +++ b/test/parallel/test-stream-readable-needReadable.js @@ -1,22 +1,18 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const Readable = require('../../lib/ours/index').Readable - const readable = new Readable({ read: () => {} -}) // Initialized to false. +}) +// Initialized to false. assert.strictEqual(readable._readableState.needReadable, false) readable.on( 'readable', @@ -25,8 +21,9 @@ readable.on( assert.strictEqual(readable._readableState.needReadable, false) readable.read() }) -) // If a readable listener is attached, then a readable event is needed. +) +// If a readable listener is attached, then a readable event is needed. assert.strictEqual(readable._readableState.needReadable, true) readable.push('foo') readable.push(null) @@ -69,8 +66,9 @@ setImmediate( ) const flowing = new Readable({ read: () => {} -}) // Notice this must be above the on('data') call. +}) +// Notice this must be above the on('data') call. flowing.push('foooo') flowing.push('bar') flowing.push('quo') @@ -78,9 +76,10 @@ process.nextTick( common.mustCall(() => { flowing.push(null) }) -) // When the buffer already has enough data, and the stream is -// in flowing mode, there is no need for the readable event. +) +// When the buffer already has enough data, and the stream is +// in flowing mode, there is no need for the readable event. flowing.on( 'data', common.mustCall(function (data) { @@ -95,7 +94,6 @@ slowProducer.on( common.mustCall(() => { const chunk = slowProducer.read(8) const state = slowProducer._readableState - if (chunk === null) { // The buffer doesn't have enough data, and the stream is not need, // we need to notify the reader when data arrives. @@ -125,8 +123,8 @@ process.nextTick( ) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-next-no-null.js b/test/parallel/test-stream-readable-next-no-null.js index 585f34069..5e2fc01b1 100644 --- a/test/parallel/test-stream-readable-next-no-null.js +++ b/test/parallel/test-stream-readable-next-no-null.js @@ -1,20 +1,15 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const { mustNotCall, expectsError } = require('../common') - const { Readable } = require('../../lib/ours/index') - async function* generate() { yield null } - const stream = Readable.from(generate()) stream.on( 'error', @@ -29,8 +24,8 @@ stream.on( mustNotCall((chunk) => {}) ) stream.on('end', mustNotCall()) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-no-unneeded-readable.js b/test/parallel/test-stream-readable-no-unneeded-readable.js index 89235fa26..a2cd06941 100644 --- a/test/parallel/test-stream-readable-no-unneeded-readable.js +++ b/test/parallel/test-stream-readable-no-unneeded-readable.js @@ -1,42 +1,36 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable, PassThrough } = require('../../lib/ours/index') - function test(r) { const wrapper = new Readable({ read: () => { let data = r.read() - if (data) { wrapper.push(data) return } - r.once('readable', function () { data = r.read() - if (data) { wrapper.push(data) - } // else: the end event should fire + } + // else: the end event should fire }) } }) + r.once('end', function () { wrapper.push(null) }) wrapper.resume() wrapper.once('end', common.mustCall()) } - { const source = new Readable({ read: () => {} @@ -53,7 +47,6 @@ function test(r) { const r = new Readable({ read: () => { const chunk = pushChunks.shift() - if (chunk) { // synchronous call r.push(chunk) @@ -65,8 +58,8 @@ function test(r) { }) test(r) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-object-multi-push-async.js b/test/parallel/test-stream-readable-object-multi-push-async.js index ff8eb0a83..eefacf1d2 100644 --- a/test/parallel/test-stream-readable-object-multi-push-async.js +++ b/test/parallel/test-stream-readable-object-multi-push-async.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - const MAX = 42 const BATCH = 10 { @@ -25,39 +20,32 @@ const BATCH = 10 this.destroy(err) return } - if (data.length === 0) { silentConsole.log('pushing null') this.push(null) return } - silentConsole.log('pushing') data.forEach((d) => this.push(d)) }) }, Math.floor(MAX / BATCH) + 2) }) let i = 0 - function fetchData(cb) { if (i > MAX) { setTimeout(cb, 10, null, []) } else { const array = [] const max = i + BATCH - for (; i < max; i++) { array.push(i) } - setTimeout(cb, 10, null, array) } } - readable.on('readable', () => { let data silentConsole.log('readable emitted') - while ((data = readable.read()) !== null) { silentConsole.log(data) } @@ -79,35 +67,29 @@ const BATCH = 10 this.destroy(err) return } - if (data.length === 0) { silentConsole.log('pushing null') this.push(null) return } - silentConsole.log('pushing') data.forEach((d) => this.push(d)) }) }, Math.floor(MAX / BATCH) + 2) }) let i = 0 - function fetchData(cb) { if (i > MAX) { setTimeout(cb, 10, null, []) } else { const array = [] const max = i + BATCH - for (; i < max; i++) { array.push(i) } - setTimeout(cb, 10, null, array) } } - readable.on('data', (data) => { silentConsole.log('data emitted', data) }) @@ -128,10 +110,8 @@ const BATCH = 10 this.destroy(err) return } - silentConsole.log('pushing') data.forEach((d) => this.push(d)) - if (data[BATCH - 1] >= MAX) { silentConsole.log('pushing null') this.push(null) @@ -140,18 +120,14 @@ const BATCH = 10 }, Math.floor(MAX / BATCH) + 1) }) let i = 0 - function fetchData(cb) { const array = [] const max = i + BATCH - for (; i < max; i++) { array.push(i) } - setTimeout(cb, 10, null, array) } - readable.on('data', (data) => { silentConsole.log('data emitted', data) }) @@ -194,8 +170,8 @@ const BATCH = 10 readable.push(null) }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-pause-and-resume.js b/test/parallel/test-stream-readable-pause-and-resume.js index b745e7a4d..464f0c3ab 100644 --- a/test/parallel/test-stream-readable-pause-and-resume.js +++ b/test/parallel/test-stream-readable-pause-and-resume.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - let ticks = 18 let expectedData = 19 const rs = new Readable({ @@ -25,7 +20,6 @@ const rs = new Readable({ }) rs.on('end', common.mustCall()) readAndPause() - function readAndPause() { // Does a on(data) -> pause -> wait -> resume -> on(data) ... loop. // Expects on(data) to never fire if the stream is paused. @@ -42,14 +36,11 @@ function readAndPause() { rs.on('data', ondata) } - { const readable = new Readable({ read() {} }) - function read() {} - readable.setEncoding('utf8') readable.on('readable', read) readable.removeListener('readable', read) @@ -60,13 +51,10 @@ function readAndPause() { } { const { PassThrough } = require('../../lib/ours/index') - const source3 = new PassThrough() const target3 = new PassThrough() const chunk = Buffer.allocUnsafe(1000) - while (target3.write(chunk)); - source3.pipe(target3) target3.on( 'drain', @@ -76,8 +64,8 @@ function readAndPause() { ) target3.on('data', () => {}) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-readable-then-resume.js b/test/parallel/test-stream-readable-readable-then-resume.js index c5d57d6c4..8926f4057 100644 --- a/test/parallel/test-stream-readable-readable-then-resume.js +++ b/test/parallel/test-stream-readable-readable-then-resume.js @@ -1,36 +1,31 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') +const assert = require('assert') -const assert = require('assert') // This test verifies that a stream could be resumed after +// This test verifies that a stream could be resumed after // removing the readable event in the same tick check( new Readable({ objectMode: true, highWaterMark: 1, - read() { if (!this.first) { this.push('hello') this.first = true return } - this.push(null) } }) ) - function check(s) { const readableListener = common.mustNotCall() s.on('readable', readableListener) @@ -39,8 +34,8 @@ function check(s) { s.removeListener('readable', readableListener) s.resume() } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-readable.js b/test/parallel/test-stream-readable-readable.js index 340a588ce..65dc93d72 100644 --- a/test/parallel/test-stream-readable-readable.js +++ b/test/parallel/test-stream-readable-readable.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - { const r = new Readable({ read() {} @@ -56,8 +51,8 @@ const { Readable } = require('../../lib/ours/index') }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-reading-readingMore.js b/test/parallel/test-stream-readable-reading-readingMore.js index e97d9e727..804ac8167 100644 --- a/test/parallel/test-stream-readable-reading-readingMore.js +++ b/test/parallel/test-stream-readable-reading-readingMore.js @@ -1,24 +1,20 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const Readable = require('../../lib/ours/index').Readable - { const readable = new Readable({ read(size) {} }) - const state = readable._readableState // Starting off with false initially. + const state = readable._readableState + // Starting off with false initially. assert.strictEqual(state.reading, false) assert.strictEqual(state.readingMore, false) readable.on( @@ -26,31 +22,31 @@ const Readable = require('../../lib/ours/index').Readable common.mustCall((data) => { // While in a flowing state with a 'readable' listener // we should not be reading more - if (readable.readableFlowing) assert.strictEqual(state.readingMore, true) // Reading as long as we've not ended + if (readable.readableFlowing) assert.strictEqual(state.readingMore, true) + // Reading as long as we've not ended assert.strictEqual(state.reading, !state.ended) }, 2) ) - function onStreamEnd() { // End of stream; state.reading is false // And so should be readingMore. assert.strictEqual(state.readingMore, false) assert.strictEqual(state.reading, false) } - const expectedReadingMore = [true, true, false] readable.on( 'readable', common.mustCall(() => { // There is only one readingMore scheduled from on('data'), // after which everything is governed by the .read() call - assert.strictEqual(state.readingMore, expectedReadingMore.shift()) // If the stream has ended, we shouldn't be reading + assert.strictEqual(state.readingMore, expectedReadingMore.shift()) - assert.strictEqual(state.ended, !state.reading) // Consume all the data + // If the stream has ended, we shouldn't be reading + assert.strictEqual(state.ended, !state.reading) + // Consume all the data while (readable.read() !== null); - if (expectedReadingMore.length === 0) // Reached end of stream process.nextTick(common.mustCall(onStreamEnd, 1)) @@ -58,21 +54,25 @@ const Readable = require('../../lib/ours/index').Readable ) readable.on('end', common.mustCall(onStreamEnd)) readable.push('pushed') - readable.read(6) // reading + readable.read(6) + // reading assert.strictEqual(state.reading, true) - assert.strictEqual(state.readingMore, true) // add chunk to front + assert.strictEqual(state.readingMore, true) - readable.unshift('unshifted') // end + // add chunk to front + readable.unshift('unshifted') + // end readable.push(null) } { const readable = new Readable({ read(size) {} }) - const state = readable._readableState // Starting off with false initially. + const state = readable._readableState + // Starting off with false initially. assert.strictEqual(state.reading, false) assert.strictEqual(state.readingMore, false) readable.on( @@ -80,41 +80,45 @@ const Readable = require('../../lib/ours/index').Readable common.mustCall((data) => { // While in a flowing state without a 'readable' listener // we should be reading more - if (readable.readableFlowing) assert.strictEqual(state.readingMore, true) // Reading as long as we've not ended + if (readable.readableFlowing) assert.strictEqual(state.readingMore, true) + // Reading as long as we've not ended assert.strictEqual(state.reading, !state.ended) }, 2) ) - function onStreamEnd() { // End of stream; state.reading is false // And so should be readingMore. assert.strictEqual(state.readingMore, false) assert.strictEqual(state.reading, false) } - readable.on('end', common.mustCall(onStreamEnd)) - readable.push('pushed') // Stop emitting 'data' events + readable.push('pushed') + // Stop emitting 'data' events assert.strictEqual(state.flowing, true) - readable.pause() // paused + readable.pause() + // paused assert.strictEqual(state.reading, false) assert.strictEqual(state.flowing, false) readable.resume() assert.strictEqual(state.reading, false) - assert.strictEqual(state.flowing, true) // add chunk to front + assert.strictEqual(state.flowing, true) - readable.unshift('unshifted') // end + // add chunk to front + readable.unshift('unshifted') + // end readable.push(null) } { const readable = new Readable({ read(size) {} }) - const state = readable._readableState // Starting off with false initially. + const state = readable._readableState + // Starting off with false initially. assert.strictEqual(state.reading, false) assert.strictEqual(state.readingMore, false) const onReadable = common.mustNotCall() @@ -127,36 +131,40 @@ const Readable = require('../../lib/ours/index').Readable }, 2) ) readable.removeListener('readable', onReadable) - function onStreamEnd() { // End of stream; state.reading is false // And so should be readingMore. assert.strictEqual(state.readingMore, false) assert.strictEqual(state.reading, false) } - readable.on('end', common.mustCall(onStreamEnd)) - readable.push('pushed') // We are still not flowing, we will be resuming in the next tick + readable.push('pushed') - assert.strictEqual(state.flowing, false) // Wait for nextTick, so the readableListener flag resets + // We are still not flowing, we will be resuming in the next tick + assert.strictEqual(state.flowing, false) + // Wait for nextTick, so the readableListener flag resets process.nextTick(function () { - readable.resume() // Stop emitting 'data' events + readable.resume() + // Stop emitting 'data' events assert.strictEqual(state.flowing, true) - readable.pause() // paused + readable.pause() + // paused assert.strictEqual(state.flowing, false) readable.resume() - assert.strictEqual(state.flowing, true) // add chunk to front + assert.strictEqual(state.flowing, true) - readable.unshift('unshifted') // end + // add chunk to front + readable.unshift('unshifted') + // end readable.push(null) }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-resume-hwm.js b/test/parallel/test-stream-readable-resume-hwm.js index 22bf32ea6..9dd9df57e 100644 --- a/test/parallel/test-stream-readable-resume-hwm.js +++ b/test/parallel/test-stream-readable-resume-hwm.js @@ -1,33 +1,34 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const { Readable } = require('../../lib/ours/index') -const { Readable } = require('../../lib/ours/index') // readable.resume() should not lead to a ._read() call being scheduled +// readable.resume() should not lead to a ._read() call being scheduled // when we exceed the high water mark already. const readable = new Readable({ read: common.mustNotCall(), highWaterMark: 100 -}) // Fill up the internal buffer so that we definitely exceed the HWM: +}) + +// Fill up the internal buffer so that we definitely exceed the HWM: +for (let i = 0; i < 10; i++) readable.push('a'.repeat(200)) -for (let i = 0; i < 10; i++) readable.push('a'.repeat(200)) // Call resume, and pause after one chunk. +// Call resume, and pause after one chunk. // The .pause() is just so that we don’t empty the buffer fully, which would // be a valid reason to call ._read(). - readable.resume() readable.once( 'data', common.mustCall(() => readable.pause()) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-resumeScheduled.js b/test/parallel/test-stream-readable-resumeScheduled.js index a696ba6d5..1f50e3960 100644 --- a/test/parallel/test-stream-readable-resumeScheduled.js +++ b/test/parallel/test-stream-readable-resumeScheduled.js @@ -1,27 +1,27 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } -const common = require('../common') // Testing Readable Stream resumeScheduled state +const common = require('../common') -const assert = require('assert') +// Testing Readable Stream resumeScheduled state +const assert = require('assert') const { Readable, Writable } = require('../../lib/ours/index') - { // pipe() test case const r = new Readable({ read() {} }) - const w = new Writable() // resumeScheduled should start = `false`. + const w = new Writable() - assert.strictEqual(r._readableState.resumeScheduled, false) // Calling pipe() should change the state value = true. + // resumeScheduled should start = `false`. + assert.strictEqual(r._readableState.resumeScheduled, false) + // Calling pipe() should change the state value = true. r.pipe(w) assert.strictEqual(r._readableState.resumeScheduled, true) process.nextTick( @@ -34,11 +34,13 @@ const { Readable, Writable } = require('../../lib/ours/index') // 'data' listener test case const r = new Readable({ read() {} - }) // resumeScheduled should start = `false`. + }) + // resumeScheduled should start = `false`. assert.strictEqual(r._readableState.resumeScheduled, false) - r.push(Buffer.from([1, 2, 3])) // Adding 'data' listener should change the state value + r.push(Buffer.from([1, 2, 3])) + // Adding 'data' listener should change the state value r.on( 'data', common.mustCall(() => { @@ -56,10 +58,12 @@ const { Readable, Writable } = require('../../lib/ours/index') // resume() test case const r = new Readable({ read() {} - }) // resumeScheduled should start = `false`. + }) - assert.strictEqual(r._readableState.resumeScheduled, false) // Calling resume() should change the state value. + // resumeScheduled should start = `false`. + assert.strictEqual(r._readableState.resumeScheduled, false) + // Calling resume() should change the state value. r.resume() assert.strictEqual(r._readableState.resumeScheduled, true) r.on( @@ -75,8 +79,8 @@ const { Readable, Writable } = require('../../lib/ours/index') }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-setEncoding-existing-buffers.js b/test/parallel/test-stream-readable-setEncoding-existing-buffers.js index 11a0ed83e..fc391bf64 100644 --- a/test/parallel/test-stream-readable-setEncoding-existing-buffers.js +++ b/test/parallel/test-stream-readable-setEncoding-existing-buffers.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const { Readable } = require('../../lib/ours/index') - const assert = require('assert') - { // Call .setEncoding() while there are bytes already in the buffer. const r = new Readable({ @@ -61,8 +56,8 @@ const assert = require('assert') assert.deepStrictEqual(chunks, ['🎉']) }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-setEncoding-null.js b/test/parallel/test-stream-readable-setEncoding-null.js index 0ee0e8ecf..606370500 100644 --- a/test/parallel/test-stream-readable-setEncoding-null.js +++ b/test/parallel/test-stream-readable-setEncoding-null.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - { const readable = new Readable({ encoding: 'hex' @@ -21,8 +16,8 @@ const { Readable } = require('../../lib/ours/index') readable.setEncoding(null) assert.strictEqual(readable._readableState.encoding, 'utf8') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-unpipe-resume.js b/test/parallel/test-stream-readable-unpipe-resume.js index deb18e508..acbf6720c 100644 --- a/test/parallel/test-stream-readable-unpipe-resume.js +++ b/test/parallel/test-stream-readable-unpipe-resume.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const fs = require('fs') - const readStream = fs.createReadStream(process.execPath) const transformStream = new stream.Transform({ transform: common.mustCall(() => { @@ -22,8 +17,8 @@ const transformStream = new stream.Transform({ }) readStream.on('end', common.mustCall()) readStream.pipe(transformStream).resume() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-unshift.js b/test/parallel/test-stream-readable-unshift.js index 380706e0b..2a554747f 100644 --- a/test/parallel/test-stream-readable-unshift.js +++ b/test/parallel/test-stream-readable-unshift.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - { // Check that strings are saved as Buffer const readable = new Readable({ @@ -62,7 +57,6 @@ const { Readable } = require('../../lib/ours/index') } { const streamEncoding = 'base64' - function checkEncoding(readable) { // chunk encodings const encodings = ['utf8', 'binary', 'hex', 'base64'] @@ -74,11 +68,11 @@ const { Readable } = require('../../lib/ours/index') assert.strictEqual(chunk.toString(encoding), string) }, encodings.length) ) - for (const encoding of encodings) { - const string = 'abc' // If encoding is the same as the state.encoding the string is - // saved as is + const string = 'abc' + // If encoding is the same as the state.encoding the string is + // saved as is const expect = encoding !== streamEncoding ? Buffer.from(string, encoding).toString(streamEncoding) : string expected.push({ encoding, @@ -87,7 +81,6 @@ const { Readable } = require('../../lib/ours/index') readable.unshift(string, encoding) } } - const r1 = new Readable({ read() {} }) @@ -95,7 +88,6 @@ const { Readable } = require('../../lib/ours/index') checkEncoding(r1) const r2 = new Readable({ read() {}, - encoding: streamEncoding }) checkEncoding(r2) @@ -104,7 +96,6 @@ const { Readable } = require('../../lib/ours/index') // Both .push & .unshift should have the same behaviour // When setting an encoding, each chunk should be emitted with that encoding const encoding = 'base64' - function checkEncoding(readable) { const string = 'abc' readable.on( @@ -116,7 +107,6 @@ const { Readable } = require('../../lib/ours/index') readable.push(string) readable.unshift(string) } - const r1 = new Readable({ read() {} }) @@ -124,7 +114,6 @@ const { Readable } = require('../../lib/ours/index') checkEncoding(r1) const r2 = new Readable({ read() {}, - encoding }) checkEncoding(r2) @@ -133,7 +122,6 @@ const { Readable } = require('../../lib/ours/index') // Check that ObjectMode works const readable = new Readable({ objectMode: true, - read() {} }) const chunks = ['a', 1, {}, []] @@ -143,7 +131,6 @@ const { Readable } = require('../../lib/ours/index') assert.strictEqual(chunk, chunks.pop()) }, chunks.length) ) - for (const chunk of chunks) { readable.unshift(chunk) } @@ -151,31 +138,26 @@ const { Readable } = require('../../lib/ours/index') { // Should not throw: https://github.com/nodejs/node/issues/27192 const highWaterMark = 50 - class ArrayReader extends Readable { constructor(opt) { super({ highWaterMark - }) // The error happened only when pushing above hwm - + }) + // The error happened only when pushing above hwm this.buffer = new Array(highWaterMark * 2).fill(0).map(String) } - _read(size) { while (this.buffer.length) { const chunk = this.buffer.shift() - if (!this.buffer.length) { this.push(chunk) this.push(null) return true } - if (!this.push(chunk)) return } } } - function onRead() { while (null !== stream.read()) { // Remove the 'readable' listener before unshifting @@ -187,7 +169,6 @@ const { Readable } = require('../../lib/ours/index') break } } - const stream = new ArrayReader() stream.once('readable', common.mustCall(onRead)) stream.on( @@ -195,8 +176,8 @@ const { Readable } = require('../../lib/ours/index') common.mustCall(() => {}) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readable-with-unimplemented-_read.js b/test/parallel/test-stream-readable-with-unimplemented-_read.js index 588bfb222..1fccc976a 100644 --- a/test/parallel/test-stream-readable-with-unimplemented-_read.js +++ b/test/parallel/test-stream-readable-with-unimplemented-_read.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const readable = new Readable() readable.read() readable.on( @@ -22,8 +18,8 @@ readable.on( }) ) readable.on('close', common.mustCall()) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-readableListening-state.js b/test/parallel/test-stream-readableListening-state.js index 5c37e4b14..29e6acc17 100644 --- a/test/parallel/test-stream-readableListening-state.js +++ b/test/parallel/test-stream-readableListening-state.js @@ -1,22 +1,18 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const r = new stream.Readable({ read: () => {} -}) // readableListening state should start in `false`. +}) +// readableListening state should start in `false`. assert.strictEqual(r._readableState.readableListening, false) r.on( 'readable', @@ -28,8 +24,9 @@ r.on( r.push(Buffer.from('Testing readableListening state')) const r2 = new stream.Readable({ read: () => {} -}) // readableListening state should start in `false`. +}) +// readableListening state should start in `false`. assert.strictEqual(r2._readableState.readableListening, false) r2.on( 'data', @@ -40,8 +37,8 @@ r2.on( }) ) r2.push(Buffer.from('Testing readableListening state')) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-reduce.js b/test/parallel/test-stream-reduce.js index 4c4f60004..b0a7ccd77 100644 --- a/test/parallel/test-stream-reduce.js +++ b/test/parallel/test-stream-reduce.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,24 +12,17 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const assert = require('assert') - function sum(p, c) { return p + c } - { // Does the same thing as `(await stream.toArray()).reduce(...)` ;(async () => { @@ -45,14 +35,13 @@ function sum(p, c) { [[1, 2], sum], [[1, 2, 3], (x, y) => y] ] - for (const [values, fn, initial] of tests) { const streamReduce = await Readable.from(values).reduce(fn, initial) const arrayReduce = values.reduce(fn, initial) assert.deepStrictEqual(streamReduce, arrayReduce) - } // Does the same thing as `(await stream.toArray()).reduce(...)` with an + } + // Does the same thing as `(await stream.toArray()).reduce(...)` with an // asynchronous reducer - for (const [values, fn, initial] of tests) { const streamReduce = await Readable.from(values) .map(async (x) => x) @@ -87,7 +76,6 @@ function sum(p, c) { if (p === 1) { throw new Error('boom') } - return c }, 0), /boom/ @@ -162,7 +150,6 @@ function sum(p, c) { signal.addEventListener('abort', common.mustCall(), { once: true }) - if (c === 3) { await new Promise(() => {}) // Explicitly do not pass signal here } @@ -203,8 +190,8 @@ function sum(p, c) { const result = Readable.from([1, 2, 3, 4, 5]).reduce(sum, 0) assert.ok(result instanceof Promise) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-some-find-every.mjs b/test/parallel/test-stream-some-find-every.mjs index 34c8e2a8a..30298d0d0 100644 --- a/test/parallel/test-stream-some-find-every.mjs +++ b/test/parallel/test-stream-some-find-every.mjs @@ -1,183 +1,215 @@ -import * as common from '../common/index.mjs'; -import { setTimeout } from 'timers/promises'; -import { Readable }from '../../lib/ours/index.js'; -import assert from 'assert'; -import tap from 'tap'; - +import * as common from '../common/index.mjs' +import { setTimeout } from 'timers/promises' +import { Readable } from '../../lib/ours/index.js' +import assert from 'assert' +import tap from 'tap' function oneTo5() { - return Readable.from([1, 2, 3, 4, 5]); + return Readable.from([1, 2, 3, 4, 5]) } function oneTo5Async() { return oneTo5().map(async (x) => { - await Promise.resolve(); - return x; - }); + await Promise.resolve() + return x + }) } { // Some, find, and every work with a synchronous stream and predicate - assert.strictEqual(await oneTo5().some((x) => x > 3), true); - assert.strictEqual(await oneTo5().every((x) => x > 3), false); - assert.strictEqual(await oneTo5().find((x) => x > 3), 4); - assert.strictEqual(await oneTo5().some((x) => x > 6), false); - assert.strictEqual(await oneTo5().every((x) => x < 6), true); - assert.strictEqual(await oneTo5().find((x) => x > 6), undefined); - assert.strictEqual(await Readable.from([]).some(() => true), false); - assert.strictEqual(await Readable.from([]).every(() => true), true); - assert.strictEqual(await Readable.from([]).find(() => true), undefined); + assert.strictEqual(await oneTo5().some((x) => x > 3), true) + assert.strictEqual(await oneTo5().every((x) => x > 3), false) + assert.strictEqual(await oneTo5().find((x) => x > 3), 4) + assert.strictEqual(await oneTo5().some((x) => x > 6), false) + assert.strictEqual(await oneTo5().every((x) => x < 6), true) + assert.strictEqual(await oneTo5().find((x) => x > 6), undefined) + assert.strictEqual(await Readable.from([]).some(() => true), false) + assert.strictEqual(await Readable.from([]).every(() => true), true) + assert.strictEqual(await Readable.from([]).find(() => true), undefined) } { // Some, find, and every work with an asynchronous stream and synchronous predicate - assert.strictEqual(await oneTo5Async().some((x) => x > 3), true); - assert.strictEqual(await oneTo5Async().every((x) => x > 3), false); - assert.strictEqual(await oneTo5Async().find((x) => x > 3), 4); - assert.strictEqual(await oneTo5Async().some((x) => x > 6), false); - assert.strictEqual(await oneTo5Async().every((x) => x < 6), true); - assert.strictEqual(await oneTo5Async().find((x) => x > 6), undefined); + assert.strictEqual(await oneTo5Async().some((x) => x > 3), true) + assert.strictEqual(await oneTo5Async().every((x) => x > 3), false) + assert.strictEqual(await oneTo5Async().find((x) => x > 3), 4) + assert.strictEqual(await oneTo5Async().some((x) => x > 6), false) + assert.strictEqual(await oneTo5Async().every((x) => x < 6), true) + assert.strictEqual(await oneTo5Async().find((x) => x > 6), undefined) } { // Some, find, and every work on synchronous streams with an asynchronous predicate - assert.strictEqual(await oneTo5().some(async (x) => x > 3), true); - assert.strictEqual(await oneTo5().every(async (x) => x > 3), false); - assert.strictEqual(await oneTo5().find(async (x) => x > 3), 4); - assert.strictEqual(await oneTo5().some(async (x) => x > 6), false); - assert.strictEqual(await oneTo5().every(async (x) => x < 6), true); - assert.strictEqual(await oneTo5().find(async (x) => x > 6), undefined); + assert.strictEqual(await oneTo5().some(async (x) => x > 3), true) + assert.strictEqual(await oneTo5().every(async (x) => x > 3), false) + assert.strictEqual(await oneTo5().find(async (x) => x > 3), 4) + assert.strictEqual(await oneTo5().some(async (x) => x > 6), false) + assert.strictEqual(await oneTo5().every(async (x) => x < 6), true) + assert.strictEqual(await oneTo5().find(async (x) => x > 6), undefined) } { // Some, find, and every work on asynchronous streams with an asynchronous predicate - assert.strictEqual(await oneTo5Async().some(async (x) => x > 3), true); - assert.strictEqual(await oneTo5Async().every(async (x) => x > 3), false); - assert.strictEqual(await oneTo5Async().find(async (x) => x > 3), 4); - assert.strictEqual(await oneTo5Async().some(async (x) => x > 6), false); - assert.strictEqual(await oneTo5Async().every(async (x) => x < 6), true); - assert.strictEqual(await oneTo5Async().find(async (x) => x > 6), undefined); + assert.strictEqual(await oneTo5Async().some(async (x) => x > 3), true) + assert.strictEqual(await oneTo5Async().every(async (x) => x > 3), false) + assert.strictEqual(await oneTo5Async().find(async (x) => x > 3), 4) + assert.strictEqual(await oneTo5Async().some(async (x) => x > 6), false) + assert.strictEqual(await oneTo5Async().every(async (x) => x < 6), true) + assert.strictEqual(await oneTo5Async().find(async (x) => x > 6), undefined) } { async function checkDestroyed(stream) { - await setTimeout(); - assert.strictEqual(stream.destroyed, true); + await setTimeout() + assert.strictEqual(stream.destroyed, true) } { // Some, find, and every short circuit - const someStream = oneTo5(); - await someStream.some(common.mustCall((x) => x > 2, 3)); - await checkDestroyed(someStream); + const someStream = oneTo5() + await someStream.some(common.mustCall((x) => x > 2, 3)) + await checkDestroyed(someStream) - const everyStream = oneTo5(); - await everyStream.every(common.mustCall((x) => x < 3, 3)); - await checkDestroyed(everyStream); + const everyStream = oneTo5() + await everyStream.every(common.mustCall((x) => x < 3, 3)) + await checkDestroyed(everyStream) - const findStream = oneTo5(); - await findStream.find(common.mustCall((x) => x > 1, 2)); - await checkDestroyed(findStream); + const findStream = oneTo5() + await findStream.find(common.mustCall((x) => x > 1, 2)) + await checkDestroyed(findStream) // When short circuit isn't possible the whole stream is iterated - await oneTo5().some(common.mustCall(() => false, 5)); - await oneTo5().every(common.mustCall(() => true, 5)); - await oneTo5().find(common.mustCall(() => false, 5)); + await oneTo5().some(common.mustCall(() => false, 5)) + await oneTo5().every(common.mustCall(() => true, 5)) + await oneTo5().find(common.mustCall(() => false, 5)) } { // Some, find, and every short circuit async stream/predicate - const someStream = oneTo5Async(); - await someStream.some(common.mustCall(async (x) => x > 2, 3)); - await checkDestroyed(someStream); + const someStream = oneTo5Async() + await someStream.some(common.mustCall(async (x) => x > 2, 3)) + await checkDestroyed(someStream) - const everyStream = oneTo5Async(); - await everyStream.every(common.mustCall(async (x) => x < 3, 3)); - await checkDestroyed(everyStream); + const everyStream = oneTo5Async() + await everyStream.every(common.mustCall(async (x) => x < 3, 3)) + await checkDestroyed(everyStream) - const findStream = oneTo5Async(); - await findStream.find(common.mustCall(async (x) => x > 1, 2)); - await checkDestroyed(findStream); + const findStream = oneTo5Async() + await findStream.find(common.mustCall(async (x) => x > 1, 2)) + await checkDestroyed(findStream) // When short circuit isn't possible the whole stream is iterated - await oneTo5Async().some(common.mustCall(async () => false, 5)); - await oneTo5Async().every(common.mustCall(async () => true, 5)); - await oneTo5Async().find(common.mustCall(async () => false, 5)); + await oneTo5Async().some(common.mustCall(async () => false, 5)) + await oneTo5Async().every(common.mustCall(async () => true, 5)) + await oneTo5Async().find(common.mustCall(async () => false, 5)) } } { // Concurrency doesn't affect which value is found. - const found = await Readable.from([1, 2]).find(async (val) => { - if (val === 1) { - await setTimeout(100); - } - return true; - }, { concurrency: 2 }); - assert.strictEqual(found, 1); + const found = await Readable.from([1, 2]).find( + async (val) => { + if (val === 1) { + await setTimeout(100) + } + return true + }, + { concurrency: 2 } + ) + assert.strictEqual(found, 1) } { // Support for AbortSignal for (const op of ['some', 'every', 'find']) { { - const ac = new AbortController(); - assert.rejects(Readable.from([1, 2, 3])[op]( - () => new Promise(() => { }), - { signal: ac.signal } - ), { - name: 'AbortError', - }, `${op} should abort correctly with sync abort`).then(common.mustCall()); - ac.abort(); + const ac = new AbortController() + assert + .rejects( + Readable.from([1, 2, 3])[op](() => new Promise(() => {}), { signal: ac.signal }), + { + name: 'AbortError' + }, + `${op} should abort correctly with sync abort` + ) + .then(common.mustCall()) + ac.abort() } { // Support for pre-aborted AbortSignal - assert.rejects(Readable.from([1, 2, 3])[op]( - () => new Promise(() => { }), - { signal: AbortSignal.abort() } - ), { - name: 'AbortError', - }, `${op} should abort with pre-aborted abort controller`).then(common.mustCall()); + assert + .rejects( + Readable.from([1, 2, 3])[op](() => new Promise(() => {}), { signal: AbortSignal.abort() }), + { + name: 'AbortError' + }, + `${op} should abort with pre-aborted abort controller` + ) + .then(common.mustCall()) } } } { // Error cases for (const op of ['some', 'every', 'find']) { - assert.rejects(async () => { - await Readable.from([1])[op](1); - }, /ERR_INVALID_ARG_TYPE/, `${op} should throw for invalid function`).then(common.mustCall()); - assert.rejects(async () => { - await Readable.from([1])[op]((x) => x, { - concurrency: 'Foo' - }); - }, /ERR_OUT_OF_RANGE/, `${op} should throw for invalid concurrency`).then(common.mustCall()); - assert.rejects(async () => { - await Readable.from([1])[op]((x) => x, 1); - }, /ERR_INVALID_ARG_TYPE/, `${op} should throw for invalid concurrency`).then(common.mustCall()); - assert.rejects(async () => { - await Readable.from([1])[op]((x) => x, { - signal: true - }); - }, /ERR_INVALID_ARG_TYPE/, `${op} should throw for invalid signal`).then(common.mustCall()); + assert + .rejects( + async () => { + await Readable.from([1])[op](1) + }, + /ERR_INVALID_ARG_TYPE/, + `${op} should throw for invalid function` + ) + .then(common.mustCall()) + assert + .rejects( + async () => { + await Readable.from([1])[op]((x) => x, { + concurrency: 'Foo' + }) + }, + /ERR_OUT_OF_RANGE/, + `${op} should throw for invalid concurrency` + ) + .then(common.mustCall()) + assert + .rejects( + async () => { + await Readable.from([1])[op]((x) => x, 1) + }, + /ERR_INVALID_ARG_TYPE/, + `${op} should throw for invalid concurrency` + ) + .then(common.mustCall()) + assert + .rejects( + async () => { + await Readable.from([1])[op]((x) => x, { + signal: true + }) + }, + /ERR_INVALID_ARG_TYPE/, + `${op} should throw for invalid signal` + ) + .then(common.mustCall()) } } { for (const op of ['some', 'every', 'find']) { - const stream = oneTo5(); + const stream = oneTo5() Object.defineProperty(stream, 'map', { - value: common.mustNotCall(() => {}), - }); + value: common.mustNotCall(() => {}) + }) // Check that map isn't getting called. - stream[op](() => {}); + stream[op](() => {}) } } - /* replacement start */ - process.on('beforeExit', (code) => { - if(code === 0) { - tap.pass('test succeeded'); - } else { - tap.fail(`test failed - exited code ${code}`); - } - }); - /* replacement end */ +/* replacement start */ +process.on('beforeExit', (code) => { + if (code === 0) { + tap.pass('test succeeded') + } else { + tap.fail(`test failed - exited code ${code}`) + } +}) +/* replacement end */ diff --git a/test/parallel/test-stream-toArray.js b/test/parallel/test-stream-toArray.js index 8f3e9b6e7..2c8094035 100644 --- a/test/parallel/test-stream-toArray.js +++ b/test/parallel/test-stream-toArray.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,20 +12,14 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const assert = require('assert') - { // Works on a synchronous stream ;(async () => { @@ -40,7 +31,6 @@ const assert = require('assert') .fill() .map((_, i) => i) ] - for (const test of tests) { const stream = Readable.from(test) const result = await stream.toArray() @@ -72,7 +62,6 @@ const assert = require('assert') .fill() .map((_, i) => i) ] - for (const test of tests) { const stream = Readable.from(test).map((x) => Promise.resolve(x)) const result = await stream.toArray() @@ -130,8 +119,8 @@ const assert = require('assert') }, /ERR_INVALID_ARG_TYPE/) .then(common.mustCall()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-callback-twice.js b/test/parallel/test-stream-transform-callback-twice.js index 0ab6afd27..f1437576c 100644 --- a/test/parallel/test-stream-transform-callback-twice.js +++ b/test/parallel/test-stream-transform-callback-twice.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Transform } = require('../../lib/ours/index') - const stream = new Transform({ transform(chunk, enc, cb) { cb() @@ -26,8 +22,8 @@ stream.on( }) ) stream.write('foo') -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-constructor-set-methods.js b/test/parallel/test-stream-transform-constructor-set-methods.js index 0404839fe..9ab0c48c7 100644 --- a/test/parallel/test-stream-transform-constructor-set-methods.js +++ b/test/parallel/test-stream-transform-constructor-set-methods.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Transform } = require('../../lib/ours/index') - const t = new Transform() assert.throws( () => { @@ -24,19 +19,15 @@ assert.throws( message: 'The _transform() method is not implemented' } ) - const _transform = common.mustCall((chunk, _, next) => { next() }) - const _final = common.mustCall((next) => { next() }) - const _flush = common.mustCall((next) => { next() }) - const t2 = new Transform({ transform: _transform, flush: _flush, @@ -47,8 +38,8 @@ assert.strictEqual(t2._flush, _flush) assert.strictEqual(t2._final, _final) t2.end(Buffer.from('blerg')) t2.resume() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-destroy.js b/test/parallel/test-stream-transform-destroy.js index 895e6a1ee..b635df131 100644 --- a/test/parallel/test-stream-transform-destroy.js +++ b/test/parallel/test-stream-transform-destroy.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Transform } = require('../../lib/ours/index') - const assert = require('assert') - { const transform = new Transform({ transform(chunk, enc, cb) {} @@ -63,7 +58,6 @@ const assert = require('assert') const expected = new Error('kaboom') const transform = new Transform({ transform(chunk, enc, cb) {}, - destroy: common.mustCall(function (err, cb) { assert.strictEqual(err, expected) cb() @@ -72,8 +66,9 @@ const assert = require('assert') transform.resume() transform.on('end', common.mustNotCall('no end event')) transform.on('close', common.mustCall()) - transform.on('finish', common.mustNotCall('no finish event')) // Error is swallowed by the custom _destroy + transform.on('finish', common.mustNotCall('no finish event')) + // Error is swallowed by the custom _destroy transform.on('error', common.mustNotCall('no error event')) transform.destroy(expected) } @@ -130,8 +125,8 @@ const assert = require('assert') ) transform.destroy() } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-final-sync.js b/test/parallel/test-stream-transform-final-sync.js index 7999d44ca..c53289820 100644 --- a/test/parallel/test-stream-transform-final-sync.js +++ b/test/parallel/test-stream-transform-final-sync.js @@ -1,19 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') +let state = 0 -let state = 0 // What you do +// What you do // // const stream = new stream.Transform({ // transform: function transformCallback(chunk, _, next) { @@ -68,27 +65,27 @@ const t = new stream.Transform({ transform: common.mustCall(function (chunk, _, next) { // transformCallback part 1 assert.strictEqual(++state, chunk) - this.push(state) // transformCallback part 2 - + this.push(state) + // transformCallback part 2 assert.strictEqual(++state, chunk + 2) process.nextTick(next) }, 3), final: common.mustCall(function (done) { - state++ // finalCallback part 1 - + state++ + // finalCallback part 1 assert.strictEqual(state, 10) - state++ // finalCallback part 2 - + state++ + // finalCallback part 2 assert.strictEqual(state, 11) done() }, 1), flush: common.mustCall(function (done) { - state++ // fluchCallback part 1 - + state++ + // fluchCallback part 1 assert.strictEqual(state, 12) process.nextTick(function () { - state++ // fluchCallback part 2 - + state++ + // fluchCallback part 2 assert.strictEqual(state, 13) done() }) @@ -97,16 +94,16 @@ const t = new stream.Transform({ t.on( 'finish', common.mustCall(function () { - state++ // finishListener - + state++ + // finishListener assert.strictEqual(state, 15) }, 1) ) t.on( 'end', common.mustCall(function () { - state++ // endEvent - + state++ + // endEvent assert.strictEqual(state, 16) }, 1) ) @@ -122,13 +119,13 @@ t.write(4) t.end( 7, common.mustCall(function () { - state++ // endMethodCallback - + state++ + // endMethodCallback assert.strictEqual(state, 14) }, 1) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-final.js b/test/parallel/test-stream-transform-final.js index 0014844a5..d8536708e 100644 --- a/test/parallel/test-stream-transform-final.js +++ b/test/parallel/test-stream-transform-final.js @@ -1,19 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') +let state = 0 -let state = 0 // What you do: +// What you do: // // const stream = new stream.Transform({ // transform: function transformCallback(chunk, _, next) { @@ -45,6 +42,7 @@ let state = 0 // What you do: // t.end(7, endMethodCallback); // // The order things are called + // 1. transformCallback part 1 // 2. dataListener // 3. transformCallback part 2 @@ -67,29 +65,29 @@ const t = new stream.Transform({ transform: common.mustCall(function (chunk, _, next) { // transformCallback part 1 assert.strictEqual(++state, chunk) - this.push(state) // transformCallback part 2 - + this.push(state) + // transformCallback part 2 assert.strictEqual(++state, chunk + 2) process.nextTick(next) }, 3), final: common.mustCall(function (done) { - state++ // finalCallback part 1 - + state++ + // finalCallback part 1 assert.strictEqual(state, 10) setTimeout(function () { - state++ // finalCallback part 2 - + state++ + // finalCallback part 2 assert.strictEqual(state, 11) done() }, 100) }, 1), flush: common.mustCall(function (done) { - state++ // flushCallback part 1 - + state++ + // flushCallback part 1 assert.strictEqual(state, 12) process.nextTick(function () { - state++ // flushCallback part 2 - + state++ + // flushCallback part 2 assert.strictEqual(state, 13) done() }) @@ -98,16 +96,16 @@ const t = new stream.Transform({ t.on( 'finish', common.mustCall(function () { - state++ // finishListener - + state++ + // finishListener assert.strictEqual(state, 15) }, 1) ) t.on( 'end', common.mustCall(function () { - state++ // end event - + state++ + // end event assert.strictEqual(state, 16) }, 1) ) @@ -123,13 +121,13 @@ t.write(4) t.end( 7, common.mustCall(function () { - state++ // endMethodCallback - + state++ + // endMethodCallback assert.strictEqual(state, 14) }, 1) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-flush-data.js b/test/parallel/test-stream-transform-flush-data.js index 754104852..de90e053a 100644 --- a/test/parallel/test-stream-transform-flush-data.js +++ b/test/parallel/test-stream-transform-flush-data.js @@ -1,28 +1,20 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const Transform = require('../../lib/ours/index').Transform - const expected = 'asdf' - function _transform(d, e, n) { n() } - function _flush(n) { n(null, expected) } - const t = new Transform({ transform: _transform, flush: _flush @@ -31,8 +23,8 @@ t.end(Buffer.from('blerg')) t.on('data', (data) => { assert.strictEqual(data.toString(), expected) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-hwm0.js b/test/parallel/test-stream-transform-hwm0.js index 6459fde5c..30fafec0b 100644 --- a/test/parallel/test-stream-transform-hwm0.js +++ b/test/parallel/test-stream-transform-hwm0.js @@ -1,22 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Transform } = require('../../lib/ours/index') - const t = new Transform({ objectMode: true, highWaterMark: 0, - transform(chunk, enc, callback) { process.nextTick(() => callback(null, chunk, enc)) } @@ -46,8 +40,8 @@ t.once( ) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-objectmode-falsey-value.js b/test/parallel/test-stream-transform-objectmode-falsey-value.js index e2ae60a7e..7942c6442 100644 --- a/test/parallel/test-stream-transform-objectmode-falsey-value.js +++ b/test/parallel/test-stream-transform-objectmode-falsey-value.js @@ -18,21 +18,17 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const PassThrough = stream.PassThrough const src = new PassThrough({ objectMode: true @@ -65,8 +61,8 @@ const int = setInterval( }, expect.length + 1), 1 ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-split-highwatermark.js b/test/parallel/test-stream-transform-split-highwatermark.js index b3f05203b..7ab990a4f 100644 --- a/test/parallel/test-stream-transform-split-highwatermark.js +++ b/test/parallel/test-stream-transform-split-highwatermark.js @@ -1,26 +1,21 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { Transform, Readable, Writable } = require('../../lib/ours/index') - const DEFAULT = 16 * 1024 - function testTransform(expectedReadableHwm, expectedWritableHwm, options) { const t = new Transform(options) assert.strictEqual(t._readableState.highWaterMark, expectedReadableHwm) assert.strictEqual(t._writableState.highWaterMark, expectedWritableHwm) -} // Test overriding defaultHwm +} +// Test overriding defaultHwm testTransform(666, DEFAULT, { readableHighWaterMark: 666 }) @@ -30,8 +25,9 @@ testTransform(DEFAULT, 777, { testTransform(666, 777, { readableHighWaterMark: 666, writableHighWaterMark: 777 -}) // Test highWaterMark overriding +}) +// Test highWaterMark overriding testTransform(555, 555, { highWaterMark: 555, readableHighWaterMark: 666 @@ -44,8 +40,9 @@ testTransform(555, 555, { highWaterMark: 555, readableHighWaterMark: 666, writableHighWaterMark: 777 -}) // Test undefined, null +}) +// Test undefined, null ;[undefined, null].forEach((v) => { testTransform(DEFAULT, DEFAULT, { readableHighWaterMark: v @@ -61,8 +58,9 @@ testTransform(555, 555, { highWaterMark: v, writableHighWaterMark: 777 }) -}) // test NaN +}) +// test NaN { assert.throws( () => { @@ -88,8 +86,9 @@ testTransform(555, 555, { message: "The property 'options.writableHighWaterMark' is invalid. " + 'Received NaN' } ) -} // Test non Duplex streams ignore the options +} +// Test non Duplex streams ignore the options { const r = new Readable({ readableHighWaterMark: 666 @@ -100,8 +99,8 @@ testTransform(555, 555, { }) assert.strictEqual(w._writableState.highWaterMark, DEFAULT) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-transform-split-objectmode.js b/test/parallel/test-stream-transform-split-objectmode.js index db93fe934..869596375 100644 --- a/test/parallel/test-stream-transform-split-objectmode.js +++ b/test/parallel/test-stream-transform-split-objectmode.js @@ -18,21 +18,17 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const Transform = require('../../lib/ours/index').Transform - const parser = new Transform({ readableObjectMode: true }) @@ -42,13 +38,11 @@ assert.strictEqual(parser.readableHighWaterMark, 16) assert.strictEqual(parser.writableHighWaterMark, 16 * 1024) assert.strictEqual(parser.readableHighWaterMark, parser._readableState.highWaterMark) assert.strictEqual(parser.writableHighWaterMark, parser._writableState.highWaterMark) - parser._transform = function (chunk, enc, callback) { callback(null, { val: chunk[0] }) } - let parsed parser.on('data', function (obj) { parsed = obj @@ -66,11 +60,9 @@ assert.strictEqual(serializer.readableHighWaterMark, 16 * 1024) assert.strictEqual(serializer.writableHighWaterMark, 16) assert.strictEqual(parser.readableHighWaterMark, parser._readableState.highWaterMark) assert.strictEqual(parser.writableHighWaterMark, parser._writableState.highWaterMark) - serializer._transform = function (obj, _, callback) { callback(null, Buffer.from([obj.val])) } - let serialized serializer.on('data', function (chunk) { serialized = chunk @@ -81,8 +73,8 @@ serializer.write({ process.on('exit', function () { assert.strictEqual(serialized[0], 42) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-uint8array.js b/test/parallel/test-stream-uint8array.js index a57e13da1..d770a8682 100644 --- a/test/parallel/test-stream-uint8array.js +++ b/test/parallel/test-stream-uint8array.js @@ -1,34 +1,28 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable, Writable } = require('../../lib/ours/index') - const ABC = new Uint8Array([0x41, 0x42, 0x43]) const DEF = new Uint8Array([0x44, 0x45, 0x46]) const GHI = new Uint8Array([0x47, 0x48, 0x49]) { // Simple Writable test. + let n = 0 const writable = new Writable({ write: common.mustCall((chunk, encoding, cb) => { assert(chunk instanceof Buffer) - if (n++ === 0) { assert.strictEqual(String(chunk), 'ABC') } else { assert.strictEqual(String(chunk), 'DEF') } - cb() }, 2) }) @@ -37,6 +31,7 @@ const GHI = new Uint8Array([0x47, 0x48, 0x49]) } { // Writable test, pass in Uint8Array in object mode. + const writable = new Writable({ objectMode: true, write: common.mustCall((chunk, encoding, cb) => { @@ -93,8 +88,8 @@ const GHI = new Uint8Array([0x47, 0x48, 0x49]) const out = readable.read() assert.strictEqual(out, 'ABCDEF') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-unpipe-event.js b/test/parallel/test-stream-unpipe-event.js index 0ce62499e..58a3bbf17 100644 --- a/test/parallel/test-stream-unpipe-event.js +++ b/test/parallel/test-stream-unpipe-event.js @@ -1,34 +1,26 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Writable, Readable } = require('../../lib/ours/index') - class NullWriteable extends Writable { _write(chunk, encoding, callback) { return callback() } } - class QuickEndReadable extends Readable { _read() { this.push(null) } } - class NeverEndReadable extends Readable { _read() {} } - { const dest = new NullWriteable() const src = new QuickEndReadable() @@ -97,8 +89,8 @@ class NeverEndReadable extends Readable { assert.strictEqual(src._readableState.pipes.length, 0) }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-unshift-empty-chunk.js b/test/parallel/test-stream-unshift-empty-chunk.js index 89dccd6c9..2e9c312fa 100644 --- a/test/parallel/test-stream-unshift-empty-chunk.js +++ b/test/parallel/test-stream-unshift-empty-chunk.js @@ -18,44 +18,39 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') +const assert = require('assert') -const assert = require('assert') // This test verifies that stream.unshift(Buffer.alloc(0)) or +// This test verifies that stream.unshift(Buffer.alloc(0)) or // stream.unshift('') does not set state.reading=false. - const Readable = require('../../lib/ours/index').Readable - const r = new Readable() let nChunks = 10 const chunk = Buffer.alloc(10, 'x') - r._read = function (n) { setImmediate(() => { r.push(--nChunks === 0 ? null : chunk) }) } - let readAll = false const seen = [] r.on('readable', () => { let chunk - while ((chunk = r.read()) !== null) { - seen.push(chunk.toString()) // Simulate only reading a certain amount of the data, + seen.push(chunk.toString()) + // Simulate only reading a certain amount of the data, // and then putting the rest of the chunk back into the // stream, like a parser might do. We just fill it with // 'y' so that it's easy to see which bits were touched, // and which were not. - const putBack = Buffer.alloc(readAll ? 0 : 5, 'y') readAll = !readAll r.unshift(putBack) @@ -85,8 +80,8 @@ r.on('end', () => { assert.deepStrictEqual(seen, expect) silentConsole.log('ok') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-unshift-read-race.js b/test/parallel/test-stream-unshift-read-race.js index fd0981272..75c9b6b83 100644 --- a/test/parallel/test-stream-unshift-read-race.js +++ b/test/parallel/test-stream-unshift-read-race.js @@ -18,18 +18,18 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const assert = require('assert') -const assert = require('assert') // This test verifies that: +// This test verifies that: // 1. unshift() does not cause colliding _read() calls. // 2. unshift() after the 'end' event is an error, but after the EOF // signalling null, it is ok, and just creates a new readable chunk. @@ -37,7 +37,6 @@ const assert = require('assert') // This test verifies that: // 4. _read() is not called after pushing the EOF null chunk. const stream = require('../../lib/ours/index') - const hwm = 10 const r = stream.Readable({ highWaterMark: hwm, @@ -45,25 +44,21 @@ const r = stream.Readable({ }) const chunks = 10 const data = Buffer.allocUnsafe(chunks * hwm + Math.ceil(hwm / 2)) - for (let i = 0; i < data.length; i++) { const c = 'asdf'.charCodeAt(i % 4) data[i] = c } - let pos = 0 let pushedNull = false - r._read = function (n) { - assert(!pushedNull, '_read after null push') // Every third chunk is fast + assert(!pushedNull, '_read after null push') + // Every third chunk is fast push(!(chunks % 3)) - function push(fast) { assert(!pushedNull, 'push() after null push') const c = pos >= data.length ? null : data.slice(pos, pos + n) pushedNull = c === null - if (fast) { pos += n r.push(c) @@ -77,7 +72,6 @@ r._read = function (n) { } } } - function pushError() { r.unshift(Buffer.allocUnsafe(1)) w.end() @@ -92,19 +86,15 @@ function pushError() { } ) } - const w = stream.Writable() const written = [] - w._write = function (chunk, encoding, cb) { written.push(chunk.toString()) cb() } - r.on('end', common.mustNotCall()) r.on('readable', function () { let chunk - while (null !== (chunk = r.read(10))) { w.write(chunk) if (chunk.length > 4) r.unshift(Buffer.from('1234')) @@ -119,28 +109,22 @@ w.on( assert.strictEqual(written[0], 'asdfasdfas') let asdf = 'd' silentConsole.error(`0: ${written[0]}`) - for (let i = 1; i < written.length; i++) { silentConsole.error(`${i.toString(32)}: ${written[i]}`) assert.strictEqual(written[i].slice(0, 4), '1234') - for (let j = 4; j < written[i].length; j++) { const c = written[i].charAt(j) assert.strictEqual(c, asdf) - switch (asdf) { case 'a': asdf = 's' break - case 's': asdf = 'd' break - case 'd': asdf = 'f' break - case 'f': asdf = 'a' break @@ -153,8 +137,8 @@ process.on('exit', function () { assert.strictEqual(written.length, 18) silentConsole.log('ok') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-aborted.js b/test/parallel/test-stream-writable-aborted.js index bc82a85c8..c2d298f21 100644 --- a/test/parallel/test-stream-writable-aborted.js +++ b/test/parallel/test-stream-writable-aborted.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { Writable } = require('../../lib/ours/index') - { const writable = new Writable({ write() {} @@ -30,8 +25,8 @@ const { Writable } = require('../../lib/ours/index') writable.destroy() assert.strictEqual(writable.writableAborted, true) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-change-default-encoding.js b/test/parallel/test-stream-writable-change-default-encoding.js index 4f4b1b697..31935af34 100644 --- a/test/parallel/test-stream-writable-change-default-encoding.js +++ b/test/parallel/test-stream-writable-change-default-encoding.js @@ -18,33 +18,27 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - class MyWritable extends stream.Writable { constructor(fn, options) { super(options) this.fn = fn } - _write(chunk, encoding, callback) { this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding) callback() } } - ;(function defaultCondingIsUtf8() { const m = new MyWritable( function (isBuffer, type, enc) { @@ -57,7 +51,6 @@ class MyWritable extends stream.Writable { m.write('foo') m.end() })() - ;(function changeDefaultEncodingToAscii() { const m = new MyWritable( function (isBuffer, type, enc) { @@ -70,8 +63,9 @@ class MyWritable extends stream.Writable { m.setDefaultEncoding('ascii') m.write('bar') m.end() -})() // Change default encoding to invalid value. +})() +// Change default encoding to invalid value. assert.throws( () => { const m = new MyWritable((isBuffer, type, enc) => {}, { @@ -87,7 +81,6 @@ assert.throws( message: 'Unknown encoding: {}' } ) - ;(function checkVariableCaseEncoding() { const m = new MyWritable( function (isBuffer, type, enc) { @@ -101,8 +94,8 @@ assert.throws( m.write('bar') m.end() })() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-clear-buffer.js b/test/parallel/test-stream-writable-clear-buffer.js index f1a390c6e..7be01a19f 100644 --- a/test/parallel/test-stream-writable-clear-buffer.js +++ b/test/parallel/test-stream-writable-clear-buffer.js @@ -1,37 +1,32 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} -} // This test ensures that the _writeableState.bufferedRequestCount and +} +// This test ensures that the _writeableState.bufferedRequestCount and // the actual buffered request count are the same. const common = require('../common') - const Stream = require('../../lib/ours/index') - const assert = require('assert') - class StreamWritable extends Stream.Writable { constructor() { super({ objectMode: true }) - } // Refs: https://github.com/nodejs/node/issues/6758 + } + + // Refs: https://github.com/nodejs/node/issues/6758 // We need a timer like on the original issue thread. // Otherwise the code will never reach our test case. - _write(chunk, encoding, cb) { setImmediate(cb) } } - const testStream = new StreamWritable() testStream.cork() - for (let i = 1; i <= 5; i++) { testStream.write( i, @@ -40,10 +35,9 @@ for (let i = 1; i <= 5; i++) { }) ) } - testStream.end() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-constructor-set-methods.js b/test/parallel/test-stream-writable-constructor-set-methods.js index 1821dff1a..20064e683 100644 --- a/test/parallel/test-stream-writable-constructor-set-methods.js +++ b/test/parallel/test-stream-writable-constructor-set-methods.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Writable } = require('../../lib/ours/index') - const bufferBlerg = Buffer.from('blerg') const w = new Writable() assert.throws( @@ -25,16 +20,13 @@ assert.throws( message: 'The _write() method is not implemented' } ) - const _write = common.mustCall((chunk, _, next) => { next() }) - const _writev = common.mustCall((chunks, next) => { assert.strictEqual(chunks.length, 2) next() }) - const w2 = new Writable({ write: _write, writev: _writev @@ -46,8 +38,8 @@ w2.cork() w2.write(bufferBlerg) w2.write(bufferBlerg) w2.end() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-decoded-encoding.js b/test/parallel/test-stream-writable-decoded-encoding.js index 5528943b2..6d2deb946 100644 --- a/test/parallel/test-stream-writable-decoded-encoding.js +++ b/test/parallel/test-stream-writable-decoded-encoding.js @@ -18,33 +18,27 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - class MyWritable extends stream.Writable { constructor(fn, options) { super(options) this.fn = fn } - _write(chunk, encoding, callback) { this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding) callback() } } - { const m = new MyWritable( function (isBuffer, type, enc) { @@ -73,8 +67,8 @@ class MyWritable extends stream.Writable { m.write('some-text', 'utf8') m.end() } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-destroy.js b/test/parallel/test-stream-writable-destroy.js index 8c6ea069d..cc5afb2f8 100644 --- a/test/parallel/test-stream-writable-destroy.js +++ b/test/parallel/test-stream-writable-destroy.js @@ -1,10 +1,7 @@ /* replacement start */ const AbortController = globalThis.AbortController || require('abort-controller').AbortController - const AbortSignal = globalThis.AbortSignal || require('abort-controller').AbortSignal - const EventTarget = globalThis.EventTarget || require('event-target-shim').EventTarget - if (typeof AbortSignal.abort !== 'function') { AbortSignal.abort = function () { const controller = new AbortController() @@ -15,20 +12,14 @@ if (typeof AbortSignal.abort !== 'function') { /* replacement end */ ;('use strict') - const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable, addAbortSignal } = require('../../lib/ours/index') - const assert = require('assert') - { const write = new Writable({ write(chunk, enc, cb) { @@ -76,12 +67,10 @@ const assert = require('assert') cb() } }) - write._destroy = function (err, cb) { assert.strictEqual(err, expected) cb(err) } - const expected = new Error('kaboom') write.on('finish', common.mustNotCall('no finish event')) write.on('close', common.mustCall()) @@ -99,7 +88,6 @@ const assert = require('assert') write(chunk, enc, cb) { cb() }, - destroy: common.mustCall(function (err, cb) { assert.strictEqual(err, expected) cb() @@ -107,8 +95,9 @@ const assert = require('assert') }) const expected = new Error('kaboom') write.on('finish', common.mustNotCall('no finish event')) - write.on('close', common.mustCall()) // Error is swallowed by the custom _destroy + write.on('close', common.mustCall()) + // Error is swallowed by the custom _destroy write.on('error', common.mustNotCall('no error event')) write.destroy(expected) assert.strictEqual(write.destroyed, true) @@ -202,7 +191,6 @@ const assert = require('assert') destroy: common.mustCall(function (err, cb) { process.nextTick(cb, new Error('kaboom 1')) }), - write(chunk, enc, cb) { cb() } @@ -228,9 +216,10 @@ const assert = require('assert') writable.destroy() assert.strictEqual(writable.destroyed, true) assert.strictEqual(writable._writableState.errored, null) - assert.strictEqual(writable._writableState.errorEmitted, false) // Test case where `writable.destroy()` is called again with an error before - // the `_destroy()` callback is called. + assert.strictEqual(writable._writableState.errorEmitted, false) + // Test case where `writable.destroy()` is called again with an error before + // the `_destroy()` callback is called. writable.destroy(new Error('kaboom 2')) assert.strictEqual(writable._writableState.errorEmitted, false) assert.strictEqual(writable._writableState.errored, null) @@ -243,8 +232,9 @@ const assert = require('assert') } }) write.destroyed = true - assert.strictEqual(write.destroyed, true) // The internal destroy() mechanism should not be triggered + assert.strictEqual(write.destroyed, true) + // The internal destroy() mechanism should not be triggered write.on('close', common.mustNotCall()) write.destroy() } @@ -254,7 +244,6 @@ const assert = require('assert') this.destroyed = false Writable.call(this) } - Object.setPrototypeOf(MyWritable.prototype, Writable.prototype) Object.setPrototypeOf(MyWritable, Writable) new MyWritable() @@ -288,7 +277,6 @@ const assert = require('assert') 'close', common.mustCall(() => { write._undestroy() - write.end() }) ) @@ -338,6 +326,7 @@ const assert = require('assert') } { // Call end(cb) after error & destroy + const write = new Writable({ write(chunk, enc, cb) { cb(new Error('asd')) @@ -361,6 +350,7 @@ const assert = require('assert') } { // Call end(cb) after finish & destroy + const write = new Writable({ write(chunk, enc, cb) { cb() @@ -385,14 +375,13 @@ const assert = require('assert') { // Call end(cb) after error & destroy and don't trigger // unhandled exception. + const write = new Writable({ write(chunk, enc, cb) { process.nextTick(cb) } }) - const _err = new Error('asd') - write.once( 'error', common.mustCall((err) => { @@ -409,13 +398,12 @@ const assert = require('assert') } { // Call buffered write callback with error - const _err = new Error('asd') + const _err = new Error('asd') const write = new Writable({ write(chunk, enc, cb) { process.nextTick(cb, _err) }, - autoDestroy: false }) write.cork() @@ -441,6 +429,7 @@ const assert = require('assert') } { // Ensure callback order. + let state = 0 const write = new Writable({ write(chunk, enc, cb) { @@ -467,7 +456,6 @@ const assert = require('assert') { const write = new Writable({ autoDestroy: false, - write(chunk, enc, cb) { cb() cb() @@ -505,7 +493,6 @@ const assert = require('assert') const ac = new AbortController() const write = new Writable({ signal: ac.signal, - write(chunk, enc, cb) { cb() } @@ -524,7 +511,6 @@ const assert = require('assert') const signal = AbortSignal.abort() const write = new Writable({ signal, - write(chunk, enc, cb) { cb() } @@ -553,9 +539,8 @@ const assert = require('assert') const s = new Writable({ final() {} }) - - const _err = new Error('oh no') // Remove `callback` and it works - + const _err = new Error('oh no') + // Remove `callback` and it works s.end( common.mustCall((err) => { assert.strictEqual(err, _err) @@ -569,8 +554,8 @@ const assert = require('assert') ) s.destroy(_err) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-end-cb-error.js b/test/parallel/test-stream-writable-end-cb-error.js index c18650055..17c23ae44 100644 --- a/test/parallel/test-stream-writable-end-cb-error.js +++ b/test/parallel/test-stream-writable-end-cb-error.js @@ -1,28 +1,20 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - { // Invoke end callback on failure. const writable = new stream.Writable() - const _err = new Error('kaboom') - writable._write = (chunk, encoding, cb) => { process.nextTick(cb, _err) } - writable.on( 'error', common.mustCall((err) => { @@ -44,11 +36,9 @@ const stream = require('../../lib/ours/index') { // Don't invoke end callback twice const writable = new stream.Writable() - writable._write = (chunk, encoding, cb) => { process.nextTick(cb) } - let called = false writable.end( 'asd', @@ -76,7 +66,6 @@ const stream = require('../../lib/ours/index') write(chunk, encoding, callback) { setImmediate(callback) }, - finish(callback) { setImmediate(callback) } @@ -111,8 +100,8 @@ const stream = require('../../lib/ours/index') ) w.on('finish', common.mustNotCall()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-end-cb-uncaught.js b/test/parallel/test-stream-writable-end-cb-uncaught.js index 802be0398..04d331c4e 100644 --- a/test/parallel/test-stream-writable-end-cb-uncaught.js +++ b/test/parallel/test-stream-writable-end-cb-uncaught.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - process.on( 'uncaughtException', common.mustCall((err) => { @@ -20,25 +15,21 @@ process.on( }) ) const writable = new stream.Writable() - const _err = new Error('kaboom') - writable._write = (chunk, encoding, cb) => { cb() } - writable._final = (cb) => { cb(_err) } - writable.write('asd') writable.end( common.mustCall((err) => { assert.strictEqual(err, _err) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-end-multiple.js b/test/parallel/test-stream-writable-end-multiple.js index 868c79b49..8986f083e 100644 --- a/test/parallel/test-stream-writable-end-multiple.js +++ b/test/parallel/test-stream-writable-end-multiple.js @@ -1,24 +1,17 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const writable = new stream.Writable() - writable._write = (chunk, encoding, cb) => { setTimeout(() => cb(), 10) } - writable.end('testing ended state', common.mustCall()) writable.end(common.mustCall()) writable.on( @@ -34,8 +27,8 @@ writable.on( ticked = true }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-ended-state.js b/test/parallel/test-stream-writable-ended-state.js index f91d66b56..0dbc4d1c2 100644 --- a/test/parallel/test-stream-writable-ended-state.js +++ b/test/parallel/test-stream-writable-ended-state.js @@ -1,27 +1,20 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const writable = new stream.Writable() - writable._write = (chunk, encoding, cb) => { assert.strictEqual(writable._writableState.ended, false) assert.strictEqual(writable._writableState.writable, undefined) assert.strictEqual(writable.writableEnded, false) cb() } - assert.strictEqual(writable._writableState.ended, false) assert.strictEqual(writable._writableState.writable, undefined) assert.strictEqual(writable.writable, true) @@ -39,8 +32,8 @@ assert.strictEqual(writable._writableState.ended, true) assert.strictEqual(writable._writableState.writable, undefined) assert.strictEqual(writable.writable, false) assert.strictEqual(writable.writableEnded, true) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-final-async.js b/test/parallel/test-stream-writable-final-async.js index f4643db8e..4be04adc5 100644 --- a/test/parallel/test-stream-writable-final-async.js +++ b/test/parallel/test-stream-writable-final-async.js @@ -1,34 +1,26 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Duplex } = require('../../lib/ours/index') - const st = require('timers').setTimeout - function setTimeout(ms) { return new Promise((resolve) => { st(resolve, ms) }) } - { class Foo extends Duplex { async _final(callback) { await setTimeout(common.platformTimeout(1)) callback() } - _read() {} } - const foo = new Foo() foo._write = common.mustCall((chunk, encoding, cb) => { cb() @@ -36,8 +28,8 @@ function setTimeout(ms) { foo.end('test', common.mustCall()) foo.on('error', common.mustNotCall()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-final-destroy.js b/test/parallel/test-stream-writable-final-destroy.js index bb5b529d4..fd0c6a27f 100644 --- a/test/parallel/test-stream-writable-final-destroy.js +++ b/test/parallel/test-stream-writable-final-destroy.js @@ -1,22 +1,17 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable } = require('../../lib/ours/index') - { const w = new Writable({ write(chunk, encoding, callback) { callback(null) }, - final(callback) { queueMicrotask(callback) } @@ -27,8 +22,8 @@ const { Writable } = require('../../lib/ours/index') w.on('finish', common.mustNotCall()) w.on('close', common.mustCall()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-final-throw.js b/test/parallel/test-stream-writable-final-throw.js index 1bd88cbbb..8a6d316c0 100644 --- a/test/parallel/test-stream-writable-final-throw.js +++ b/test/parallel/test-stream-writable-final-throw.js @@ -1,25 +1,19 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Duplex } = require('../../lib/ours/index') - { class Foo extends Duplex { _final(callback) { throw new Error('fhqwhgads') } - _read() {} } - const foo = new Foo() foo._write = common.mustCall((chunk, encoding, cb) => { cb() @@ -32,8 +26,8 @@ const { Duplex } = require('../../lib/ours/index') ) foo.on('error', common.mustCall()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-finish-destroyed.js b/test/parallel/test-stream-writable-finish-destroyed.js index e18a70f22..7ef5eed4b 100644 --- a/test/parallel/test-stream-writable-finish-destroyed.js +++ b/test/parallel/test-stream-writable-finish-destroyed.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable } = require('../../lib/ours/index') - { const w = new Writable({ write: common.mustCall((chunk, encoding, cb) => { @@ -50,8 +46,8 @@ const { Writable } = require('../../lib/ours/index') w.end() w.destroy() } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-finished-state.js b/test/parallel/test-stream-writable-finished-state.js index d4fefe06f..2d1d8e8a7 100644 --- a/test/parallel/test-stream-writable-finished-state.js +++ b/test/parallel/test-stream-writable-finished-state.js @@ -1,26 +1,19 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const writable = new stream.Writable() - writable._write = (chunk, encoding, cb) => { // The state finished should start in false. assert.strictEqual(writable._writableState.finished, false) cb() } - writable.on( 'finish', common.mustCall(() => { @@ -33,8 +26,8 @@ writable.end( assert.strictEqual(writable._writableState.finished, true) }) ) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-finished.js b/test/parallel/test-stream-writable-finished.js index 8d31f4fea..fe1cda8e0 100644 --- a/test/parallel/test-stream-writable-finished.js +++ b/test/parallel/test-stream-writable-finished.js @@ -1,32 +1,28 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable } = require('../../lib/ours/index') +const assert = require('assert') -const assert = require('assert') // basic - +// basic { // Find it on Writable.prototype assert(Reflect.has(Writable.prototype, 'writableFinished')) -} // event +} +// event { const writable = new Writable() - writable._write = (chunk, encoding, cb) => { // The state finished should start in false. assert.strictEqual(writable.writableFinished, false) cb() } - writable.on( 'finish', common.mustCall(() => { @@ -42,6 +38,7 @@ const assert = require('assert') // basic } { // Emit finish asynchronously. + const w = new Writable({ write(chunk, encoding, cb) { cb() @@ -52,6 +49,7 @@ const assert = require('assert') // basic } { // Emit prefinish synchronously. + const w = new Writable({ write(chunk, encoding, cb) { cb() @@ -69,11 +67,11 @@ const assert = require('assert') // basic } { // Emit prefinish synchronously w/ final. + const w = new Writable({ write(chunk, encoding, cb) { cb() }, - final(cb) { cb() } @@ -90,12 +88,12 @@ const assert = require('assert') // basic } { // Call _final synchronously. + let sync = true const w = new Writable({ write(chunk, encoding, cb) { cb() }, - final: common.mustCall((cb) => { assert.strictEqual(sync, true) cb() @@ -104,8 +102,8 @@ const assert = require('assert') // basic w.end() sync = false } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-invalid-chunk.js b/test/parallel/test-stream-writable-invalid-chunk.js index 429058116..32247b7c4 100644 --- a/test/parallel/test-stream-writable-invalid-chunk.js +++ b/test/parallel/test-stream-writable-invalid-chunk.js @@ -1,25 +1,19 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - function testWriteType(val, objectMode, code) { const writable = new stream.Writable({ objectMode, write: () => {} }) writable.on('error', common.mustNotCall()) - if (code) { assert.throws( () => { @@ -33,7 +27,6 @@ function testWriteType(val, objectMode, code) { writable.write(val) } } - testWriteType([], false, 'ERR_INVALID_ARG_TYPE') testWriteType({}, false, 'ERR_INVALID_ARG_TYPE') testWriteType(0, false, 'ERR_INVALID_ARG_TYPE') @@ -48,8 +41,8 @@ testWriteType(true, true) testWriteType(0.0, true) testWriteType(undefined, true) testWriteType(null, true, 'ERR_STREAM_NULL_VALUES') -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-needdrain-state.js b/test/parallel/test-stream-writable-needdrain-state.js index 0876c3742..fea356626 100644 --- a/test/parallel/test-stream-writable-needdrain-state.js +++ b/test/parallel/test-stream-writable-needdrain-state.js @@ -1,30 +1,23 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - const assert = require('assert') - const transform = new stream.Transform({ transform: _transform, highWaterMark: 1 }) - function _transform(chunk, encoding, cb) { process.nextTick(() => { assert.strictEqual(transform._writableState.needDrain, true) cb() }) } - assert.strictEqual(transform._writableState.needDrain, false) transform.write( 'asdasd', @@ -33,8 +26,8 @@ transform.write( }) ) assert.strictEqual(transform._writableState.needDrain, true) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-null.js b/test/parallel/test-stream-writable-null.js index e60d895a5..60706dd48 100644 --- a/test/parallel/test-stream-writable-null.js +++ b/test/parallel/test-stream-writable-null.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - class MyWritable extends stream.Writable { constructor(options) { super({ @@ -20,13 +15,11 @@ class MyWritable extends stream.Writable { ...options }) } - _write(chunk, encoding, callback) { assert.notStrictEqual(chunk, null) callback() } } - { const m = new MyWritable({ objectMode: true @@ -69,8 +62,8 @@ class MyWritable extends stream.Writable { }) m.write(false, assert.ifError) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-properties.js b/test/parallel/test-stream-writable-properties.js index 80ed31463..b92668763 100644 --- a/test/parallel/test-stream-writable-properties.js +++ b/test/parallel/test-stream-writable-properties.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { Writable } = require('../../lib/ours/index') - { const w = new Writable() assert.strictEqual(w.writableCorked, 0) @@ -29,8 +24,8 @@ const { Writable } = require('../../lib/ours/index') w.uncork() assert.strictEqual(w.writableCorked, 0) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-samecb-singletick.js b/test/parallel/test-stream-writable-samecb-singletick.js index bb3cf482f..e6b0f162d 100644 --- a/test/parallel/test-stream-writable-samecb-singletick.js +++ b/test/parallel/test-stream-writable-samecb-singletick.js @@ -1,19 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Console } = require('console') - const { Writable } = require('../../lib/ours/index') +const async_hooks = require('async_hooks') -const async_hooks = require('async_hooks') // Make sure that repeated calls to silentConsole.log(), and by extension +// Make sure that repeated calls to silentConsole.log(), and by extension // stream.write() for the underlying stream, allocate exactly 1 tick object. // At the time of writing, that is enough to ensure a flat memory profile // from repeated silentConsole.log() calls, rather than having callbacks pile up @@ -36,17 +33,15 @@ const console = new Console( }, 100) }) ) - for (let i = 0; i < 100; i++) console.log(i) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { hook.disable() }) /* replacement end */ /* replacement start */ - process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-writable.js b/test/parallel/test-stream-writable-writable.js index d5918c242..66d46fdab 100644 --- a/test/parallel/test-stream-writable-writable.js +++ b/test/parallel/test-stream-writable-writable.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Writable } = require('../../lib/ours/index') - { const w = new Writable({ write() {} @@ -52,8 +47,8 @@ const { Writable } = require('../../lib/ours/index') w.end() assert.strictEqual(w.writable, false) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-write-cb-error.js b/test/parallel/test-stream-writable-write-cb-error.js index 9d505f159..f14e4da48 100644 --- a/test/parallel/test-stream-writable-write-cb-error.js +++ b/test/parallel/test-stream-writable-write-cb-error.js @@ -1,23 +1,21 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable } = require('../../lib/ours/index') +const assert = require('assert') -const assert = require('assert') // Ensure callback is always invoked before +// Ensure callback is always invoked before // error is emitted. Regardless if error was // sync or async. { - let callbackCalled = false // Sync Error - + let callbackCalled = false + // Sync Error const writable = new Writable({ write: common.mustCall((buf, enc, cb) => { cb(new Error()) @@ -37,8 +35,8 @@ const assert = require('assert') // Ensure callback is always invoked before ) } { - let callbackCalled = false // Async Error - + let callbackCalled = false + // Async Error const writable = new Writable({ write: common.mustCall((buf, enc, cb) => { process.nextTick(cb, new Error()) @@ -65,14 +63,13 @@ const assert = require('assert') // Ensure callback is always invoked before }) }) writable.on('error', common.mustCall()) - let cnt = 0 // Ensure we don't live lock on sync error - + let cnt = 0 + // Ensure we don't live lock on sync error while (writable.write('a')) cnt++ - assert.strictEqual(cnt, 0) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-write-cb-twice.js b/test/parallel/test-stream-writable-write-cb-twice.js index b66f28153..b2b6ff698 100644 --- a/test/parallel/test-stream-writable-write-cb-twice.js +++ b/test/parallel/test-stream-writable-write-cb-twice.js @@ -1,16 +1,12 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable } = require('../../lib/ours/index') - { // Sync + Sync const writable = new Writable({ @@ -66,8 +62,8 @@ const { Writable } = require('../../lib/ours/index') }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-write-error.js b/test/parallel/test-stream-writable-write-error.js index 248a79096..2ba22f083 100644 --- a/test/parallel/test-stream-writable-write-error.js +++ b/test/parallel/test-stream-writable-write-error.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Writable } = require('../../lib/ours/index') - function expectError(w, args, code, sync) { if (sync) { if (code) { @@ -43,12 +38,10 @@ function expectError(w, args, code, sync) { ) } } - function test(autoDestroy) { { const w = new Writable({ autoDestroy, - _write() {} }) w.end() @@ -57,7 +50,6 @@ function test(autoDestroy) { { const w = new Writable({ autoDestroy, - _write() {} }) w.destroy() @@ -65,7 +57,6 @@ function test(autoDestroy) { { const w = new Writable({ autoDestroy, - _write() {} }) expectError(w, [null], 'ERR_STREAM_NULL_VALUES', true) @@ -73,7 +64,6 @@ function test(autoDestroy) { { const w = new Writable({ autoDestroy, - _write() {} }) expectError(w, [{}], 'ERR_INVALID_ARG_TYPE', true) @@ -82,17 +72,15 @@ function test(autoDestroy) { const w = new Writable({ decodeStrings: false, autoDestroy, - _write() {} }) expectError(w, ['asd', 'noencoding'], 'ERR_UNKNOWN_ENCODING', true) } } - test(false) test(true) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writable-write-writev-finish.js b/test/parallel/test-stream-writable-write-writev-finish.js index d6cd55a39..77e782355 100644 --- a/test/parallel/test-stream-writable-write-writev-finish.js +++ b/test/parallel/test-stream-writable-write-writev-finish.js @@ -1,26 +1,22 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') +const stream = require('../../lib/ours/index') -const stream = require('../../lib/ours/index') // Ensure consistency between the finish event when using cork() +// Ensure consistency between the finish event when using cork() // and writev and when not using them { const writable = new stream.Writable() - writable._write = (chunks, encoding, cb) => { cb(new Error('write test error')) } - writable.on('finish', common.mustNotCall()) writable.on('prefinish', common.mustNotCall()) writable.on( @@ -33,11 +29,9 @@ const stream = require('../../lib/ours/index') // Ensure consistency between the } { const writable = new stream.Writable() - writable._write = (chunks, encoding, cb) => { setImmediate(cb, new Error('write test error')) } - writable.on('finish', common.mustNotCall()) writable.on('prefinish', common.mustNotCall()) writable.on( @@ -50,15 +44,12 @@ const stream = require('../../lib/ours/index') // Ensure consistency between the } { const writable = new stream.Writable() - writable._write = (chunks, encoding, cb) => { cb(new Error('write test error')) } - writable._writev = (chunks, cb) => { cb(new Error('writev test error')) } - writable.on('finish', common.mustNotCall()) writable.on('prefinish', common.mustNotCall()) writable.on( @@ -75,15 +66,12 @@ const stream = require('../../lib/ours/index') // Ensure consistency between the } { const writable = new stream.Writable() - writable._write = (chunks, encoding, cb) => { setImmediate(cb, new Error('write test error')) } - writable._writev = (chunks, cb) => { setImmediate(cb, new Error('writev test error')) } - writable.on('finish', common.mustNotCall()) writable.on('prefinish', common.mustNotCall()) writable.on( @@ -97,50 +85,42 @@ const stream = require('../../lib/ours/index') // Ensure consistency between the setImmediate(function () { writable.end('test') }) -} // Regression test for +} + +// Regression test for // https://github.com/nodejs/node/issues/13812 { const rs = new stream.Readable() rs.push('ok') rs.push(null) - rs._read = () => {} - const ws = new stream.Writable() ws.on('finish', common.mustNotCall()) ws.on('error', common.mustCall()) - ws._write = (chunk, encoding, done) => { setImmediate(done, new Error()) } - rs.pipe(ws) } { const rs = new stream.Readable() rs.push('ok') rs.push(null) - rs._read = () => {} - const ws = new stream.Writable() ws.on('finish', common.mustNotCall()) ws.on('error', common.mustCall()) - ws._write = (chunk, encoding, done) => { done(new Error()) } - rs.pipe(ws) } { const w = new stream.Writable() - w._write = (chunk, encoding, cb) => { process.nextTick(cb) } - w.on('error', common.mustCall()) w.on('finish', common.mustNotCall()) w.on('prefinish', () => { @@ -150,19 +130,17 @@ const stream = require('../../lib/ours/index') // Ensure consistency between the } { const w = new stream.Writable() - w._write = (chunk, encoding, cb) => { process.nextTick(cb) } - w.on('error', common.mustCall()) w.on('finish', () => { w.write("shouldn't write in finish listener") }) w.end() } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writableState-ending.js b/test/parallel/test-stream-writableState-ending.js index 6eaac1958..6b7bd5c3b 100644 --- a/test/parallel/test-stream-writableState-ending.js +++ b/test/parallel/test-stream-writableState-ending.js @@ -1,32 +1,24 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const writable = new stream.Writable() - function testStates(ending, finished, ended) { assert.strictEqual(writable._writableState.ending, ending) assert.strictEqual(writable._writableState.finished, finished) assert.strictEqual(writable._writableState.ended, ended) } - writable._write = (chunk, encoding, cb) => { // Ending, finished, ended start in false. testStates(false, false, false) cb() } - writable.on('finish', () => { // Ending, finished, ended = true. testStates(true, true, true) @@ -34,14 +26,16 @@ writable.on('finish', () => { const result = writable.end('testing function end()', () => { // Ending, finished, ended = true. testStates(true, true, true) -}) // End returns the writable instance +}) -assert.strictEqual(result, writable) // Ending, ended = true. -// finished = false. +// End returns the writable instance +assert.strictEqual(result, writable) +// Ending, ended = true. +// finished = false. testStates(true, false, true) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js b/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js index 99b3a46c7..1f38765e1 100644 --- a/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js +++ b/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const writable = new stream.Writable() writable._writev = common.mustCall((chunks, cb) => { assert.strictEqual(chunks.length, 2) @@ -20,42 +15,48 @@ writable._writev = common.mustCall((chunks, cb) => { }, 1) writable._write = common.mustCall((chunk, encoding, cb) => { cb() -}, 1) // first cork +}, 1) +// first cork writable.cork() assert.strictEqual(writable._writableState.corked, 1) -assert.strictEqual(writable._writableState.bufferedRequestCount, 0) // cork again +assert.strictEqual(writable._writableState.bufferedRequestCount, 0) +// cork again writable.cork() -assert.strictEqual(writable._writableState.corked, 2) // The first chunk is buffered +assert.strictEqual(writable._writableState.corked, 2) +// The first chunk is buffered writable.write('first chunk') -assert.strictEqual(writable._writableState.bufferedRequestCount, 1) // First uncork does nothing +assert.strictEqual(writable._writableState.bufferedRequestCount, 1) +// First uncork does nothing writable.uncork() assert.strictEqual(writable._writableState.corked, 1) assert.strictEqual(writable._writableState.bufferedRequestCount, 1) -process.nextTick(uncork) // The second chunk is buffered, because we uncork at the end of tick +process.nextTick(uncork) +// The second chunk is buffered, because we uncork at the end of tick writable.write('second chunk') assert.strictEqual(writable._writableState.corked, 1) assert.strictEqual(writable._writableState.bufferedRequestCount, 2) - function uncork() { // Second uncork flushes the buffer writable.uncork() assert.strictEqual(writable._writableState.corked, 0) - assert.strictEqual(writable._writableState.bufferedRequestCount, 0) // Verify that end() uncorks correctly + assert.strictEqual(writable._writableState.bufferedRequestCount, 0) + // Verify that end() uncorks correctly writable.cork() writable.write('third chunk') - writable.end() // End causes an uncork() as well + writable.end() + // End causes an uncork() as well assert.strictEqual(writable._writableState.corked, 0) assert.strictEqual(writable._writableState.bufferedRequestCount, 0) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-write-destroy.js b/test/parallel/test-stream-write-destroy.js index 031e4bfdf..1af41d005 100644 --- a/test/parallel/test-stream-write-destroy.js +++ b/test/parallel/test-stream-write-destroy.js @@ -1,17 +1,15 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') +const { Writable } = require('../../lib/ours/index') -const { Writable } = require('../../lib/ours/index') // Test interaction between calling .destroy() on a writable and pending +// Test interaction between calling .destroy() on a writable and pending // writes. for (const withPendingData of [false, true]) { @@ -21,14 +19,12 @@ for (const withPendingData of [false, true]) { write(data, enc, cb) { callbacks.push(cb) }, - // Effectively disable the HWM to observe 'drain' events more easily. highWaterMark: 1 }) let chunksWritten = 0 let drains = 0 w.on('drain', () => drains++) - function onWrite(err) { if (err) { assert.strictEqual(w.destroyed, true) @@ -37,20 +33,17 @@ for (const withPendingData of [false, true]) { chunksWritten++ } } - w.write('abc', onWrite) assert.strictEqual(chunksWritten, 0) assert.strictEqual(drains, 0) callbacks.shift()() assert.strictEqual(chunksWritten, 1) assert.strictEqual(drains, 1) - if (withPendingData) { // Test 2 cases: There either is or is not data still in the write queue. // (The second write will never actually get executed either way.) w.write('def', onWrite) } - if (useEnd) { // Again, test 2 cases: Either we indicate that we want to end the // writable or not. @@ -58,7 +51,6 @@ for (const withPendingData of [false, true]) { } else { w.write('ghi', onWrite) } - assert.strictEqual(chunksWritten, 1) w.destroy() assert.strictEqual(chunksWritten, 1) @@ -68,8 +60,8 @@ for (const withPendingData of [false, true]) { assert.strictEqual(drains, 1) } } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-write-drain.js b/test/parallel/test-stream-write-drain.js index dffbb1827..769cbd641 100644 --- a/test/parallel/test-stream-write-drain.js +++ b/test/parallel/test-stream-write-drain.js @@ -1,28 +1,26 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const { Writable } = require('../../lib/ours/index') -const { Writable } = require('../../lib/ours/index') // Don't emit 'drain' if ended +// Don't emit 'drain' if ended const w = new Writable({ write(data, enc, cb) { process.nextTick(cb) }, - highWaterMark: 1 }) w.on('drain', common.mustNotCall()) w.write('asd') w.end() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-write-final.js b/test/parallel/test-stream-write-final.js index 0b21343a9..ef549dc8b 100644 --- a/test/parallel/test-stream-write-final.js +++ b/test/parallel/test-stream-write-final.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - let shutdown = false const w = new stream.Writable({ final: common.mustCall(function (cb) { @@ -34,8 +29,8 @@ w.on( ) w.write(Buffer.allocUnsafe(1)) w.end(Buffer.allocUnsafe(0)) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream-writev.js b/test/parallel/test-stream-writev.js index 17b91aa47..19c0e2a55 100644 --- a/test/parallel/test-stream-writev.js +++ b/test/parallel/test-stream-writev.js @@ -18,23 +18,18 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const queue = [] - for (let decode = 0; decode < 2; decode++) { for (let uncork = 0; uncork < 2; uncork++) { for (let multi = 0; multi < 2; multi++) { @@ -42,20 +37,16 @@ for (let decode = 0; decode < 2; decode++) { } } } - run() - function run() { const t = queue.pop() if (t) test(t[0], t[1], t[2], run) else silentConsole.log('ok') } - function test(decode, uncork, multi, next) { silentConsole.log(`# decode=${decode} uncork=${uncork} multi=${multi}`) let counter = 0 let expectCount = 0 - function cnt(msg) { expectCount++ const expect = expectCount @@ -65,7 +56,6 @@ function test(decode, uncork, multi, next) { assert.strictEqual(counter, expect) } } - const w = new stream.Writable({ decodeStrings: decode }) @@ -116,7 +106,6 @@ function test(decode, uncork, multi, next) { } ] let actualChunks - w._writev = function (chunks, cb) { actualChunks = chunks.map(function (chunk) { return { @@ -126,7 +115,6 @@ function test(decode, uncork, multi, next) { }) cb() } - w.cork() w.write('hello, ', 'ascii', cnt('hello')) w.write('world', 'utf8', cnt('world')) @@ -144,7 +132,6 @@ function test(decode, uncork, multi, next) { next() }) } - { const w = new stream.Writable({ writev: common.mustCall(function (chunks, cb) { @@ -153,8 +140,8 @@ function test(decode, uncork, multi, next) { }) w.write('asd', common.mustCall()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-base64-single-char-read-end.js b/test/parallel/test-stream2-base64-single-char-read-end.js index afab641d3..df875b828 100644 --- a/test/parallel/test-stream2-base64-single-char-read-end.js +++ b/test/parallel/test-stream2-base64-single-char-read-end.js @@ -18,28 +18,23 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const { Readable: R, Writable: W } = require('../../lib/ours/index') - const assert = require('assert') - const src = new R({ encoding: 'base64' }) const dst = new W() let hasRead = false const accum = [] - src._read = function (n) { if (!hasRead) { hasRead = true @@ -49,12 +44,10 @@ src._read = function (n) { }) } } - dst._write = function (chunk, enc, cb) { accum.push(chunk) cb() } - src.on('end', function () { assert.strictEqual(String(Buffer.concat(accum)), 'MQ==') clearTimeout(timeout) @@ -63,8 +56,8 @@ src.pipe(dst) const timeout = setTimeout(function () { assert.fail('timed out waiting for _write') }, 100) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-basic.js b/test/parallel/test-stream2-basic.js index 81ef6080a..753e97a68 100644 --- a/test/parallel/test-stream2-basic.js +++ b/test/parallel/test-stream2-basic.js @@ -18,23 +18,18 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable: R, Writable: W } = require('../../lib/ours/index') - const assert = require('assert') - const EE = require('events').EventEmitter - class TestReader extends R { constructor(n) { super() @@ -42,19 +37,16 @@ class TestReader extends R { this._pos = 0 this._bufs = 10 } - _read(n) { const max = this._buffer.length - this._pos n = Math.max(n, 0) const toRead = Math.min(n, max) - if (toRead === 0) { // Simulate the read buffer filling up with some more bytes some time // in the future. setTimeout(() => { this._pos = 0 this._bufs -= 1 - if (this._bufs <= 0) { // read them all! if (!this.ended) this.push(null) @@ -67,33 +59,27 @@ class TestReader extends R { }, 10) return } - const ret = this._buffer.slice(this._pos, this._pos + toRead) - this._pos += toRead this.push(ret) } } - class TestWriter extends EE { constructor() { super() this.received = [] this.flush = false } - write(c) { this.received.push(c.toString()) this.emit('write', c) return true } - end(c) { if (c) this.write(c) this.emit('end', this.received) } } - { // Test basic functionality const r = new TestReader(20) @@ -123,17 +109,13 @@ class TestWriter extends EE { }) ) let readSize = 1 - function flow() { let res - while (null !== (res = r.read(readSize++))) { reads.push(res.toString()) } - r.once('readable', flow) } - flow() } { @@ -151,8 +133,9 @@ class TestWriter extends EE { } ;[1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function (SPLIT) { // Verify unpipe - const r = new TestReader(5) // Unpipe after 3 writes, then write to another stream instead. + const r = new TestReader(5) + // Unpipe after 3 writes, then write to another stream instead. let expect = ['xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx'] expect = [expect.slice(0, SPLIT), expect.slice(SPLIT)] const w = [new TestWriter(), new TestWriter()] @@ -207,8 +190,9 @@ class TestWriter extends EE { } ;[1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function (SPLIT) { // Verify multi-unpipe - const r = new TestReader(5) // Unpipe after 3 writes, then write to another stream instead. + const r = new TestReader(5) + // Unpipe after 3 writes, then write to another stream instead. let expect = ['xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx'] expect = [expect.slice(0, SPLIT), expect.slice(SPLIT)] const w = [new TestWriter(), new TestWriter(), new TestWriter()] @@ -253,7 +237,6 @@ class TestWriter extends EE { r.push(['four']) r.push(null) const w1 = new R() - w1.write = function (chunk) { assert.strictEqual(chunk[0], 'one') w1.emit('close') @@ -262,47 +245,38 @@ class TestWriter extends EE { r.pipe(w3) }) } - w1.end = common.mustNotCall() r.pipe(w1) const expected = ['two', 'two', 'three', 'three', 'four', 'four'] const w2 = new R() - w2.write = function (chunk) { assert.strictEqual(chunk[0], expected.shift()) assert.strictEqual(counter, 0) counter++ - if (chunk[0] === 'four') { return true } - setTimeout(function () { counter-- w2.emit('drain') }, 10) return false } - w2.end = common.mustCall() const w3 = new R() - w3.write = function (chunk) { assert.strictEqual(chunk[0], expected.shift()) assert.strictEqual(counter, 1) counter++ - if (chunk[0] === 'four') { return true } - setTimeout(function () { counter-- w3.emit('drain') }, 50) return false } - w3.end = common.mustCall(function () { assert.strictEqual(counter, 2) assert.strictEqual(expected.length, 0) @@ -319,13 +293,11 @@ class TestWriter extends EE { const v = r.read(0) assert.strictEqual(v, null) const w = new R() - w.write = function (buffer) { written = true assert.strictEqual(ended, false) assert.strictEqual(buffer.toString(), 'foo') } - w.end = common.mustCall(function () { ended = true assert.strictEqual(written, true) @@ -336,11 +308,9 @@ class TestWriter extends EE { // Verify synchronous _read ending const r = new R() let called = false - r._read = function (n) { r.push(null) } - r.once('end', function () { // Verify that this is called before the next tick called = true @@ -357,12 +327,10 @@ class TestWriter extends EE { }) let onReadable = false let readCalled = 0 - r._read = function (n) { if (readCalled++ === 2) r.push(null) else r.push(Buffer.from('asdf')) } - r.on('readable', function () { onReadable = true r.read() @@ -406,8 +374,8 @@ class TestWriter extends EE { }) assert.strictEqual(w.writableObjectMode, true) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-compatibility.js b/test/parallel/test-stream2-compatibility.js index c6bbfdb07..590f5817c 100644 --- a/test/parallel/test-stream2-compatibility.js +++ b/test/parallel/test-stream2-compatibility.js @@ -18,23 +18,18 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const { Readable: R, Writable: W } = require('../../lib/ours/index') - const assert = require('assert') - let ondataCalled = 0 - class TestReader extends R { constructor() { super() @@ -43,40 +38,35 @@ class TestReader extends R { ondataCalled++ }) } - _read(n) { this.push(this._buffer) this._buffer = Buffer.alloc(0) } } - const reader = new TestReader() setImmediate(function () { assert.strictEqual(ondataCalled, 1) silentConsole.log('ok') reader.push(null) }) - class TestWriter extends W { constructor() { super() this.write('foo') this.end() } - _write(chunk, enc, cb) { cb() } } - const writer = new TestWriter() process.on('exit', function () { assert.strictEqual(reader.readable, false) assert.strictEqual(writer.writable, false) silentConsole.log('ok') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-decode-partial.js b/test/parallel/test-stream2-decode-partial.js index 3616e3f7a..8ebac01ac 100644 --- a/test/parallel/test-stream2-decode-partial.js +++ b/test/parallel/test-stream2-decode-partial.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const { Readable } = require('../../lib/ours/index') - const assert = require('assert') - let buf = '' const euro = Buffer.from([0xe2, 0x82, 0xac]) const cent = Buffer.from([0xc2, 0xa2]) @@ -30,8 +25,8 @@ readable.on('data', function (data) { process.on('exit', function () { assert.strictEqual(buf, '€¢') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-finish-pipe-error.js b/test/parallel/test-stream2-finish-pipe-error.js index 622f7151b..7e8cbe624 100644 --- a/test/parallel/test-stream2-finish-pipe-error.js +++ b/test/parallel/test-stream2-finish-pipe-error.js @@ -1,34 +1,27 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const stream = require('../../lib/ours/index') - process.on('uncaughtException', common.mustCall()) const r = new stream.Readable() - r._read = function (size) { r.push(Buffer.allocUnsafe(size)) } - const w = new stream.Writable() - w._write = function (data, encoding, cb) { cb(null) } +r.pipe(w) -r.pipe(w) // end() after pipe should cause unhandled exception - +// end() after pipe should cause unhandled exception w.end() -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-finish-pipe.js b/test/parallel/test-stream2-finish-pipe.js index afb5e5a89..d3abfb4e0 100644 --- a/test/parallel/test-stream2-finish-pipe.js +++ b/test/parallel/test-stream2-finish-pipe.js @@ -18,41 +18,35 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const stream = require('../../lib/ours/index') - const r = new stream.Readable() - r._read = function (size) { r.push(Buffer.allocUnsafe(size)) } - const w = new stream.Writable() - w._write = function (data, encoding, cb) { process.nextTick(cb, null) } +r.pipe(w) -r.pipe(w) // end() must be called in nextTick or a WRITE_AFTER_END error occurs. - +// end() must be called in nextTick or a WRITE_AFTER_END error occurs. process.nextTick(() => { // This might sound unrealistic, but it happens in net.js. When // socket.allowHalfOpen === false, EOF will cause .destroySoon() call which // ends the writable side of net.Socket. w.end() }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-httpclient-response-end.js b/test/parallel/test-stream2-httpclient-response-end.js index fbee5912d..a492eb20e 100644 --- a/test/parallel/test-stream2-httpclient-response-end.js +++ b/test/parallel/test-stream2-httpclient-response-end.js @@ -1,18 +1,13 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const http = require('http') - const msg = 'Hello' const server = http .createServer(function (req, res) { @@ -33,7 +28,6 @@ const server = http common.mustCall(function () { silentConsole.log('readable event') let chunk - while ((chunk = res.read()) !== null) { data += chunk } @@ -50,8 +44,8 @@ const server = http } ) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-large-read-stall.js b/test/parallel/test-stream2-large-read-stall.js index e76dedaa7..8208dcdf6 100644 --- a/test/parallel/test-stream2-large-read-stall.js +++ b/test/parallel/test-stream2-large-read-stall.js @@ -18,27 +18,25 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const assert = require('assert') -const assert = require('assert') // If everything aligns so that you do a read(n) of exactly the +// If everything aligns so that you do a read(n) of exactly the // remaining buffer, then make sure that 'end' still emits. const READSIZE = 100 const PUSHSIZE = 20 const PUSHCOUNT = 1000 const HWM = 50 - const Readable = require('../../lib/ours/index').Readable - const r = new Readable({ highWaterMark: HWM }) @@ -47,13 +45,11 @@ r._read = push r.on('readable', function () { silentConsole.error('>> readable') let ret - do { silentConsole.error(` > read(${READSIZE})`) ret = r.read(READSIZE) silentConsole.error(` < ${ret && ret.length} (${rs.length} remain)`) } while (ret && ret.length === READSIZE) - silentConsole.error('<< after read()', ret && ret.length, rs.needReadable, rs.length) }) r.on( @@ -63,20 +59,17 @@ r.on( }) ) let pushes = 0 - function push() { if (pushes > PUSHCOUNT) return - if (pushes++ === PUSHCOUNT) { silentConsole.error(' push(EOF)') return r.push(null) } - silentConsole.error(` push #${pushes}`) if (r.push(Buffer.allocUnsafe(PUSHSIZE))) setTimeout(push, 1) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-objects.js b/test/parallel/test-stream2-objects.js index d6fcf1440..1acd4b641 100644 --- a/test/parallel/test-stream2-objects.js +++ b/test/parallel/test-stream2-objects.js @@ -18,37 +18,30 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable, Writable } = require('../../lib/ours/index') - const assert = require('assert') - function toArray(callback) { const stream = new Writable({ objectMode: true }) const list = [] - stream.write = function (chunk) { list.push(chunk) } - stream.end = common.mustCall(function () { callback(list) }) return stream } - function fromArray(list) { const r = new Readable({ objectMode: true @@ -60,7 +53,6 @@ function fromArray(list) { r.push(null) return r } - { // Verify that objects can be read from the stream const r = fromArray([ @@ -135,12 +127,10 @@ function fromArray(list) { two: '2' } ] - r._read = function (n) { const item = list.shift() r.push(item || null) } - r.pipe( toArray( common.mustCall(function (list) { @@ -169,14 +159,12 @@ function fromArray(list) { two: '2' } ] - r._read = function (n) { const item = list.shift() process.nextTick(function () { r.push(item || null) }) } - r.pipe( toArray( common.mustCall(function (list) { @@ -253,11 +241,9 @@ function fromArray(list) { }) let calls = 0 const list = ['1', '2', '3', '4', '5', '6', '7', '8'] - r._read = function (n) { calls++ } - list.forEach(function (c) { r.push(c) }) @@ -277,7 +263,6 @@ function fromArray(list) { objectMode: true }) r._read = common.mustNotCall() - for (let i = 0; i < 6; i++) { const bool = r.push(i) assert.strictEqual(bool, i !== 5) @@ -288,14 +273,12 @@ function fromArray(list) { const w = new Writable({ objectMode: true }) - w._write = function (chunk, encoding, cb) { assert.deepStrictEqual(chunk, { foo: 'bar' }) cb() } - w.on('finish', common.mustCall()) w.write({ foo: 'bar' @@ -308,12 +291,10 @@ function fromArray(list) { objectMode: true }) const list = [] - w._write = function (chunk, encoding, cb) { list.push(chunk) cb() } - w.on( 'finish', common.mustCall(function () { @@ -333,12 +314,10 @@ function fromArray(list) { objectMode: true }) const list = [] - w._write = function (chunk, encoding, cb) { list.push(chunk) process.nextTick(cb) } - w.on( 'finish', common.mustCall(function () { @@ -358,7 +337,6 @@ function fromArray(list) { objectMode: true }) let called = false - w._write = function (chunk, encoding, cb) { assert.strictEqual(chunk, 'foo') process.nextTick(function () { @@ -366,7 +344,6 @@ function fromArray(list) { cb() }) } - w.on( 'finish', common.mustCall(function () { @@ -376,8 +353,8 @@ function fromArray(list) { w.write('foo') w.end() } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-pipe-error-handling.js b/test/parallel/test-stream2-pipe-error-handling.js index f6fc74204..5f3559b73 100644 --- a/test/parallel/test-stream2-pipe-error-handling.js +++ b/test/parallel/test-stream2-pipe-error-handling.js @@ -18,44 +18,34 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - { let count = 1000 const source = new stream.Readable() - source._read = function (n) { n = Math.min(count, n) count -= n source.push(Buffer.allocUnsafe(n)) } - let unpipedDest - source.unpipe = function (dest) { unpipedDest = dest stream.Readable.prototype.unpipe.call(this, dest) } - const dest = new stream.Writable() - dest._write = function (chunk, encoding, cb) { cb() } - source.pipe(dest) let gotErr = null dest.on('error', function (err) { @@ -74,28 +64,22 @@ const stream = require('../../lib/ours/index') { let count = 1000 const source = new stream.Readable() - source._read = function (n) { n = Math.min(count, n) count -= n source.push(Buffer.allocUnsafe(n)) } - let unpipedDest - source.unpipe = function (dest) { unpipedDest = dest stream.Readable.prototype.unpipe.call(this, dest) } - const dest = new stream.Writable({ autoDestroy: false }) - dest._write = function (chunk, encoding, cb) { cb() } - source.pipe(dest) let unpipedSource dest.on('unpipe', function (src) { @@ -103,19 +87,17 @@ const stream = require('../../lib/ours/index') }) const err = new Error('This stream turned into bacon.') let gotErr = null - try { dest.emit('error', err) } catch (e) { gotErr = e } - assert.strictEqual(gotErr, err) assert.strictEqual(unpipedSource, source) assert.strictEqual(unpipedDest, dest) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-pipe-error-once-listener.js b/test/parallel/test-stream2-pipe-error-once-listener.js index 0158b0544..e4a4a0cd9 100644 --- a/test/parallel/test-stream2-pipe-error-once-listener.js +++ b/test/parallel/test-stream2-pipe-error-once-listener.js @@ -18,33 +18,28 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const stream = require('../../lib/ours/index') - class Read extends stream.Readable { _read(size) { this.push('x') this.push(null) } } - class Write extends stream.Writable { _write(buffer, encoding, cb) { this.emit('error', new Error('boom')) this.emit('alldone') } } - const read = new Read() const write = new Write() write.once('error', () => {}) @@ -55,8 +50,8 @@ process.on('exit', function (c) { silentConsole.error('error thrown even with listener') }) read.pipe(write) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-push.js b/test/parallel/test-stream2-push.js index 4c78fe445..7be29e96b 100644 --- a/test/parallel/test-stream2-push.js +++ b/test/parallel/test-stream2-push.js @@ -18,34 +18,30 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const { Readable, Writable } = require('../../lib/ours/index') +const EE = require('events').EventEmitter -const EE = require('events').EventEmitter // A mock thing a bit like the net.Socket/tcp_wrap.handle interaction +// A mock thing a bit like the net.Socket/tcp_wrap.handle interaction const stream = new Readable({ highWaterMark: 16, encoding: 'utf8' }) const source = new EE() - stream._read = function () { silentConsole.error('stream._read') readStart() } - let ended = false stream.on('end', function () { ended = true @@ -59,12 +55,10 @@ source.on('end', function () { stream.push(null) }) let reading = false - function readStart() { silentConsole.error('readStart') reading = true } - function readStop() { silentConsole.error('readStop') reading = false @@ -73,7 +67,6 @@ function readStop() { if (r !== null) writer.write(r) }) } - const writer = new Writable({ decodeStrings: false }) @@ -86,20 +79,19 @@ const expectWritten = [ 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg' ] - writer._write = function (chunk, encoding, cb) { silentConsole.error(`WRITE ${chunk}`) written.push(chunk) process.nextTick(cb) } +writer.on('finish', finish) -writer.on('finish', finish) // Now emit some chunks. +// Now emit some chunks. const chunk = 'asdfg' let set = 0 readStart() data() - function data() { assert(reading) source.emit('data', chunk) @@ -113,13 +105,11 @@ function data() { if (set++ < 5) setTimeout(data, 10) else end() } - function finish() { silentConsole.error('finish') assert.deepStrictEqual(written, expectWritten) silentConsole.log('ok') } - function end() { source.emit('end') assert(!reading) @@ -128,8 +118,8 @@ function end() { assert(ended) }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-read-sync-stack.js b/test/parallel/test-stream2-read-sync-stack.js index 099a4729b..ce9a7690e 100644 --- a/test/parallel/test-stream2-read-sync-stack.js +++ b/test/parallel/test-stream2-read-sync-stack.js @@ -18,37 +18,35 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') +const Readable = require('../../lib/ours/index').Readable -const Readable = require('../../lib/ours/index').Readable // This tests synchronous read callbacks and verifies that even if they nest +// This tests synchronous read callbacks and verifies that even if they nest // heavily the process handles it without an error const r = new Readable() const N = 256 * 1024 let reads = 0 - r._read = function (n) { const chunk = reads++ === N ? null : Buffer.allocUnsafe(1) r.push(chunk) } - r.on('readable', function onReadable() { if (!(r.readableLength % 256)) silentConsole.error('readable', r.readableLength) r.read(N * 2) }) r.on('end', common.mustCall()) r.read(0) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-readable-empty-buffer-no-eof.js b/test/parallel/test-stream2-readable-empty-buffer-no-eof.js index eda761371..c4aa3b4a1 100644 --- a/test/parallel/test-stream2-readable-empty-buffer-no-eof.js +++ b/test/parallel/test-stream2-readable-empty-buffer-no-eof.js @@ -18,26 +18,23 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const Readable = require('../../lib/ours/index').Readable - test1() test2() - function test1() { - const r = new Readable() // Should not end when we get a Buffer.alloc(0) or '' as the _read + const r = new Readable() + + // Should not end when we get a Buffer.alloc(0) or '' as the _read // result that just means that there is *temporarily* no data, but to // go ahead and try again later. // @@ -49,51 +46,40 @@ function test1() { const buf = Buffer.alloc(5, 'x') let reads = 5 - r._read = function (n) { switch (reads--) { case 5: return setImmediate(() => { return r.push(buf) }) - case 4: setImmediate(() => { return r.push(Buffer.alloc(0)) }) return setImmediate(r.read.bind(r, 0)) - case 3: setImmediate(r.read.bind(r, 0)) return process.nextTick(() => { return r.push(Buffer.alloc(0)) }) - case 2: setImmediate(r.read.bind(r, 0)) return r.push(Buffer.alloc(0)) // Not-EOF! - case 1: return r.push(buf) - case 0: return r.push(null) // EOF - default: throw new Error('unreachable') } } - const results = [] - function flow() { let chunk - while (null !== (chunk = r.read())) results.push(String(chunk)) } - r.on('readable', flow) r.on('end', () => { results.push('EOF') @@ -104,27 +90,20 @@ function test1() { silentConsole.log('ok') }) } - function test2() { const r = new Readable({ encoding: 'base64' }) let reads = 5 - r._read = function (n) { if (!reads--) return r.push(null) // EOF - return r.push(Buffer.from('x')) } - const results = [] - function flow() { let chunk - while (null !== (chunk = r.read())) results.push(String(chunk)) } - r.on('readable', flow) r.on('end', () => { results.push('EOF') @@ -135,8 +114,8 @@ function test2() { silentConsole.log('ok') }) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-readable-from-list.js b/test/parallel/test-stream2-readable-from-list.js index c883c05d2..3d7b2aaea 100644 --- a/test/parallel/test-stream2-readable-from-list.js +++ b/test/parallel/test-stream2-readable-from-list.js @@ -18,105 +18,107 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + // Flags: --expose-internals + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const fromList = require('../../lib/ours/index').Readable._fromList - const BufferList = require('../../lib/internal/streams/buffer_list') - const util = require('util') - function bufferListFromArray(arr) { const bl = new BufferList() - for (let i = 0; i < arr.length; ++i) bl.push(arr[i]) - return bl } - { // Verify behavior with buffers let list = [Buffer.from('foog'), Buffer.from('bark'), Buffer.from('bazy'), Buffer.from('kuel')] list = bufferListFromArray(list) assert.strictEqual(typeof list.head, 'object') assert.strictEqual(typeof list.tail, 'object') - assert.strictEqual(list.length, 4) // Read more than the first element. + assert.strictEqual(list.length, 4) + // Read more than the first element. let ret = fromList(6, { buffer: list, length: 16 }) - assert.strictEqual(ret.toString(), 'foogba') // Read exactly the first element. + assert.strictEqual(ret.toString(), 'foogba') + // Read exactly the first element. ret = fromList(2, { buffer: list, length: 10 }) - assert.strictEqual(ret.toString(), 'rk') // Read less than the first element. + assert.strictEqual(ret.toString(), 'rk') + // Read less than the first element. ret = fromList(2, { buffer: list, length: 8 }) - assert.strictEqual(ret.toString(), 'ba') // Read more than we have. + assert.strictEqual(ret.toString(), 'ba') + // Read more than we have. ret = fromList(100, { buffer: list, length: 6 }) - assert.strictEqual(ret.toString(), 'zykuel') // all consumed. + assert.strictEqual(ret.toString(), 'zykuel') + // all consumed. assert.deepStrictEqual(list, new BufferList()) } { // Verify behavior with strings let list = ['foog', 'bark', 'bazy', 'kuel'] - list = bufferListFromArray(list) // Read more than the first element. + list = bufferListFromArray(list) + // Read more than the first element. let ret = fromList(6, { buffer: list, length: 16, decoder: true }) - assert.strictEqual(ret, 'foogba') // Read exactly the first element. + assert.strictEqual(ret, 'foogba') + // Read exactly the first element. ret = fromList(2, { buffer: list, length: 10, decoder: true }) - assert.strictEqual(ret, 'rk') // Read less than the first element. + assert.strictEqual(ret, 'rk') + // Read less than the first element. ret = fromList(2, { buffer: list, length: 8, decoder: true }) - assert.strictEqual(ret, 'ba') // Read more than we have. + assert.strictEqual(ret, 'ba') + // Read more than we have. ret = fromList(100, { buffer: list, length: 6, decoder: true }) - assert.strictEqual(ret, 'zykuel') // all consumed. + assert.strictEqual(ret, 'zykuel') + // all consumed. assert.deepStrictEqual(list, new BufferList()) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-readable-legacy-drain.js b/test/parallel/test-stream2-readable-legacy-drain.js index a90325aa3..db68158ad 100644 --- a/test/parallel/test-stream2-readable-legacy-drain.js +++ b/test/parallel/test-stream2-readable-legacy-drain.js @@ -18,51 +18,42 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const Stream = require('../../lib/ours/index') - const Readable = Stream.Readable const r = new Readable() const N = 256 let reads = 0 - r._read = function (n) { return r.push(++reads === N ? null : Buffer.allocUnsafe(1)) } - r.on('end', common.mustCall()) const w = new Stream() w.writable = true let buffered = 0 - w.write = function (c) { buffered += c.length process.nextTick(drain) return false } - function drain() { assert(buffered <= 3) buffered = 0 w.emit('drain') } - w.end = common.mustCall() r.pipe(w) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-readable-non-empty-end.js b/test/parallel/test-stream2-readable-non-empty-end.js index bf4245d5f..f99a0a55f 100644 --- a/test/parallel/test-stream2-readable-non-empty-end.js +++ b/test/parallel/test-stream2-readable-non-empty-end.js @@ -18,73 +18,61 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - let len = 0 const chunks = new Array(10) - for (let i = 1; i <= 10; i++) { chunks[i - 1] = Buffer.allocUnsafe(i) len += i } - const test = new Readable() let n = 0 - test._read = function (size) { const chunk = chunks[n++] setTimeout(function () { test.push(chunk === undefined ? null : chunk) }, 1) } - test.on('end', thrower) - function thrower() { throw new Error('this should not happen!') } - let bytesread = 0 test.on('readable', function () { const b = len - bytesread - 1 const res = test.read(b) - if (res) { bytesread += res.length silentConsole.error(`br=${bytesread} len=${len}`) setTimeout(next, 1) } - test.read(0) }) test.read(0) - function next() { // Now let's make 'end' happen test.removeListener('end', thrower) - test.on('end', common.mustCall()) // One to get the last byte + test.on('end', common.mustCall()) + // One to get the last byte let r = test.read() assert(r) assert.strictEqual(r.length, 1) r = test.read() assert.strictEqual(r, null) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-readable-wrap-destroy.js b/test/parallel/test-stream2-readable-wrap-destroy.js index b2c615b65..2b93a9c79 100644 --- a/test/parallel/test-stream2-readable-wrap-destroy.js +++ b/test/parallel/test-stream2-readable-wrap-destroy.js @@ -1,24 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const EE = require('events').EventEmitter - const oldStream = new EE() - oldStream.pause = () => {} - oldStream.resume = () => {} - { new Readable({ autoDestroy: false, @@ -33,8 +25,8 @@ oldStream.resume = () => {} }).wrap(oldStream) oldStream.emit('close') } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-readable-wrap-empty.js b/test/parallel/test-stream2-readable-wrap-empty.js index 3b23b719a..69471dd7f 100644 --- a/test/parallel/test-stream2-readable-wrap-empty.js +++ b/test/parallel/test-stream2-readable-wrap-empty.js @@ -18,32 +18,25 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Readable } = require('../../lib/ours/index') - const EE = require('events').EventEmitter - const oldStream = new EE() - oldStream.pause = () => {} - oldStream.resume = () => {} - const newStream = new Readable().wrap(oldStream) newStream.on('readable', () => {}).on('end', common.mustCall()) oldStream.emit('end') -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-readable-wrap-error.js b/test/parallel/test-stream2-readable-wrap-error.js index 80c4e37c0..e7979406e 100644 --- a/test/parallel/test-stream2-readable-wrap-error.js +++ b/test/parallel/test-stream2-readable-wrap-error.js @@ -1,26 +1,18 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable } = require('../../lib/ours/index') - const EE = require('events').EventEmitter - class LegacyStream extends EE { pause() {} - resume() {} } - { const err = new Error() const oldStream = new LegacyStream() @@ -55,8 +47,8 @@ class LegacyStream extends EE { ) oldStream.emit('error', err) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-readable-wrap.js b/test/parallel/test-stream2-readable-wrap.js index b56629e39..6290b6a9b 100644 --- a/test/parallel/test-stream2-readable-wrap.js +++ b/test/parallel/test-stream2-readable-wrap.js @@ -18,23 +18,18 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable, Writable } = require('../../lib/ours/index') - const EE = require('events').EventEmitter - function runTest(highWaterMark, objectMode, produce) { const old = new EE() const r = new Readable({ @@ -43,17 +38,16 @@ function runTest(highWaterMark, objectMode, produce) { }) assert.strictEqual(r, r.wrap(old)) r.on('end', common.mustCall()) - old.pause = function () { old.emit('pause') flowing = false } - old.resume = function () { old.emit('resume') flow() - } // Make sure pause is only emitted once. + } + // Make sure pause is only emitted once. let pausing = false r.on('pause', () => { assert.strictEqual(pausing, false) @@ -66,33 +60,27 @@ function runTest(highWaterMark, objectMode, produce) { let chunks = 10 let oldEnded = false const expected = [] - function flow() { flowing = true - while (flowing && chunks-- > 0) { const item = produce() expected.push(item) old.emit('data', item) } - if (chunks <= 0) { oldEnded = true old.emit('end') } } - const w = new Writable({ highWaterMark: highWaterMark * 2, objectMode }) const written = [] - w._write = function (chunk, encoding, cb) { written.push(chunk) setTimeout(cb, 1) } - w.on( 'finish', common.mustCall(function () { @@ -101,13 +89,11 @@ function runTest(highWaterMark, objectMode, produce) { ) r.pipe(w) flow() - function performAsserts() { assert(oldEnded) assert.deepStrictEqual(written, expected) } } - runTest(100, false, function () { return Buffer.allocUnsafe(100) }) @@ -136,8 +122,8 @@ const objectChunks = [ runTest(1, true, function () { return objectChunks.shift() }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-set-encoding.js b/test/parallel/test-stream2-set-encoding.js index 59194e4bd..dcff597c5 100644 --- a/test/parallel/test-stream2-set-encoding.js +++ b/test/parallel/test-stream2-set-encoding.js @@ -18,28 +18,23 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { Readable: R } = require('../../lib/ours/index') - class TestReader extends R { constructor(n, opts) { super(opts) this.pos = 0 this.len = n || 100 } - _read(n) { setTimeout(() => { if (this.pos >= this.len) { @@ -47,22 +42,18 @@ class TestReader extends R { this.push(null) return this.push(null) } - n = Math.min(n, this.len - this.pos) - if (n <= 0) { // Double push(null) to test eos handling this.push(null) return this.push(null) } - this.pos += n const ret = Buffer.alloc(n, 'a') return this.push(ret) }, 1) } } - { // Verify utf8 encoding const tr = new TestReader(100) @@ -82,7 +73,6 @@ class TestReader extends R { ] tr.on('readable', function flow() { let chunk - while (null !== (chunk = tr.read(10))) out.push(chunk) }) tr.on( @@ -121,7 +111,6 @@ class TestReader extends R { ] tr.on('readable', function flow() { let chunk - while (null !== (chunk = tr.read(10))) out.push(chunk) }) tr.on( @@ -156,7 +145,6 @@ class TestReader extends R { ] tr.on('readable', function flow() { let chunk - while (null !== (chunk = tr.read(13))) out.push(chunk) }) tr.on( @@ -189,7 +177,6 @@ class TestReader extends R { ] tr.on('readable', function flow() { let chunk - while (null !== (chunk = tr.read(10))) out.push(chunk) }) tr.on( @@ -219,7 +206,6 @@ class TestReader extends R { ] tr.on('readable', function flow() { let chunk - while (null !== (chunk = tr.read(10))) out.push(chunk) }) tr.on( @@ -259,7 +245,6 @@ class TestReader extends R { ] tr.on('readable', function flow() { let chunk - while (null !== (chunk = tr.read(10))) out.push(chunk) }) tr.on( @@ -295,7 +280,6 @@ class TestReader extends R { ] tr.on('readable', function flow() { let chunk - while (null !== (chunk = tr.read(13))) out.push(chunk) }) tr.on( @@ -329,7 +313,6 @@ class TestReader extends R { ] tr.on('readable', function flow() { let chunk - while (null !== (chunk = tr.read(10))) out.push(chunk) }) tr.on( @@ -344,8 +327,8 @@ class TestReader extends R { const tr = new TestReader(100) assert.deepStrictEqual(tr.setEncoding('utf8'), tr) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-transform.js b/test/parallel/test-stream2-transform.js index ac91527cd..cba8b939b 100644 --- a/test/parallel/test-stream2-transform.js +++ b/test/parallel/test-stream2-transform.js @@ -18,38 +18,31 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const { PassThrough, Transform } = require('../../lib/ours/index') - { // Verify writable side consumption const tx = new Transform({ highWaterMark: 10 }) let transformed = 0 - tx._transform = function (chunk, encoding, cb) { transformed += chunk.length tx.push(chunk) cb() } - for (let i = 1; i <= 10; i++) { tx.write(Buffer.allocUnsafe(i)) } - tx.end() assert.strictEqual(tx.readableLength, 10) assert.strictEqual(transformed, 10) @@ -111,13 +104,11 @@ const { PassThrough, Transform } = require('../../lib/ours/index') { // Perform a simple transform const pt = new Transform() - pt._transform = function (c, e, cb) { const ret = Buffer.alloc(c.length, 'x') pt.push(ret) cb() } - pt.write(Buffer.from('foog')) pt.write(Buffer.from('bark')) pt.write(Buffer.from('bazy')) @@ -133,12 +124,10 @@ const { PassThrough, Transform } = require('../../lib/ours/index') const pt = new Transform({ objectMode: true }) - pt._transform = function (c, e, cb) { pt.push(JSON.stringify(c)) cb() } - pt.write(1) pt.write(true) pt.write(false) @@ -160,14 +149,12 @@ const { PassThrough, Transform } = require('../../lib/ours/index') { // Verify async passthrough const pt = new Transform() - pt._transform = function (chunk, encoding, cb) { setTimeout(function () { pt.push(chunk) cb() }, 10) } - pt.write(Buffer.from('foog')) pt.write(Buffer.from('bark')) pt.write(Buffer.from('bazy')) @@ -185,8 +172,9 @@ const { PassThrough, Transform } = require('../../lib/ours/index') } { // Verify asymmetric transform (expand) - const pt = new Transform() // Emit each chunk 2 times. + const pt = new Transform() + // Emit each chunk 2 times. pt._transform = function (chunk, encoding, cb) { setTimeout(function () { pt.push(chunk) @@ -196,7 +184,6 @@ const { PassThrough, Transform } = require('../../lib/ours/index') }, 10) }, 10) } - pt.write(Buffer.from('foog')) pt.write(Buffer.from('bark')) pt.write(Buffer.from('bazy')) @@ -217,33 +204,29 @@ const { PassThrough, Transform } = require('../../lib/ours/index') } { // Verify asymmetric transform (compress) - const pt = new Transform() // Each output is the first char of 3 consecutive chunks, - // or whatever's left. + const pt = new Transform() + // Each output is the first char of 3 consecutive chunks, + // or whatever's left. pt.state = '' - pt._transform = function (chunk, encoding, cb) { if (!chunk) chunk = '' const s = chunk.toString() setTimeout(() => { this.state += s.charAt(0) - if (this.state.length === 3) { pt.push(Buffer.from(this.state)) this.state = '' } - cb() }, 10) } - pt._flush = function (cb) { // Just output whatever we have. pt.push(Buffer.from(this.state)) this.state = '' cb() } - pt.write(Buffer.from('aaaa')) pt.write(Buffer.from('bbbb')) pt.write(Buffer.from('cccc')) @@ -258,8 +241,9 @@ const { PassThrough, Transform } = require('../../lib/ours/index') pt.write(Buffer.from('bbbb')) pt.write(Buffer.from('cccc')) pt.write(Buffer.from('dddd')) - pt.end() // 'abcdeabcdeabcd' + pt.end() + // 'abcdeabcdeabcd' pt.on( 'finish', common.mustCall(function () { @@ -268,9 +252,10 @@ const { PassThrough, Transform } = require('../../lib/ours/index') assert.strictEqual(pt.read(5).toString(), 'abcd') }) ) -} // This tests for a stall when data is written to a full stream -// that has empty transforms. +} +// This tests for a stall when data is written to a full stream +// that has empty transforms. { // Verify complex transform behavior let count = 0 @@ -278,7 +263,6 @@ const { PassThrough, Transform } = require('../../lib/ours/index') const pt = new Transform({ highWaterMark: 3 }) - pt._transform = function (c, e, cb) { if (count++ === 1) saved = c else { @@ -286,12 +270,10 @@ const { PassThrough, Transform } = require('../../lib/ours/index') pt.push(saved) saved = null } - pt.push(c) } cb() } - pt.once('readable', function () { process.nextTick(function () { pt.write(Buffer.from('d')) @@ -402,7 +384,6 @@ const { PassThrough, Transform } = require('../../lib/ours/index') const jp = new Transform({ objectMode: true }) - jp._transform = function (data, encoding, cb) { try { jp.push(JSON.parse(data)) @@ -410,9 +391,10 @@ const { PassThrough, Transform } = require('../../lib/ours/index') } catch (er) { cb(er) } - } // Anything except null/undefined is fine. - // those are "magic" in the stream API, because they signal EOF. + } + // Anything except null/undefined is fine. + // those are "magic" in the stream API, because they signal EOF. const objects = [ { foo: 'bar' @@ -440,8 +422,8 @@ const { PassThrough, Transform } = require('../../lib/ours/index') const res = jp.read() assert.deepStrictEqual(res, obj) }) - jp.end() // Read one more time to get the 'end' event - + jp.end() + // Read one more time to get the 'end' event jp.read() process.nextTick( common.mustCall(function () { @@ -454,7 +436,6 @@ const { PassThrough, Transform } = require('../../lib/ours/index') const js = new Transform({ objectMode: true }) - js._transform = function (data, encoding, cb) { try { js.push(JSON.stringify(data)) @@ -462,9 +443,10 @@ const { PassThrough, Transform } = require('../../lib/ours/index') } catch (er) { cb(er) } - } // Anything except null/undefined is fine. - // those are "magic" in the stream API, because they signal EOF. + } + // Anything except null/undefined is fine. + // those are "magic" in the stream API, because they signal EOF. const objects = [ { foo: 'bar' @@ -492,8 +474,8 @@ const { PassThrough, Transform } = require('../../lib/ours/index') const res = js.read() assert.strictEqual(res, JSON.stringify(obj)) }) - js.end() // Read one more time to get the 'end' event - + js.end() + // Read one more time to get the 'end' event js.read() process.nextTick( common.mustCall(function () { @@ -501,8 +483,8 @@ const { PassThrough, Transform } = require('../../lib/ours/index') }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-unpipe-drain.js b/test/parallel/test-stream2-unpipe-drain.js index 1d2c64e3a..ccae8d202 100644 --- a/test/parallel/test-stream2-unpipe-drain.js +++ b/test/parallel/test-stream2-unpipe-drain.js @@ -18,41 +18,35 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - class TestWriter extends stream.Writable { _write(buffer, encoding, callback) { - silentConsole.log('write called') // Super slow write stream (callback never called) + silentConsole.log('write called') + // Super slow write stream (callback never called) } } const dest = new TestWriter() - class TestReader extends stream.Readable { constructor() { super() this.reads = 0 } - _read(size) { this.reads += 1 this.push(Buffer.alloc(size)) } } - const src1 = new TestReader() const src2 = new TestReader() src1.pipe(dest) @@ -70,8 +64,8 @@ process.on('exit', () => { assert.strictEqual(src1.reads, 2) assert.strictEqual(src2.reads, 2) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-unpipe-leak.js b/test/parallel/test-stream2-unpipe-leak.js index 629c75592..790df11fb 100644 --- a/test/parallel/test-stream2-unpipe-leak.js +++ b/test/parallel/test-stream2-unpipe-leak.js @@ -18,51 +18,42 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const chunk = Buffer.from('hallo') - class TestWriter extends stream.Writable { _write(buffer, encoding, callback) { callback(null) } } +const dest = new TestWriter() -const dest = new TestWriter() // Set this high so that we'd trigger a nextTick warning +// Set this high so that we'd trigger a nextTick warning // and/or RangeError if we do maybeReadMore wrong. - class TestReader extends stream.Readable { constructor() { super({ highWaterMark: 0x10000 }) } - _read(size) { this.push(chunk) } } - const src = new TestReader() - for (let i = 0; i < 10; i++) { src.pipe(dest) src.unpipe(dest) } - assert.strictEqual(src.listeners('end').length, 0) assert.strictEqual(src.listeners('readable').length, 0) assert.strictEqual(dest.listeners('unpipe').length, 0) @@ -77,8 +68,8 @@ process.on('exit', function () { assert(src.readableLength >= src.readableHighWaterMark) silentConsole.log('ok') }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream2-writable.js b/test/parallel/test-stream2-writable.js index 26808e277..2e600650e 100644 --- a/test/parallel/test-stream2-writable.js +++ b/test/parallel/test-stream2-writable.js @@ -18,28 +18,23 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const { Writable: W, Duplex: D } = require('../../lib/ours/index') - const assert = require('assert') - class TestWriter extends W { constructor(opts) { super(opts) this.buffer = [] this.written = 0 } - _write(chunk, encoding, cb) { // Simulate a small unpredictable latency setTimeout(() => { @@ -49,13 +44,10 @@ class TestWriter extends W { }, Math.floor(Math.random() * 10)) } } - const chunks = new Array(50) - for (let i = 0; i < chunks.length; i++) { chunks[i] = 'x'.repeat(i) } - { // Verify fast writing const tw = new TestWriter({ @@ -87,7 +79,6 @@ for (let i = 0; i < chunks.length; i++) { }) ) let i = 0 - ;(function W() { tw.write(chunks[i++]) if (i < chunks.length) setTimeout(W, 10) @@ -112,14 +103,11 @@ for (let i = 0; i < chunks.length; i++) { drains++ }) let i = 0 - ;(function W() { let ret - do { ret = tw.write(chunks[i++]) } while (ret !== false && i < chunks.length) - if (i < chunks.length) { assert(tw.writableLength >= 50) tw.once('drain', W) @@ -163,13 +151,11 @@ for (let i = 0; i < chunks.length; i++) { highWaterMark: 100, decodeStrings: false }) - tw._write = function (chunk, encoding, cb) { assert.strictEqual(typeof chunk, 'string') chunk = Buffer.from(chunk, encoding) return TestWriter.prototype._write.call(this, chunk, encoding, cb) } - const encodings = [ 'hex', 'utf8', @@ -219,8 +205,8 @@ for (let i = 0; i < chunks.length; i++) { process.nextTick( common.mustCall(function () { // Got chunks in the right order - assert.deepStrictEqual(tw.buffer, chunks) // Called all callbacks - + assert.deepStrictEqual(tw.buffer, chunks) + // Called all callbacks assert.deepStrictEqual(callbacks._called, chunks) }) ) @@ -324,7 +310,6 @@ const helloWorldBuffer = Buffer.from('hello world') // Verify stream doesn't end while writing const w = new W() let wrote = false - w._write = function (chunk, e, cb) { assert.strictEqual(this.writing, undefined) wrote = true @@ -334,7 +319,6 @@ const helloWorldBuffer = Buffer.from('hello world') cb() }, 1) } - w.on( 'finish', common.mustCall(function () { @@ -349,14 +333,12 @@ const helloWorldBuffer = Buffer.from('hello world') // Verify finish does not come before write() callback const w = new W() let writeCb = false - w._write = function (chunk, e, cb) { setTimeout(function () { writeCb = true cb() }, 10) } - w.on( 'finish', common.mustCall(function () { @@ -370,11 +352,9 @@ const helloWorldBuffer = Buffer.from('hello world') // Verify finish does not come before synchronous _write() callback const w = new W() let writeCb = false - w._write = function (chunk, e, cb) { cb() } - w.on( 'finish', common.mustCall(function () { @@ -389,11 +369,9 @@ const helloWorldBuffer = Buffer.from('hello world') { // Verify finish is emitted if the last chunk is empty const w = new W() - w._write = function (chunk, e, cb) { process.nextTick(cb) } - w.on('finish', common.mustCall()) w.write(Buffer.allocUnsafe(1)) w.end(Buffer.alloc(0)) @@ -409,11 +387,9 @@ const helloWorldBuffer = Buffer.from('hello world') cb() }, 100) }) - w._write = function (chunk, e, cb) { process.nextTick(cb) } - w.on( 'finish', common.mustCall(function () { @@ -473,19 +449,17 @@ const helloWorldBuffer = Buffer.from('hello world') w._final = common.mustCall(function (cb) { cb(new Error()) }) - w._write = function (chunk, e, cb) { process.nextTick(cb) } - w.on('error', common.mustCall()) w.on('prefinish', common.mustNotCall()) w.on('finish', common.mustNotCall()) w.write(Buffer.allocUnsafe(1)) w.end(Buffer.allocUnsafe(0)) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream3-cork-end.js b/test/parallel/test-stream3-cork-end.js index 861cd5a40..92849640b 100644 --- a/test/parallel/test-stream3-cork-end.js +++ b/test/parallel/test-stream3-cork-end.js @@ -1,19 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') +const Writable = stream.Writable -const Writable = stream.Writable // Test the buffering behavior of Writable streams. +// Test the buffering behavior of Writable streams. // // The call to cork() triggers storing chunks which are flushed // on calling end() and the stream subsequently ended. @@ -24,71 +21,75 @@ const expectedChunks = ['please', 'buffer', 'me', 'kindly'] const inputChunks = expectedChunks.slice(0) let seenChunks = [] let seenEnd = false -const w = new Writable() // Let's arrange to store the chunks. - +const w = new Writable() +// Let's arrange to store the chunks. w._write = function (chunk, encoding, cb) { // Stream end event is not seen before the last write. - assert.ok(!seenEnd) // Default encoding given none was specified. - + assert.ok(!seenEnd) + // Default encoding given none was specified. assert.strictEqual(encoding, 'buffer') seenChunks.push(chunk) cb() -} // Let's record the stream end event. - +} +// Let's record the stream end event. w.on('finish', () => { seenEnd = true }) - function writeChunks(remainingChunks, callback) { const writeChunk = remainingChunks.shift() let writeState - if (writeChunk) { setImmediate(() => { - writeState = w.write(writeChunk) // We were not told to stop writing. - + writeState = w.write(writeChunk) + // We were not told to stop writing. assert.ok(writeState) writeChunks(remainingChunks, callback) }) } else { callback() } -} // Do an initial write. - -w.write('stuff') // The write was immediate. - -assert.strictEqual(seenChunks.length, 1) // Reset the seen chunks. +} -seenChunks = [] // Trigger stream buffering. +// Do an initial write. +w.write('stuff') +// The write was immediate. +assert.strictEqual(seenChunks.length, 1) +// Reset the seen chunks. +seenChunks = [] -w.cork() // Write the bufferedChunks. +// Trigger stream buffering. +w.cork() +// Write the bufferedChunks. writeChunks(inputChunks, () => { // Should not have seen anything yet. - assert.strictEqual(seenChunks.length, 0) // Trigger flush and ending the stream. + assert.strictEqual(seenChunks.length, 0) - w.end() // Stream should not ended in current tick. + // Trigger flush and ending the stream. + w.end() - assert.ok(!seenEnd) // Buffered bytes should be seen in current tick. + // Stream should not ended in current tick. + assert.ok(!seenEnd) - assert.strictEqual(seenChunks.length, 4) // Did the chunks match. + // Buffered bytes should be seen in current tick. + assert.strictEqual(seenChunks.length, 4) + // Did the chunks match. for (let i = 0, l = expectedChunks.length; i < l; i++) { - const seen = seenChunks[i] // There was a chunk. - + const seen = seenChunks[i] + // There was a chunk. assert.ok(seen) - const expected = Buffer.from(expectedChunks[i]) // It was what we expected. - + const expected = Buffer.from(expectedChunks[i]) + // It was what we expected. assert.ok(seen.equals(expected)) } - setImmediate(() => { // Stream should have ended in next tick. assert.ok(seenEnd) }) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream3-cork-uncork.js b/test/parallel/test-stream3-cork-uncork.js index a6940337c..e0a89eddb 100644 --- a/test/parallel/test-stream3-cork-uncork.js +++ b/test/parallel/test-stream3-cork-uncork.js @@ -1,19 +1,16 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') +const Writable = stream.Writable -const Writable = stream.Writable // Test the buffering behavior of Writable streams. +// Test the buffering behavior of Writable streams. // // The call to cork() triggers storing chunks which are flushed // on calling uncork() in the same tick. @@ -24,67 +21,70 @@ const expectedChunks = ['please', 'buffer', 'me', 'kindly'] const inputChunks = expectedChunks.slice(0) let seenChunks = [] let seenEnd = false -const w = new Writable() // Let's arrange to store the chunks. - +const w = new Writable() +// Let's arrange to store the chunks. w._write = function (chunk, encoding, cb) { // Default encoding given none was specified. assert.strictEqual(encoding, 'buffer') seenChunks.push(chunk) cb() -} // Let's record the stream end event. - +} +// Let's record the stream end event. w.on('finish', () => { seenEnd = true }) - function writeChunks(remainingChunks, callback) { const writeChunk = remainingChunks.shift() let writeState - if (writeChunk) { setImmediate(() => { - writeState = w.write(writeChunk) // We were not told to stop writing. - + writeState = w.write(writeChunk) + // We were not told to stop writing. assert.ok(writeState) writeChunks(remainingChunks, callback) }) } else { callback() } -} // Do an initial write. - -w.write('stuff') // The write was immediate. - -assert.strictEqual(seenChunks.length, 1) // Reset the chunks seen so far. +} -seenChunks = [] // Trigger stream buffering. +// Do an initial write. +w.write('stuff') +// The write was immediate. +assert.strictEqual(seenChunks.length, 1) +// Reset the chunks seen so far. +seenChunks = [] -w.cork() // Write the bufferedChunks. +// Trigger stream buffering. +w.cork() +// Write the bufferedChunks. writeChunks(inputChunks, () => { // Should not have seen anything yet. - assert.strictEqual(seenChunks.length, 0) // Trigger writing out the buffer. + assert.strictEqual(seenChunks.length, 0) - w.uncork() // Buffered bytes should be seen in current tick. + // Trigger writing out the buffer. + w.uncork() - assert.strictEqual(seenChunks.length, 4) // Did the chunks match. + // Buffered bytes should be seen in current tick. + assert.strictEqual(seenChunks.length, 4) + // Did the chunks match. for (let i = 0, l = expectedChunks.length; i < l; i++) { - const seen = seenChunks[i] // There was a chunk. - + const seen = seenChunks[i] + // There was a chunk. assert.ok(seen) - const expected = Buffer.from(expectedChunks[i]) // It was what we expected. - + const expected = Buffer.from(expectedChunks[i]) + // It was what we expected. assert.ok(seen.equals(expected)) } - setImmediate(() => { // The stream should not have been ended. assert.ok(!seenEnd) }) }) -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-stream3-pause-then-read.js b/test/parallel/test-stream3-pause-then-read.js index c62fd3e2d..e5272baa5 100644 --- a/test/parallel/test-stream3-pause-then-read.js +++ b/test/parallel/test-stream3-pause-then-read.js @@ -18,21 +18,17 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const Readable = stream.Readable const Writable = stream.Writable const totalChunks = 100 @@ -43,37 +39,30 @@ const r = new Readable({ highWaterMark: 1000 }) let chunks = totalChunks - r._read = function (n) { silentConsole.log('_read called', chunks) if (!(chunks % 2)) setImmediate(push) else if (!(chunks % 3)) process.nextTick(push) else push() } - let totalPushed = 0 - function push() { const chunk = chunks-- > 0 ? Buffer.alloc(chunkSize, 'x') : null - if (chunk) { totalPushed += chunk.length } - silentConsole.log('chunks', chunks) r.push(chunk) } +read100() -read100() // First we read 100 bytes. - +// First we read 100 bytes. function read100() { readn(100, onData) } - function readn(n, then) { silentConsole.error(`read ${n}`) expectEndingData -= n - ;(function read() { const c = r.read(n) silentConsole.error('c', c) @@ -84,33 +73,34 @@ function readn(n, then) { then() } })() -} // Then we listen to some data events. +} +// Then we listen to some data events. function onData() { expectEndingData -= 100 silentConsole.error('onData') let seen = 0 r.on('data', function od(c) { seen += c.length - if (seen >= 100) { // Seen enough r.removeListener('data', od) r.pause() - if (seen > 100) { // Oh no, seen too much! // Put the extra back. const diff = seen - 100 r.unshift(c.slice(c.length - diff)) silentConsole.error('seen too much', seen, diff) - } // Nothing should be lost in-between. + } + // Nothing should be lost in-between. setImmediate(pipeLittle) } }) -} // Just pipe 200 bytes, then unshift the extra and unpipe. +} +// Just pipe 200 bytes, then unshift the extra and unpipe. function pipeLittle() { expectEndingData -= 200 silentConsole.error('pipe a little') @@ -120,15 +110,12 @@ function pipeLittle() { assert.strictEqual(written, 200) setImmediate(read1234) }) - w._write = function (chunk, encoding, cb) { written += chunk.length - if (written >= 200) { r.unpipe(w) w.end() cb() - if (written > 200) { const diff = written - 200 written -= diff @@ -138,17 +125,16 @@ function pipeLittle() { setImmediate(cb) } } - r.pipe(w) -} // Now read 1234 more bytes. +} +// Now read 1234 more bytes. function read1234() { readn(1234, resumePause) } - function resumePause() { - silentConsole.error('resumePause') // Don't read anything, just resume and re-pause a whole bunch. - + silentConsole.error('resumePause') + // Don't read anything, just resume and re-pause a whole bunch. r.resume() r.pause() r.resume() @@ -161,17 +147,14 @@ function resumePause() { r.pause() setImmediate(pipe) } - function pipe() { silentConsole.error('pipe the rest') const w = new Writable() let written = 0 - w._write = function (chunk, encoding, cb) { written += chunk.length cb() } - w.on('finish', () => { silentConsole.error('written', written, totalPushed) assert.strictEqual(written, expectEndingData) @@ -180,8 +163,8 @@ function pipe() { }) r.pipe(w) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded') diff --git a/test/parallel/test-streams-highwatermark.js b/test/parallel/test-streams-highwatermark.js index ab8b49999..1ff481e5c 100644 --- a/test/parallel/test-streams-highwatermark.js +++ b/test/parallel/test-streams-highwatermark.js @@ -1,24 +1,19 @@ 'use strict' const tap = require('tap') - const silentConsole = { log() {}, - error() {} } const common = require('../common') - const assert = require('assert') - const stream = require('../../lib/ours/index') - const { inspect } = require('util') - { // This test ensures that the stream implementation correctly handles values // for highWaterMark which exceed the range of signed 32 bit integers and // rejects invalid values. + // This number exceeds the range of 32 bit integer arithmetic but should still // be handled correctly. const ovfl = Number.MAX_SAFE_INTEGER @@ -30,7 +25,6 @@ const { inspect } = require('util') highWaterMark: ovfl }) assert.strictEqual(writable._writableState.highWaterMark, ovfl) - for (const invalidHwm of [true, false, '5', {}, -5, NaN]) { for (const type of [stream.Readable, stream.Writable]) { assert.throws( @@ -52,10 +46,10 @@ const { inspect } = require('util') // This test ensures that the push method's implementation // correctly handles the edge case where the highWaterMark and // the state.length are both zero + const readable = stream.Readable({ highWaterMark: 0 }) - for (let i = 0; i < 3; i++) { const needMoreData = readable.push() assert.strictEqual(needMoreData, true) @@ -65,6 +59,7 @@ const { inspect } = require('util') // This test ensures that the read(n) method's implementation // correctly handles the edge case where the highWaterMark, state.length // and n are all zero + const readable = stream.Readable({ highWaterMark: 0 }) @@ -96,8 +91,8 @@ const { inspect } = require('util') }) ) } -/* replacement start */ +/* replacement start */ process.on('beforeExit', (code) => { if (code === 0) { tap.pass('test succeeded')