1unit 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
12interface
13
14uses
15  TestFramework,
16  Antlr.Runtime.Collections,
17  Antlr.Runtime.Tree,
18  Classes,
19  SysUtils,
20  Antlr.Runtime,
21  Antlr.Runtime.Tools;
22
23type
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
58    function CreateCommonTreeNodeStream(const T: IANTLRInterface): ITreeNodeStream;
59    function GetStringOfEntireStreamContentsWithNodeTypesOnly(
60      const Nodes: ITreeNodeStream): String;
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
89    function CreateTreeAdaptor: ITreeAdaptor;
90    function CreateTree(const Token: IToken): ITree;
91    function CreateToken(const TokenType: Integer; const Text: String): IToken;
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
196implementation
197
198procedure TestICommonTree.SetUp;
199begin
200end;
201
202procedure TestICommonTree.TearDown;
203begin
204end;
205
206procedure TestICommonTree.Test4Nodes;
207var
208  R0: ICommonTree;
209begin
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);
217end;
218
219procedure TestICommonTree.TestAddListToExistChildren;
220var
221  Root, R0, C0, C1, C2: ICommonTree;
222begin
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);
249end;
250
251procedure TestICommonTree.TestBecomeRoot;
252var
253  OldRoot, NewRoot: ICommonTree;
254  Adaptor: ITreeAdaptor;
255begin
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;
265end;
266
267procedure TestICommonTree.TestBecomeRoot2;
268var
269  OldRoot, NewRoot: ICommonTree;
270  Adaptor: ITreeAdaptor;
271begin
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;
280end;
281
282procedure TestICommonTree.TestBecomeRoot3;
283var
284  OldRoot, NewRoot: ICommonTree;
285  Adaptor: ITreeAdaptor;
286begin
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;
297end;
298
299procedure TestICommonTree.TestBecomeRoot5;
300var
301  OldRoot, NewRoot: ICommonTree;
302  Adaptor: ITreeAdaptor;
303begin
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;
313end;
314
315procedure TestICommonTree.TestBecomeRoot6;
316var
317  Root0, Root1: ICommonTree;
318  Adaptor: ITreeAdaptor;
319begin
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;
328end;
329
330procedure TestICommonTree.TestDupTree;
331var
332  R0, R1, Dup: ICommonTree;
333  R2: ITree;
334  Adaptor: ICommonTreeAdaptor;
335begin
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;
353end;
354
355procedure TestICommonTree.TestList;
356var
357  R0, C0, C1, C2: ICommonTree;
358begin
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);
376end;
377
378procedure TestICommonTree.TestList2;
379var
380  Root, R0, C0, C1, C2: ICommonTree;
381begin
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);
407end;
408
409procedure TestICommonTree.TestReplaceAllWithOne;
410var
411  T, NewChild: ICommonTree;
412begin
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;
421end;
422
423procedure TestICommonTree.TestReplaceAllWithTwo;
424var
425  Adaptor: ITreeAdaptor;
426  T, NewChildren: ICommonTree;
427begin
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;
439end;
440
441procedure TestICommonTree.TestReplaceAtLeft;
442var
443  T, NewChild: ICommonTree;
444begin
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;
453end;
454
455procedure TestICommonTree.TestReplaceAtRight;
456var
457  T, NewChild: ICommonTree;
458begin
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;
467end;
468
469procedure TestICommonTree.TestReplaceInMiddle;
470var
471  T, NewChild: ICommonTree;
472begin
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;
481end;
482
483procedure TestICommonTree.TestReplaceOneWithTwoAtLeft;
484var
485  Adaptor: ITreeAdaptor;
486  T, NewChildren: ICommonTree;
487begin
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;
499end;
500
501procedure TestICommonTree.TestReplaceOneWithTwoAtRight;
502var
503  Adaptor: ITreeAdaptor;
504  T, NewChildren: ICommonTree;
505begin
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;
517end;
518
519procedure TestICommonTree.TestReplaceOneWithTwoInMiddle;
520var
521  Adaptor: ITreeAdaptor;
522  T, NewChildren: ICommonTree;
523begin
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;
535end;
536
537procedure TestICommonTree.TestReplaceTwoWithOneAtLeft;
538var
539  T, NewChild: ICommonTree;
540begin
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;
549end;
550
551procedure TestICommonTree.TestReplaceTwoWithOneAtRight;
552var
553  T, NewChild: ICommonTree;
554begin
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;
563end;
564
565procedure TestICommonTree.TestReplaceWithNoChildren;
566var
567  T, NewChild: ICommonTree;
568  Error: Boolean;
569begin
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);
580end;
581
582procedure TestICommonTree.TestReplaceWithOneChildren;
583var
584  T, C0, NewChild: ICommonTree;
585begin
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;
594end;
595
596procedure TestICommonTree.TestSingleNode;
597var
598  T: ICommonTree;
599begin
600  T := TCommonTree.Create(TCommonToken.Create(101));
601  CheckNull(T.Parent);
602  CheckEquals(T.ChildIndex, -1);
603end;
604
605function TestICommonTreeNodeStream.CreateCommonTreeNodeStream(
606  const T: IANTLRInterface): ITreeNodeStream;
607begin
608  Result := TCommonTreeNodeStream.Create(T);
609end;
610
611function TestICommonTreeNodeStream.CreateUnBufferedTreeNodeStream(
612  const T: IANTLRInterface): ITreeNodeStream;
613begin
614  Result := TUnBufferedTreeNodeStream.Create(T);
615end;
616
617function TestICommonTreeNodeStream.GetStringOfEntireStreamContentsWithNodeTypesOnly(
618  const Nodes: ITreeNodeStream): String;
619var
620  Buf: TStringBuilder;
621  I, TokenType: Integer;
622  T: IANTLRInterface;
623begin
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;
640end;
641
642procedure TestICommonTreeNodeStream.SetUp;
643begin
644end;
645
646procedure TestICommonTreeNodeStream.TearDown;
647begin
648end;
649
650procedure TestICommonTreeNodeStream.Test4Nodes;
651var
652  T: ITree;
653  Stream: ITreeNodeStream;
654begin
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');
664end;
665
666procedure TestICommonTreeNodeStream.TestAoverB;
667var
668  T: ITree;
669  Stream: ITreeNodeStream;
670begin
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');
677end;
678
679procedure TestICommonTreeNodeStream.TestBufferOverflow;
680var
681  Buf, Buf2: TStringBuilder;
682  Stream: ITreeNodeStream;
683  T: ITree;
684  I: Integer;
685begin
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;
714end;
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>
728procedure TestICommonTreeNodeStream.TestBufferWrap;
729const
730  N = 10;
731  WrapBy = 4; // wrap around by 4 nodes
732var
733  T: ITree;
734  I, Remaining: Integer;
735  Stream: ITreeNodeStream;
736  Node: ITree;
737begin
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;
762end;
763
764procedure TestICommonTreeNodeStream.TestFlatList;
765var
766  Root: ITree;
767  Stream: ITreeNodeStream;
768begin
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');
777end;
778
779procedure TestICommonTreeNodeStream.TestList;
780var
781  Root, T, U: ITree;
782  Stream: ITreeNodeStream;
783begin
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');
799end;
800
801procedure TestICommonTreeNodeStream.TestListWithOneNode;
802var
803  Root: ITree;
804  Stream: ITreeNodeStream;
805begin
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');
812end;
813
814procedure TestICommonTreeNodeStream.TestLT;
815var
816  T: ITree;
817  Stream: ITreeNodeStream;
818begin
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);
837end;
838
839procedure TestICommonTreeNodeStream.TestMarkRewindEntire;
840var
841  R0, R1, R2: ITree;
842  Stream: ICommonTreeNodeStream;
843  M, K: Integer;
844begin
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);
878end;
879
880procedure TestICommonTreeNodeStream.TestMarkRewindInMiddle;
881var
882  R0, R1, R2: ITree;
883  Stream: ICommonTreeNodeStream;
884  M, K: Integer;
885begin
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);
928end;
929
930procedure TestICommonTreeNodeStream.TestMarkRewindNested;
931var
932  R0, R1, R2: ITree;
933  Stream: ICommonTreeNodeStream;
934  M, M2: Integer;
935begin
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);
972end;
973
974procedure TestICommonTreeNodeStream.TestNestedPushPop;
975const
976  IndexOf102 = 2;
977  IndexOf104 = 6;
978  IndexOf107 = 12;
979var
980  R0, R1, R2, R3: ITree;
981  Stream: ICommonTreeNodeStream;
982  K: Integer;
983begin
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);
1036end;
1037
1038procedure TestICommonTreeNodeStream.TestPushPop;
1039const
1040  IndexOf102 = 2;
1041  IndexOf107 = 12;
1042var
1043  R0, R1, R2, R3: ITree;
1044  Stream: ICommonTreeNodeStream;
1045  K: Integer;
1046begin
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);
1084end;
1085
1086procedure TestICommonTreeNodeStream.TestPushPopFromEOF;
1087const
1088  IndexOf102 = 2;
1089  IndexOf104 = 6;
1090var
1091  R0, R1, R2, R3: ITree;
1092  Stream: ICommonTreeNodeStream;
1093begin
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);
1142end;
1143
1144procedure TestICommonTreeNodeStream.TestSeek;
1145var
1146  R0, R1, R2: ITree;
1147  Stream: ICommonTreeNodeStream;
1148begin
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);
1172end;
1173
1174procedure TestICommonTreeNodeStream.TestSeekFromStart;
1175var
1176  R0, R1, R2: ITree;
1177  Stream: ICommonTreeNodeStream;
1178begin
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);
1199end;
1200
1201procedure TestICommonTreeNodeStream.TestSingleNode;
1202var
1203  T: ITree;
1204  Stream: ITreeNodeStream;
1205begin
1206  T := TCommonTree.Create(TCommonToken.Create(101));
1207  Stream := CreateCommonTreeNodeStream(T);
1208  CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101');
1209  CheckEquals(Stream.ToString, ' 101');
1210end;
1211
1212procedure TestICommonTreeNodeStream.TestStackStretch;
1213var
1214  R0: ICommonTree;
1215  Stream: ICommonTreeNodeStream;
1216  I: Integer;
1217begin
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);
1228end;
1229
1230function TestIRewriteRuleXxxxStream.CreateToken(const TokenType: Integer;
1231  const Text: String): IToken;
1232begin
1233  Result := TCommonToken.Create(TokenType, Text);
1234end;
1235
1236function TestIRewriteRuleXxxxStream.CreateTokenList(
1237  const Count: Integer): IList<IToken>;
1238var
1239  I: Integer;
1240begin
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'));
1245end;
1246
1247function TestIRewriteRuleXxxxStream.CreateTree(const Token: IToken): ITree;
1248begin
1249  Result := TCommonTree.Create(Token);
1250end;
1251
1252function TestIRewriteRuleXxxxStream.CreateTreeAdaptor: ITreeAdaptor;
1253begin
1254  Result := TCommonTreeAdaptor.Create;
1255end;
1256
1257procedure TestIRewriteRuleXxxxStream.SetUp;
1258begin
1259end;
1260
1261procedure TestIRewriteRuleXxxxStream.TearDown;
1262begin
1263end;
1264
1265procedure TestIRewriteRuleXxxxStream.TestRewriteRuleNodeStreamConstructors;
1266var
1267  NodeTest1, NodeTest2, NodeTest3: IRewriteRuleNodeStream;
1268begin
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));
1278end;
1279
1280procedure TestIRewriteRuleXxxxStream.TestRewriteRuleSubtreeStreamConstructors;
1281var
1282  SubtreeTest1, SubtreeTest2, SubtreeTest3: IRewriteRuleSubtreeStream;
1283begin
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));
1293end;
1294
1295procedure TestIRewriteRuleXxxxStream.TestRewriteRuleTokenStreamConstructors;
1296var
1297  TokenTest1, TokenTest2, TokenTest3: IRewriteRuleTokenStream;
1298begin
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));
1308end;
1309
1310procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWhileEmpty1;
1311const
1312  Description = 'RewriteRuleNodeStream test';
1313var
1314  NodeTest: IRewriteRuleNodeStream;
1315begin
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;
1325end;
1326
1327procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWhileEmpty2;
1328const
1329  Description = 'RewriteRuleNodeStream test';
1330var
1331  NodeTest: IRewriteRuleNodeStream;
1332begin
1333  ExpectedException := ERewriteEmptyStreamException;
1334  NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, Description);
1335  NodeTest.NextTree;
1336end;
1337
1338procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWithElements;
1339var
1340  NodeTest: IRewriteRuleNodeStream;
1341  Token1, Token2: IToken;
1342  Tree1, Tree2: ITree;
1343  ReturnedTree: ICommonTree;
1344begin
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;
1389end;
1390
1391procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWhileEmpty1;
1392const
1393  Description = 'RewriteRuleSubtreeStream test';
1394var
1395  SubtreeTest: IRewriteRuleSubtreeStream;
1396begin
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;
1406end;
1407
1408procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWhileEmpty2;
1409const
1410  Description = 'RewriteRuleSubtreeStream test';
1411var
1412  SubtreeTest: IRewriteRuleSubtreeStream;
1413begin
1414  ExpectedException := ERewriteEmptyStreamException;
1415  SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, Description);
1416  SubtreeTest.NextTree;
1417end;
1418
1419procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWithElements;
1420var
1421  SubtreeTest: IRewriteRuleSubtreeStream;
1422  Token1, Token2: IToken;
1423  Tree1, Tree2: ITree;
1424  ReturnedTree: ICommonTree;
1425begin
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;
1469end;
1470
1471procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty1;
1472const
1473  Description = 'RewriteRuleTokenStream test';
1474var
1475  TokenTest: IRewriteRuleTokenStream;
1476begin
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;
1486end;
1487
1488procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty2;
1489const
1490  Description = 'RewriteRuleTokenStream test';
1491var
1492  TokenTest: IRewriteRuleTokenStream;
1493begin
1494  ExpectedException := ERewriteEmptyStreamException;
1495  TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description);
1496  TokenTest.NextTree;
1497end;
1498
1499procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty3;
1500const
1501  Description = 'RewriteRuleTokenStream test';
1502var
1503  TokenTest: IRewriteRuleTokenStream;
1504begin
1505  ExpectedException := ERewriteEmptyStreamException;
1506  TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description);
1507  TokenTest.NextToken;
1508end;
1509
1510procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWithElements;
1511var
1512  TokenTest: IRewriteRuleTokenStream;
1513  Token1, Token2, ReturnedToken: IToken;
1514  Tree: ICommonTree;
1515begin
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;
1567end;
1568
1569constructor TestITreeWizard.Create(MethodName: String);
1570const
1571  TOKENS: array [0..11] of String = ('', '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'ID', 'VAR');
1572var
1573  I: Integer;
1574begin
1575  inherited;
1576  SetLength(FTokens,Length(TOKENS));
1577  for I := 0 to Length(TOKENS) - 1 do
1578    FTokens[I] := TOKENS[I];
1579end;
1580
1581procedure TestITreeWizard.SetUp;
1582begin
1583end;
1584
1585procedure TestITreeWizard.TearDown;
1586begin
1587end;
1588
1589procedure TestITreeWizard.TestDoubleLevelTree;
1590var
1591  Adaptor: ITreeAdaptor;
1592  Wiz: ITreeWizard;
1593  T: ICommonTree;
1594begin
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)');
1599end;
1600
1601procedure TestITreeWizard.TestEquals;
1602var
1603  Adaptor: ITreeAdaptor;
1604  Wiz: ITreeWizard;
1605  T1, T2: ICommonTree;
1606begin
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));
1612end;
1613
1614procedure TestITreeWizard.TestEqualsWithMismatchedText;
1615var
1616  Adaptor: ITreeAdaptor;
1617  Wiz: ITreeWizard;
1618  T1, T2: ICommonTree;
1619begin
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));
1625end;
1626
1627procedure TestITreeWizard.TestEqualsWithText;
1628var
1629  Adaptor: ITreeAdaptor;
1630  Wiz: ITreeWizard;
1631  T1, T2: ICommonTree;
1632begin
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));
1638end;
1639
1640procedure TestITreeWizard.TestFindPattern;
1641var
1642  Adaptor: ITreeAdaptor;
1643  Wiz: ITreeWizard;
1644  T: ICommonTree;
1645  Subtrees, Elements: IList<IANTLRInterface>;
1646begin
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));
1653end;
1654
1655procedure TestITreeWizard.TestInvalidListTree;
1656var
1657  Adaptor: ITreeAdaptor;
1658  Wiz: ITreeWizard;
1659  T: ICommonTree;
1660begin
1661  Adaptor := TCommonTreeAdaptor.Create;
1662  Wiz := TTreeWizard.Create(Adaptor, FTokens);
1663  T := Wiz.CreateTreeOrNode('A B C') as ICommonTree;
1664  CheckNull(T);
1665end;
1666
1667procedure TestITreeWizard.TestListTree;
1668var
1669  Adaptor: ITreeAdaptor;
1670  Wiz: ITreeWizard;
1671  T: ICommonTree;
1672begin
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');
1677end;
1678
1679procedure TestITreeWizard.TestNoRepeatsIndex;
1680var
1681  Adaptor: ITreeAdaptor;
1682  Wiz: ITreeWizard;
1683  T: ICommonTree;
1684  M: IDictionary<Integer, IList<IANTLRInterface>>;
1685begin
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));
1691end;
1692
1693procedure TestITreeWizard.TestNoRepeatsVisit;
1694var
1695  Adaptor: ITreeAdaptor;
1696  Wiz: ITreeWizard;
1697  T: ICommonTree;
1698  Elements: IList<IANTLRInterface>;
1699  Visitor: IContextVisitor;
1700begin
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));
1708end;
1709
1710procedure TestITreeWizard.TestNoRepeatsVisit2;
1711var
1712  Adaptor: ITreeAdaptor;
1713  Wiz: ITreeWizard;
1714  T: ICommonTree;
1715  Elements: IList<IANTLRInterface>;
1716  Visitor: IContextVisitor;
1717begin
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));
1725end;
1726
1727procedure TestITreeWizard.TestParse;
1728var
1729  Adaptor: ITreeAdaptor;
1730  Wiz: ITreeWizard;
1731  T: ICommonTree;
1732begin
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)'));
1737end;
1738
1739procedure TestITreeWizard.TestParseFlatTree;
1740var
1741  Adaptor: ITreeAdaptor;
1742  Wiz: ITreeWizard;
1743  T: ICommonTree;
1744begin
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)'));
1749end;
1750
1751procedure TestITreeWizard.TestParseLabels;
1752var
1753  Adaptor: ITreeAdaptor;
1754  Wiz: ITreeWizard;
1755  T: ICommonTree;
1756  Labels: IDictionary<String, IANTLRInterface>;
1757begin
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);
1766end;
1767
1768procedure TestITreeWizard.TestParseLabelsAndTestText;
1769var
1770  Adaptor: ITreeAdaptor;
1771  Wiz: ITreeWizard;
1772  T: ICommonTree;
1773  Labels: IDictionary<String, IANTLRInterface>;
1774begin
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);
1783end;
1784
1785procedure TestITreeWizard.TestParseLabelsInNestedTree;
1786var
1787  Adaptor: ITreeAdaptor;
1788  Wiz: ITreeWizard;
1789  T: ICommonTree;
1790  Labels: IDictionary<String, IANTLRInterface>;
1791begin
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);
1802end;
1803
1804procedure TestITreeWizard.TestParseSingleNode;
1805var
1806  Adaptor: ITreeAdaptor;
1807  Wiz: ITreeWizard;
1808  T: ICommonTree;
1809begin
1810  Adaptor := TCommonTreeAdaptor.Create;
1811  Wiz := TTreeWizard.Create(Adaptor, FTokens);
1812  T := Wiz.CreateTreeOrNode('A') as ICommonTree;
1813  CheckTrue(Wiz.Parse(T, 'A'));
1814end;
1815
1816procedure TestITreeWizard.TestParseWithText;
1817var
1818  Adaptor: ITreeAdaptor;
1819  Wiz: ITreeWizard;
1820  T: ICommonTree;
1821begin
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)'));
1828end;
1829
1830procedure TestITreeWizard.TestParseWithTextFails;
1831var
1832  Adaptor: ITreeAdaptor;
1833  Wiz: ITreeWizard;
1834  T: ICommonTree;
1835begin
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)'));
1840end;
1841
1842procedure TestITreeWizard.TestParseWithWildcardLabels;
1843var
1844  Adaptor: ITreeAdaptor;
1845  Wiz: ITreeWizard;
1846  T: ICommonTree;
1847  Labels: IDictionary<String, IANTLRInterface>;
1848begin
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);
1856end;
1857
1858procedure TestITreeWizard.TestRepeatsIndex;
1859var
1860  Adaptor: ITreeAdaptor;
1861  Wiz: ITreeWizard;
1862  T: ICommonTree;
1863  M: IDictionary<Integer, IList<IANTLRInterface>>;
1864begin
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));
1870end;
1871
1872procedure TestITreeWizard.TestRepeatsVisit;
1873var
1874  Adaptor: ITreeAdaptor;
1875  Wiz: ITreeWizard;
1876  T: ICommonTree;
1877  Elements: IList<IANTLRInterface>;
1878  Visitor: IContextVisitor;
1879begin
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));
1887end;
1888
1889procedure TestITreeWizard.TestRepeatsVisit2;
1890var
1891  Adaptor: ITreeAdaptor;
1892  Wiz: ITreeWizard;
1893  T: ICommonTree;
1894  Elements: IList<IANTLRInterface>;
1895  Visitor: IContextVisitor;
1896begin
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));
1904end;
1905
1906procedure TestITreeWizard.TestRepeatsVisitWithContext;
1907var
1908  Adaptor: ITreeAdaptor;
1909  Wiz: ITreeWizard;
1910  T: ICommonTree;
1911  Elements: IList<IANTLRInterface>;
1912  Visitor: IContextVisitor;
1913begin
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));
1921end;
1922
1923procedure TestITreeWizard.TestRepeatsVisitWithNullParentAndContext;
1924var
1925  Adaptor: ITreeAdaptor;
1926  Wiz: ITreeWizard;
1927  T: ICommonTree;
1928  Elements: IList<IANTLRInterface>;
1929  Visitor: IContextVisitor;
1930begin
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));
1938end;
1939
1940procedure TestITreeWizard.TestSingleLevelTree;
1941var
1942  Adaptor: ITreeAdaptor;
1943  Wiz: ITreeWizard;
1944  T: ICommonTree;
1945begin
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)');
1950end;
1951
1952procedure TestITreeWizard.TestSingleNode;
1953var
1954  Adaptor: ITreeAdaptor;
1955  Wiz: ITreeWizard;
1956  T: ICommonTree;
1957begin
1958  Adaptor := TCommonTreeAdaptor.Create;
1959  Wiz := TTreeWizard.Create(Adaptor, FTokens);
1960  T := Wiz.CreateTreeOrNode('ID') as ICommonTree;
1961  CheckEquals(T.ToStringTree, 'ID');
1962end;
1963
1964procedure TestITreeWizard.TestSingleNodeIndex;
1965var
1966  Adaptor: ITreeAdaptor;
1967  Wiz: ITreeWizard;
1968  T: ICommonTree;
1969  M: IDictionary<Integer, IList<IANTLRInterface>>;
1970begin
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));
1976end;
1977
1978procedure TestITreeWizard.TestSingleNodeTree;
1979var
1980  Adaptor: ITreeAdaptor;
1981  Wiz: ITreeWizard;
1982  T: ICommonTree;
1983begin
1984  Adaptor := TCommonTreeAdaptor.Create;
1985  Wiz := TTreeWizard.Create(Adaptor, FTokens);
1986  T := Wiz.CreateTreeOrNode('(A)') as ICommonTree;
1987  CheckEquals(T.ToStringTree, 'A');
1988end;
1989
1990procedure TestITreeWizard.TestSingleNodeWithArg;
1991var
1992  Adaptor: ITreeAdaptor;
1993  Wiz: ITreeWizard;
1994  T: ICommonTree;
1995begin
1996  Adaptor := TCommonTreeAdaptor.Create;
1997  Wiz := TTreeWizard.Create(Adaptor, FTokens);
1998  T := Wiz.CreateTreeOrNode('ID[foo]') as ICommonTree;
1999  CheckEquals(T.ToStringTree, 'foo');
2000end;
2001
2002procedure TestITreeWizard.TestVisitPattern;
2003var
2004  Adaptor: ITreeAdaptor;
2005  Wiz: ITreeWizard;
2006  T: ICommonTree;
2007  Elements: IList<IANTLRInterface>;
2008  Visitor: IContextVisitor;
2009begin
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));
2017end;
2018
2019procedure TestITreeWizard.TestVisitPatternMultiple;
2020var
2021  Adaptor: ITreeAdaptor;
2022  Wiz: ITreeWizard;
2023  T: ICommonTree;
2024  Elements: IList<IANTLRInterface>;
2025  Visitor: IContextVisitor;
2026begin
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));
2034end;
2035
2036procedure TestITreeWizard.TestVisitPatternMultipleWithLabels;
2037var
2038  Adaptor: ITreeAdaptor;
2039  Wiz: ITreeWizard;
2040  T: ICommonTree;
2041  Elements: IList<IANTLRInterface>;
2042  Visitor: IContextVisitor;
2043begin
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));
2051end;
2052
2053procedure TestITreeWizard.TestWildcard;
2054var
2055  Adaptor: ITreeAdaptor;
2056  Wiz: ITreeWizard;
2057  T: ICommonTree;
2058begin
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 . .)'));
2063end;
2064
2065{ TestITreeWizard.TRecordAllElementsVisitor }
2066
2067constructor TestITreeWizard.TRecordAllElementsVisitor.Create(
2068  const AList: IList<IANTLRInterface>);
2069begin
2070  inherited Create;
2071  FList := AList;
2072end;
2073
2074procedure TestITreeWizard.TRecordAllElementsVisitor.Visit(
2075  const T: IANTLRInterface);
2076begin
2077  FList.Add(T);
2078end;
2079
2080{ TestITreeWizard.TTest1ContextVisitor }
2081
2082constructor TestITreeWizard.TTest1ContextVisitor.Create(
2083  const AAdaptor: ITreeAdaptor; const AList: IList<IANTLRInterface>);
2084begin
2085  inherited Create;
2086  FAdaptor := AAdaptor;
2087  FList := AList;
2088end;
2089
2090procedure TestITreeWizard.TTest1ContextVisitor.Visit(const T,
2091  Parent: IANTLRInterface; const ChildIndex: Integer;
2092  const Labels: IDictionary<String, IANTLRInterface>);
2093var
2094  S: String;
2095begin
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) + ']'));
2102end;
2103
2104{ TestITreeWizard.TTest2ContextVisitor }
2105
2106constructor TestITreeWizard.TTest2ContextVisitor.Create(
2107  const AAdaptor: ITreeAdaptor; const AList: IList<IANTLRInterface>);
2108begin
2109  inherited Create;
2110  FAdaptor := AAdaptor;
2111  FList := AList;
2112end;
2113
2114procedure TestITreeWizard.TTest2ContextVisitor.Visit(const T,
2115  Parent: IANTLRInterface; const ChildIndex: Integer;
2116  const Labels: IDictionary<String, IANTLRInterface>);
2117var
2118  S: String;
2119begin
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));
2127end;
2128
2129initialization
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);
2135end.
2136
2137