@@ -451,64 +451,86 @@ module.exports['Split multipart message with embedded inline message/rfc88'] = t
451451 ) ;
452452} ;
453453
454- module . exports [ 'handles line break lines split into 2 -byte chunks' ] = test => {
454+ module . exports [ 'handles line break lines split into n -byte chunks' ] = async test => {
455455 const message = fs . readFileSync ( __dirname + '/fixtures/original.txt' ) ;
456456
457457 const MAX_HEAD_SIZE = 2 * 1024 * 1024 ;
458- const splitter = new MessageSplitter ( {
459- ignoreEmbedded : true ,
460- maxHeadSize : MAX_HEAD_SIZE
461- } ) ;
462-
463- splitter . on ( 'data' , data => {
464- switch ( data . type ) {
465- case 'node' :
466- // node header block
467- break ;
468- case 'data' :
469- // multipart message structure
470- // this is not related to any specific 'node' block as it includes
471- // everything between the end of some node body and between the next header
472- console . log ( JSON . stringify ( data . value . toString ( ) ) ) ;
473- break ;
474- case 'body' :
475- // Leaf element body. Includes the body for the last 'node' block. You might
476- // have several 'body' calls for a single 'node' block
477- console . log ( JSON . stringify ( data . value . toString ( ) ) ) ;
478- // console.log(data.value.toString());
479- break ;
480- }
481- } ) ;
482458
483459 // Create a Transform stream that processes at most 2 bytes at a time
484- class TwoByteChunker extends Transform {
460+ class NByteChunker extends Transform {
485461 constructor ( options ) {
486462 super ( options ) ;
463+ this . numOfBytes = options . numOfBytes || 2 ;
487464 }
488465
489466 _transform ( chunk , encoding , callback ) {
490- // Process the chunk in 2-byte segments
491- for ( let i = 0 ; i < chunk . length ; i += 2 ) {
492- const twoByteChunk = chunk . slice ( i , i + 2 ) ;
493- // Push each 2-byte chunk to the output
494- this . push ( twoByteChunk ) ;
495- // console.log(`Processing chunk: ${JSON.stringify(twoByteChunk.toString())}`);
467+ // Process the chunk in n-byte segments
468+ for ( let i = 0 ; i < chunk . length ; i += this . numOfBytes ) {
469+ const nByteChunk = chunk . slice ( i , i + this . numOfBytes ) ;
470+ // Push each n-byte chunk to the output
471+ this . push ( nByteChunk ) ;
496472 }
497473 callback ( ) ;
498474 }
499475 }
500476
501- // Create a source stream with some test data
502- const source = Readable . from ( message ) ;
503-
504- console . log ( JSON . stringify ( message . toString ( ) ) ) ; // Log raw message string for reference
505-
506- // Pipe through our chunker
507- const chunker = new TwoByteChunker ( ) ;
477+ for ( let i = 1 ; i <= 11 ; i ++ ) {
478+ // 1 - 11 byte chunks
479+ const splitter = new MessageSplitter ( {
480+ ignoreEmbedded : true ,
481+ maxHeadSize : MAX_HEAD_SIZE
482+ } ) ;
483+
484+ // Pipe through our chunker
485+ const chunker = new NByteChunker ( { numOfBytes : i } ) ;
486+
487+ // Create a source stream with some test data
488+ const source = Readable . from ( message ) ;
489+
490+ source . pipe ( chunker ) . pipe ( splitter ) ;
491+
492+ const collectedLines = [ ] ;
493+
494+ splitter . on ( 'data' , data => {
495+ switch ( data . type ) {
496+ case 'node' :
497+ // node header block
498+ break ;
499+ case 'data' :
500+ // multipart message structure
501+ // this is not related to any specific 'node' block as it includes
502+ // everything between the end of some node body and between the next header
503+ collectedLines . push ( JSON . stringify ( data . value . toString ( ) ) ) ;
504+ break ;
505+ case 'body' :
506+ // Leaf element body. Includes the body for the last 'node' block. You might
507+ // have several 'body' calls for a single 'node' block
508+ collectedLines . push ( JSON . stringify ( data . value . toString ( ) ) ) ;
509+ break ;
510+ }
511+ } ) ;
512+
513+ // eslint-disable-next-line no-await-in-loop
514+ await new Promise ( resolve => {
515+ splitter . on ( 'end' , ( ) => resolve ( ) ) ;
516+ } ) ; // Wait until splitter is done
517+
518+ for ( const str of collectedLines ) {
519+ // Check for lone \r or \n (without \r\n)
520+ test . equal ( str . includes ( '\r' ) && ! str . includes ( '\r\n' ) , false ) ;
521+ test . equal ( str . includes ( '\n' ) && ! str . includes ( '\r\n' ) , false ) ;
522+
523+ if ( ! str . includes ( '\r\n' ) ) {
524+ // no CRLF
525+ test . equal ( ! str . includes ( '\r' ) && ! str . includes ( '\r\n' ) , true ) ;
526+ test . equal ( ! str . includes ( '\n' ) && ! str . includes ( '\r\n' ) , true ) ;
527+ continue ;
528+ }
508529
509- source . pipe ( chunker ) . pipe ( splitter ) ;
530+ test . equal ( str . includes ( '\r\n' ) , true ) ; // has CRLF
531+ }
532+ }
510533
511- test . expect ( 0 ) ;
512534 test . done ( ) ;
513535} ;
514536
0 commit comments