1 unit Antlr.Runtime.Tree.Tests;
2 {
3 
4   Delphi DUnit Test Case
5   ----------------------
6   This unit contains a skeleton test case class generated by the Test Case Wizard.
7   Modify the generated code to correctly setup and call the methods from the unit
8   being tested.
9 
10 }
11 
12 interface
13 
14 uses
15   TestFramework,
16   Antlr.Runtime.Collections,
17   Antlr.Runtime.Tree,
18   Classes,
19   SysUtils,
20   Antlr.Runtime,
21   Antlr.Runtime.Tools;
22 
23 type
24   // Test methods for class ICommonTree
25   TestICommonTree = class(TTestCase)
26   public
27     procedure SetUp; override;
28     procedure TearDown; override;
29   published
30     procedure TestSingleNode;
31     procedure Test4Nodes;
32     procedure TestList;
33     procedure TestList2;
34     procedure TestAddListToExistChildren;
35     procedure TestDupTree;
36     procedure TestBecomeRoot;
37     procedure TestBecomeRoot2;
38     procedure TestBecomeRoot3;
39     procedure TestBecomeRoot5;
40     procedure TestBecomeRoot6;
41     procedure TestReplaceWithNoChildren;
42     procedure TestReplaceWithOneChildren;
43     procedure TestReplaceInMiddle;
44     procedure TestReplaceAtLeft;
45     procedure TestReplaceAtRight;
46     procedure TestReplaceOneWithTwoAtLeft;
47     procedure TestReplaceOneWithTwoAtRight;
48     procedure TestReplaceOneWithTwoInMiddle;
49     procedure TestReplaceTwoWithOneAtLeft;
50     procedure TestReplaceTwoWithOneAtRight;
51     procedure TestReplaceAllWithOne;
52     procedure TestReplaceAllWithTwo;
53   end;
54 
55   // Test methods for class ICommonTreeNodeStream
56   TestICommonTreeNodeStream = class(TTestCase)
57   private
CreateCommonTreeNodeStream(const T: IANTLRInterface)58     function CreateCommonTreeNodeStream(const T: IANTLRInterface): ITreeNodeStream;
GetStringOfEntireStreamContentsWithNodeTypesOnly(59     function GetStringOfEntireStreamContentsWithNodeTypesOnly(
60       const Nodes: ITreeNodeStream): String;
CreateUnBufferedTreeNodeStream(const T: IANTLRInterface)61     function CreateUnBufferedTreeNodeStream(const T: IANTLRInterface): ITreeNodeStream;
62   public
63     procedure SetUp; override;
64     procedure TearDown; override;
65   published
66     procedure TestSingleNode;
67     procedure Test4Nodes;
68     procedure TestList;
69     procedure TestFlatList;
70     procedure TestListWithOneNode;
71     procedure TestAoverB;
72     procedure TestLT;
73     procedure TestMarkRewindEntire;
74     procedure TestMarkRewindInMiddle;
75     procedure TestMarkRewindNested;
76     procedure TestSeek;
77     procedure TestSeekFromStart;
78     procedure TestPushPop;
79     procedure TestNestedPushPop;
80     procedure TestPushPopFromEOF;
81     procedure TestStackStretch;
82     procedure TestBufferOverflow;
83     procedure TestBufferWrap;
84   end;
85 
86   // Test methods for class IRewriteRuleXxxxStream
87   TestIRewriteRuleXxxxStream = class(TTestCase)
88   strict private
CreateTreeAdaptor()89     function CreateTreeAdaptor: ITreeAdaptor;
CreateTree(const Token: IToken)90     function CreateTree(const Token: IToken): ITree;
CreateToken(const TokenType: Integer; const Text: String)91     function CreateToken(const TokenType: Integer; const Text: String): IToken;
CreateTokenList(const Count: Integer)92     function CreateTokenList(const Count: Integer): IList<IToken>;
93   public
94     procedure SetUp; override;
95     procedure TearDown; override;
96   published
97     procedure TestRewriteRuleTokenStreamConstructors;
98     procedure TestRewriteRuleSubtreeStreamConstructors;
99     procedure TestRewriteRuleNodeStreamConstructors;
100 
101     procedure TestRRTokenStreamBehaviourWhileEmpty1;
102     procedure TestRRSubtreeStreamBehaviourWhileEmpty1;
103     procedure TestRRNodeStreamBehaviourWhileEmpty1;
104 
105     procedure TestRRTokenStreamBehaviourWhileEmpty2;
106     procedure TestRRSubtreeStreamBehaviourWhileEmpty2;
107     procedure TestRRNodeStreamBehaviourWhileEmpty2;
108 
109     procedure TestRRTokenStreamBehaviourWhileEmpty3;
110 
111     procedure TestRRTokenStreamBehaviourWithElements;
112     procedure TestRRSubtreeStreamBehaviourWithElements;
113     procedure TestRRNodeStreamBehaviourWithElements;
114   end;
115 
116   // Test methods for class ITreeWizard
117   TestITreeWizard = class(TTestCase)
118   strict private
119     FTokens: TStringArray;
120   strict private
121     type
122       TRecordAllElementsVisitor = class sealed(TTreeWizard.TVisitor)
123       strict private
124         FList: IList<IANTLRInterface>;
125       strict protected
126         procedure Visit(const T: IANTLRInterface); override;
127       public
128         constructor Create(const AList: IList<IANTLRInterface>);
129       end;
130 
131       TTest1ContextVisitor = class sealed(TANTLRObject, IContextVisitor)
132       strict private
133         FAdaptor: ITreeAdaptor;
134         FList: IList<IANTLRInterface>;
135       protected
136         { IContextVisitor }
137         procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer;
138           const Labels: IDictionary<String, IANTLRInterface>);
139       public
140         constructor Create(const AAdaptor: ITreeAdaptor;
141           const AList: IList<IANTLRInterface>);
142       end;
143 
144       TTest2ContextVisitor = class sealed(TANTLRObject, IContextVisitor)
145       strict private
146         FAdaptor: ITreeAdaptor;
147         FList: IList<IANTLRInterface>;
148       protected
149         { IContextVisitor }
150         procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer;
151           const Labels: IDictionary<String, IANTLRInterface>);
152       public
153         constructor Create(const AAdaptor: ITreeAdaptor;
154           const AList: IList<IANTLRInterface>);
155       end;
156   public
157     constructor Create(MethodName: String); override;
158     procedure SetUp; override;
159     procedure TearDown; override;
160   published
161     procedure TestSingleNode;
162     procedure TestSingleNodeWithArg;
163     procedure TestSingleNodeTree;
164     procedure TestSingleLevelTree;
165     procedure TestListTree;
166     procedure TestInvalidListTree;
167     procedure TestDoubleLevelTree;
168     procedure TestSingleNodeIndex;
169     procedure TestNoRepeatsIndex;
170     procedure TestRepeatsIndex;
171     procedure TestNoRepeatsVisit;
172     procedure TestNoRepeatsVisit2;
173     procedure TestRepeatsVisit;
174     procedure TestRepeatsVisit2;
175     procedure TestRepeatsVisitWithContext;
176     procedure TestRepeatsVisitWithNullParentAndContext;
177     procedure TestVisitPattern;
178     procedure TestVisitPatternMultiple;
179     procedure TestVisitPatternMultipleWithLabels;
180     procedure TestParse;
181     procedure TestParseSingleNode;
182     procedure TestParseFlatTree;
183     procedure TestWildcard;
184     procedure TestParseWithText;
185     procedure TestParseWithTextFails;
186     procedure TestParseLabels;
187     procedure TestParseWithWildcardLabels;
188     procedure TestParseLabelsAndTestText;
189     procedure TestParseLabelsInNestedTree;
190     procedure TestEquals;
191     procedure TestEqualsWithText;
192     procedure TestEqualsWithMismatchedText;
193     procedure TestFindPattern;
194   end;
195 
196 implementation
197 
198 procedure TestICommonTree.SetUp;
199 begin
200 end;
201 
202 procedure TestICommonTree.TearDown;
203 begin
204 end;
205 
206 procedure TestICommonTree.Test4Nodes;
207 var
208   R0: ICommonTree;
209 begin
210   // ^(101 ^(102 103) 104)
211   R0 := TCommonTree.Create(TCommonToken.Create(101));
212   R0.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
213   R0.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103)));
214   R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
215   CheckNull(R0.Parent);
216   CheckEquals(R0.ChildIndex,-1);
217 end;
218 
219 procedure TestICommonTree.TestAddListToExistChildren;
220 var
221   Root, R0, C0, C1, C2: ICommonTree;
222 begin
223   // Add child ^(nil 101 102 103) to root ^(5 6)
224   // should add 101 102 103 to end of 5's child list
225   Root := TCommonTree.Create(TCommonToken.Create(5));
226   Root.AddChild(TCommonTree.Create(TCommonToken.Create(6)));
227 
228   // child tree
229   R0 := TCommonTree.Create(IToken(nil));
230   C0 := TCommonTree.Create(TCommonToken.Create(101));
231   C1 := TCommonTree.Create(TCommonToken.Create(102));
232   C2 := TCommonTree.Create(TCommonToken.Create(103));
233   R0.AddChild(C0);
234   R0.AddChild(C1);
235   R0.AddChild(C2);
236 
237   Root.AddChild(R0);
238 
239   CheckNull(Root.Parent);
240   CheckEquals(Root.ChildIndex, -1);
241 
242   // check children of root all point at root
243   Check(C0.Parent = Root);
244   Check(C0.ChildIndex = 1);
245   Check(C1.Parent = Root);
246   Check(C1.ChildIndex = 2);
247   Check(C2.Parent = Root);
248   Check(C2.ChildIndex = 3);
249 end;
250 
251 procedure TestICommonTree.TestBecomeRoot;
252 var
253   OldRoot, NewRoot: ICommonTree;
254   Adaptor: ITreeAdaptor;
255 begin
256   // 5 becomes new root of ^(nil 101 102 103)
257   NewRoot := TCommonTree.Create(TCommonToken.Create(5));
258   OldRoot := TCommonTree.Create(IToken(nil));
259   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(101)));
260   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
261   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
262   Adaptor := TCommonTreeAdaptor.Create;
263   Adaptor.BecomeRoot(NewRoot, OldRoot);
264   NewRoot.SanityCheckParentAndChildIndexes;
265 end;
266 
267 procedure TestICommonTree.TestBecomeRoot2;
268 var
269   OldRoot, NewRoot: ICommonTree;
270   Adaptor: ITreeAdaptor;
271 begin
272   // 5 becomes new root of ^(101 102 103)
273   NewRoot := TCommonTree.Create(TCommonToken.Create(5));
274   OldRoot := TCommonTree.Create(TCommonToken.Create(101));
275   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
276   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
277   Adaptor := TCommonTreeAdaptor.Create;
278   Adaptor.BecomeRoot(NewRoot, OldRoot);
279   NewRoot.SanityCheckParentAndChildIndexes;
280 end;
281 
282 procedure TestICommonTree.TestBecomeRoot3;
283 var
284   OldRoot, NewRoot: ICommonTree;
285   Adaptor: ITreeAdaptor;
286 begin
287   // ^(nil 5) becomes new root of ^(nil 101 102 103)
288   NewRoot := TCommonTree.Create(IToken(nil));
289   NewRoot.AddChild(TCommonTree.Create(TCommonToken.Create(5)));
290   OldRoot := TCommonTree.Create(IToken(nil));
291   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(101)));
292   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
293   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
294   Adaptor := TCommonTreeAdaptor.Create;
295   Adaptor.BecomeRoot(NewRoot, OldRoot);
296   NewRoot.SanityCheckParentAndChildIndexes;
297 end;
298 
299 procedure TestICommonTree.TestBecomeRoot5;
300 var
301   OldRoot, NewRoot: ICommonTree;
302   Adaptor: ITreeAdaptor;
303 begin
304   // ^(nil 5) becomes new root of ^(101 102 103)
305   NewRoot := TCommonTree.Create(IToken(nil));
306   NewRoot.AddChild(TCommonTree.Create(TCommonToken.Create(5)));
307   OldRoot := TCommonTree.Create(TCommonToken.Create(101));
308   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
309   OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
310   Adaptor := TCommonTreeAdaptor.Create;
311   Adaptor.BecomeRoot(NewRoot, OldRoot);
312   NewRoot.SanityCheckParentAndChildIndexes;
313 end;
314 
315 procedure TestICommonTree.TestBecomeRoot6;
316 var
317   Root0, Root1: ICommonTree;
318   Adaptor: ITreeAdaptor;
319 begin
320   // emulates construction of ^(5 6)
321   Adaptor := TCommonTreeAdaptor.Create;
322   Root0 := Adaptor.GetNilNode as ICommonTree;
323   Root1 := Adaptor.GetNilNode as ICommonTree;
324   Root1 := Adaptor.BecomeRoot(TCommonTree.Create(TCommonToken.Create(5)), Root1) as ICommonTree;
325   Adaptor.AddChild(Root1, TCommonTree.Create(TCommonToken.Create(6)));
326   Adaptor.AddChild(Root0, Root1);
327   Root0.SanityCheckParentAndChildIndexes;
328 end;
329 
330 procedure TestICommonTree.TestDupTree;
331 var
332   R0, R1, Dup: ICommonTree;
333   R2: ITree;
334   Adaptor: ICommonTreeAdaptor;
335 begin
336   // ^(101 ^(102 103 ^(106 107) ) 104 105)
337   R0 := TCommonTree.Create(TCommonToken.Create(101));
338   R1 := TCommonTree.Create(TCommonToken.Create(102));
339   R0.AddChild(R1);
340   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
341   R2 := TCommonTree.Create(TCommonToken.Create(106));
342   R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
343   R1.AddChild(R2);
344   R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
345   R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
346 
347   Adaptor := TCommonTreeAdaptor.Create;
348   Dup := Adaptor.DupTree(R0) as ICommonTree;
349 
350   CheckNull(Dup.Parent);
351   CheckEquals(Dup.ChildIndex, -1);
352   Dup.SanityCheckParentAndChildIndexes;
353 end;
354 
355 procedure TestICommonTree.TestList;
356 var
357   R0, C0, C1, C2: ICommonTree;
358 begin
359   // ^(nil 101 102 103)
360   R0 := TCommonTree.Create(IToken(nil));
361   C0 := TCommonTree.Create(TCommonToken.Create(101));
362   C1 := TCommonTree.Create(TCommonToken.Create(102));
363   C2 := TCommonTree.Create(TCommonToken.Create(103));
364   R0.AddChild(C0);
365   R0.AddChild(C1);
366   R0.AddChild(C2);
367 
368   CheckNull(R0.Parent);
369   CheckEquals(R0.ChildIndex, -1);
370   Check(C0.Parent = R0);
371   CheckEquals(C0.ChildIndex, 0);
372   Check(C1.Parent = R0);
373   CheckEquals(C1.ChildIndex, 1);
374   Check(C2.Parent = R0);
375   CheckEquals(C2.ChildIndex, 2);
376 end;
377 
378 procedure TestICommonTree.TestList2;
379 var
380   Root, R0, C0, C1, C2: ICommonTree;
381 begin
382   // Add child ^(nil 101 102 103) to root 5
383   // should pull 101 102 103 directly to become 5's child list
384   Root := TCommonTree.Create(TClassicToken.Create(5));
385 
386   // child tree
387   R0 := TCommonTree.Create(IToken(nil));
388   C0 := TCommonTree.Create(TCommonToken.Create(101));
389   C1 := TCommonTree.Create(TCommonToken.Create(102));
390   C2 := TCommonTree.Create(TCommonToken.Create(103));
391   R0.AddChild(C0);
392   R0.AddChild(C1);
393   R0.AddChild(C2);
394 
395   Root.AddChild(R0);
396 
397   CheckNull(Root.Parent);
398   CheckEquals(Root.ChildIndex, -1);
399 
400   // check children of root all point at root
401   Check(C0.Parent = Root);
402   Check(C0.ChildIndex = 0);
403   Check(C1.Parent = Root);
404   Check(C1.ChildIndex = 1);
405   Check(C2.Parent = Root);
406   Check(C2.ChildIndex = 2);
407 end;
408 
409 procedure TestICommonTree.TestReplaceAllWithOne;
410 var
411   T, NewChild: ICommonTree;
412 begin
413   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
414   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
415   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
416   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
417   NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
418   T.ReplaceChildren(0, 2, NewChild);
419   CheckEquals(T.ToStringTree, '(a x)');
420   T.SanityCheckParentAndChildIndexes;
421 end;
422 
423 procedure TestICommonTree.TestReplaceAllWithTwo;
424 var
425   Adaptor: ITreeAdaptor;
426   T, NewChildren: ICommonTree;
427 begin
428   Adaptor := TCommonTreeAdaptor.Create;
429   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
430   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
431   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
432   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
433   NewChildren := Adaptor.GetNilNode as ICommonTree;
434   NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x')));
435   NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y')));
436   T.ReplaceChildren(0, 2, NewChildren);
437   CheckEquals(T.ToStringTree, '(a x y)');
438   T.SanityCheckParentAndChildIndexes;
439 end;
440 
441 procedure TestICommonTree.TestReplaceAtLeft;
442 var
443   T, NewChild: ICommonTree;
444 begin
445   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
446   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); // index 0
447   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
448   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
449   NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
450   T.ReplaceChildren(0, 0, NewChild);
451   CheckEquals(T.ToStringTree, '(a x c d)');
452   T.SanityCheckParentAndChildIndexes;
453 end;
454 
455 procedure TestICommonTree.TestReplaceAtRight;
456 var
457   T, NewChild: ICommonTree;
458 begin
459   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
460   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
461   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
462   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); // index 2
463   NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
464   T.ReplaceChildren(2, 2, NewChild);
465   CheckEquals(T.ToStringTree, '(a b c x)');
466   T.SanityCheckParentAndChildIndexes;
467 end;
468 
469 procedure TestICommonTree.TestReplaceInMiddle;
470 var
471   T, NewChild: ICommonTree;
472 begin
473   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
474   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
475   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); // index 1
476   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
477   NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
478   T.ReplaceChildren(1, 1, NewChild);
479   CheckEquals(T.ToStringTree, '(a b x d)');
480   T.SanityCheckParentAndChildIndexes;
481 end;
482 
483 procedure TestICommonTree.TestReplaceOneWithTwoAtLeft;
484 var
485   Adaptor: ITreeAdaptor;
486   T, NewChildren: ICommonTree;
487 begin
488   Adaptor := TCommonTreeAdaptor.Create;
489   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
490   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
491   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
492   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
493   NewChildren := Adaptor.GetNilNode as ICommonTree;
494   NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x')));
495   NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y')));
496   T.ReplaceChildren(0, 0, NewChildren);
497   CheckEquals(T.ToStringTree, '(a x y c d)');
498   T.SanityCheckParentAndChildIndexes;
499 end;
500 
501 procedure TestICommonTree.TestReplaceOneWithTwoAtRight;
502 var
503   Adaptor: ITreeAdaptor;
504   T, NewChildren: ICommonTree;
505 begin
506   Adaptor := TCommonTreeAdaptor.Create;
507   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
508   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
509   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
510   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
511   NewChildren := Adaptor.GetNilNode as ICommonTree;
512   NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x')));
513   NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y')));
514   T.ReplaceChildren(2, 2, NewChildren);
515   CheckEquals(T.ToStringTree, '(a b c x y)');
516   T.SanityCheckParentAndChildIndexes;
517 end;
518 
519 procedure TestICommonTree.TestReplaceOneWithTwoInMiddle;
520 var
521   Adaptor: ITreeAdaptor;
522   T, NewChildren: ICommonTree;
523 begin
524   Adaptor := TCommonTreeAdaptor.Create;
525   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
526   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
527   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
528   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
529   NewChildren := Adaptor.GetNilNode as ICommonTree;
530   NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x')));
531   NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y')));
532   T.ReplaceChildren(1, 1, NewChildren);
533   CheckEquals(T.ToStringTree, '(a b x y d)');
534   T.SanityCheckParentAndChildIndexes;
535 end;
536 
537 procedure TestICommonTree.TestReplaceTwoWithOneAtLeft;
538 var
539   T, NewChild: ICommonTree;
540 begin
541   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
542   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
543   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
544   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
545   NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
546   T.ReplaceChildren(0, 1, NewChild);
547   CheckEquals(T.ToStringTree, '(a x d)');
548   T.SanityCheckParentAndChildIndexes;
549 end;
550 
551 procedure TestICommonTree.TestReplaceTwoWithOneAtRight;
552 var
553   T, NewChild: ICommonTree;
554 begin
555   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
556   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
557   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
558   T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
559   NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
560   T.ReplaceChildren(1, 2, NewChild);
561   CheckEquals(T.ToStringTree, '(a b x)');
562   T.SanityCheckParentAndChildIndexes;
563 end;
564 
565 procedure TestICommonTree.TestReplaceWithNoChildren;
566 var
567   T, NewChild: ICommonTree;
568   Error: Boolean;
569 begin
570   Exit; // already checked. Avoid exception
571   T := TCommonTree.Create(TCommonToken.Create(101));
572   NewChild := TCommonTree.Create(TCommonToken.Create(5));
573   Error := False;
574   try
575     T.ReplaceChildren(0, 0, NewChild);
576   except
577     Error := True;
578   end;
579   CheckTrue(Error);
580 end;
581 
582 procedure TestICommonTree.TestReplaceWithOneChildren;
583 var
584   T, C0, NewChild: ICommonTree;
585 begin
586   // assume token type 99 and use text
587   T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
588   C0 := TCommonTree.Create(TCommonToken.Create(99, 'b'));
589   T.AddChild(C0);
590   NewChild := TCommonTree.Create(TCommonToken.Create(99, 'c'));
591   T.ReplaceChildren(0, 0, NewChild);
592   CheckEquals(T.ToStringTree,'(a c)');
593   T.SanityCheckParentAndChildIndexes;
594 end;
595 
596 procedure TestICommonTree.TestSingleNode;
597 var
598   T: ICommonTree;
599 begin
600   T := TCommonTree.Create(TCommonToken.Create(101));
601   CheckNull(T.Parent);
602   CheckEquals(T.ChildIndex, -1);
603 end;
604 
CreateCommonTreeNodeStreamnull605 function TestICommonTreeNodeStream.CreateCommonTreeNodeStream(
606   const T: IANTLRInterface): ITreeNodeStream;
607 begin
608   Result := TCommonTreeNodeStream.Create(T);
609 end;
610 
TestICommonTreeNodeStream.CreateUnBufferedTreeNodeStream(611 function TestICommonTreeNodeStream.CreateUnBufferedTreeNodeStream(
612   const T: IANTLRInterface): ITreeNodeStream;
613 begin
614   Result := TUnBufferedTreeNodeStream.Create(T);
615 end;
616 
TestICommonTreeNodeStream.GetStringOfEntireStreamContentsWithNodeTypesOnly(617 function TestICommonTreeNodeStream.GetStringOfEntireStreamContentsWithNodeTypesOnly(
618   const Nodes: ITreeNodeStream): String;
619 var
620   Buf: TStringBuilder;
621   I, TokenType: Integer;
622   T: IANTLRInterface;
623 begin
624   Buf := TStringBuilder.Create;
625   try
626     for I := 0 to Nodes.Size - 1 do
627     begin
628       T := Nodes.LT(I + 1);
629       TokenType := Nodes.TreeAdaptor.GetNodeType(T);
630       if (TokenType <> TToken.DOWN) and (TokenType <> TToken.UP) then
631       begin
632         Buf.Append(' ');
633         Buf.Append(TokenType)
634       end;
635     end;
636     Result := Buf.ToString;
637   finally
638     Buf.Free;
639   end;
640 end;
641 
642 procedure TestICommonTreeNodeStream.SetUp;
643 begin
644 end;
645 
646 procedure TestICommonTreeNodeStream.TearDown;
647 begin
648 end;
649 
650 procedure TestICommonTreeNodeStream.Test4Nodes;
651 var
652   T: ITree;
653   Stream: ITreeNodeStream;
654 begin
655   /// Test a tree with four nodes - ^(101 ^(102 103) 104)
656   T := TCommonTree.Create(TCommonToken.Create(101));
657   T.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
658   T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103)));
659   T.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
660 
661   Stream := CreateCommonTreeNodeStream(T);
662   CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103 104');
663   CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 3');
664 end;
665 
666 procedure TestICommonTreeNodeStream.TestAoverB;
667 var
668   T: ITree;
669   Stream: ITreeNodeStream;
670 begin
671   T := TCommonTree.Create(TCommonToken.Create(101));
672   T.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
673 
674   Stream := CreateCommonTreeNodeStream(T);
675   CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102');
676   CheckEquals(Stream.ToString, ' 101 2 102 3');
677 end;
678 
679 procedure TestICommonTreeNodeStream.TestBufferOverflow;
680 var
681   Buf, Buf2: TStringBuilder;
682   Stream: ITreeNodeStream;
683   T: ITree;
684   I: Integer;
685 begin
686   Buf := TStringBuilder.Create;
687   Buf2 := TStringBuilder.Create;
688   try
689     // make ^(101 102 ... n)
690     T := TCommonTree.Create(TCommonToken.Create(101));
691     Buf.Append(' 101');
692     Buf2.Append(' 101');
693     Buf2.Append(' ');
694     Buf2.Append(TToken.DOWN);
695 
696     for I := 0 to TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE + 10 do
697     begin
698       T.AddChild(TCommonTree.Create(TCommonToken.Create(102 + I)));
699       Buf.Append(' ');
700       Buf.Append(102 + I);
701       Buf2.Append(' ');
702       Buf2.Append(102 + I);
703     end;
704     Buf2.Append(' ');
705     Buf2.Append(TToken.UP);
706 
707     Stream := CreateUnBufferedTreeNodeStream(T);
708     CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream), Buf.ToString);
709     CheckEquals(Stream.ToString, Buf2.ToString);
710   finally
711     Buf2.Free;
712     Buf.Free;
713   end;
714 end;
715 
716 /// <summary>
717 /// Test what happens when tail hits the end of the buffer, but there
718 /// is more room left.
719 /// </summary>
720 /// <remarks>
721 /// Specifically that would mean that head is not at 0 but has
722 /// advanced somewhere to the middle of the lookahead buffer.
723 ///
724 /// Use Consume() to advance N nodes into lookahead.  Then use LT()
725 /// to load at least INITIAL_LOOKAHEAD_BUFFER_SIZE-N nodes so the
726 /// buffer has to wrap.
727 /// </remarks>
728 procedure TestICommonTreeNodeStream.TestBufferWrap;
729 const
730   N = 10;
731   WrapBy = 4; // wrap around by 4 nodes
732 var
733   T: ITree;
734   I, Remaining: Integer;
735   Stream: ITreeNodeStream;
736   Node: ITree;
737 begin
738   // make tree with types: 1 2 ... INITIAL_LOOKAHEAD_BUFFER_SIZE+N
739   T := TCommonTree.Create(IToken(nil));
740   for I := 0 to TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE + N - 1 do
741     T.AddChild(TCommonTree.Create(TCommonToken.Create(I + 1)));
742 
743   // move head to index N
744   Stream := CreateUnBufferedTreeNodeStream(T);
745   for I := 1 to N do
746   begin
747     // consume N
748     Node := Stream.LT(1) as ITree;
749     CheckEquals(Node.TokenType, I);
750     Stream.Consume;
751   end;
752 
753   // now use LT to lookahead past end of buffer
754   Remaining := TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE - N;
755   CheckTrue(WrapBy < N);
756   for I := 1 to Remaining + WrapBy do
757   begin
758     // wrap past end of buffer
759     Node := Stream.LT(I) as ITree; // look ahead to ith token
760     CheckEquals(Node.TokenType, N + I);
761   end;
762 end;
763 
764 procedure TestICommonTreeNodeStream.TestFlatList;
765 var
766   Root: ITree;
767   Stream: ITreeNodeStream;
768 begin
769   Root := TCommonTree.Create(IToken(nil));
770   Root.AddChild(TCommonTree.Create(TCommonToken.Create(101)));
771   Root.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
772   Root.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
773 
774   Stream := CreateCommonTreeNodeStream(Root);
775   CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103');
776   CheckEquals(Stream.ToString, ' 101 102 103');
777 end;
778 
779 procedure TestICommonTreeNodeStream.TestList;
780 var
781   Root, T, U: ITree;
782   Stream: ITreeNodeStream;
783 begin
784   Root := TCommonTree.Create(IToken(nil));
785 
786   T := TCommonTree.Create(TCommonToken.Create(101));
787   T.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
788   T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103)));
789   T.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
790 
791   U := TCommonTree.Create(TCommonToken.Create(105));
792 
793   Root.AddChild(T);
794   Root.AddChild(U);
795 
796   Stream := CreateCommonTreeNodeStream(Root);
797   CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103 104 105');
798   CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 3 105');
799 end;
800 
801 procedure TestICommonTreeNodeStream.TestListWithOneNode;
802 var
803   Root: ITree;
804   Stream: ITreeNodeStream;
805 begin
806   Root := TCommonTree.Create(IToken(nil));
807   Root.AddChild(TCommonTree.Create(TCommonToken.Create(101)));
808 
809   Stream := CreateCommonTreeNodeStream(Root);
810   CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101');
811   CheckEquals(Stream.ToString, ' 101');
812 end;
813 
814 procedure TestICommonTreeNodeStream.TestLT;
815 var
816   T: ITree;
817   Stream: ITreeNodeStream;
818 begin
819   // ^(101 ^(102 103) 104)
820   T := TCommonTree.Create(TCommonToken.Create(101));
821   T.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
822   T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103)));
823   T.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
824 
825   Stream := CreateCommonTreeNodeStream(T);
826   CheckEquals((Stream.LT(1) as ITree).TokenType,101);
827   CheckEquals((Stream.LT(2) as ITree).TokenType,TToken.DOWN);
828   CheckEquals((Stream.LT(3) as ITree).TokenType,102);
829   CheckEquals((Stream.LT(4) as ITree).TokenType,TToken.DOWN);
830   CheckEquals((Stream.LT(5) as ITree).TokenType,103);
831   CheckEquals((Stream.LT(6) as ITree).TokenType,TToken.UP);
832   CheckEquals((Stream.LT(7) as ITree).TokenType,104);
833   CheckEquals((Stream.LT(8) as ITree).TokenType,TToken.UP);
834   CheckEquals((Stream.LT(9) as ITree).TokenType,TToken.EOF);
835   // check way ahead
836   CheckEquals((Stream.LT(100) as ITree).TokenType,TToken.EOF);
837 end;
838 
839 procedure TestICommonTreeNodeStream.TestMarkRewindEntire;
840 var
841   R0, R1, R2: ITree;
842   Stream: ICommonTreeNodeStream;
843   M, K: Integer;
844 begin
845   // ^(101 ^(102 103 ^(106 107) ) 104 105)
846   // stream has 7 real + 6 nav nodes
847   // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
848   R0 := TCommonTree.Create(TCommonToken.Create(101));
849   R1 := TCommonTree.Create(TCommonToken.Create(102));
850   R0.AddChild(R1);
851   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
852   R2 := TCommonTree.Create(TCommonToken.Create(106));
853   R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
854   R1.AddChild(R2);
855   R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
856   R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
857 
858   Stream := TCommonTreeNodeStream.Create(R0);
859   M := Stream.Mark;
860   for K := 1 to 13 do
861   begin
862     // consume til end
863     Stream.LT(1);
864     Stream.Consume;
865   end;
866   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
867   CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP);
868   Stream.Rewind(M);
869 
870   for K := 1 to 13 do
871   begin
872     // consume til end
873     Stream.LT(1);
874     Stream.Consume;
875   end;
876   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
877   CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP);
878 end;
879 
880 procedure TestICommonTreeNodeStream.TestMarkRewindInMiddle;
881 var
882   R0, R1, R2: ITree;
883   Stream: ICommonTreeNodeStream;
884   M, K: Integer;
885 begin
886   // ^(101 ^(102 103 ^(106 107) ) 104 105)
887   // stream has 7 real + 6 nav nodes
888   // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
889   R0 := TCommonTree.Create(TCommonToken.Create(101));
890   R1 := TCommonTree.Create(TCommonToken.Create(102));
891   R0.AddChild(R1);
892   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
893   R2 := TCommonTree.Create(TCommonToken.Create(106));
894   R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
895   R1.AddChild(R2);
896   R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
897   R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
898 
899   Stream := TCommonTreeNodeStream.Create(R0);
900   for K := 1 to 7 do
901   begin
902     // consume til middle
903     Stream.Consume;
904   end;
905   CheckEquals((Stream.LT(1) as ITree).TokenType,107);
906   M := Stream.Mark;
907   Stream.Consume; // consume 107
908   Stream.Consume; // consume UP
909   Stream.Consume; // consume UP
910   Stream.Consume; // consume 104
911   Stream.Rewind(M);
912 
913   CheckEquals((Stream.LT(1) as ITree).TokenType,107);
914   Stream.Consume;
915   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
916   Stream.Consume;
917   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
918   Stream.Consume;
919   CheckEquals((Stream.LT(1) as ITree).TokenType,104);
920   Stream.Consume;
921   // now we're past rewind position
922   CheckEquals((Stream.LT(1) as ITree).TokenType,105);
923   Stream.Consume;
924   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
925   Stream.Consume;
926   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
927   CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP);
928 end;
929 
930 procedure TestICommonTreeNodeStream.TestMarkRewindNested;
931 var
932   R0, R1, R2: ITree;
933   Stream: ICommonTreeNodeStream;
934   M, M2: Integer;
935 begin
936   // ^(101 ^(102 103 ^(106 107) ) 104 105)
937   // stream has 7 real + 6 nav nodes
938   // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
939   R0 := TCommonTree.Create(TCommonToken.Create(101));
940   R1 := TCommonTree.Create(TCommonToken.Create(102));
941   R0.AddChild(R1);
942   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
943   R2 := TCommonTree.Create(TCommonToken.Create(106));
944   R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
945   R1.AddChild(R2);
946   R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
947   R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
948 
949   Stream := TCommonTreeNodeStream.Create(R0);
950   M := Stream.Mark; // MARK at start
951   Stream.Consume; // consume 101
952   Stream.Consume; // consume DN
953   M2:= Stream.Mark; // MARK on 102
954   Stream.Consume; // consume 102
955   Stream.Consume; // consume DN
956   Stream.Consume; // consume 103
957   Stream.Consume; // consume 106
958   Stream.Rewind(M2);
959   CheckEquals((Stream.LT(1) as ITree).TokenType,102);
960   Stream.Consume;
961   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
962   Stream.Consume;
963   // stop at 103 and rewind to start
964   Stream.Rewind(M); // REWIND to 101
965   CheckEquals((Stream.LT(1) as ITree).TokenType,101);
966   Stream.Consume;
967   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
968   Stream.Consume;
969   CheckEquals((Stream.LT(1) as ITree).TokenType,102);
970   Stream.Consume;
971   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
972 end;
973 
974 procedure TestICommonTreeNodeStream.TestNestedPushPop;
975 const
976   IndexOf102 = 2;
977   IndexOf104 = 6;
978   IndexOf107 = 12;
979 var
980   R0, R1, R2, R3: ITree;
981   Stream: ICommonTreeNodeStream;
982   K: Integer;
983 begin
984   // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
985   // stream has 9 real + 8 nav nodes
986   // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP
987   R0 := TCommonTree.Create(TCommonToken.Create(101));
988   R1 := TCommonTree.Create(TCommonToken.Create(102));
989   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
990   R0.AddChild(R1);
991   R2 := TCommonTree.Create(TCommonToken.Create(104));
992   R2.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
993   R0.AddChild(R2);
994   R3 := TCommonTree.Create(TCommonToken.Create(106));
995   R3.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
996   R0.AddChild(R3);
997   R0.AddChild(TCommonTree.Create(TCommonToken.Create(108)));
998   R0.AddChild(TCommonTree.Create(TCommonToken.Create(109)));
999 
1000   Stream := TCommonTreeNodeStream.Create(R0);
1001   CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3');
1002 
1003   // Assume we want to hit node 107 and then "call 102", which
1004   // calls 104, then return
1005   for K := 1 to IndexOf107 do
1006     // consume til 107 node
1007     Stream.Consume;
1008 
1009   CheckEquals((Stream.LT(1) as ITree).TokenType,107);
1010   // CALL 102
1011   Stream.Push(IndexOf102);
1012   CheckEquals((Stream.LT(1) as ITree).TokenType,102);
1013   Stream.Consume; // consume 102
1014   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
1015   Stream.Consume; // consume DN
1016   CheckEquals((Stream.LT(1) as ITree).TokenType,103);
1017   Stream.Consume; // consume 103
1018 
1019   // CALL 104
1020   Stream.Push(IndexOf104);
1021   CheckEquals((Stream.LT(1) as ITree).TokenType,104);
1022   Stream.Consume; // consume 104
1023   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
1024   Stream.Consume; // consume DN
1025   CheckEquals((Stream.LT(1) as ITree).TokenType,105);
1026   Stream.Consume; // consume 1045
1027   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
1028 
1029   // RETURN (to UP node in 102 subtree)
1030   Stream.Pop;
1031   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
1032 
1033   // RETURN (to empty stack)
1034   Stream.Pop;
1035   CheckEquals((Stream.LT(1) as ITree).TokenType,107);
1036 end;
1037 
1038 procedure TestICommonTreeNodeStream.TestPushPop;
1039 const
1040   IndexOf102 = 2;
1041   IndexOf107 = 12;
1042 var
1043   R0, R1, R2, R3: ITree;
1044   Stream: ICommonTreeNodeStream;
1045   K: Integer;
1046 begin
1047   // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
1048   // stream has 9 real + 8 nav nodes
1049   // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP
1050   R0 := TCommonTree.Create(TCommonToken.Create(101));
1051   R1 := TCommonTree.Create(TCommonToken.Create(102));
1052   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
1053   R0.AddChild(R1);
1054   R2 := TCommonTree.Create(TCommonToken.Create(104));
1055   R2.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
1056   R0.AddChild(R2);
1057   R3 := TCommonTree.Create(TCommonToken.Create(106));
1058   R3.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
1059   R0.AddChild(R3);
1060   R0.AddChild(TCommonTree.Create(TCommonToken.Create(108)));
1061   R0.AddChild(TCommonTree.Create(TCommonToken.Create(109)));
1062 
1063   Stream := TCommonTreeNodeStream.Create(R0);
1064   CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3');
1065 
1066   // Assume we want to hit node 107 and then "call 102" then return
1067   for K := 1 to IndexOf107 do
1068     // consume til 107 node
1069     Stream.Consume;
1070 
1071   // CALL 102
1072   CheckEquals((Stream.LT(1) as ITree).TokenType,107);
1073   Stream.Push(IndexOf102);
1074   CheckEquals((Stream.LT(1) as ITree).TokenType,102);
1075   Stream.Consume; // consume 102
1076   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
1077   Stream.Consume; // consume DN
1078   CheckEquals((Stream.LT(1) as ITree).TokenType,103);
1079   Stream.Consume; // consume 103
1080   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
1081   // RETURN
1082   Stream.Pop;
1083   CheckEquals((Stream.LT(1) as ITree).TokenType,107);
1084 end;
1085 
1086 procedure TestICommonTreeNodeStream.TestPushPopFromEOF;
1087 const
1088   IndexOf102 = 2;
1089   IndexOf104 = 6;
1090 var
1091   R0, R1, R2, R3: ITree;
1092   Stream: ICommonTreeNodeStream;
1093 begin
1094   // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
1095   // stream has 9 real + 8 nav nodes
1096   // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP
1097   R0 := TCommonTree.Create(TCommonToken.Create(101));
1098   R1 := TCommonTree.Create(TCommonToken.Create(102));
1099   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
1100   R0.AddChild(R1);
1101   R2 := TCommonTree.Create(TCommonToken.Create(104));
1102   R2.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
1103   R0.AddChild(R2);
1104   R3 := TCommonTree.Create(TCommonToken.Create(106));
1105   R3.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
1106   R0.AddChild(R3);
1107   R0.AddChild(TCommonTree.Create(TCommonToken.Create(108)));
1108   R0.AddChild(TCommonTree.Create(TCommonToken.Create(109)));
1109 
1110   Stream := TCommonTreeNodeStream.Create(R0);
1111   CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3');
1112 
1113   while (Stream.LA(1) <> TToken.EOF) do
1114     Stream.Consume;
1115   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
1116 
1117   // CALL 102
1118   Stream.Push(IndexOf102);
1119   CheckEquals((Stream.LT(1) as ITree).TokenType,102);
1120   Stream.Consume; // consume 102
1121   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
1122   Stream.Consume; // consume DN
1123   CheckEquals((Stream.LT(1) as ITree).TokenType,103);
1124   Stream.Consume; // consume 103
1125   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
1126   // RETURN (to empty stack)
1127   Stream.Pop;
1128   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
1129 
1130   // CALL 104
1131   Stream.Push(IndexOf104);
1132   CheckEquals((Stream.LT(1) as ITree).TokenType,104);
1133   Stream.Consume; // consume 104
1134   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
1135   Stream.Consume; // consume DN
1136   CheckEquals((Stream.LT(1) as ITree).TokenType,105);
1137   Stream.Consume; // consume 105
1138   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
1139   // RETURN (to empty stack)
1140   Stream.Pop;
1141   CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
1142 end;
1143 
1144 procedure TestICommonTreeNodeStream.TestSeek;
1145 var
1146   R0, R1, R2: ITree;
1147   Stream: ICommonTreeNodeStream;
1148 begin
1149   // ^(101 ^(102 103 ^(106 107) ) 104 105)
1150   // stream has 7 real + 6 nav nodes
1151   // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
1152   R0 := TCommonTree.Create(TCommonToken.Create(101));
1153   R1 := TCommonTree.Create(TCommonToken.Create(102));
1154   R0.AddChild(R1);
1155   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
1156   R2 := TCommonTree.Create(TCommonToken.Create(106));
1157   R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
1158   R1.AddChild(R2);
1159   R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
1160   R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
1161 
1162   Stream := TCommonTreeNodeStream.Create(R0);
1163   Stream.Consume; // consume 101
1164   Stream.Consume; // consume DN
1165   Stream.Consume; // consume 102
1166   Stream.Seek(7); // seek to 107
1167   CheckEquals((Stream.LT(1) as ITree).TokenType,107);
1168   Stream.Consume; // consume 107
1169   Stream.Consume; // consume UP
1170   Stream.Consume; // consume UP
1171   CheckEquals((Stream.LT(1) as ITree).TokenType,104);
1172 end;
1173 
1174 procedure TestICommonTreeNodeStream.TestSeekFromStart;
1175 var
1176   R0, R1, R2: ITree;
1177   Stream: ICommonTreeNodeStream;
1178 begin
1179   // ^(101 ^(102 103 ^(106 107) ) 104 105)
1180   // stream has 7 real + 6 nav nodes
1181   // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
1182   R0 := TCommonTree.Create(TCommonToken.Create(101));
1183   R1 := TCommonTree.Create(TCommonToken.Create(102));
1184   R0.AddChild(R1);
1185   R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
1186   R2 := TCommonTree.Create(TCommonToken.Create(106));
1187   R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
1188   R1.AddChild(R2);
1189   R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
1190   R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
1191 
1192   Stream := TCommonTreeNodeStream.Create(R0);
1193   Stream.Seek(7); // seek to 107
1194   CheckEquals((Stream.LT(1) as ITree).TokenType,107);
1195   Stream.Consume; // consume 107
1196   Stream.Consume; // consume UP
1197   Stream.Consume; // consume UP
1198   CheckEquals((Stream.LT(1) as ITree).TokenType,104);
1199 end;
1200 
1201 procedure TestICommonTreeNodeStream.TestSingleNode;
1202 var
1203   T: ITree;
1204   Stream: ITreeNodeStream;
1205 begin
1206   T := TCommonTree.Create(TCommonToken.Create(101));
1207   Stream := CreateCommonTreeNodeStream(T);
1208   CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101');
1209   CheckEquals(Stream.ToString, ' 101');
1210 end;
1211 
1212 procedure TestICommonTreeNodeStream.TestStackStretch;
1213 var
1214   R0: ICommonTree;
1215   Stream: ICommonTreeNodeStream;
1216   I: Integer;
1217 begin
1218   // make more than INITIAL_CALL_STACK_SIZE pushes
1219   R0 := TCommonTree.Create(TCommonToken.Create(101));
1220   Stream := TCommonTreeNodeStream.Create(R0);
1221 
1222   // go 1 over initial size
1223   for I := 1 to TCommonTreeNodeStream.INITIAL_CALL_STACK_SIZE + 1 do
1224     Stream.Push(I);
1225 
1226   CheckEquals(Stream.Pop, 10);
1227   CheckEquals(Stream.Pop, 9);
1228 end;
1229 
CreateTokennull1230 function TestIRewriteRuleXxxxStream.CreateToken(const TokenType: Integer;
1231   const Text: String): IToken;
1232 begin
1233   Result := TCommonToken.Create(TokenType, Text);
1234 end;
1235 
CreateTokenListnull1236 function TestIRewriteRuleXxxxStream.CreateTokenList(
1237   const Count: Integer): IList<IToken>;
1238 var
1239   I: Integer;
1240 begin
1241   Result := TList<IToken>.Create;
1242   for I := 0 to Count - 1 do
1243     Result.Add(TCommonToken.Create(I + 1,'test token ' + IntToStr(I + 1)
1244       + ' without any real context'));
1245 end;
1246 
CreateTreenull1247 function TestIRewriteRuleXxxxStream.CreateTree(const Token: IToken): ITree;
1248 begin
1249   Result := TCommonTree.Create(Token);
1250 end;
1251 
TestIRewriteRuleXxxxStream.CreateTreeAdaptor()1252 function TestIRewriteRuleXxxxStream.CreateTreeAdaptor: ITreeAdaptor;
1253 begin
1254   Result := TCommonTreeAdaptor.Create;
1255 end;
1256 
1257 procedure TestIRewriteRuleXxxxStream.SetUp;
1258 begin
1259 end;
1260 
1261 procedure TestIRewriteRuleXxxxStream.TearDown;
1262 begin
1263 end;
1264 
1265 procedure TestIRewriteRuleXxxxStream.TestRewriteRuleNodeStreamConstructors;
1266 var
1267   NodeTest1, NodeTest2, NodeTest3: IRewriteRuleNodeStream;
1268 begin
1269   NodeTest1 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor,
1270     'RewriteRuleNodeStream test1');
1271 
1272   NodeTest2 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor,
1273     'RewriteRuleNodeStream test2',
1274     CreateToken(1,'test token without any real context'));
1275 
1276   NodeTest3 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor,
1277     'RewriteRuleNodeStream test3', CreateTokenList(4));
1278 end;
1279 
1280 procedure TestIRewriteRuleXxxxStream.TestRewriteRuleSubtreeStreamConstructors;
1281 var
1282   SubtreeTest1, SubtreeTest2, SubtreeTest3: IRewriteRuleSubtreeStream;
1283 begin
1284   SubtreeTest1 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor,
1285     'RewriteRuleSubtreeStream test1');
1286 
1287   SubtreeTest2 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor,
1288     'RewriteRuleSubtreeStream test2',
1289     CreateToken(1,'test token without any real context'));
1290 
1291   SubtreeTest3 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor,
1292     'RewriteRuleSubtreeStream test3', CreateTokenList(4));
1293 end;
1294 
1295 procedure TestIRewriteRuleXxxxStream.TestRewriteRuleTokenStreamConstructors;
1296 var
1297   TokenTest1, TokenTest2, TokenTest3: IRewriteRuleTokenStream;
1298 begin
1299   TokenTest1 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor,
1300     'RewriteRuleTokenStream test1');
1301 
1302   TokenTest2 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor,
1303     'RewriteRuleTokenStream test2',
1304     CreateToken(1, 'test token without any real context'));
1305 
1306   TokenTest3 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor,
1307     'RewriteRuleTokenStream test3', CreateTokenList(4));
1308 end;
1309 
1310 procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWhileEmpty1;
1311 const
1312   Description = 'RewriteRuleNodeStream test';
1313 var
1314   NodeTest: IRewriteRuleNodeStream;
1315 begin
1316   ExpectedException := ERewriteEmptyStreamException;
1317   NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, Description);
1318 
1319   CheckFalse(NodeTest.HasNext);
1320   CheckEquals(Description, NodeTest.Description);
1321   CheckEquals(NodeTest.Size, 0);
1322   NodeTest.Reset;
1323   CheckEquals(NodeTest.Size, 0);
1324   NodeTest.NextNode;
1325 end;
1326 
1327 procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWhileEmpty2;
1328 const
1329   Description = 'RewriteRuleNodeStream test';
1330 var
1331   NodeTest: IRewriteRuleNodeStream;
1332 begin
1333   ExpectedException := ERewriteEmptyStreamException;
1334   NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, Description);
1335   NodeTest.NextTree;
1336 end;
1337 
1338 procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWithElements;
1339 var
1340   NodeTest: IRewriteRuleNodeStream;
1341   Token1, Token2: IToken;
1342   Tree1, Tree2: ITree;
1343   ReturnedTree: ICommonTree;
1344 begin
1345   ExpectedException := ERewriteCardinalityException;
1346   NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, 'RewriteRuleNodeStream test');
1347   Token1 := CreateToken(1, 'test token without any real context');
1348   Tree1 := CreateTree(Token1);
1349 
1350   // Test Add()
1351   NodeTest.Add(Tree1);
1352   CheckEquals(NodeTest.Size, 1);
1353   CheckTrue(NodeTest.HasNext);
1354 
1355   // Test NextNode()
1356   ReturnedTree := NodeTest.NextNode as ICommoNTree;
1357   CheckEquals(ReturnedTree.TokenType, Tree1.TokenType);
1358   CheckEquals(NodeTest.Size, 1);
1359   CheckFalse(NodeTest.HasNext);
1360   NodeTest.Reset;
1361   CheckEquals(NodeTest.Size, 1);
1362   CheckTrue(NodeTest.HasNext);
1363 
1364   // Test NextTree()
1365   ReturnedTree := NodeTest.NextTree as ICommonTree;
1366   Check(SameObj(Token1, ReturnedTree.Token));
1367   CheckEquals(NodeTest.Size, 1);
1368   CheckFalse(NodeTest.HasNext);
1369   NodeTest.Reset;
1370   CheckEquals(NodeTest.Size, 1);
1371   CheckTrue(NodeTest.HasNext);
1372 
1373   // Test, what happens with two elements
1374   Token2 := CreateToken(2, 'test token without any real context');
1375   Tree2 := CreateTree(Token2);
1376   NodeTest.Add(Tree2);
1377   CheckEquals(NodeTest.Size, 2);
1378   CheckTrue(NodeTest.HasNext);
1379   ReturnedTree := NodeTest.NextTree as ICommonTree;
1380   Check(SameObj(Token1, ReturnedTree.Token));
1381   CheckEquals(NodeTest.Size, 2);
1382   CheckTrue(NodeTest.HasNext);
1383   ReturnedTree := NodeTest.NextTree as ICommonTree;
1384   Check(SameObj(Token2, ReturnedTree.Token));
1385   CheckFalse(NodeTest.HasNext);
1386 
1387   // Test exception
1388   NodeTest.NextTree;
1389 end;
1390 
1391 procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWhileEmpty1;
1392 const
1393   Description = 'RewriteRuleSubtreeStream test';
1394 var
1395   SubtreeTest: IRewriteRuleSubtreeStream;
1396 begin
1397   ExpectedException := ERewriteEmptyStreamException;
1398   SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, Description);
1399 
1400   CheckFalse(SubtreeTest.HasNext);
1401   CheckEquals(Description, SubtreeTest.Description);
1402   CheckEquals(SubtreeTest.Size, 0);
1403   SubtreeTest.Reset;
1404   CheckEquals(SubtreeTest.Size, 0);
1405   SubtreeTest.NextNode;
1406 end;
1407 
1408 procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWhileEmpty2;
1409 const
1410   Description = 'RewriteRuleSubtreeStream test';
1411 var
1412   SubtreeTest: IRewriteRuleSubtreeStream;
1413 begin
1414   ExpectedException := ERewriteEmptyStreamException;
1415   SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, Description);
1416   SubtreeTest.NextTree;
1417 end;
1418 
1419 procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWithElements;
1420 var
1421   SubtreeTest: IRewriteRuleSubtreeStream;
1422   Token1, Token2: IToken;
1423   Tree1, Tree2: ITree;
1424   ReturnedTree: ICommonTree;
1425 begin
1426   ExpectedException := ERewriteCardinalityException;
1427   SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, 'RewriteRuleSubtreeStream test');
1428   Token1 := CreateToken(1, 'test token without any real context');
1429   Tree1 := CreateTree(Token1);
1430 
1431   // Test Add()
1432   SubtreeTest.Add(Tree1);
1433   CheckEquals(SubtreeTest.Size, 1);
1434   CheckTrue(SubtreeTest.HasNext);
1435 
1436   // Test NextNode()
1437   Check(SameObj(SubtreeTest.NextNode, Tree1));
1438   CheckEquals(SubtreeTest.Size, 1);
1439   CheckFalse(SubtreeTest.HasNext);
1440   SubtreeTest.Reset;
1441   CheckEquals(SubtreeTest.Size, 1);
1442   CheckTrue(SubtreeTest.HasNext);
1443 
1444   // Test NextTree()
1445   ReturnedTree := SubtreeTest.NextTree as ICommonTree;
1446   Check(SameObj(Token1, ReturnedTree.Token));
1447   CheckEquals(SubtreeTest.Size, 1);
1448   CheckFalse(SubtreeTest.HasNext);
1449   SubtreeTest.Reset;
1450   CheckEquals(SubtreeTest.Size, 1);
1451   CheckTrue(SubtreeTest.HasNext);
1452 
1453   // Test, what happens with two elements
1454   Token2 := CreateToken(2, 'test token without any real context');
1455   Tree2 := CreateTree(Token2);
1456   SubtreeTest.Add(Tree2);
1457   CheckEquals(SubtreeTest.Size, 2);
1458   CheckTrue(SubtreeTest.HasNext);
1459   ReturnedTree := SubtreeTest.NextTree as ICommonTree;
1460   Check(SameObj(Token1, ReturnedTree.Token));
1461   CheckEquals(SubtreeTest.Size, 2);
1462   CheckTrue(SubtreeTest.HasNext);
1463   ReturnedTree := SubtreeTest.NextTree as ICommonTree;
1464   Check(SameObj(Token2, ReturnedTree.Token));
1465   CheckFalse(SubtreeTest.HasNext);
1466 
1467   // Test exception
1468   SubtreeTest.NextTree;
1469 end;
1470 
1471 procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty1;
1472 const
1473   Description = 'RewriteRuleTokenStream test';
1474 var
1475   TokenTest: IRewriteRuleTokenStream;
1476 begin
1477   ExpectedException := ERewriteEmptyStreamException;
1478   TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description);
1479 
1480   CheckFalse(TokenTest.HasNext);
1481   CheckEquals(Description, TokenTest.Description);
1482   CheckEquals(TokenTest.Size, 0);
1483   TokenTest.Reset;
1484   CheckEquals(TokenTest.Size, 0);
1485   TokenTest.NextNode;
1486 end;
1487 
1488 procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty2;
1489 const
1490   Description = 'RewriteRuleTokenStream test';
1491 var
1492   TokenTest: IRewriteRuleTokenStream;
1493 begin
1494   ExpectedException := ERewriteEmptyStreamException;
1495   TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description);
1496   TokenTest.NextTree;
1497 end;
1498 
1499 procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty3;
1500 const
1501   Description = 'RewriteRuleTokenStream test';
1502 var
1503   TokenTest: IRewriteRuleTokenStream;
1504 begin
1505   ExpectedException := ERewriteEmptyStreamException;
1506   TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description);
1507   TokenTest.NextToken;
1508 end;
1509 
1510 procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWithElements;
1511 var
1512   TokenTest: IRewriteRuleTokenStream;
1513   Token1, Token2, ReturnedToken: IToken;
1514   Tree: ICommonTree;
1515 begin
1516   ExpectedException := ERewriteCardinalityException;
1517   TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, 'RewriteRuleTokenStream test');
1518   Token1 := CreateToken(1, 'test token without any real context');
1519 
1520   // Test Add()
1521   TokenTest.Add(Token1);
1522   CheckEquals(TokenTest.Size, 1);
1523   CheckTrue(TokenTest.HasNext);
1524 
1525   // Test NextNode()
1526   Tree := TokenTest.NextNode as ICommonTree;
1527   Check(SameObj(Tree.Token, Token1));
1528   CheckEquals(TokenTest.Size, 1);
1529   CheckFalse(TokenTest.HasNext);
1530   TokenTest.Reset;
1531   CheckEquals(TokenTest.Size, 1);
1532   CheckTrue(TokenTest.HasNext);
1533 
1534   // Test NextToken()
1535   ReturnedToken := TokenTest.NextToken;
1536   Check(SameObj(Token1, ReturnedToken));
1537   CheckEquals(TokenTest.Size, 1);
1538   CheckFalse(TokenTest.HasNext);
1539   TokenTest.Reset;
1540   CheckEquals(TokenTest.Size, 1);
1541   CheckTrue(TokenTest.HasNext);
1542 
1543   // Test NextTree()
1544   ReturnedToken := TokenTest.NextTree as IToken;
1545   Check(SameObj(Token1, ReturnedToken));
1546   CheckEquals(TokenTest.Size, 1);
1547   CheckFalse(TokenTest.HasNext);
1548   TokenTest.Reset;
1549   CheckEquals(TokenTest.Size, 1);
1550   CheckTrue(TokenTest.HasNext);
1551 
1552   // Test, what happens with two elements
1553   Token2 := CreateToken(2, 'test token without any real context');
1554   TokenTest.Add(Token2);
1555   CheckEquals(TokenTest.Size, 2);
1556   CheckTrue(TokenTest.HasNext);
1557   ReturnedToken := TokenTest.NextToken;
1558   Check(SameObj(Token1, ReturnedToken));
1559   CheckEquals(TokenTest.Size, 2);
1560   CheckTrue(TokenTest.HasNext);
1561   ReturnedToken := TokenTest.NextToken;
1562   Check(SameObj(Token2, ReturnedToken));
1563   CheckFalse(TokenTest.HasNext);
1564 
1565   // Test exception
1566   TokenTest.NextToken;
1567 end;
1568 
1569 constructor TestITreeWizard.Create(MethodName: String);
1570 const
1571   TOKENS: array [0..11] of String = ('', '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'ID', 'VAR');
1572 var
1573   I: Integer;
1574 begin
1575   inherited;
1576   SetLength(FTokens,Length(TOKENS));
1577   for I := 0 to Length(TOKENS) - 1 do
1578     FTokens[I] := TOKENS[I];
1579 end;
1580 
1581 procedure TestITreeWizard.SetUp;
1582 begin
1583 end;
1584 
1585 procedure TestITreeWizard.TearDown;
1586 begin
1587 end;
1588 
1589 procedure TestITreeWizard.TestDoubleLevelTree;
1590 var
1591   Adaptor: ITreeAdaptor;
1592   Wiz: ITreeWizard;
1593   T: ICommonTree;
1594 begin
1595   Adaptor := TCommonTreeAdaptor.Create;
1596   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1597   T := Wiz.CreateTreeOrNode('(A (B C) (B D) E)') as ICommonTree;
1598   CheckEquals(T.ToStringTree, '(A (B C) (B D) E)');
1599 end;
1600 
1601 procedure TestITreeWizard.TestEquals;
1602 var
1603   Adaptor: ITreeAdaptor;
1604   Wiz: ITreeWizard;
1605   T1, T2: ICommonTree;
1606 begin
1607   Adaptor := TCommonTreeAdaptor.Create;
1608   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1609   T1 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
1610   T2 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
1611   CheckTrue(Wiz.Equals(T1, T2, Adaptor));
1612 end;
1613 
1614 procedure TestITreeWizard.TestEqualsWithMismatchedText;
1615 var
1616   Adaptor: ITreeAdaptor;
1617   Wiz: ITreeWizard;
1618   T1, T2: ICommonTree;
1619 begin
1620   Adaptor := TCommonTreeAdaptor.Create;
1621   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1622   T1 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree;
1623   T2 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
1624   CheckFalse(Wiz.Equals(T1, T2, Adaptor));
1625 end;
1626 
1627 procedure TestITreeWizard.TestEqualsWithText;
1628 var
1629   Adaptor: ITreeAdaptor;
1630   Wiz: ITreeWizard;
1631   T1, T2: ICommonTree;
1632 begin
1633   Adaptor := TCommonTreeAdaptor.Create;
1634   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1635   T1 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree;
1636   T2 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree;
1637   CheckTrue(Wiz.Equals(T1, T2, Adaptor));
1638 end;
1639 
1640 procedure TestITreeWizard.TestFindPattern;
1641 var
1642   Adaptor: ITreeAdaptor;
1643   Wiz: ITreeWizard;
1644   T: ICommonTree;
1645   Subtrees, Elements: IList<IANTLRInterface>;
1646 begin
1647   Adaptor := TCommonTreeAdaptor.Create;
1648   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1649   T := Wiz.CreateTreeOrNode('(A B C (A[foo] B[bar]) (D (A[big] B[dog])))') as ICommonTree;
1650   Subtrees := Wiz.Find(T, '(A B)');
1651   Elements := Subtrees;
1652   CheckEquals('[foo, big]', TCollectionUtils.ListToString(Elements));
1653 end;
1654 
1655 procedure TestITreeWizard.TestInvalidListTree;
1656 var
1657   Adaptor: ITreeAdaptor;
1658   Wiz: ITreeWizard;
1659   T: ICommonTree;
1660 begin
1661   Adaptor := TCommonTreeAdaptor.Create;
1662   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1663   T := Wiz.CreateTreeOrNode('A B C') as ICommonTree;
1664   CheckNull(T);
1665 end;
1666 
1667 procedure TestITreeWizard.TestListTree;
1668 var
1669   Adaptor: ITreeAdaptor;
1670   Wiz: ITreeWizard;
1671   T: ICommonTree;
1672 begin
1673   Adaptor := TCommonTreeAdaptor.Create;
1674   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1675   T := Wiz.CreateTreeOrNode('(nil A B C)') as ICommonTree;
1676   CheckEquals(T.ToStringTree, 'A B C');
1677 end;
1678 
1679 procedure TestITreeWizard.TestNoRepeatsIndex;
1680 var
1681   Adaptor: ITreeAdaptor;
1682   Wiz: ITreeWizard;
1683   T: ICommonTree;
1684   M: IDictionary<Integer, IList<IANTLRInterface>>;
1685 begin
1686   Adaptor := TCommonTreeAdaptor.Create;
1687   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1688   T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree;
1689   M := Wiz.Index(T);
1690   CheckEquals('{5=[A], 8=[D], 7=[C], 6=[B]}' ,TCollectionUtils.DictionaryToString(M));
1691 end;
1692 
1693 procedure TestITreeWizard.TestNoRepeatsVisit;
1694 var
1695   Adaptor: ITreeAdaptor;
1696   Wiz: ITreeWizard;
1697   T: ICommonTree;
1698   Elements: IList<IANTLRInterface>;
1699   Visitor: IContextVisitor;
1700 begin
1701   Adaptor := TCommonTreeAdaptor.Create;
1702   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1703   T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree;
1704   Elements := TList<IANTLRInterface>.Create;
1705   Visitor := TRecordAllElementsVisitor.Create(Elements);
1706   Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor);
1707   CheckEquals('[B]' ,TCollectionUtils.ListToString(Elements));
1708 end;
1709 
1710 procedure TestITreeWizard.TestNoRepeatsVisit2;
1711 var
1712   Adaptor: ITreeAdaptor;
1713   Wiz: ITreeWizard;
1714   T: ICommonTree;
1715   Elements: IList<IANTLRInterface>;
1716   Visitor: IContextVisitor;
1717 begin
1718   Adaptor := TCommonTreeAdaptor.Create;
1719   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1720   T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
1721   Elements := TList<IANTLRInterface>.Create;
1722   Visitor := TRecordAllElementsVisitor.Create(Elements);
1723   Wiz.Visit(T, Wiz.GetTokenType('C'), Visitor);
1724   CheckEquals('[C]' ,TCollectionUtils.ListToString(Elements));
1725 end;
1726 
1727 procedure TestITreeWizard.TestParse;
1728 var
1729   Adaptor: ITreeAdaptor;
1730   Wiz: ITreeWizard;
1731   T: ICommonTree;
1732 begin
1733   Adaptor := TCommonTreeAdaptor.Create;
1734   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1735   T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
1736   CheckTrue(Wiz.Parse(T, '(A B C)'));
1737 end;
1738 
1739 procedure TestITreeWizard.TestParseFlatTree;
1740 var
1741   Adaptor: ITreeAdaptor;
1742   Wiz: ITreeWizard;
1743   T: ICommonTree;
1744 begin
1745   Adaptor := TCommonTreeAdaptor.Create;
1746   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1747   T := Wiz.CreateTreeOrNode('(nil A B C)') as ICommonTree;
1748   CheckTrue(Wiz.Parse(T, '(nil A B C)'));
1749 end;
1750 
1751 procedure TestITreeWizard.TestParseLabels;
1752 var
1753   Adaptor: ITreeAdaptor;
1754   Wiz: ITreeWizard;
1755   T: ICommonTree;
1756   Labels: IDictionary<String, IANTLRInterface>;
1757 begin
1758   Adaptor := TCommonTreeAdaptor.Create;
1759   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1760   T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
1761   Labels := TDictionary<String, IANTLRInterface>.Create;
1762   CheckTrue(Wiz.Parse(T, '(%a:A %b:B %c:C)', Labels));
1763   CheckEquals('A', Labels['a'].ToString);
1764   CheckEquals('B', Labels['b'].ToString);
1765   CheckEquals('C', Labels['c'].ToString);
1766 end;
1767 
1768 procedure TestITreeWizard.TestParseLabelsAndTestText;
1769 var
1770   Adaptor: ITreeAdaptor;
1771   Wiz: ITreeWizard;
1772   T: ICommonTree;
1773   Labels: IDictionary<String, IANTLRInterface>;
1774 begin
1775   Adaptor := TCommonTreeAdaptor.Create;
1776   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1777   T := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree;
1778   Labels := TDictionary<String, IANTLRInterface>.Create;
1779   CheckTrue(Wiz.Parse(T, '(%a:A %b:B[foo] %c:C)', Labels));
1780   CheckEquals('A', Labels['a'].ToString);
1781   CheckEquals('foo', Labels['b'].ToString);
1782   CheckEquals('C', Labels['c'].ToString);
1783 end;
1784 
1785 procedure TestITreeWizard.TestParseLabelsInNestedTree;
1786 var
1787   Adaptor: ITreeAdaptor;
1788   Wiz: ITreeWizard;
1789   T: ICommonTree;
1790   Labels: IDictionary<String, IANTLRInterface>;
1791 begin
1792   Adaptor := TCommonTreeAdaptor.Create;
1793   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1794   T := Wiz.CreateTreeOrNode('(A (B C) (D E))') as ICommonTree;
1795   Labels := TDictionary<String, IANTLRInterface>.Create;
1796   CheckTrue(Wiz.Parse(T, '(%a:A (%b:B %c:C) (%d:D %e:E) )', Labels));
1797   CheckEquals('A', Labels['a'].ToString);
1798   CheckEquals('B', Labels['b'].ToString);
1799   CheckEquals('C', Labels['c'].ToString);
1800   CheckEquals('D', Labels['d'].ToString);
1801   CheckEquals('E', Labels['e'].ToString);
1802 end;
1803 
1804 procedure TestITreeWizard.TestParseSingleNode;
1805 var
1806   Adaptor: ITreeAdaptor;
1807   Wiz: ITreeWizard;
1808   T: ICommonTree;
1809 begin
1810   Adaptor := TCommonTreeAdaptor.Create;
1811   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1812   T := Wiz.CreateTreeOrNode('A') as ICommonTree;
1813   CheckTrue(Wiz.Parse(T, 'A'));
1814 end;
1815 
1816 procedure TestITreeWizard.TestParseWithText;
1817 var
1818   Adaptor: ITreeAdaptor;
1819   Wiz: ITreeWizard;
1820   T: ICommonTree;
1821 begin
1822   Adaptor := TCommonTreeAdaptor.Create;
1823   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1824   T := Wiz.CreateTreeOrNode('(A B[foo] C[bar])') as ICommonTree;
1825   // C pattern has no text arg so despite [bar] in t, no need
1826   // to match text--check structure only.
1827   CheckTrue(Wiz.Parse(T, '(A B[foo] C)'));
1828 end;
1829 
1830 procedure TestITreeWizard.TestParseWithTextFails;
1831 var
1832   Adaptor: ITreeAdaptor;
1833   Wiz: ITreeWizard;
1834   T: ICommonTree;
1835 begin
1836   Adaptor := TCommonTreeAdaptor.Create;
1837   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1838   T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
1839   CheckFalse(Wiz.Parse(T, '(A[foo] B C)'));
1840 end;
1841 
1842 procedure TestITreeWizard.TestParseWithWildcardLabels;
1843 var
1844   Adaptor: ITreeAdaptor;
1845   Wiz: ITreeWizard;
1846   T: ICommonTree;
1847   Labels: IDictionary<String, IANTLRInterface>;
1848 begin
1849   Adaptor := TCommonTreeAdaptor.Create;
1850   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1851   T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
1852   Labels := TDictionary<String, IANTLRInterface>.Create;
1853   CheckTrue(Wiz.Parse(T, '(A %b:. %c:.)', Labels));
1854   CheckEquals('B', Labels['b'].ToString);
1855   CheckEquals('C', Labels['c'].ToString);
1856 end;
1857 
1858 procedure TestITreeWizard.TestRepeatsIndex;
1859 var
1860   Adaptor: ITreeAdaptor;
1861   Wiz: ITreeWizard;
1862   T: ICommonTree;
1863   M: IDictionary<Integer, IList<IANTLRInterface>>;
1864 begin
1865   Adaptor := TCommonTreeAdaptor.Create;
1866   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1867   T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
1868   M := Wiz.Index(T);
1869   CheckEquals('{5=[A, A], 8=[D, D], 7=[C], 6=[B, B, B]}' ,TCollectionUtils.DictionaryToString(M));
1870 end;
1871 
1872 procedure TestITreeWizard.TestRepeatsVisit;
1873 var
1874   Adaptor: ITreeAdaptor;
1875   Wiz: ITreeWizard;
1876   T: ICommonTree;
1877   Elements: IList<IANTLRInterface>;
1878   Visitor: IContextVisitor;
1879 begin
1880   Adaptor := TCommonTreeAdaptor.Create;
1881   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1882   T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
1883   Elements := TList<IANTLRInterface>.Create;
1884   Visitor := TRecordAllElementsVisitor.Create(Elements);
1885   Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor);
1886   CheckEquals('[B, B, B]' ,TCollectionUtils.ListToString(Elements));
1887 end;
1888 
1889 procedure TestITreeWizard.TestRepeatsVisit2;
1890 var
1891   Adaptor: ITreeAdaptor;
1892   Wiz: ITreeWizard;
1893   T: ICommonTree;
1894   Elements: IList<IANTLRInterface>;
1895   Visitor: IContextVisitor;
1896 begin
1897   Adaptor := TCommonTreeAdaptor.Create;
1898   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1899   T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
1900   Elements := TList<IANTLRInterface>.Create;
1901   Visitor := TRecordAllElementsVisitor.Create(Elements);
1902   Wiz.Visit(T, Wiz.GetTokenType('A'), Visitor);
1903   CheckEquals('[A, A]' ,TCollectionUtils.ListToString(Elements));
1904 end;
1905 
1906 procedure TestITreeWizard.TestRepeatsVisitWithContext;
1907 var
1908   Adaptor: ITreeAdaptor;
1909   Wiz: ITreeWizard;
1910   T: ICommonTree;
1911   Elements: IList<IANTLRInterface>;
1912   Visitor: IContextVisitor;
1913 begin
1914   Adaptor := TCommonTreeAdaptor.Create;
1915   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1916   T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
1917   Elements := TList<IANTLRInterface>.Create;
1918   Visitor := TTest1ContextVisitor.Create(Adaptor, Elements);
1919   Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor);
1920   CheckEquals('[B@A[0], B@A[1], B@A[2]]', TCollectionUtils.ListToString(Elements));
1921 end;
1922 
1923 procedure TestITreeWizard.TestRepeatsVisitWithNullParentAndContext;
1924 var
1925   Adaptor: ITreeAdaptor;
1926   Wiz: ITreeWizard;
1927   T: ICommonTree;
1928   Elements: IList<IANTLRInterface>;
1929   Visitor: IContextVisitor;
1930 begin
1931   Adaptor := TCommonTreeAdaptor.Create;
1932   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1933   T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
1934   Elements := TList<IANTLRInterface>.Create;
1935   Visitor := TTest1ContextVisitor.Create(Adaptor, Elements);
1936   Wiz.Visit(T, Wiz.GetTokenType('A'), Visitor);
1937   CheckEquals('[A@nil[0], A@A[1]]', TCollectionUtils.ListToString(Elements));
1938 end;
1939 
1940 procedure TestITreeWizard.TestSingleLevelTree;
1941 var
1942   Adaptor: ITreeAdaptor;
1943   Wiz: ITreeWizard;
1944   T: ICommonTree;
1945 begin
1946   Adaptor := TCommonTreeAdaptor.Create;
1947   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1948   T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree;
1949   CheckEquals(T.ToStringTree, '(A B C D)');
1950 end;
1951 
1952 procedure TestITreeWizard.TestSingleNode;
1953 var
1954   Adaptor: ITreeAdaptor;
1955   Wiz: ITreeWizard;
1956   T: ICommonTree;
1957 begin
1958   Adaptor := TCommonTreeAdaptor.Create;
1959   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1960   T := Wiz.CreateTreeOrNode('ID') as ICommonTree;
1961   CheckEquals(T.ToStringTree, 'ID');
1962 end;
1963 
1964 procedure TestITreeWizard.TestSingleNodeIndex;
1965 var
1966   Adaptor: ITreeAdaptor;
1967   Wiz: ITreeWizard;
1968   T: ICommonTree;
1969   M: IDictionary<Integer, IList<IANTLRInterface>>;
1970 begin
1971   Adaptor := TCommonTreeAdaptor.Create;
1972   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1973   T := Wiz.CreateTreeOrNode('ID') as ICommonTree;
1974   M := Wiz.Index(T);
1975   CheckEquals('{10=[ID]}' ,TCollectionUtils.DictionaryToString(M));
1976 end;
1977 
1978 procedure TestITreeWizard.TestSingleNodeTree;
1979 var
1980   Adaptor: ITreeAdaptor;
1981   Wiz: ITreeWizard;
1982   T: ICommonTree;
1983 begin
1984   Adaptor := TCommonTreeAdaptor.Create;
1985   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1986   T := Wiz.CreateTreeOrNode('(A)') as ICommonTree;
1987   CheckEquals(T.ToStringTree, 'A');
1988 end;
1989 
1990 procedure TestITreeWizard.TestSingleNodeWithArg;
1991 var
1992   Adaptor: ITreeAdaptor;
1993   Wiz: ITreeWizard;
1994   T: ICommonTree;
1995 begin
1996   Adaptor := TCommonTreeAdaptor.Create;
1997   Wiz := TTreeWizard.Create(Adaptor, FTokens);
1998   T := Wiz.CreateTreeOrNode('ID[foo]') as ICommonTree;
1999   CheckEquals(T.ToStringTree, 'foo');
2000 end;
2001 
2002 procedure TestITreeWizard.TestVisitPattern;
2003 var
2004   Adaptor: ITreeAdaptor;
2005   Wiz: ITreeWizard;
2006   T: ICommonTree;
2007   Elements: IList<IANTLRInterface>;
2008   Visitor: IContextVisitor;
2009 begin
2010   Adaptor := TCommonTreeAdaptor.Create;
2011   Wiz := TTreeWizard.Create(Adaptor, FTokens);
2012   T := Wiz.CreateTreeOrNode('(A B C (A B) D)') as ICommonTree;
2013   Elements := TList<IANTLRInterface>.Create;
2014   Visitor := TRecordAllElementsVisitor.Create(Elements);
2015   Wiz.Visit(T, '(A B)', Visitor);
2016   CheckEquals('[A]', TCollectionUtils.ListToString(Elements));
2017 end;
2018 
2019 procedure TestITreeWizard.TestVisitPatternMultiple;
2020 var
2021   Adaptor: ITreeAdaptor;
2022   Wiz: ITreeWizard;
2023   T: ICommonTree;
2024   Elements: IList<IANTLRInterface>;
2025   Visitor: IContextVisitor;
2026 begin
2027   Adaptor := TCommonTreeAdaptor.Create;
2028   Wiz := TTreeWizard.Create(Adaptor, FTokens);
2029   T := Wiz.CreateTreeOrNode('(A B C (A B) (D (A B)))') as ICommonTree;
2030   Elements := TList<IANTLRInterface>.Create;
2031   Visitor := TTest1ContextVisitor.Create(Adaptor, Elements);
2032   Wiz.Visit(T, '(A B)', Visitor);
2033   CheckEquals('[A@A[2], A@D[0]]', TCollectionUtils.ListToString(Elements));
2034 end;
2035 
2036 procedure TestITreeWizard.TestVisitPatternMultipleWithLabels;
2037 var
2038   Adaptor: ITreeAdaptor;
2039   Wiz: ITreeWizard;
2040   T: ICommonTree;
2041   Elements: IList<IANTLRInterface>;
2042   Visitor: IContextVisitor;
2043 begin
2044   Adaptor := TCommonTreeAdaptor.Create;
2045   Wiz := TTreeWizard.Create(Adaptor, FTokens);
2046   T := Wiz.CreateTreeOrNode('(A B C (A[foo] B[bar]) (D (A[big] B[dog])))') as ICommonTree;
2047   Elements := TList<IANTLRInterface>.Create;
2048   Visitor := TTest2ContextVisitor.Create(Adaptor, Elements);
2049   Wiz.Visit(T, '(%a:A %b:B)', Visitor);
2050   CheckEquals('[foo@A[2]foo&bar, big@D[0]big&dog]', TCollectionUtils.ListToString(Elements));
2051 end;
2052 
2053 procedure TestITreeWizard.TestWildcard;
2054 var
2055   Adaptor: ITreeAdaptor;
2056   Wiz: ITreeWizard;
2057   T: ICommonTree;
2058 begin
2059   Adaptor := TCommonTreeAdaptor.Create;
2060   Wiz := TTreeWizard.Create(Adaptor, FTokens);
2061   T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
2062   CheckTrue(Wiz.Parse(T, '(A . .)'));
2063 end;
2064 
2065 { TestITreeWizard.TRecordAllElementsVisitor }
2066 
2067 constructor TestITreeWizard.TRecordAllElementsVisitor.Create(
2068   const AList: IList<IANTLRInterface>);
2069 begin
2070   inherited Create;
2071   FList := AList;
2072 end;
2073 
2074 procedure TestITreeWizard.TRecordAllElementsVisitor.Visit(
2075   const T: IANTLRInterface);
2076 begin
2077   FList.Add(T);
2078 end;
2079 
2080 { TestITreeWizard.TTest1ContextVisitor }
2081 
2082 constructor TestITreeWizard.TTest1ContextVisitor.Create(
2083   const AAdaptor: ITreeAdaptor; const AList: IList<IANTLRInterface>);
2084 begin
2085   inherited Create;
2086   FAdaptor := AAdaptor;
2087   FList := AList;
2088 end;
2089 
2090 procedure TestITreeWizard.TTest1ContextVisitor.Visit(const T,
2091   Parent: IANTLRInterface; const ChildIndex: Integer;
2092   const Labels: IDictionary<String, IANTLRInterface>);
2093 var
2094   S: String;
2095 begin
2096   S := FAdaptor.GetNodeText(T) + '@';
2097   if Assigned(Parent) then
2098     S := S + FAdaptor.GetNodeText(Parent)
2099   else
2100     S := S + 'nil';
2101   FList.Add(TANTLRString.Create(S + '[' + IntToStr(ChildIndex) + ']'));
2102 end;
2103 
2104 { TestITreeWizard.TTest2ContextVisitor }
2105 
2106 constructor TestITreeWizard.TTest2ContextVisitor.Create(
2107   const AAdaptor: ITreeAdaptor; const AList: IList<IANTLRInterface>);
2108 begin
2109   inherited Create;
2110   FAdaptor := AAdaptor;
2111   FList := AList;
2112 end;
2113 
2114 procedure TestITreeWizard.TTest2ContextVisitor.Visit(const T,
2115   Parent: IANTLRInterface; const ChildIndex: Integer;
2116   const Labels: IDictionary<String, IANTLRInterface>);
2117 var
2118   S: String;
2119 begin
2120   S := FAdaptor.GetNodeText(T) + '@';
2121   if Assigned(Parent) then
2122     S := S + FAdaptor.GetNodeText(Parent)
2123   else
2124     S := S + 'nil';
2125   FList.Add(TANTLRString.Create(S + '[' + IntToStr(ChildIndex) + ']'
2126     + Labels['a'].ToString + '&' + Labels['b'].ToString));
2127 end;
2128 
2129 initialization
2130   // Register any test cases with the test runner
2131   RegisterTest(TestICommonTree.Suite);
2132   RegisterTest(TestICommonTreeNodeStream.Suite);
2133   RegisterTest(TestIRewriteRuleXxxxStream.Suite);
2134   RegisterTest(TestITreeWizard.Suite);
2135 end.
2136 
2137