@ -20,49 +20,13 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict' ;
'use strict' ;
require ( '../common' ) ;
const common = require ( '../common' ) ;
const assert = require ( 'assert' ) ;
const assert = require ( 'assert' ) ;
const PassThrough = require ( '_stream_passthrough' ) ;
const PassThrough = require ( '_stream_passthrough' ) ;
const Transform = require ( '_stream_transform' ) ;
const Transform = require ( '_stream_transform' ) ;
// tiny node-tap lookalike.
{
const tests = [ ] ;
// Verify writable side consumption
let count = 0 ;
function test ( name , fn ) {
count ++ ;
tests . push ( [ name , fn ] ) ;
}
function run ( ) {
const next = tests . shift ( ) ;
if ( ! next )
return console . error ( 'ok' ) ;
const name = next [ 0 ] ;
const fn = next [ 1 ] ;
console . log ( '# %s' , name ) ;
fn ( {
same : assert . deepStrictEqual ,
equal : assert . strictEqual ,
ok : assert ,
end : function ( ) {
count -- ;
run ( ) ;
}
} ) ;
}
// ensure all tests have run
process . on ( 'exit' , function ( ) {
assert . strictEqual ( count , 0 ) ;
} ) ;
process . nextTick ( run ) ;
/////
test ( 'writable side consumption' , function ( t ) {
const tx = new Transform ( {
const tx = new Transform ( {
highWaterMark : 10
highWaterMark : 10
} ) ;
} ) ;
@ -79,17 +43,16 @@ test('writable side consumption', function(t) {
}
}
tx . end ( ) ;
tx . end ( ) ;
t . e qual( tx . _ readableState . length , 10 ) ;
assert . strictE qual( tx . _ readableState . length , 10 ) ;
t . e qual( transformed , 10 ) ;
assert . strictE qual( transformed , 10 ) ;
t . e qual( tx . _ transformState . writechunk . length , 5 ) ;
assert . strictE qual( tx . _ transformState . writechunk . length , 5 ) ;
t . same ( tx . _ writableState . getBuffer ( ) . map ( function ( c ) {
assert . deepStrictEqual ( tx . _ writableState . getBuffer ( ) . map ( function ( c ) {
return c . chunk . length ;
return c . chunk . length ;
} ) , [ 6 , 7 , 8 , 9 , 10 ] ) ;
} ) , [ 6 , 7 , 8 , 9 , 10 ] ) ;
}
t . end ( ) ;
{
} ) ;
// Verify passthrough behavior
test ( 'passthrough' , function ( t ) {
const pt = new PassThrough ( ) ;
const pt = new PassThrough ( ) ;
pt . write ( Buffer . from ( 'foog' ) ) ;
pt . write ( Buffer . from ( 'foog' ) ) ;
@ -98,14 +61,14 @@ test('passthrough', function(t) {
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . end ( ) ;
pt . end ( ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'foogb' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'foogb' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'arkba' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'arkba' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'zykue' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'zykue' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'l' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'l' ) ;
t . end ( ) ;
}
} ) ;
test ( 'object passthrough' , function ( t ) {
{
// Verify object passthrough behavior
const pt = new PassThrough ( { objectMode : true } ) ;
const pt = new PassThrough ( { objectMode : true } ) ;
pt . write ( 1 ) ;
pt . write ( 1 ) ;
@ -117,25 +80,24 @@ test('object passthrough', function(t) {
pt . write ( { a : 'b' } ) ;
pt . write ( { a : 'b' } ) ;
pt . end ( ) ;
pt . end ( ) ;
t . equal ( pt . read ( ) , 1 ) ;
assert . strictEqual ( pt . read ( ) , 1 ) ;
t . equal ( pt . read ( ) , true ) ;
assert . strictEqual ( pt . read ( ) , true ) ;
t . equal ( pt . read ( ) , false ) ;
assert . strictEqual ( pt . read ( ) , false ) ;
t . equal ( pt . read ( ) , 0 ) ;
assert . strictEqual ( pt . read ( ) , 0 ) ;
t . equal ( pt . read ( ) , 'foo' ) ;
assert . strictEqual ( pt . read ( ) , 'foo' ) ;
t . equal ( pt . read ( ) , '' ) ;
assert . strictEqual ( pt . read ( ) , '' ) ;
t . same ( pt . read ( ) , { a : 'b' } ) ;
assert . deepStrictEqual ( pt . read ( ) , { a : 'b' } ) ;
t . end ( ) ;
}
} ) ;
test ( 'passthrough constructor' , function ( t ) {
{
// Verify passthrough constructor behavior
const pt = PassThrough ( ) ;
const pt = PassThrough ( ) ;
assert ( pt instanceof PassThrough ) ;
assert ( pt instanceof PassThrough ) ;
}
t . end ( ) ;
{
} ) ;
// Perform a simple transform
test ( 'simple transform' , function ( t ) {
const pt = new Transform ( ) ;
const pt = new Transform ( ) ;
pt . _ transform = function ( c , e , cb ) {
pt . _ transform = function ( c , e , cb ) {
const ret = Buffer . alloc ( c . length , 'x' ) ;
const ret = Buffer . alloc ( c . length , 'x' ) ;
@ -149,14 +111,14 @@ test('simple transform', function(t) {
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . end ( ) ;
pt . end ( ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'xxxxx' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'xxxxx' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'xxxxx' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'xxxxx' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'xxxxx' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'xxxxx' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'x' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'x' ) ;
t . end ( ) ;
}
} ) ;
test ( 'simple object transform' , function ( t ) {
{
// Verify simple object transform
const pt = new Transform ( { objectMode : true } ) ;
const pt = new Transform ( { objectMode : true } ) ;
pt . _ transform = function ( c , e , cb ) {
pt . _ transform = function ( c , e , cb ) {
pt . push ( JSON . stringify ( c ) ) ;
pt . push ( JSON . stringify ( c ) ) ;
@ -172,17 +134,17 @@ test('simple object transform', function(t) {
pt . write ( { a : 'b' } ) ;
pt . write ( { a : 'b' } ) ;
pt . end ( ) ;
pt . end ( ) ;
t . equal ( pt . read ( ) , '1' ) ;
assert . strictEqual ( pt . read ( ) , '1' ) ;
t . equal ( pt . read ( ) , 'true' ) ;
assert . strictEqual ( pt . read ( ) , 'true' ) ;
t . equal ( pt . read ( ) , 'false' ) ;
assert . strictEqual ( pt . read ( ) , 'false' ) ;
t . equal ( pt . read ( ) , '0' ) ;
assert . strictEqual ( pt . read ( ) , '0' ) ;
t . equal ( pt . read ( ) , '"foo"' ) ;
assert . strictEqual ( pt . read ( ) , '"foo"' ) ;
t . equal ( pt . read ( ) , '""' ) ;
assert . strictEqual ( pt . read ( ) , '""' ) ;
t . equal ( pt . read ( ) , '{"a":"b"}' ) ;
assert . strictEqual ( pt . read ( ) , '{"a":"b"}' ) ;
t . end ( ) ;
}
} ) ;
test ( 'async passthrough' , function ( t ) {
{
// Verify async passthrough
const pt = new Transform ( ) ;
const pt = new Transform ( ) ;
pt . _ transform = function ( chunk , encoding , cb ) {
pt . _ transform = function ( chunk , encoding , cb ) {
setTimeout ( function ( ) {
setTimeout ( function ( ) {
@ -197,16 +159,16 @@ test('async passthrough', function(t) {
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . end ( ) ;
pt . end ( ) ;
pt . on ( 'finish' , function ( ) {
pt . on ( 'finish' , common . mustCall ( function ( ) {
t . equal ( pt . read ( 5 ) . toString ( ) , 'foogb' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'foogb' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'arkba' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'arkba' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'zykue' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'zykue' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'l' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'l' ) ;
t . end ( ) ;
} ) ) ;
} ) ;
}
} ) ;
test ( 'assymetric transform (expand)' , function ( t ) {
{
// Verify assymetric transform (expand)
const pt = new Transform ( ) ;
const pt = new Transform ( ) ;
// emit each chunk 2 times.
// emit each chunk 2 times.
@ -226,19 +188,19 @@ test('assymetric transform (expand)', function(t) {
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . end ( ) ;
pt . end ( ) ;
pt . on ( 'finish' , function ( ) {
pt . on ( 'finish' , common . mustCall ( function ( ) {
t . equal ( pt . read ( 5 ) . toString ( ) , 'foogf' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'foogf' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'oogba' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'oogba' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'rkbar' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'rkbar' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'kbazy' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'kbazy' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'bazyk' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'bazyk' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'uelku' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'uelku' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'el' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'el' ) ;
t . end ( ) ;
} ) ) ;
} ) ;
}
} ) ;
test ( 'assymetric transform (compress)' , function ( t ) {
{
// Verify assymetric trasform (compress)
const pt = new Transform ( ) ;
const pt = new Transform ( ) ;
// each output is the first char of 3 consecutive chunks,
// each output is the first char of 3 consecutive chunks,
@ -283,17 +245,17 @@ test('assymetric transform (compress)', function(t) {
pt . end ( ) ;
pt . end ( ) ;
// 'abcdeabcdeabcd'
// 'abcdeabcdeabcd'
pt . on ( 'finish' , function ( ) {
pt . on ( 'finish' , common . mustCall ( function ( ) {
t . equal ( pt . read ( 5 ) . toString ( ) , 'abcde' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'abcde' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'abcde' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'abcde' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'abcd' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'abcd' ) ;
t . end ( ) ;
} ) ) ;
} ) ;
}
} ) ;
// this tests for a stall when data is written to a full stream
// this tests for a stall when data is written to a full stream
// that has empty transforms.
// that has empty transforms.
test ( 'complex transform' , function ( t ) {
{
// Verify compex transform behavior
let count = 0 ;
let count = 0 ;
let saved = null ;
let saved = null ;
const pt = new Transform ( { highWaterMark : 3 } ) ;
const pt = new Transform ( { highWaterMark : 3 } ) ;
@ -314,118 +276,96 @@ test('complex transform', function(t) {
pt . once ( 'readable' , function ( ) {
pt . once ( 'readable' , function ( ) {
process . nextTick ( function ( ) {
process . nextTick ( function ( ) {
pt . write ( Buffer . from ( 'd' ) ) ;
pt . write ( Buffer . from ( 'd' ) ) ;
pt . write ( Buffer . from ( 'ef' ) , function ( ) {
pt . write ( Buffer . from ( 'ef' ) , common . mustCall ( function ( ) {
pt . end ( ) ;
pt . end ( ) ;
t . end ( ) ;
} ) ) ;
} ) ;
assert . strictEqual ( pt . read ( ) . toString ( ) , 'abcdef' ) ;
t . equal ( pt . read ( ) . toString ( ) , 'abcdef' ) ;
assert . strictEqual ( pt . read ( ) , null ) ;
t . equal ( pt . read ( ) , null ) ;
} ) ;
} ) ;
} ) ;
} ) ;
pt . write ( Buffer . from ( 'abc' ) ) ;
pt . write ( Buffer . from ( 'abc' ) ) ;
} ) ;
}
test ( 'passthrough event emission' , function ( t ) {
{
// Verify passthrough event emission
const pt = new PassThrough ( ) ;
const pt = new PassThrough ( ) ;
let emits = 0 ;
let emits = 0 ;
pt . on ( 'readable' , function ( ) {
pt . on ( 'readable' , function ( ) {
console . error ( '>>> emit readable %d' , emits ) ;
emits ++ ;
emits ++ ;
} ) ;
} ) ;
pt . write ( Buffer . from ( 'foog' ) ) ;
pt . write ( Buffer . from ( 'foog' ) ) ;
console . error ( 'need emit 0' ) ;
pt . write ( Buffer . from ( 'bark' ) ) ;
pt . write ( Buffer . from ( 'bark' ) ) ;
console . error ( 'should have emitted readable now 1 === %d' , emits ) ;
assert . strictEqual ( emits , 1 ) ;
t . equal ( emits , 1 ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'foogb' ) ;
assert . strictEqual ( String ( pt . read ( 5 ) ) , 'null' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'foogb' ) ;
t . equal ( String ( pt . read ( 5 ) ) , 'null' ) ;
console . error ( 'need emit 1' ) ;
pt . write ( Buffer . from ( 'bazy' ) ) ;
pt . write ( Buffer . from ( 'bazy' ) ) ;
console . error ( 'should have emitted, but not again' ) ;
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . write ( Buffer . from ( 'kuel' ) ) ;
console . error ( 'should have emitted readable now 2 === %d' , emits ) ;
assert . strictEqual ( emits , 2 ) ;
t . equal ( emits , 2 ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'arkba' ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'zykue' ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'arkba' ) ;
assert . strictEqual ( pt . read ( 5 ) , null ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'zykue' ) ;
t . equal ( pt . read ( 5 ) , null ) ;
console . error ( 'need emit 2' ) ;
pt . end ( ) ;
pt . end ( ) ;
t . equal ( emits , 3 ) ;
assert . strictEqual ( emits , 3 ) ;
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'l' ) ;
assert . strictEqual ( pt . read ( 5 ) , null ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'l' ) ;
assert . strictEqual ( emits , 3 ) ;
t . equal ( pt . read ( 5 ) , null ) ;
}
console . error ( 'should not have emitted again' ) ;
t . equal ( emits , 3 ) ;
t . end ( ) ;
} ) ;
test ( 'passthrough event emission reordered' , function ( t ) {
{
// Verify passthrough event emission reordering
const pt = new PassThrough ( ) ;
const pt = new PassThrough ( ) ;
let emits = 0 ;
let emits = 0 ;
pt . on ( 'readable' , function ( ) {
pt . on ( 'readable' , function ( ) {
console . error ( 'emit readable' , emits ) ;
emits ++ ;
emits ++ ;
} ) ;
} ) ;
pt . write ( Buffer . from ( 'foog' ) ) ;
pt . write ( Buffer . from ( 'foog' ) ) ;
console . error ( 'need emit 0' ) ;
pt . write ( Buffer . from ( 'bark' ) ) ;
pt . write ( Buffer . from ( 'bark' ) ) ;
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' ) ;
assert . strictEqual ( emits , 1 ) ;
pt . once ( 'readable' , function ( ) {
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'foogb' ) ;
t . e qual ( pt . read ( 5 ) . toString ( ) , 'arkba' ) ;
assert . strictEqual ( pt . read ( 5 ) , null ) ;
t . equal ( pt . read ( 5 ) , null ) ;
pt . once ( 'readable' , common . mustCall ( function ( ) {
assert . strictEqual ( pt . read ( 5 ) . toString ( ) , 'arkba' ) ;
console . error ( 'need emit 2' ) ;
assert . strictEqual ( pt . read ( 5 ) , null ) ;
pt . once ( 'readable' , function ( ) {
t . equal ( pt . read ( 5 ) . toString ( ) , 'zykue' ) ;
pt . once ( 'readable' , common . mustCall ( function ( ) {
t . e qual( pt . read ( 5 ) , null ) ;
assert . strictE qual( pt . read ( 5 ) . toString ( ) , 'zykue' ) ;
pt . once ( 'readable' , function ( ) {
assert . strictEqual ( pt . read ( 5 ) , null ) ;
t . equal ( pt . read ( 5 ) . toString ( ) , 'l' ) ;
pt . once ( 'readable' , common . mustCall ( function ( ) {
t . e qual( pt . read ( 5 ) , null ) ;
assert . strictE qual( pt . read ( 5 ) . toString ( ) , 'l' ) ;
t . equal ( emits , 4 ) ;
assert . strictEqual ( pt . read ( 5 ) , null ) ;
t . end ( ) ;
assert . strictEqual ( emits , 4 ) ;
} ) ;
} ) ) ;
pt . end ( ) ;
pt . end ( ) ;
} ) ;
} ) ) ;
pt . write ( Buffer . from ( 'kuel' ) ) ;
pt . write ( Buffer . from ( 'kuel' ) ) ;
} ) ;
} ) ) ;
pt . write ( Buffer . from ( 'bazy' ) ) ;
pt . write ( Buffer . from ( 'bazy' ) ) ;
} ) ;
}
test ( 'passthrough facaded' , function ( t ) {
{
console . error ( 'passthrough facaded' ) ;
// Verify passthrough facade
const pt = new PassThrough ( ) ;
const pt = new PassThrough ( ) ;
const datas = [ ] ;
const datas = [ ] ;
pt . on ( 'data' , function ( chunk ) {
pt . on ( 'data' , function ( chunk ) {
datas . push ( chunk . toString ( ) ) ;
datas . push ( chunk . toString ( ) ) ;
} ) ;
} ) ;
pt . on ( 'end' , function ( ) {
pt . on ( 'end' , common . mustCall ( function ( ) {
t . same ( datas , [ 'foog' , 'bark' , 'bazy' , 'kuel' ] ) ;
assert . deepStrictEqual ( datas , [ 'foog' , 'bark' , 'bazy' , 'kuel' ] ) ;
t . end ( ) ;
} ) ) ;
} ) ;
pt . write ( Buffer . from ( 'foog' ) ) ;
pt . write ( Buffer . from ( 'foog' ) ) ;
setTimeout ( function ( ) {
setTimeout ( function ( ) {
@ -440,10 +380,10 @@ test('passthrough facaded', function(t) {
} , 10 ) ;
} , 10 ) ;
} , 10 ) ;
} , 10 ) ;
} , 10 ) ;
} , 10 ) ;
} ) ;
}
test ( 'object transform (json parse)' , function ( t ) {
{
console . error ( 'json parse stream' ) ;
// Verify object transform (JSON parse)
const jp = new Transform ( { objectMode : true } ) ;
const jp = new Transform ( { objectMode : true } ) ;
jp . _ transform = function ( data , encoding , cb ) {
jp . _ transform = function ( data , encoding , cb ) {
try {
try {
@ -471,21 +411,20 @@ test('object transform (json parse)', function(t) {
objects . forEach ( function ( obj ) {
objects . forEach ( function ( obj ) {
jp . write ( JSON . stringify ( obj ) ) ;
jp . write ( JSON . stringify ( obj ) ) ;
const res = jp . read ( ) ;
const res = jp . read ( ) ;
t . same ( res , obj ) ;
assert . deepStrictEqual ( res , obj ) ;
} ) ;
} ) ;
jp . end ( ) ;
jp . end ( ) ;
// read one more time to get the 'end' event
// read one more time to get the 'end' event
jp . read ( ) ;
jp . read ( ) ;
process . nextTick ( function ( ) {
process . nextTick ( common . mustCall ( function ( ) {
t . ok ( ended ) ;
assert . strictEqual ( ended , true ) ;
t . end ( ) ;
} ) ) ;
} ) ;
}
} ) ;
test ( 'object transform (json stringify)' , function ( t ) {
{
console . error ( 'json parse stream' ) ;
// Verify object transform (JSON stringify)
const js = new Transform ( { objectMode : true } ) ;
const js = new Transform ( { objectMode : true } ) ;
js . _ transform = function ( data , encoding , cb ) {
js . _ transform = function ( data , encoding , cb ) {
try {
try {
@ -513,15 +452,14 @@ test('object transform (json stringify)', function(t) {
objects . forEach ( function ( obj ) {
objects . forEach ( function ( obj ) {
js . write ( obj ) ;
js . write ( obj ) ;
const res = js . read ( ) ;
const res = js . read ( ) ;
t . e qual( res , JSON . stringify ( obj ) ) ;
assert . strictE qual( res , JSON . stringify ( obj ) ) ;
} ) ;
} ) ;
js . end ( ) ;
js . end ( ) ;
// read one more time to get the 'end' event
// read one more time to get the 'end' event
js . read ( ) ;
js . read ( ) ;
process . nextTick ( function ( ) {
process . nextTick ( common . mustCall ( function ( ) {
t . ok ( ended ) ;
assert . strictEqual ( ended , true ) ;
t . end ( ) ;
} ) ) ;
} ) ;
}
} ) ;