@@ -98,4 +98,69 @@ describe('AST Utils', () => {
9898 expectType < PartialTestNode > ( ( null as unknown ) as ResultType ) ;
9999 expectType < ResultType > ( ( null as unknown ) as PartialTestNode ) ;
100100 } ) ;
101+
102+ test ( 'copyAstNode with trace should add all involved ast nodes to trace' , ( ) => {
103+ interface MyType extends AstNode {
104+ readonly $type : 'MyType' ;
105+ name ?: string ;
106+ singleChild ?: MyType ;
107+ children ?: MyType [ ] ;
108+ buddy ?: Reference < MyType > ;
109+ }
110+
111+ const root : MyType = {
112+ $type : 'MyType' ,
113+ name : 'root' ,
114+ singleChild : {
115+ $type : 'MyType' ,
116+ name : 'singleChild' ,
117+ } ,
118+ children : [
119+ {
120+ $type : 'MyType' ,
121+ name : 'child1' ,
122+ buddy : {
123+ $refText : 'child2' ,
124+ get ref ( ) { return root . children ?. [ 1 ] ; } ,
125+ }
126+ } ,
127+ {
128+ $type : 'MyType' ,
129+ name : 'child2' ,
130+ buddy : {
131+ $refText : 'child1' ,
132+ get ref ( ) { return root . children ?. [ 0 ] ; } ,
133+ }
134+ }
135+ ]
136+ } ;
137+
138+ const trace = new Map < AstNode , AstNode > ( ) ;
139+
140+ // a simple reference builder function that identifies the to be referenced nodes
141+ // based on the trace map and the original reference
142+ // this approach might not work in general because of project-specific details
143+ // but it nicely illustrates the utility of the trace map and also checks it's proper population
144+ const buildReference : Parameters < typeof AstUtils . copyAstNode > [ '1' ] = ( _ , _1 , _2 , _3 , origRef ) => ( {
145+ ...origRef ,
146+ get ref ( ) { return origRef . ref && trace . get ( origRef . ref ) ; }
147+ } ) ;
148+
149+ const copy = AstUtils . copyAstNode ( root , buildReference , trace ) ;
150+
151+ expect ( trace . get ( root ) ) . toBe ( copy ) ;
152+ expect ( trace . get ( copy ) ) . toBe ( root ) ;
153+
154+ expect ( trace . get ( root . singleChild ! ) ) . toBe ( copy . singleChild ) ;
155+ expect ( trace . get ( copy . singleChild ! ) ) . toBe ( root . singleChild ) ;
156+
157+ expect ( trace . get ( root . children ! [ 0 ] ) ) . toBe ( copy . children ! [ 0 ] ) ;
158+ expect ( trace . get ( copy . children ! [ 0 ] ) ) . toBe ( root . children ! [ 0 ] ) ;
159+
160+ expect ( trace . get ( root . children ! [ 1 ] ) ) . toBe ( copy . children ! [ 1 ] ) ;
161+ expect ( trace . get ( copy . children ! [ 1 ] ) ) . toBe ( root . children ! [ 1 ] ) ;
162+
163+ expect ( copy . children ! [ 1 ] . buddy ! . ref ) . toBe ( copy . children ! [ 0 ] ) ;
164+ expect ( copy . children ! [ 0 ] . buddy ! . ref ) . toBe ( copy . children ! [ 1 ] ) ;
165+ } ) ;
101166} ) ;
0 commit comments