StreamSpec
Automatic checking of the Stream implementations.
stream-spec
instruments your stream to verify that it has correct behaviour.
All you need to do to test a stream is to wrap it with stream-spec
, and then pipe
some test data through it.
it's purpose it to make it easy to test user-land streams have correct behavour.
correct stream behaviour illustrated
correct stream behaviour explained
stream api design style
a simple test
using stream-tester
var spec = require('stream-spec')
var tester = require('stream-tester')
spec(stream)
.through({strict: true})
.validateOnExit()
tester.createRandomStream(function () {
return 'line ' + Math.random() + '\n'
}, 1000)
.pipe(stream)
.pipe(tester.createPauseStream())
send 1000 random lines through the stream and check that
it buffers on pause.
types of Stream
Writable (but not readable)
a WritableStream
must implement write
, end
, destroy
and emit 'drain'
if it pauses,
and 'close'
after the stream ends, or is destroyed.
If the stream is sync (does no io) it probably does not need to pause, so the write()
should never equal false
spec(stream)
.writable()
.drainable()
.validateOnExit()
Readable (but not writable)
a ReadableStream
must emit 'data'
, 'end'
, and implement destroy
,
and 'close'
after the stream ends, or is destroyed.
is strongly recommended to implement pause
and resume
If the option {strict: true}
is passed, it means the stream is not allowed to emit
'data'
or 'end'
when the stream is paused.
If the option {end: false}
is passed, then end may not be emitted.
spec(stream)
.readable()
.pausable({strict: true}))
.validateOnExit()
Through (sync writable and readable, aka: 'filter')
A Stream
that is both readable and writable, and where the input is processed and then emitted as output, more or less directly.
Example, zlib. contrast this with duplex stream.
when you call pause()
on a ThroughStream
, it should change it into a paused state on the writable side also,
and write()===false
. Calling resume()
should cause 'drain'
to be emitted eventually.
If the option {strict: true}
is passed, it means the stream is not allowed to emit
'data'
or 'end'
when the stream is paused.
spec(stream)
.through({strict: true})
.validateOnExit()
Duplex
A Stream
that is both readable and writable, but the streams go off to some other place or thing,
and are not coupled directly. The readable and writable side of a DuplexStream
each have their own pause state.
If the option {strict: true}
is passed, it means the stream is not allowed to emit
'data'
or 'end'
when the stream is paused.
spec(stream)
.duplex({strict: true})
.validateOnExit()
other options
spec(stream, name)
spec(stream, {
name: name,
strict: true,
error: true,
error: false,
})