unit Antlr.Runtime.Tree.Tests; { Delphi DUnit Test Case ---------------------- This unit contains a skeleton test case class generated by the Test Case Wizard. Modify the generated code to correctly setup and call the methods from the unit being tested. } interface uses TestFramework, Antlr.Runtime.Collections, Antlr.Runtime.Tree, Classes, SysUtils, Antlr.Runtime, Antlr.Runtime.Tools; type // Test methods for class ICommonTree TestICommonTree = class(TTestCase) public procedure SetUp; override; procedure TearDown; override; published procedure TestSingleNode; procedure Test4Nodes; procedure TestList; procedure TestList2; procedure TestAddListToExistChildren; procedure TestDupTree; procedure TestBecomeRoot; procedure TestBecomeRoot2; procedure TestBecomeRoot3; procedure TestBecomeRoot5; procedure TestBecomeRoot6; procedure TestReplaceWithNoChildren; procedure TestReplaceWithOneChildren; procedure TestReplaceInMiddle; procedure TestReplaceAtLeft; procedure TestReplaceAtRight; procedure TestReplaceOneWithTwoAtLeft; procedure TestReplaceOneWithTwoAtRight; procedure TestReplaceOneWithTwoInMiddle; procedure TestReplaceTwoWithOneAtLeft; procedure TestReplaceTwoWithOneAtRight; procedure TestReplaceAllWithOne; procedure TestReplaceAllWithTwo; end; // Test methods for class ICommonTreeNodeStream TestICommonTreeNodeStream = class(TTestCase) private function CreateCommonTreeNodeStream(const T: IANTLRInterface): ITreeNodeStream; function GetStringOfEntireStreamContentsWithNodeTypesOnly( const Nodes: ITreeNodeStream): String; function CreateUnBufferedTreeNodeStream(const T: IANTLRInterface): ITreeNodeStream; public procedure SetUp; override; procedure TearDown; override; published procedure TestSingleNode; procedure Test4Nodes; procedure TestList; procedure TestFlatList; procedure TestListWithOneNode; procedure TestAoverB; procedure TestLT; procedure TestMarkRewindEntire; procedure TestMarkRewindInMiddle; procedure TestMarkRewindNested; procedure TestSeek; procedure TestSeekFromStart; procedure TestPushPop; procedure TestNestedPushPop; procedure TestPushPopFromEOF; procedure TestStackStretch; procedure TestBufferOverflow; procedure TestBufferWrap; end; // Test methods for class IRewriteRuleXxxxStream TestIRewriteRuleXxxxStream = class(TTestCase) strict private function CreateTreeAdaptor: ITreeAdaptor; function CreateTree(const Token: IToken): ITree; function CreateToken(const TokenType: Integer; const Text: String): IToken; function CreateTokenList(const Count: Integer): IList; public procedure SetUp; override; procedure TearDown; override; published procedure TestRewriteRuleTokenStreamConstructors; procedure TestRewriteRuleSubtreeStreamConstructors; procedure TestRewriteRuleNodeStreamConstructors; procedure TestRRTokenStreamBehaviourWhileEmpty1; procedure TestRRSubtreeStreamBehaviourWhileEmpty1; procedure TestRRNodeStreamBehaviourWhileEmpty1; procedure TestRRTokenStreamBehaviourWhileEmpty2; procedure TestRRSubtreeStreamBehaviourWhileEmpty2; procedure TestRRNodeStreamBehaviourWhileEmpty2; procedure TestRRTokenStreamBehaviourWhileEmpty3; procedure TestRRTokenStreamBehaviourWithElements; procedure TestRRSubtreeStreamBehaviourWithElements; procedure TestRRNodeStreamBehaviourWithElements; end; // Test methods for class ITreeWizard TestITreeWizard = class(TTestCase) strict private FTokens: TStringArray; strict private type TRecordAllElementsVisitor = class sealed(TTreeWizard.TVisitor) strict private FList: IList; strict protected procedure Visit(const T: IANTLRInterface); override; public constructor Create(const AList: IList); end; TTest1ContextVisitor = class sealed(TANTLRObject, IContextVisitor) strict private FAdaptor: ITreeAdaptor; FList: IList; protected { IContextVisitor } procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer; const Labels: IDictionary); public constructor Create(const AAdaptor: ITreeAdaptor; const AList: IList); end; TTest2ContextVisitor = class sealed(TANTLRObject, IContextVisitor) strict private FAdaptor: ITreeAdaptor; FList: IList; protected { IContextVisitor } procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer; const Labels: IDictionary); public constructor Create(const AAdaptor: ITreeAdaptor; const AList: IList); end; public constructor Create(MethodName: String); override; procedure SetUp; override; procedure TearDown; override; published procedure TestSingleNode; procedure TestSingleNodeWithArg; procedure TestSingleNodeTree; procedure TestSingleLevelTree; procedure TestListTree; procedure TestInvalidListTree; procedure TestDoubleLevelTree; procedure TestSingleNodeIndex; procedure TestNoRepeatsIndex; procedure TestRepeatsIndex; procedure TestNoRepeatsVisit; procedure TestNoRepeatsVisit2; procedure TestRepeatsVisit; procedure TestRepeatsVisit2; procedure TestRepeatsVisitWithContext; procedure TestRepeatsVisitWithNullParentAndContext; procedure TestVisitPattern; procedure TestVisitPatternMultiple; procedure TestVisitPatternMultipleWithLabels; procedure TestParse; procedure TestParseSingleNode; procedure TestParseFlatTree; procedure TestWildcard; procedure TestParseWithText; procedure TestParseWithTextFails; procedure TestParseLabels; procedure TestParseWithWildcardLabels; procedure TestParseLabelsAndTestText; procedure TestParseLabelsInNestedTree; procedure TestEquals; procedure TestEqualsWithText; procedure TestEqualsWithMismatchedText; procedure TestFindPattern; end; implementation procedure TestICommonTree.SetUp; begin end; procedure TestICommonTree.TearDown; begin end; procedure TestICommonTree.Test4Nodes; var R0: ICommonTree; begin // ^(101 ^(102 103) 104) R0 := TCommonTree.Create(TCommonToken.Create(101)); R0.AddChild(TCommonTree.Create(TCommonToken.Create(102))); R0.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(104))); CheckNull(R0.Parent); CheckEquals(R0.ChildIndex,-1); end; procedure TestICommonTree.TestAddListToExistChildren; var Root, R0, C0, C1, C2: ICommonTree; begin // Add child ^(nil 101 102 103) to root ^(5 6) // should add 101 102 103 to end of 5's child list Root := TCommonTree.Create(TCommonToken.Create(5)); Root.AddChild(TCommonTree.Create(TCommonToken.Create(6))); // child tree R0 := TCommonTree.Create(IToken(nil)); C0 := TCommonTree.Create(TCommonToken.Create(101)); C1 := TCommonTree.Create(TCommonToken.Create(102)); C2 := TCommonTree.Create(TCommonToken.Create(103)); R0.AddChild(C0); R0.AddChild(C1); R0.AddChild(C2); Root.AddChild(R0); CheckNull(Root.Parent); CheckEquals(Root.ChildIndex, -1); // check children of root all point at root Check(C0.Parent = Root); Check(C0.ChildIndex = 1); Check(C1.Parent = Root); Check(C1.ChildIndex = 2); Check(C2.Parent = Root); Check(C2.ChildIndex = 3); end; procedure TestICommonTree.TestBecomeRoot; var OldRoot, NewRoot: ICommonTree; Adaptor: ITreeAdaptor; begin // 5 becomes new root of ^(nil 101 102 103) NewRoot := TCommonTree.Create(TCommonToken.Create(5)); OldRoot := TCommonTree.Create(IToken(nil)); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(101))); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102))); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103))); Adaptor := TCommonTreeAdaptor.Create; Adaptor.BecomeRoot(NewRoot, OldRoot); NewRoot.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestBecomeRoot2; var OldRoot, NewRoot: ICommonTree; Adaptor: ITreeAdaptor; begin // 5 becomes new root of ^(101 102 103) NewRoot := TCommonTree.Create(TCommonToken.Create(5)); OldRoot := TCommonTree.Create(TCommonToken.Create(101)); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102))); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103))); Adaptor := TCommonTreeAdaptor.Create; Adaptor.BecomeRoot(NewRoot, OldRoot); NewRoot.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestBecomeRoot3; var OldRoot, NewRoot: ICommonTree; Adaptor: ITreeAdaptor; begin // ^(nil 5) becomes new root of ^(nil 101 102 103) NewRoot := TCommonTree.Create(IToken(nil)); NewRoot.AddChild(TCommonTree.Create(TCommonToken.Create(5))); OldRoot := TCommonTree.Create(IToken(nil)); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(101))); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102))); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103))); Adaptor := TCommonTreeAdaptor.Create; Adaptor.BecomeRoot(NewRoot, OldRoot); NewRoot.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestBecomeRoot5; var OldRoot, NewRoot: ICommonTree; Adaptor: ITreeAdaptor; begin // ^(nil 5) becomes new root of ^(101 102 103) NewRoot := TCommonTree.Create(IToken(nil)); NewRoot.AddChild(TCommonTree.Create(TCommonToken.Create(5))); OldRoot := TCommonTree.Create(TCommonToken.Create(101)); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102))); OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103))); Adaptor := TCommonTreeAdaptor.Create; Adaptor.BecomeRoot(NewRoot, OldRoot); NewRoot.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestBecomeRoot6; var Root0, Root1: ICommonTree; Adaptor: ITreeAdaptor; begin // emulates construction of ^(5 6) Adaptor := TCommonTreeAdaptor.Create; Root0 := Adaptor.GetNilNode as ICommonTree; Root1 := Adaptor.GetNilNode as ICommonTree; Root1 := Adaptor.BecomeRoot(TCommonTree.Create(TCommonToken.Create(5)), Root1) as ICommonTree; Adaptor.AddChild(Root1, TCommonTree.Create(TCommonToken.Create(6))); Adaptor.AddChild(Root0, Root1); Root0.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestDupTree; var R0, R1, Dup: ICommonTree; R2: ITree; Adaptor: ICommonTreeAdaptor; begin // ^(101 ^(102 103 ^(106 107) ) 104 105) R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R0.AddChild(R1); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R2 := TCommonTree.Create(TCommonToken.Create(106)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R1.AddChild(R2); R0.AddChild(TCommonTree.Create(TCommonToken.Create(104))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(105))); Adaptor := TCommonTreeAdaptor.Create; Dup := Adaptor.DupTree(R0) as ICommonTree; CheckNull(Dup.Parent); CheckEquals(Dup.ChildIndex, -1); Dup.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestList; var R0, C0, C1, C2: ICommonTree; begin // ^(nil 101 102 103) R0 := TCommonTree.Create(IToken(nil)); C0 := TCommonTree.Create(TCommonToken.Create(101)); C1 := TCommonTree.Create(TCommonToken.Create(102)); C2 := TCommonTree.Create(TCommonToken.Create(103)); R0.AddChild(C0); R0.AddChild(C1); R0.AddChild(C2); CheckNull(R0.Parent); CheckEquals(R0.ChildIndex, -1); Check(C0.Parent = R0); CheckEquals(C0.ChildIndex, 0); Check(C1.Parent = R0); CheckEquals(C1.ChildIndex, 1); Check(C2.Parent = R0); CheckEquals(C2.ChildIndex, 2); end; procedure TestICommonTree.TestList2; var Root, R0, C0, C1, C2: ICommonTree; begin // Add child ^(nil 101 102 103) to root 5 // should pull 101 102 103 directly to become 5's child list Root := TCommonTree.Create(TClassicToken.Create(5)); // child tree R0 := TCommonTree.Create(IToken(nil)); C0 := TCommonTree.Create(TCommonToken.Create(101)); C1 := TCommonTree.Create(TCommonToken.Create(102)); C2 := TCommonTree.Create(TCommonToken.Create(103)); R0.AddChild(C0); R0.AddChild(C1); R0.AddChild(C2); Root.AddChild(R0); CheckNull(Root.Parent); CheckEquals(Root.ChildIndex, -1); // check children of root all point at root Check(C0.Parent = Root); Check(C0.ChildIndex = 0); Check(C1.Parent = Root); Check(C1.ChildIndex = 1); Check(C2.Parent = Root); Check(C2.ChildIndex = 2); end; procedure TestICommonTree.TestReplaceAllWithOne; var T, NewChild: ICommonTree; begin T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x')); T.ReplaceChildren(0, 2, NewChild); CheckEquals(T.ToStringTree, '(a x)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceAllWithTwo; var Adaptor: ITreeAdaptor; T, NewChildren: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChildren := Adaptor.GetNilNode as ICommonTree; NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x'))); NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y'))); T.ReplaceChildren(0, 2, NewChildren); CheckEquals(T.ToStringTree, '(a x y)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceAtLeft; var T, NewChild: ICommonTree; begin T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); // index 0 T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x')); T.ReplaceChildren(0, 0, NewChild); CheckEquals(T.ToStringTree, '(a x c d)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceAtRight; var T, NewChild: ICommonTree; begin T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); // index 2 NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x')); T.ReplaceChildren(2, 2, NewChild); CheckEquals(T.ToStringTree, '(a b c x)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceInMiddle; var T, NewChild: ICommonTree; begin T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); // index 1 T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x')); T.ReplaceChildren(1, 1, NewChild); CheckEquals(T.ToStringTree, '(a b x d)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceOneWithTwoAtLeft; var Adaptor: ITreeAdaptor; T, NewChildren: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChildren := Adaptor.GetNilNode as ICommonTree; NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x'))); NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y'))); T.ReplaceChildren(0, 0, NewChildren); CheckEquals(T.ToStringTree, '(a x y c d)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceOneWithTwoAtRight; var Adaptor: ITreeAdaptor; T, NewChildren: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChildren := Adaptor.GetNilNode as ICommonTree; NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x'))); NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y'))); T.ReplaceChildren(2, 2, NewChildren); CheckEquals(T.ToStringTree, '(a b c x y)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceOneWithTwoInMiddle; var Adaptor: ITreeAdaptor; T, NewChildren: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChildren := Adaptor.GetNilNode as ICommonTree; NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x'))); NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y'))); T.ReplaceChildren(1, 1, NewChildren); CheckEquals(T.ToStringTree, '(a b x y d)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceTwoWithOneAtLeft; var T, NewChild: ICommonTree; begin T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x')); T.ReplaceChildren(0, 1, NewChild); CheckEquals(T.ToStringTree, '(a x d)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceTwoWithOneAtRight; var T, NewChild: ICommonTree; begin T := TCommonTree.Create(TCommonToken.Create(99, 'a')); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x')); T.ReplaceChildren(1, 2, NewChild); CheckEquals(T.ToStringTree, '(a b x)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestReplaceWithNoChildren; var T, NewChild: ICommonTree; Error: Boolean; begin Exit; // already checked. Avoid exception T := TCommonTree.Create(TCommonToken.Create(101)); NewChild := TCommonTree.Create(TCommonToken.Create(5)); Error := False; try T.ReplaceChildren(0, 0, NewChild); except Error := True; end; CheckTrue(Error); end; procedure TestICommonTree.TestReplaceWithOneChildren; var T, C0, NewChild: ICommonTree; begin // assume token type 99 and use text T := TCommonTree.Create(TCommonToken.Create(99, 'a')); C0 := TCommonTree.Create(TCommonToken.Create(99, 'b')); T.AddChild(C0); NewChild := TCommonTree.Create(TCommonToken.Create(99, 'c')); T.ReplaceChildren(0, 0, NewChild); CheckEquals(T.ToStringTree,'(a c)'); T.SanityCheckParentAndChildIndexes; end; procedure TestICommonTree.TestSingleNode; var T: ICommonTree; begin T := TCommonTree.Create(TCommonToken.Create(101)); CheckNull(T.Parent); CheckEquals(T.ChildIndex, -1); end; function TestICommonTreeNodeStream.CreateCommonTreeNodeStream( const T: IANTLRInterface): ITreeNodeStream; begin Result := TCommonTreeNodeStream.Create(T); end; function TestICommonTreeNodeStream.CreateUnBufferedTreeNodeStream( const T: IANTLRInterface): ITreeNodeStream; begin Result := TUnBufferedTreeNodeStream.Create(T); end; function TestICommonTreeNodeStream.GetStringOfEntireStreamContentsWithNodeTypesOnly( const Nodes: ITreeNodeStream): String; var Buf: TStringBuilder; I, TokenType: Integer; T: IANTLRInterface; begin Buf := TStringBuilder.Create; try for I := 0 to Nodes.Size - 1 do begin T := Nodes.LT(I + 1); TokenType := Nodes.TreeAdaptor.GetNodeType(T); if (TokenType <> TToken.DOWN) and (TokenType <> TToken.UP) then begin Buf.Append(' '); Buf.Append(TokenType) end; end; Result := Buf.ToString; finally Buf.Free; end; end; procedure TestICommonTreeNodeStream.SetUp; begin end; procedure TestICommonTreeNodeStream.TearDown; begin end; procedure TestICommonTreeNodeStream.Test4Nodes; var T: ITree; Stream: ITreeNodeStream; begin /// Test a tree with four nodes - ^(101 ^(102 103) 104) T := TCommonTree.Create(TCommonToken.Create(101)); T.AddChild(TCommonTree.Create(TCommonToken.Create(102))); T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103))); T.AddChild(TCommonTree.Create(TCommonToken.Create(104))); Stream := CreateCommonTreeNodeStream(T); CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103 104'); CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 3'); end; procedure TestICommonTreeNodeStream.TestAoverB; var T: ITree; Stream: ITreeNodeStream; begin T := TCommonTree.Create(TCommonToken.Create(101)); T.AddChild(TCommonTree.Create(TCommonToken.Create(102))); Stream := CreateCommonTreeNodeStream(T); CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102'); CheckEquals(Stream.ToString, ' 101 2 102 3'); end; procedure TestICommonTreeNodeStream.TestBufferOverflow; var Buf, Buf2: TStringBuilder; Stream: ITreeNodeStream; T: ITree; I: Integer; begin Buf := TStringBuilder.Create; Buf2 := TStringBuilder.Create; try // make ^(101 102 ... n) T := TCommonTree.Create(TCommonToken.Create(101)); Buf.Append(' 101'); Buf2.Append(' 101'); Buf2.Append(' '); Buf2.Append(TToken.DOWN); for I := 0 to TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE + 10 do begin T.AddChild(TCommonTree.Create(TCommonToken.Create(102 + I))); Buf.Append(' '); Buf.Append(102 + I); Buf2.Append(' '); Buf2.Append(102 + I); end; Buf2.Append(' '); Buf2.Append(TToken.UP); Stream := CreateUnBufferedTreeNodeStream(T); CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream), Buf.ToString); CheckEquals(Stream.ToString, Buf2.ToString); finally Buf2.Free; Buf.Free; end; end; /// /// Test what happens when tail hits the end of the buffer, but there /// is more room left. /// /// /// Specifically that would mean that head is not at 0 but has /// advanced somewhere to the middle of the lookahead buffer. /// /// Use Consume() to advance N nodes into lookahead. Then use LT() /// to load at least INITIAL_LOOKAHEAD_BUFFER_SIZE-N nodes so the /// buffer has to wrap. /// procedure TestICommonTreeNodeStream.TestBufferWrap; const N = 10; WrapBy = 4; // wrap around by 4 nodes var T: ITree; I, Remaining: Integer; Stream: ITreeNodeStream; Node: ITree; begin // make tree with types: 1 2 ... INITIAL_LOOKAHEAD_BUFFER_SIZE+N T := TCommonTree.Create(IToken(nil)); for I := 0 to TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE + N - 1 do T.AddChild(TCommonTree.Create(TCommonToken.Create(I + 1))); // move head to index N Stream := CreateUnBufferedTreeNodeStream(T); for I := 1 to N do begin // consume N Node := Stream.LT(1) as ITree; CheckEquals(Node.TokenType, I); Stream.Consume; end; // now use LT to lookahead past end of buffer Remaining := TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE - N; CheckTrue(WrapBy < N); for I := 1 to Remaining + WrapBy do begin // wrap past end of buffer Node := Stream.LT(I) as ITree; // look ahead to ith token CheckEquals(Node.TokenType, N + I); end; end; procedure TestICommonTreeNodeStream.TestFlatList; var Root: ITree; Stream: ITreeNodeStream; begin Root := TCommonTree.Create(IToken(nil)); Root.AddChild(TCommonTree.Create(TCommonToken.Create(101))); Root.AddChild(TCommonTree.Create(TCommonToken.Create(102))); Root.AddChild(TCommonTree.Create(TCommonToken.Create(103))); Stream := CreateCommonTreeNodeStream(Root); CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103'); CheckEquals(Stream.ToString, ' 101 102 103'); end; procedure TestICommonTreeNodeStream.TestList; var Root, T, U: ITree; Stream: ITreeNodeStream; begin Root := TCommonTree.Create(IToken(nil)); T := TCommonTree.Create(TCommonToken.Create(101)); T.AddChild(TCommonTree.Create(TCommonToken.Create(102))); T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103))); T.AddChild(TCommonTree.Create(TCommonToken.Create(104))); U := TCommonTree.Create(TCommonToken.Create(105)); Root.AddChild(T); Root.AddChild(U); Stream := CreateCommonTreeNodeStream(Root); CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103 104 105'); CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 3 105'); end; procedure TestICommonTreeNodeStream.TestListWithOneNode; var Root: ITree; Stream: ITreeNodeStream; begin Root := TCommonTree.Create(IToken(nil)); Root.AddChild(TCommonTree.Create(TCommonToken.Create(101))); Stream := CreateCommonTreeNodeStream(Root); CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101'); CheckEquals(Stream.ToString, ' 101'); end; procedure TestICommonTreeNodeStream.TestLT; var T: ITree; Stream: ITreeNodeStream; begin // ^(101 ^(102 103) 104) T := TCommonTree.Create(TCommonToken.Create(101)); T.AddChild(TCommonTree.Create(TCommonToken.Create(102))); T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103))); T.AddChild(TCommonTree.Create(TCommonToken.Create(104))); Stream := CreateCommonTreeNodeStream(T); CheckEquals((Stream.LT(1) as ITree).TokenType,101); CheckEquals((Stream.LT(2) as ITree).TokenType,TToken.DOWN); CheckEquals((Stream.LT(3) as ITree).TokenType,102); CheckEquals((Stream.LT(4) as ITree).TokenType,TToken.DOWN); CheckEquals((Stream.LT(5) as ITree).TokenType,103); CheckEquals((Stream.LT(6) as ITree).TokenType,TToken.UP); CheckEquals((Stream.LT(7) as ITree).TokenType,104); CheckEquals((Stream.LT(8) as ITree).TokenType,TToken.UP); CheckEquals((Stream.LT(9) as ITree).TokenType,TToken.EOF); // check way ahead CheckEquals((Stream.LT(100) as ITree).TokenType,TToken.EOF); end; procedure TestICommonTreeNodeStream.TestMarkRewindEntire; var R0, R1, R2: ITree; Stream: ICommonTreeNodeStream; M, K: Integer; begin // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R0.AddChild(R1); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R2 := TCommonTree.Create(TCommonToken.Create(106)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R1.AddChild(R2); R0.AddChild(TCommonTree.Create(TCommonToken.Create(104))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(105))); Stream := TCommonTreeNodeStream.Create(R0); M := Stream.Mark; for K := 1 to 13 do begin // consume til end Stream.LT(1); Stream.Consume; end; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF); CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP); Stream.Rewind(M); for K := 1 to 13 do begin // consume til end Stream.LT(1); Stream.Consume; end; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF); CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP); end; procedure TestICommonTreeNodeStream.TestMarkRewindInMiddle; var R0, R1, R2: ITree; Stream: ICommonTreeNodeStream; M, K: Integer; begin // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R0.AddChild(R1); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R2 := TCommonTree.Create(TCommonToken.Create(106)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R1.AddChild(R2); R0.AddChild(TCommonTree.Create(TCommonToken.Create(104))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(105))); Stream := TCommonTreeNodeStream.Create(R0); for K := 1 to 7 do begin // consume til middle Stream.Consume; end; CheckEquals((Stream.LT(1) as ITree).TokenType,107); M := Stream.Mark; Stream.Consume; // consume 107 Stream.Consume; // consume UP Stream.Consume; // consume UP Stream.Consume; // consume 104 Stream.Rewind(M); CheckEquals((Stream.LT(1) as ITree).TokenType,107); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,104); Stream.Consume; // now we're past rewind position CheckEquals((Stream.LT(1) as ITree).TokenType,105); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF); CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP); end; procedure TestICommonTreeNodeStream.TestMarkRewindNested; var R0, R1, R2: ITree; Stream: ICommonTreeNodeStream; M, M2: Integer; begin // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R0.AddChild(R1); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R2 := TCommonTree.Create(TCommonToken.Create(106)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R1.AddChild(R2); R0.AddChild(TCommonTree.Create(TCommonToken.Create(104))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(105))); Stream := TCommonTreeNodeStream.Create(R0); M := Stream.Mark; // MARK at start Stream.Consume; // consume 101 Stream.Consume; // consume DN M2:= Stream.Mark; // MARK on 102 Stream.Consume; // consume 102 Stream.Consume; // consume DN Stream.Consume; // consume 103 Stream.Consume; // consume 106 Stream.Rewind(M2); CheckEquals((Stream.LT(1) as ITree).TokenType,102); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN); Stream.Consume; // stop at 103 and rewind to start Stream.Rewind(M); // REWIND to 101 CheckEquals((Stream.LT(1) as ITree).TokenType,101); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,102); Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN); end; procedure TestICommonTreeNodeStream.TestNestedPushPop; const IndexOf102 = 2; IndexOf104 = 6; IndexOf107 = 12; var R0, R1, R2, R3: ITree; Stream: ICommonTreeNodeStream; K: Integer; begin // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109) // stream has 9 real + 8 nav nodes // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R0.AddChild(R1); R2 := TCommonTree.Create(TCommonToken.Create(104)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(105))); R0.AddChild(R2); R3 := TCommonTree.Create(TCommonToken.Create(106)); R3.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R0.AddChild(R3); R0.AddChild(TCommonTree.Create(TCommonToken.Create(108))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(109))); Stream := TCommonTreeNodeStream.Create(R0); CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3'); // Assume we want to hit node 107 and then "call 102", which // calls 104, then return for K := 1 to IndexOf107 do // consume til 107 node Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,107); // CALL 102 Stream.Push(IndexOf102); CheckEquals((Stream.LT(1) as ITree).TokenType,102); Stream.Consume; // consume 102 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN); Stream.Consume; // consume DN CheckEquals((Stream.LT(1) as ITree).TokenType,103); Stream.Consume; // consume 103 // CALL 104 Stream.Push(IndexOf104); CheckEquals((Stream.LT(1) as ITree).TokenType,104); Stream.Consume; // consume 104 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN); Stream.Consume; // consume DN CheckEquals((Stream.LT(1) as ITree).TokenType,105); Stream.Consume; // consume 1045 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP); // RETURN (to UP node in 102 subtree) Stream.Pop; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP); // RETURN (to empty stack) Stream.Pop; CheckEquals((Stream.LT(1) as ITree).TokenType,107); end; procedure TestICommonTreeNodeStream.TestPushPop; const IndexOf102 = 2; IndexOf107 = 12; var R0, R1, R2, R3: ITree; Stream: ICommonTreeNodeStream; K: Integer; begin // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109) // stream has 9 real + 8 nav nodes // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R0.AddChild(R1); R2 := TCommonTree.Create(TCommonToken.Create(104)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(105))); R0.AddChild(R2); R3 := TCommonTree.Create(TCommonToken.Create(106)); R3.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R0.AddChild(R3); R0.AddChild(TCommonTree.Create(TCommonToken.Create(108))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(109))); Stream := TCommonTreeNodeStream.Create(R0); CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3'); // Assume we want to hit node 107 and then "call 102" then return for K := 1 to IndexOf107 do // consume til 107 node Stream.Consume; // CALL 102 CheckEquals((Stream.LT(1) as ITree).TokenType,107); Stream.Push(IndexOf102); CheckEquals((Stream.LT(1) as ITree).TokenType,102); Stream.Consume; // consume 102 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN); Stream.Consume; // consume DN CheckEquals((Stream.LT(1) as ITree).TokenType,103); Stream.Consume; // consume 103 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP); // RETURN Stream.Pop; CheckEquals((Stream.LT(1) as ITree).TokenType,107); end; procedure TestICommonTreeNodeStream.TestPushPopFromEOF; const IndexOf102 = 2; IndexOf104 = 6; var R0, R1, R2, R3: ITree; Stream: ICommonTreeNodeStream; begin // ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109) // stream has 9 real + 8 nav nodes // Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R0.AddChild(R1); R2 := TCommonTree.Create(TCommonToken.Create(104)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(105))); R0.AddChild(R2); R3 := TCommonTree.Create(TCommonToken.Create(106)); R3.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R0.AddChild(R3); R0.AddChild(TCommonTree.Create(TCommonToken.Create(108))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(109))); Stream := TCommonTreeNodeStream.Create(R0); CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3'); while (Stream.LA(1) <> TToken.EOF) do Stream.Consume; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF); // CALL 102 Stream.Push(IndexOf102); CheckEquals((Stream.LT(1) as ITree).TokenType,102); Stream.Consume; // consume 102 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN); Stream.Consume; // consume DN CheckEquals((Stream.LT(1) as ITree).TokenType,103); Stream.Consume; // consume 103 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP); // RETURN (to empty stack) Stream.Pop; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF); // CALL 104 Stream.Push(IndexOf104); CheckEquals((Stream.LT(1) as ITree).TokenType,104); Stream.Consume; // consume 104 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN); Stream.Consume; // consume DN CheckEquals((Stream.LT(1) as ITree).TokenType,105); Stream.Consume; // consume 105 CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP); // RETURN (to empty stack) Stream.Pop; CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF); end; procedure TestICommonTreeNodeStream.TestSeek; var R0, R1, R2: ITree; Stream: ICommonTreeNodeStream; begin // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R0.AddChild(R1); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R2 := TCommonTree.Create(TCommonToken.Create(106)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R1.AddChild(R2); R0.AddChild(TCommonTree.Create(TCommonToken.Create(104))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(105))); Stream := TCommonTreeNodeStream.Create(R0); Stream.Consume; // consume 101 Stream.Consume; // consume DN Stream.Consume; // consume 102 Stream.Seek(7); // seek to 107 CheckEquals((Stream.LT(1) as ITree).TokenType,107); Stream.Consume; // consume 107 Stream.Consume; // consume UP Stream.Consume; // consume UP CheckEquals((Stream.LT(1) as ITree).TokenType,104); end; procedure TestICommonTreeNodeStream.TestSeekFromStart; var R0, R1, R2: ITree; Stream: ICommonTreeNodeStream; begin // ^(101 ^(102 103 ^(106 107) ) 104 105) // stream has 7 real + 6 nav nodes // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF R0 := TCommonTree.Create(TCommonToken.Create(101)); R1 := TCommonTree.Create(TCommonToken.Create(102)); R0.AddChild(R1); R1.AddChild(TCommonTree.Create(TCommonToken.Create(103))); R2 := TCommonTree.Create(TCommonToken.Create(106)); R2.AddChild(TCommonTree.Create(TCommonToken.Create(107))); R1.AddChild(R2); R0.AddChild(TCommonTree.Create(TCommonToken.Create(104))); R0.AddChild(TCommonTree.Create(TCommonToken.Create(105))); Stream := TCommonTreeNodeStream.Create(R0); Stream.Seek(7); // seek to 107 CheckEquals((Stream.LT(1) as ITree).TokenType,107); Stream.Consume; // consume 107 Stream.Consume; // consume UP Stream.Consume; // consume UP CheckEquals((Stream.LT(1) as ITree).TokenType,104); end; procedure TestICommonTreeNodeStream.TestSingleNode; var T: ITree; Stream: ITreeNodeStream; begin T := TCommonTree.Create(TCommonToken.Create(101)); Stream := CreateCommonTreeNodeStream(T); CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101'); CheckEquals(Stream.ToString, ' 101'); end; procedure TestICommonTreeNodeStream.TestStackStretch; var R0: ICommonTree; Stream: ICommonTreeNodeStream; I: Integer; begin // make more than INITIAL_CALL_STACK_SIZE pushes R0 := TCommonTree.Create(TCommonToken.Create(101)); Stream := TCommonTreeNodeStream.Create(R0); // go 1 over initial size for I := 1 to TCommonTreeNodeStream.INITIAL_CALL_STACK_SIZE + 1 do Stream.Push(I); CheckEquals(Stream.Pop, 10); CheckEquals(Stream.Pop, 9); end; function TestIRewriteRuleXxxxStream.CreateToken(const TokenType: Integer; const Text: String): IToken; begin Result := TCommonToken.Create(TokenType, Text); end; function TestIRewriteRuleXxxxStream.CreateTokenList( const Count: Integer): IList; var I: Integer; begin Result := TList.Create; for I := 0 to Count - 1 do Result.Add(TCommonToken.Create(I + 1,'test token ' + IntToStr(I + 1) + ' without any real context')); end; function TestIRewriteRuleXxxxStream.CreateTree(const Token: IToken): ITree; begin Result := TCommonTree.Create(Token); end; function TestIRewriteRuleXxxxStream.CreateTreeAdaptor: ITreeAdaptor; begin Result := TCommonTreeAdaptor.Create; end; procedure TestIRewriteRuleXxxxStream.SetUp; begin end; procedure TestIRewriteRuleXxxxStream.TearDown; begin end; procedure TestIRewriteRuleXxxxStream.TestRewriteRuleNodeStreamConstructors; var NodeTest1, NodeTest2, NodeTest3: IRewriteRuleNodeStream; begin NodeTest1 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, 'RewriteRuleNodeStream test1'); NodeTest2 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, 'RewriteRuleNodeStream test2', CreateToken(1,'test token without any real context')); NodeTest3 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, 'RewriteRuleNodeStream test3', CreateTokenList(4)); end; procedure TestIRewriteRuleXxxxStream.TestRewriteRuleSubtreeStreamConstructors; var SubtreeTest1, SubtreeTest2, SubtreeTest3: IRewriteRuleSubtreeStream; begin SubtreeTest1 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, 'RewriteRuleSubtreeStream test1'); SubtreeTest2 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, 'RewriteRuleSubtreeStream test2', CreateToken(1,'test token without any real context')); SubtreeTest3 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, 'RewriteRuleSubtreeStream test3', CreateTokenList(4)); end; procedure TestIRewriteRuleXxxxStream.TestRewriteRuleTokenStreamConstructors; var TokenTest1, TokenTest2, TokenTest3: IRewriteRuleTokenStream; begin TokenTest1 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, 'RewriteRuleTokenStream test1'); TokenTest2 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, 'RewriteRuleTokenStream test2', CreateToken(1, 'test token without any real context')); TokenTest3 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, 'RewriteRuleTokenStream test3', CreateTokenList(4)); end; procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWhileEmpty1; const Description = 'RewriteRuleNodeStream test'; var NodeTest: IRewriteRuleNodeStream; begin ExpectedException := ERewriteEmptyStreamException; NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, Description); CheckFalse(NodeTest.HasNext); CheckEquals(Description, NodeTest.Description); CheckEquals(NodeTest.Size, 0); NodeTest.Reset; CheckEquals(NodeTest.Size, 0); NodeTest.NextNode; end; procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWhileEmpty2; const Description = 'RewriteRuleNodeStream test'; var NodeTest: IRewriteRuleNodeStream; begin ExpectedException := ERewriteEmptyStreamException; NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, Description); NodeTest.NextTree; end; procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWithElements; var NodeTest: IRewriteRuleNodeStream; Token1, Token2: IToken; Tree1, Tree2: ITree; ReturnedTree: ICommonTree; begin ExpectedException := ERewriteCardinalityException; NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, 'RewriteRuleNodeStream test'); Token1 := CreateToken(1, 'test token without any real context'); Tree1 := CreateTree(Token1); // Test Add() NodeTest.Add(Tree1); CheckEquals(NodeTest.Size, 1); CheckTrue(NodeTest.HasNext); // Test NextNode() ReturnedTree := NodeTest.NextNode as ICommoNTree; CheckEquals(ReturnedTree.TokenType, Tree1.TokenType); CheckEquals(NodeTest.Size, 1); CheckFalse(NodeTest.HasNext); NodeTest.Reset; CheckEquals(NodeTest.Size, 1); CheckTrue(NodeTest.HasNext); // Test NextTree() ReturnedTree := NodeTest.NextTree as ICommonTree; Check(SameObj(Token1, ReturnedTree.Token)); CheckEquals(NodeTest.Size, 1); CheckFalse(NodeTest.HasNext); NodeTest.Reset; CheckEquals(NodeTest.Size, 1); CheckTrue(NodeTest.HasNext); // Test, what happens with two elements Token2 := CreateToken(2, 'test token without any real context'); Tree2 := CreateTree(Token2); NodeTest.Add(Tree2); CheckEquals(NodeTest.Size, 2); CheckTrue(NodeTest.HasNext); ReturnedTree := NodeTest.NextTree as ICommonTree; Check(SameObj(Token1, ReturnedTree.Token)); CheckEquals(NodeTest.Size, 2); CheckTrue(NodeTest.HasNext); ReturnedTree := NodeTest.NextTree as ICommonTree; Check(SameObj(Token2, ReturnedTree.Token)); CheckFalse(NodeTest.HasNext); // Test exception NodeTest.NextTree; end; procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWhileEmpty1; const Description = 'RewriteRuleSubtreeStream test'; var SubtreeTest: IRewriteRuleSubtreeStream; begin ExpectedException := ERewriteEmptyStreamException; SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, Description); CheckFalse(SubtreeTest.HasNext); CheckEquals(Description, SubtreeTest.Description); CheckEquals(SubtreeTest.Size, 0); SubtreeTest.Reset; CheckEquals(SubtreeTest.Size, 0); SubtreeTest.NextNode; end; procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWhileEmpty2; const Description = 'RewriteRuleSubtreeStream test'; var SubtreeTest: IRewriteRuleSubtreeStream; begin ExpectedException := ERewriteEmptyStreamException; SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, Description); SubtreeTest.NextTree; end; procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWithElements; var SubtreeTest: IRewriteRuleSubtreeStream; Token1, Token2: IToken; Tree1, Tree2: ITree; ReturnedTree: ICommonTree; begin ExpectedException := ERewriteCardinalityException; SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, 'RewriteRuleSubtreeStream test'); Token1 := CreateToken(1, 'test token without any real context'); Tree1 := CreateTree(Token1); // Test Add() SubtreeTest.Add(Tree1); CheckEquals(SubtreeTest.Size, 1); CheckTrue(SubtreeTest.HasNext); // Test NextNode() Check(SameObj(SubtreeTest.NextNode, Tree1)); CheckEquals(SubtreeTest.Size, 1); CheckFalse(SubtreeTest.HasNext); SubtreeTest.Reset; CheckEquals(SubtreeTest.Size, 1); CheckTrue(SubtreeTest.HasNext); // Test NextTree() ReturnedTree := SubtreeTest.NextTree as ICommonTree; Check(SameObj(Token1, ReturnedTree.Token)); CheckEquals(SubtreeTest.Size, 1); CheckFalse(SubtreeTest.HasNext); SubtreeTest.Reset; CheckEquals(SubtreeTest.Size, 1); CheckTrue(SubtreeTest.HasNext); // Test, what happens with two elements Token2 := CreateToken(2, 'test token without any real context'); Tree2 := CreateTree(Token2); SubtreeTest.Add(Tree2); CheckEquals(SubtreeTest.Size, 2); CheckTrue(SubtreeTest.HasNext); ReturnedTree := SubtreeTest.NextTree as ICommonTree; Check(SameObj(Token1, ReturnedTree.Token)); CheckEquals(SubtreeTest.Size, 2); CheckTrue(SubtreeTest.HasNext); ReturnedTree := SubtreeTest.NextTree as ICommonTree; Check(SameObj(Token2, ReturnedTree.Token)); CheckFalse(SubtreeTest.HasNext); // Test exception SubtreeTest.NextTree; end; procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty1; const Description = 'RewriteRuleTokenStream test'; var TokenTest: IRewriteRuleTokenStream; begin ExpectedException := ERewriteEmptyStreamException; TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description); CheckFalse(TokenTest.HasNext); CheckEquals(Description, TokenTest.Description); CheckEquals(TokenTest.Size, 0); TokenTest.Reset; CheckEquals(TokenTest.Size, 0); TokenTest.NextNode; end; procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty2; const Description = 'RewriteRuleTokenStream test'; var TokenTest: IRewriteRuleTokenStream; begin ExpectedException := ERewriteEmptyStreamException; TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description); TokenTest.NextTree; end; procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty3; const Description = 'RewriteRuleTokenStream test'; var TokenTest: IRewriteRuleTokenStream; begin ExpectedException := ERewriteEmptyStreamException; TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description); TokenTest.NextToken; end; procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWithElements; var TokenTest: IRewriteRuleTokenStream; Token1, Token2, ReturnedToken: IToken; Tree: ICommonTree; begin ExpectedException := ERewriteCardinalityException; TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, 'RewriteRuleTokenStream test'); Token1 := CreateToken(1, 'test token without any real context'); // Test Add() TokenTest.Add(Token1); CheckEquals(TokenTest.Size, 1); CheckTrue(TokenTest.HasNext); // Test NextNode() Tree := TokenTest.NextNode as ICommonTree; Check(SameObj(Tree.Token, Token1)); CheckEquals(TokenTest.Size, 1); CheckFalse(TokenTest.HasNext); TokenTest.Reset; CheckEquals(TokenTest.Size, 1); CheckTrue(TokenTest.HasNext); // Test NextToken() ReturnedToken := TokenTest.NextToken; Check(SameObj(Token1, ReturnedToken)); CheckEquals(TokenTest.Size, 1); CheckFalse(TokenTest.HasNext); TokenTest.Reset; CheckEquals(TokenTest.Size, 1); CheckTrue(TokenTest.HasNext); // Test NextTree() ReturnedToken := TokenTest.NextTree as IToken; Check(SameObj(Token1, ReturnedToken)); CheckEquals(TokenTest.Size, 1); CheckFalse(TokenTest.HasNext); TokenTest.Reset; CheckEquals(TokenTest.Size, 1); CheckTrue(TokenTest.HasNext); // Test, what happens with two elements Token2 := CreateToken(2, 'test token without any real context'); TokenTest.Add(Token2); CheckEquals(TokenTest.Size, 2); CheckTrue(TokenTest.HasNext); ReturnedToken := TokenTest.NextToken; Check(SameObj(Token1, ReturnedToken)); CheckEquals(TokenTest.Size, 2); CheckTrue(TokenTest.HasNext); ReturnedToken := TokenTest.NextToken; Check(SameObj(Token2, ReturnedToken)); CheckFalse(TokenTest.HasNext); // Test exception TokenTest.NextToken; end; constructor TestITreeWizard.Create(MethodName: String); const TOKENS: array [0..11] of String = ('', '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'ID', 'VAR'); var I: Integer; begin inherited; SetLength(FTokens,Length(TOKENS)); for I := 0 to Length(TOKENS) - 1 do FTokens[I] := TOKENS[I]; end; procedure TestITreeWizard.SetUp; begin end; procedure TestITreeWizard.TearDown; begin end; procedure TestITreeWizard.TestDoubleLevelTree; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A (B C) (B D) E)') as ICommonTree; CheckEquals(T.ToStringTree, '(A (B C) (B D) E)'); end; procedure TestITreeWizard.TestEquals; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T1, T2: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T1 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree; T2 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree; CheckTrue(Wiz.Equals(T1, T2, Adaptor)); end; procedure TestITreeWizard.TestEqualsWithMismatchedText; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T1, T2: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T1 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree; T2 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree; CheckFalse(Wiz.Equals(T1, T2, Adaptor)); end; procedure TestITreeWizard.TestEqualsWithText; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T1, T2: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T1 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree; T2 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree; CheckTrue(Wiz.Equals(T1, T2, Adaptor)); end; procedure TestITreeWizard.TestFindPattern; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Subtrees, Elements: IList; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C (A[foo] B[bar]) (D (A[big] B[dog])))') as ICommonTree; Subtrees := Wiz.Find(T, '(A B)'); Elements := Subtrees; CheckEquals('[foo, big]', TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestInvalidListTree; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('A B C') as ICommonTree; CheckNull(T); end; procedure TestITreeWizard.TestListTree; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(nil A B C)') as ICommonTree; CheckEquals(T.ToStringTree, 'A B C'); end; procedure TestITreeWizard.TestNoRepeatsIndex; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; M: IDictionary>; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree; M := Wiz.Index(T); CheckEquals('{5=[A], 8=[D], 7=[C], 6=[B]}' ,TCollectionUtils.DictionaryToString(M)); end; procedure TestITreeWizard.TestNoRepeatsVisit; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree; Elements := TList.Create; Visitor := TRecordAllElementsVisitor.Create(Elements); Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor); CheckEquals('[B]' ,TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestNoRepeatsVisit2; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree; Elements := TList.Create; Visitor := TRecordAllElementsVisitor.Create(Elements); Wiz.Visit(T, Wiz.GetTokenType('C'), Visitor); CheckEquals('[C]' ,TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestParse; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree; CheckTrue(Wiz.Parse(T, '(A B C)')); end; procedure TestITreeWizard.TestParseFlatTree; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(nil A B C)') as ICommonTree; CheckTrue(Wiz.Parse(T, '(nil A B C)')); end; procedure TestITreeWizard.TestParseLabels; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Labels: IDictionary; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree; Labels := TDictionary.Create; CheckTrue(Wiz.Parse(T, '(%a:A %b:B %c:C)', Labels)); CheckEquals('A', Labels['a'].ToString); CheckEquals('B', Labels['b'].ToString); CheckEquals('C', Labels['c'].ToString); end; procedure TestITreeWizard.TestParseLabelsAndTestText; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Labels: IDictionary; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree; Labels := TDictionary.Create; CheckTrue(Wiz.Parse(T, '(%a:A %b:B[foo] %c:C)', Labels)); CheckEquals('A', Labels['a'].ToString); CheckEquals('foo', Labels['b'].ToString); CheckEquals('C', Labels['c'].ToString); end; procedure TestITreeWizard.TestParseLabelsInNestedTree; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Labels: IDictionary; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A (B C) (D E))') as ICommonTree; Labels := TDictionary.Create; CheckTrue(Wiz.Parse(T, '(%a:A (%b:B %c:C) (%d:D %e:E) )', Labels)); CheckEquals('A', Labels['a'].ToString); CheckEquals('B', Labels['b'].ToString); CheckEquals('C', Labels['c'].ToString); CheckEquals('D', Labels['d'].ToString); CheckEquals('E', Labels['e'].ToString); end; procedure TestITreeWizard.TestParseSingleNode; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('A') as ICommonTree; CheckTrue(Wiz.Parse(T, 'A')); end; procedure TestITreeWizard.TestParseWithText; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B[foo] C[bar])') as ICommonTree; // C pattern has no text arg so despite [bar] in t, no need // to match text--check structure only. CheckTrue(Wiz.Parse(T, '(A B[foo] C)')); end; procedure TestITreeWizard.TestParseWithTextFails; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree; CheckFalse(Wiz.Parse(T, '(A[foo] B C)')); end; procedure TestITreeWizard.TestParseWithWildcardLabels; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Labels: IDictionary; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree; Labels := TDictionary.Create; CheckTrue(Wiz.Parse(T, '(A %b:. %c:.)', Labels)); CheckEquals('B', Labels['b'].ToString); CheckEquals('C', Labels['c'].ToString); end; procedure TestITreeWizard.TestRepeatsIndex; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; M: IDictionary>; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree; M := Wiz.Index(T); CheckEquals('{5=[A, A], 8=[D, D], 7=[C], 6=[B, B, B]}' ,TCollectionUtils.DictionaryToString(M)); end; procedure TestITreeWizard.TestRepeatsVisit; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree; Elements := TList.Create; Visitor := TRecordAllElementsVisitor.Create(Elements); Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor); CheckEquals('[B, B, B]' ,TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestRepeatsVisit2; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree; Elements := TList.Create; Visitor := TRecordAllElementsVisitor.Create(Elements); Wiz.Visit(T, Wiz.GetTokenType('A'), Visitor); CheckEquals('[A, A]' ,TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestRepeatsVisitWithContext; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree; Elements := TList.Create; Visitor := TTest1ContextVisitor.Create(Adaptor, Elements); Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor); CheckEquals('[B@A[0], B@A[1], B@A[2]]', TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestRepeatsVisitWithNullParentAndContext; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree; Elements := TList.Create; Visitor := TTest1ContextVisitor.Create(Adaptor, Elements); Wiz.Visit(T, Wiz.GetTokenType('A'), Visitor); CheckEquals('[A@nil[0], A@A[1]]', TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestSingleLevelTree; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree; CheckEquals(T.ToStringTree, '(A B C D)'); end; procedure TestITreeWizard.TestSingleNode; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('ID') as ICommonTree; CheckEquals(T.ToStringTree, 'ID'); end; procedure TestITreeWizard.TestSingleNodeIndex; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; M: IDictionary>; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('ID') as ICommonTree; M := Wiz.Index(T); CheckEquals('{10=[ID]}' ,TCollectionUtils.DictionaryToString(M)); end; procedure TestITreeWizard.TestSingleNodeTree; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A)') as ICommonTree; CheckEquals(T.ToStringTree, 'A'); end; procedure TestITreeWizard.TestSingleNodeWithArg; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('ID[foo]') as ICommonTree; CheckEquals(T.ToStringTree, 'foo'); end; procedure TestITreeWizard.TestVisitPattern; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C (A B) D)') as ICommonTree; Elements := TList.Create; Visitor := TRecordAllElementsVisitor.Create(Elements); Wiz.Visit(T, '(A B)', Visitor); CheckEquals('[A]', TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestVisitPatternMultiple; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C (A B) (D (A B)))') as ICommonTree; Elements := TList.Create; Visitor := TTest1ContextVisitor.Create(Adaptor, Elements); Wiz.Visit(T, '(A B)', Visitor); CheckEquals('[A@A[2], A@D[0]]', TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestVisitPatternMultipleWithLabels; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; Elements: IList; Visitor: IContextVisitor; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C (A[foo] B[bar]) (D (A[big] B[dog])))') as ICommonTree; Elements := TList.Create; Visitor := TTest2ContextVisitor.Create(Adaptor, Elements); Wiz.Visit(T, '(%a:A %b:B)', Visitor); CheckEquals('[foo@A[2]foo&bar, big@D[0]big&dog]', TCollectionUtils.ListToString(Elements)); end; procedure TestITreeWizard.TestWildcard; var Adaptor: ITreeAdaptor; Wiz: ITreeWizard; T: ICommonTree; begin Adaptor := TCommonTreeAdaptor.Create; Wiz := TTreeWizard.Create(Adaptor, FTokens); T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree; CheckTrue(Wiz.Parse(T, '(A . .)')); end; { TestITreeWizard.TRecordAllElementsVisitor } constructor TestITreeWizard.TRecordAllElementsVisitor.Create( const AList: IList); begin inherited Create; FList := AList; end; procedure TestITreeWizard.TRecordAllElementsVisitor.Visit( const T: IANTLRInterface); begin FList.Add(T); end; { TestITreeWizard.TTest1ContextVisitor } constructor TestITreeWizard.TTest1ContextVisitor.Create( const AAdaptor: ITreeAdaptor; const AList: IList); begin inherited Create; FAdaptor := AAdaptor; FList := AList; end; procedure TestITreeWizard.TTest1ContextVisitor.Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer; const Labels: IDictionary); var S: String; begin S := FAdaptor.GetNodeText(T) + '@'; if Assigned(Parent) then S := S + FAdaptor.GetNodeText(Parent) else S := S + 'nil'; FList.Add(TANTLRString.Create(S + '[' + IntToStr(ChildIndex) + ']')); end; { TestITreeWizard.TTest2ContextVisitor } constructor TestITreeWizard.TTest2ContextVisitor.Create( const AAdaptor: ITreeAdaptor; const AList: IList); begin inherited Create; FAdaptor := AAdaptor; FList := AList; end; procedure TestITreeWizard.TTest2ContextVisitor.Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer; const Labels: IDictionary); var S: String; begin S := FAdaptor.GetNodeText(T) + '@'; if Assigned(Parent) then S := S + FAdaptor.GetNodeText(Parent) else S := S + 'nil'; FList.Add(TANTLRString.Create(S + '[' + IntToStr(ChildIndex) + ']' + Labels['a'].ToString + '&' + Labels['b'].ToString)); end; initialization // Register any test cases with the test runner RegisterTest(TestICommonTree.Suite); RegisterTest(TestICommonTreeNodeStream.Suite); RegisterTest(TestIRewriteRuleXxxxStream.Suite); RegisterTest(TestITreeWizard.Suite); end.