@@ -9,11 +9,13 @@ const {
9
9
StringPrototypeReplaceAll,
10
10
StringPrototypeToUpperCase,
11
11
StringPrototypeSplit,
12
+ StringPrototypeRepeat,
12
13
RegExpPrototypeSymbolReplace,
13
14
} = primordials ;
14
15
const { inspectWithNoCustomRetry } = require ( 'internal/errors' ) ;
15
16
const Readable = require ( 'internal/streams/readable' ) ;
16
17
const { isError, kEmptyObject } = require ( 'internal/util' ) ;
18
+ const kDefaultIndent = ' ' ; // 4 spaces
17
19
const kFrameStartRegExp = / ^ { 4 } a t / ;
18
20
const kLineBreakRegExp = / \n | \r \n / ;
19
21
const kDefaultTAPVersion = 13 ;
@@ -30,8 +32,8 @@ class TapStream extends Readable {
30
32
#buffer;
31
33
#canPush;
32
34
33
- constructor ( ) {
34
- super ( ) ;
35
+ constructor ( options = kEmptyObject ) {
36
+ super ( options ) ;
35
37
this . #buffer = [ ] ;
36
38
this . #canPush = true ;
37
39
}
@@ -40,34 +42,30 @@ class TapStream extends Readable {
40
42
this . #canPush = true ;
41
43
42
44
while ( this . #buffer. length > 0 ) {
43
- const line = ArrayPrototypeShift ( this . #buffer) ;
45
+ const chunk = ArrayPrototypeShift ( this . #buffer) ;
44
46
45
- if ( ! this . #tryPush( line ) ) {
47
+ if ( ! this . #tryPush( chunk ) ) {
46
48
return ;
47
49
}
48
50
}
49
51
}
50
52
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 ) ;
53
57
}
54
58
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 ) ;
59
63
}
60
64
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 ) {
68
66
const exp = `${ explanation ? ` # ${ tapEscape ( explanation ) } ` : '' } ` ;
69
67
70
- this . #tryPush ( `${ indent } 1..${ count } ${ exp } \n` ) ;
68
+ this . #tryPushString ( `${ this . # indent( nesting ) } 1..${ count } ${ exp } \n` ) ;
71
69
}
72
70
73
71
getSkip ( reason ) {
@@ -78,32 +76,42 @@ class TapStream extends Readable {
78
76
return { __proto__ : null , todo : reason } ;
79
77
}
80
78
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` ) ;
83
82
}
84
83
85
- #details( indent , data = kEmptyObject ) {
84
+ #details( nesting , data = kEmptyObject ) {
86
85
const { error, duration, yaml } = data ;
86
+ const indent = this . #indent( nesting ) ;
87
87
let details = `${ indent } ---\n` ;
88
88
89
89
details += `${ yaml ? yaml : '' } ` ;
90
90
details += jsToYaml ( indent , 'duration_ms' , duration ) ;
91
91
details += jsToYaml ( indent , null , error ) ;
92
92
details += `${ indent } ...\n` ;
93
- this . #tryPush ( details ) ;
93
+ this . #tryPushString ( details ) ;
94
94
}
95
95
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` ) ;
99
99
}
100
100
101
101
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 ) ;
103
107
}
104
108
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 } ` ;
107
115
108
116
if ( name ) {
109
117
line += ` ${ tapEscape ( `- ${ name } ` ) } ` ;
@@ -115,7 +123,23 @@ class TapStream extends Readable {
115
123
116
124
line += '\n' ;
117
125
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
+ }
119
143
}
120
144
121
145
#tryPush( message ) {
@@ -261,4 +285,4 @@ function isAssertionLike(value) {
261
285
return value && typeof value === 'object' && 'expected' in value && 'actual' in value ;
262
286
}
263
287
264
- module . exports = { TapStream } ;
288
+ module . exports = { TapStream, kDefaultIndent } ;
0 commit comments