@@ -98,4 +98,69 @@ describe('AST Utils', () => {
98
98
expectType < PartialTestNode > ( ( null as unknown ) as ResultType ) ;
99
99
expectType < ResultType > ( ( null as unknown ) as PartialTestNode ) ;
100
100
} ) ;
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
+ } ) ;
101
166
} ) ;
0 commit comments