1
1
import { expect } from 'chai' ;
2
- import * as sinon from 'sinon' ;
3
2
import * as logger from '../src/logger' ;
4
3
5
4
const SUPPORTS_STRUCTURED_LOGS =
@@ -8,52 +7,51 @@ const SUPPORTS_STRUCTURED_LOGS =
8
7
describe ( `logger (${
9
8
SUPPORTS_STRUCTURED_LOGS ? 'structured' : 'unstructured'
10
9
} )`, ( ) => {
11
- let sandbox : sinon . SinonSandbox ;
12
- let stdoutStub : sinon . SinonStub ;
13
- let stderrStub : sinon . SinonStub ;
10
+ let stdoutWrite = process . stdout . write . bind ( process . stdout ) ;
11
+ let stderrWrite = process . stderr . write . bind ( process . stderr ) ;
12
+ let lastOut : string ;
13
+ let lastErr : string ;
14
14
15
15
beforeEach ( ( ) => {
16
- sandbox = sinon . createSandbox ( ) ;
17
- stdoutStub = sandbox . stub ( process . stdout , 'write' ) ;
18
- stderrStub = sandbox . stub ( process . stderr , 'write' ) ;
16
+ process . stdout . write = ( msg : Buffer | string , cb ?: any ) : boolean => {
17
+ lastOut = msg as string ;
18
+ return stdoutWrite ( msg , cb ) ;
19
+ } ;
20
+ process . stderr . write = ( msg : Buffer | string , cb ?: any ) : boolean => {
21
+ lastErr = msg as string ;
22
+ return stderrWrite ( msg , cb ) ;
23
+ } ;
19
24
} ) ;
20
25
21
- function expectOutput ( stdStub : sinon . SinonStub , entry : any ) {
26
+ afterEach ( ( ) => {
27
+ process . stdout . write = stdoutWrite ;
28
+ process . stderr . write = stderrWrite ;
29
+ } ) ;
30
+
31
+ function expectOutput ( last : string , entry : any ) {
22
32
if ( SUPPORTS_STRUCTURED_LOGS ) {
23
- return expect (
24
- JSON . parse ( ( stdStub . getCalls ( ) [ 0 ] . args [ 0 ] as string ) . trim ( ) )
25
- ) . to . deep . eq ( entry ) ;
33
+ return expect ( JSON . parse ( last . trim ( ) ) ) . to . deep . eq ( entry ) ;
26
34
} else {
27
35
// legacy logging is not structured, but do a sanity check
28
- return expect ( stdStub . getCalls ( ) [ 0 ] . args [ 0 ] ) . to . include ( entry . message ) ;
36
+ return expect ( last ) . to . include ( entry . message ) ;
29
37
}
30
38
}
31
39
32
40
function expectStdout ( entry : any ) {
33
- return expectOutput ( stdoutStub , entry ) ;
41
+ return expectOutput ( lastOut , entry ) ;
34
42
}
35
43
36
44
function expectStderr ( entry : any ) {
37
- return expectOutput ( stderrStub , entry ) ;
45
+ return expectOutput ( lastErr , entry ) ;
38
46
}
39
47
40
48
describe ( 'logging methods' , ( ) => {
41
- let writeStub : sinon . SinonStub ;
42
- beforeEach ( ( ) => {
43
- writeStub = sinon . stub ( logger , 'write' ) ;
44
- } ) ;
45
-
46
- afterEach ( ( ) => {
47
- writeStub . restore ( ) ;
48
- } ) ;
49
-
50
49
it ( 'should coalesce arguments into the message' , ( ) => {
51
50
logger . log ( 'hello' , { middle : 'obj' } , 'end message' ) ;
52
51
expectStdout ( {
53
52
severity : 'INFO' ,
54
53
message : "hello { middle: 'obj' } end message" ,
55
54
} ) ;
56
- sandbox . restore ( ) ; // to avoid swallowing test runner output
57
55
} ) ;
58
56
59
57
it ( 'should merge structured data from the last argument' , ( ) => {
@@ -63,7 +61,6 @@ describe(`logger (${
63
61
message : 'hello world' ,
64
62
additional : 'context' ,
65
63
} ) ;
66
- sandbox . restore ( ) ; // to avoid swallowing test runner output
67
64
} ) ;
68
65
69
66
it ( 'should not recognize null as a structured logging object' , ( ) => {
@@ -72,13 +69,46 @@ describe(`logger (${
72
69
severity : 'INFO' ,
73
70
message : 'hello world null' ,
74
71
} ) ;
75
- sandbox . restore ( ) ; // to avoid swallowing test runner output
76
72
} ) ;
77
73
} ) ;
78
74
79
75
describe ( 'write' , ( ) => {
80
76
describe ( 'structured logging' , ( ) => {
81
77
describe ( 'write' , ( ) => {
78
+ it ( 'should remove circular references' , ( ) => {
79
+ const circ : any = { b : 'foo' } ;
80
+ circ . circ = circ ;
81
+
82
+ const entry : logger . LogEntry = {
83
+ severity : 'ERROR' ,
84
+ message : 'testing circular' ,
85
+ circ,
86
+ } ;
87
+ logger . write ( entry ) ;
88
+ expectStderr ( {
89
+ severity : 'ERROR' ,
90
+ message : 'testing circular' ,
91
+ circ : { b : 'foo' , circ : '[Circular]' } ,
92
+ } ) ;
93
+ } ) ;
94
+
95
+ it ( 'should remove circular references in arrays' , ( ) => {
96
+ const circ : any = { b : 'foo' } ;
97
+ circ . circ = [ circ ] ;
98
+
99
+ const entry : logger . LogEntry = {
100
+ severity : 'ERROR' ,
101
+ message : 'testing circular' ,
102
+ circ,
103
+ } ;
104
+ logger . write ( entry ) ;
105
+ expectStderr ( {
106
+ severity : 'ERROR' ,
107
+ message : 'testing circular' ,
108
+ circ : { b : 'foo' , circ : [ '[Circular]' ] } ,
109
+ } ) ;
110
+ } ) ;
111
+
82
112
for ( const severity of [ 'DEBUG' , 'INFO' , 'NOTICE' ] ) {
83
113
it ( `should output ${ severity } severity to stdout` , ( ) => {
84
114
let entry : logger . LogEntry = {
@@ -87,7 +117,6 @@ describe(`logger (${
87
117
} ;
88
118
logger . write ( entry ) ;
89
119
expectStdout ( entry ) ;
90
- sandbox . restore ( ) ; // to avoid swallowing test runner output
91
120
} ) ;
92
121
}
93
122
@@ -105,7 +134,6 @@ describe(`logger (${
105
134
} ;
106
135
logger . write ( entry ) ;
107
136
expectStderr ( entry ) ;
108
- sandbox . restore ( ) ; // to avoid swallowing test runner output
109
137
} ) ;
110
138
}
111
139
} ) ;
0 commit comments