@@ -86,6 +86,65 @@ describe('normalize()', () => {
8686 expect ( normalize ( obj ) ) . toEqual ( { name : 'Alice' , identity : { self : '[Circular ~]' } } ) ;
8787 } ) ;
8888
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+
89148 test ( 'deep circular objects' , ( ) => {
90149 const obj = { name : 'Alice' , child : { name : 'Bob' } } as any ;
91150 obj . child . self = obj . child ;
0 commit comments