@@ -86,6 +86,65 @@ describe('normalize()', () => {
86
86
expect ( normalize ( obj ) ) . toEqual ( { name : 'Alice' , identity : { self : '[Circular ~]' } } ) ;
87
87
} ) ;
88
88
89
+ test ( 'circular objects with proxy' , ( ) => {
90
+ const obj1 = { name : 'Alice' , child : null } as any ;
91
+ const obj2 = { name : 'John' , child : null } as any ;
92
+
93
+ function getObj1 ( target : any , prop : string | number | symbol ) : any {
94
+ return prop === 'child'
95
+ ? new Proxy ( obj2 , {
96
+ get ( t , p ) {
97
+ return getObj2 ( t , p ) ;
98
+ } ,
99
+ } )
100
+ : target [ prop ] ;
101
+ }
102
+
103
+ function getObj2 ( target : any , prop : string | number | symbol ) : any {
104
+ return prop === 'child'
105
+ ? new Proxy ( obj1 , {
106
+ get ( t , p ) {
107
+ return getObj1 ( t , p ) ;
108
+ } ,
109
+ } )
110
+ : target [ prop ] ;
111
+ }
112
+
113
+ const proxy1 = new Proxy ( obj1 , {
114
+ get ( target , prop ) {
115
+ return getObj1 ( target , prop ) ;
116
+ } ,
117
+ } ) ;
118
+
119
+ const actual = normalize ( proxy1 ) ;
120
+
121
+ // This generates 100 nested objects, as we cannot identify the circular reference since they are dynamic proxies
122
+ // However, this test verifies that we can normalize at all, and do not fail out
123
+ expect ( actual ) . toEqual ( {
124
+ name : 'Alice' ,
125
+ child : { name : 'John' , child : expect . objectContaining ( { name : 'Alice' , child : expect . any ( Object ) } ) } ,
126
+ } ) ;
127
+
128
+ let last = actual ;
129
+ for ( let i = 0 ; i < 99 ; i ++ ) {
130
+ expect ( last ) . toEqual (
131
+ expect . objectContaining ( {
132
+ name : expect . any ( String ) ,
133
+ child : expect . any ( Object ) ,
134
+ } ) ,
135
+ ) ;
136
+ last = last . child ;
137
+ }
138
+
139
+ // Last one is transformed to [Object]
140
+ expect ( last ) . toEqual (
141
+ expect . objectContaining ( {
142
+ name : expect . any ( String ) ,
143
+ child : '[Object]' ,
144
+ } ) ,
145
+ ) ;
146
+ } ) ;
147
+
89
148
test ( 'deep circular objects' , ( ) => {
90
149
const obj = { name : 'Alice' , child : { name : 'Bob' } } as any ;
91
150
obj . child . self = obj . child ;
0 commit comments