@@ -9,11 +9,13 @@ const {
99 StringPrototypeReplaceAll,
1010 StringPrototypeToUpperCase,
1111 StringPrototypeSplit,
12+ StringPrototypeRepeat,
1213 RegExpPrototypeSymbolReplace,
1314} = primordials ;
1415const { inspectWithNoCustomRetry } = require ( 'internal/errors' ) ;
1516const Readable = require ( 'internal/streams/readable' ) ;
1617const { isError, kEmptyObject } = require ( 'internal/util' ) ;
18+ const kDefaultIndent = ' ' ; // 4 spaces
1719const kFrameStartRegExp = / ^ { 4 } a t / ;
1820const kLineBreakRegExp = / \n | \r \n / ;
1921const kDefaultTAPVersion = 13 ;
@@ -30,8 +32,8 @@ class TapStream extends Readable {
3032 #buffer;
3133 #canPush;
3234
33- constructor ( ) {
34- super ( ) ;
35+ constructor ( options = kEmptyObject ) {
36+ super ( options ) ;
3537 this . #buffer = [ ] ;
3638 this . #canPush = true ;
3739 }
@@ -40,34 +42,30 @@ class TapStream extends Readable {
4042 this . #canPush = true ;
4143
4244 while ( this . #buffer. length > 0 ) {
43- const line = ArrayPrototypeShift ( this . #buffer) ;
45+ const chunk = ArrayPrototypeShift ( this . #buffer) ;
4446
45- if ( ! this . #tryPush( line ) ) {
47+ if ( ! this . #tryPush( chunk ) ) {
4648 return ;
4749 }
4850 }
4951 }
5052
51- bail ( message ) {
52- this . #tryPush( `Bail out!${ message ? ` ${ tapEscape ( message ) } ` : '' } \n` ) ;
53+ fail ( nesting , testNumber , name , details , directive ) {
54+ this . #emit( 'test:fail' , { __proto__ : null , name, nesting, testNumber, details, ...directive } ) ;
55+ this . #test( nesting , testNumber , 'not ok' , name , directive ) ;
56+ this . #details( nesting , details ) ;
5357 }
5458
55- fail ( indent , testNumber , name , details , directive ) {
56- this . emit ( 'test:fail ' , { __proto__ : null , name, testNumber, details, ...directive } ) ;
57- this . #test( indent , testNumber , 'not ok' , name , directive ) ;
58- this . #details( indent , details ) ;
59+ ok ( nesting , testNumber , name , details , directive ) {
60+ this . # emit( 'test:pass ' , { __proto__ : null , name, nesting , testNumber, details, ...directive } ) ;
61+ this . #test( nesting , testNumber , 'ok' , name , directive ) ;
62+ this . #details( nesting , details ) ;
5963 }
6064
61- ok ( indent , testNumber , name , details , directive ) {
62- this . emit ( 'test:pass' , { __proto__ : null , name, testNumber, details, ...directive } ) ;
63- this . #test( indent , testNumber , 'ok' , name , directive ) ;
64- this . #details( indent , details ) ;
65- }
66-
67- plan ( indent , count , explanation ) {
65+ plan ( nesting , count , explanation ) {
6866 const exp = `${ explanation ? ` # ${ tapEscape ( explanation ) } ` : '' } ` ;
6967
70- this . #tryPush ( `${ indent } 1..${ count } ${ exp } \n` ) ;
68+ this . #tryPushString ( `${ this . # indent( nesting ) } 1..${ count } ${ exp } \n` ) ;
7169 }
7270
7371 getSkip ( reason ) {
@@ -78,32 +76,42 @@ class TapStream extends Readable {
7876 return { __proto__ : null , todo : reason } ;
7977 }
8078
81- subtest ( indent , name ) {
82- this . #tryPush( `${ indent } # Subtest: ${ tapEscape ( name ) } \n` ) ;
79+ subtest ( nesting , name ) {
80+ this . #emit( 'test:subtest' , { nesting, name } ) ;
81+ this . #tryPushString( `${ this . #indent( nesting ) } # Subtest: ${ tapEscape ( name ) } \n` ) ;
8382 }
8483
85- #details( indent , data = kEmptyObject ) {
84+ #details( nesting , data = kEmptyObject ) {
8685 const { error, duration, yaml } = data ;
86+ const indent = this . #indent( nesting ) ;
8787 let details = `${ indent } ---\n` ;
8888
8989 details += `${ yaml ? yaml : '' } ` ;
9090 details += jsToYaml ( indent , 'duration_ms' , duration ) ;
9191 details += jsToYaml ( indent , null , error ) ;
9292 details += `${ indent } ...\n` ;
93- this . #tryPush ( details ) ;
93+ this . #tryPushString ( details ) ;
9494 }
9595
96- diagnostic ( indent , message ) {
97- this . emit ( 'test:diagnostic' , message ) ;
98- this . #tryPush ( `${ indent } # ${ tapEscape ( message ) } \n` ) ;
96+ diagnostic ( nesting , message ) {
97+ this . # emit( 'test:diagnostic' , message ) ;
98+ this . #tryPushString ( `${ this . # indent( nesting ) } # ${ tapEscape ( message ) } \n` ) ;
9999 }
100100
101101 version ( spec = kDefaultTAPVersion ) {
102- this . #tryPush( `TAP version ${ spec } \n` ) ;
102+ this . #tryPushString( `TAP version ${ spec } \n` ) ;
103+ }
104+
105+ #indent( nesting ) {
106+ return StringPrototypeRepeat ( kDefaultIndent , nesting ) ;
103107 }
104108
105- #test( indent , testNumber , status , name , directive = kEmptyObject ) {
106- let line = `${ indent } ${ status } ${ testNumber } ` ;
109+ #test( nesting , testNumber , status , name , directive = kEmptyObject ) {
110+ if ( this . _readableState . objectMode ) {
111+ // early return
112+ return ;
113+ }
114+ let line = `${ this . #indent( nesting ) } ${ status } ${ testNumber } ` ;
107115
108116 if ( name ) {
109117 line += ` ${ tapEscape ( `- ${ name } ` ) } ` ;
@@ -115,7 +123,23 @@ class TapStream extends Readable {
115123
116124 line += '\n' ;
117125
118- this . #tryPush( line ) ;
126+ this . #tryPushString( line ) ;
127+ }
128+
129+ #emit( type , data ) {
130+ this . emit ( type , data ) ;
131+ this . #tryPushObject( { type, data } ) ;
132+ }
133+
134+ #tryPushString( str ) {
135+ if ( ! this . _readableState . objectMode ) {
136+ this . #tryPush( str ) ;
137+ }
138+ }
139+ #tryPushObject( obj ) {
140+ if ( this . _readableState . objectMode ) {
141+ this . #tryPush( obj ) ;
142+ }
119143 }
120144
121145 #tryPush( message ) {
@@ -261,4 +285,4 @@ function isAssertionLike(value) {
261285 return value && typeof value === 'object' && 'expected' in value && 'actual' in value ;
262286}
263287
264- module . exports = { TapStream } ;
288+ module . exports = { TapStream, kDefaultIndent } ;
0 commit comments