File tree 2 files changed +57
-16
lines changed
2 files changed +57
-16
lines changed Original file line number Diff line number Diff line change @@ -118,6 +118,50 @@ describe("logger", () => {
118
118
} ) ;
119
119
} ) ;
120
120
121
+ it ( "should not detect duplicate object as circular" , ( ) => {
122
+ const obj : any = { a : "foo" } ;
123
+ const entry : logger . LogEntry = {
124
+ severity : "ERROR" ,
125
+ message : "testing circular" ,
126
+ a : obj ,
127
+ b : obj ,
128
+ } ;
129
+ logger . write ( entry ) ;
130
+ expectStderr ( {
131
+ severity : "ERROR" ,
132
+ message : "testing circular" ,
133
+ a : { a : "foo" } ,
134
+ b : { a : "foo" } ,
135
+ } ) ;
136
+ } ) ;
137
+
138
+ it ( "should not detect duplicate object in array as circular" , ( ) => {
139
+ const obj : any = { a : "foo" } ;
140
+ const arr : any = [
141
+ { a : obj , b : obj } ,
142
+ { a : obj , b : obj } ,
143
+ ] ;
144
+ const entry : logger . LogEntry = {
145
+ severity : "ERROR" ,
146
+ message : "testing circular" ,
147
+ a : arr ,
148
+ b : arr ,
149
+ } ;
150
+ logger . write ( entry ) ;
151
+ expectStderr ( {
152
+ severity : "ERROR" ,
153
+ message : "testing circular" ,
154
+ a : [
155
+ { a : { a : "foo" } , b : { a : "foo" } } ,
156
+ { a : { a : "foo" } , b : { a : "foo" } } ,
157
+ ] ,
158
+ b : [
159
+ { a : { a : "foo" } , b : { a : "foo" } } ,
160
+ { a : { a : "foo" } , b : { a : "foo" } } ,
161
+ ] ,
162
+ } ) ;
163
+ } ) ;
164
+
121
165
it ( "should not break on objects that override toJSON" , ( ) => {
122
166
const obj : any = { a : new Date ( "August 26, 1994 12:24:00Z" ) } ;
123
167
Original file line number Diff line number Diff line change @@ -56,28 +56,25 @@ function removeCircular(obj: any, refs: any[] = []): any {
56
56
if ( typeof obj !== "object" || ! obj ) {
57
57
return obj ;
58
58
}
59
- // If the object defines its own toJSON, prefer that .
60
- if ( obj . toJSON ) {
59
+ // If the object defines its own toJSON method, use it .
60
+ if ( obj . toJSON && typeof obj . toJSON === "function" ) {
61
61
return obj . toJSON ( ) ;
62
62
}
63
- if ( refs . includes ( obj ) ) {
63
+ // Only check for circularity among ancestors in the recursion stack.
64
+ if ( refs . indexOf ( obj ) !== - 1 ) {
64
65
return "[Circular]" ;
65
- } else {
66
- refs . push ( obj ) ;
67
66
}
68
- let returnObj : any ;
69
- if ( Array . isArray ( obj ) ) {
70
- returnObj = new Array ( obj . length ) ;
71
- } else {
72
- returnObj = { } ;
73
- }
74
- for ( const k in obj ) {
75
- if ( refs . includes ( obj [ k ] ) ) {
76
- returnObj [ k ] = "[Circular]" ;
77
- } else {
78
- returnObj [ k ] = removeCircular ( obj [ k ] , refs ) ;
67
+ // Add the current object to the recursion stack.
68
+ refs . push ( obj ) ;
69
+
70
+ let returnObj : any = Array . isArray ( obj ) ? [ ] : { } ;
71
+ for ( const key in obj ) {
72
+ if ( Object . prototype . hasOwnProperty . call ( obj , key ) ) {
73
+ returnObj [ key ] = removeCircular ( obj [ key ] , refs ) ;
79
74
}
80
75
}
76
+ // Remove the current object from the stack once its properties are processed.
77
+ refs . pop ( ) ;
81
78
return returnObj ;
82
79
}
83
80
You can’t perform that action at this time.
0 commit comments