lazarus/components/synedit/test/testmarkupifdef.pas
2014-03-04 19:22:38 +00:00

2442 lines
103 KiB
ObjectPascal

unit TestMarkupIfDef;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, testregistry, TestBase, TestHighlightFoldBase, LCLProc,
SynEdit, SynEditMarkupIfDef, SynHighlighterPas, SynEditHighlighterFoldBase,
SynEditMiscClasses, SynEditFoldedView;
type
TSynMarkupIfdefNodeTypeTest =
(idnIfdef, idnElseIf, idnElse, idnEndIf, idnCommentedIfdef,
idnMustBeNil, idnSkipTest);
TPeerExpect = record
PeerType: TSynMarkupIfdefNodeTypeTest;
PeerY, PeerX: Integer;
NoAutoFree: Boolean;
end;
PPeerExpect = ^TPeerExpect;
const
NodeTypeMap: array [TSynMarkupIfdefNodeType] of TSynMarkupIfdefNodeTypeTest =
(idnIfdef, idnElseIf, idnElse, idnEndIf, idnCommentedIfdef);
type
TNodeExpect = record
ExpStart, ExpEnd, ExpEndLineOffs: Integer;
ExpType: TSynMarkupIfdefNodeTypeTest;
ExpState: TSynMarkupIfdefNodeStateEx;
TestExpState: Boolean;
OpenPeer, ClosePeer: TPeerExpect;
end;
{ TTestMarkupIfDef }
TTestMarkupIfDef = class(TTestBaseHighlighterFoldBase)
private
FTestTree: TSynMarkupHighIfDefLinesTree;
FNodeStateResponses, FNodeStateRequests: TStringList;
FOpenings: TLazSynEditNestedFoldsList;
FUseNestedComments: Boolean;
function TestTextEmpty: TStringArray;
function TestTextNoIfDef: TStringArray;
function TestTextIfDef: TStringArray;
function TestText1: TStringArray;
function TestText2: TStringArray;
function TestText3: TStringArray;
function TestText3a: TStringArray;
function TestText4: TStringArray;
function TestText5: TStringArray;
function TestText6: TStringArray;
function TestText7: TStringArray;
function TestText8: TStringArray;
function TestText9: TStringArray;
function TestText10: TStringArray;
function TestText11: TStringArray;
function TestText11a: TStringArray;
function TestText12: TStringArray;
procedure CheckOpenCloseCount(AName: String; ALine: Integer;
AExpOpenCnt, AExpCloseCnt: Integer);
procedure CheckNodes(AName: String; ALine: Integer;
AExp: array of TNodeExpect);
procedure CheckNodesXY(AName: String; ALine: Integer;
AExp: array of Integer; // [Start, end, start, end, ....]
AExpEndOffs: Integer);
//procedure CheckPeer(AName: String; ALine, ACol: Integer;
// AType: TSynMarkupIfdefNodeTypeTest; ExpLine, ExpCol: Integer);
function TesTNodeStateHandler(Sender: TObject; LinePos,
XStartPos: Integer; CurrentState: TSynMarkupIfdefNodeStateEx): TSynMarkupIfdefNodeState;
protected
function CreateTheHighLighter: TSynCustomFoldHighlighter; override;
//procedure SetUp; override;
//procedure TearDown; override;
procedure ReCreateEditForTreeTest(Lines: Array of String); reintroduce;
published
procedure TestIfDefTreeMoveOnEdit;
procedure TestIfDefTreePeerConnect;
procedure TestIfDefTreeNodeState;
end;
implementation
function dbgs(AFlag: TSynMarkupIfdefNodeTypeTest): String; overload;
begin
Result := '';
WriteStr(Result, AFlag);
end;
function ExpP(PeerType: TSynMarkupIfdefNodeTypeTest; PeerY, PeerX: Integer): PPeerExpect;
begin
New(Result);
Result^.PeerType := PeerType;
Result^.PeerY := PeerY;
Result^.PeerX := PeerX;
Result^.NoAutoFree := False;
end;
function EpIf(PeerY, PeerX: Integer): PPeerExpect;
begin
Result := ExpP(idnIfdef, PeerY, PeerX);
end;
function EpElse(PeerY, PeerX: Integer): PPeerExpect;
begin
Result := ExpP(idnElse, PeerY, PeerX);
end;
function EpElseIf(PeerY, PeerX: Integer): PPeerExpect;
begin
Result := ExpP(idnElseIf, PeerY, PeerX);
end;
function EpEnd(PeerY, PeerX: Integer): PPeerExpect;
begin
Result := ExpP(idnEndIf, PeerY, PeerX);
end;
function EpNil: PPeerExpect;
begin
Result := ExpP(idnMustBeNil, -1, -1);
end;
function EpSkip: PPeerExpect;
begin
Result := ExpP(idnSkipTest, -1, -1);
end;
function ExpN(ExpStart: Integer; ExpEnd: Integer;
ExpEndLineOffs: Integer; // Default to check for same line end
ExpType: TSynMarkupIfdefNodeTypeTest;
ExpState: TSynMarkupIfdefNodeStateEx;
Peer1: PPeerExpect = nil; Peer2: PPeerExpect = nil): TNodeExpect;
begin
Result.ExpStart := ExpStart;
Result.ExpEnd := ExpEnd;
Result.ExpEndLineOffs := ExpEndLineOffs;
Result.ExpType := ExpType;
if Peer1 = nil then Peer1 := ExpP(idnSkipTest, -1 , -1);
if Peer2 = nil then Peer2 := ExpP(idnSkipTest, -1 , -1);
Result.OpenPeer := Peer1^;
Result.ClosePeer := Peer2^;
Result.ExpState := ExpState;
Result.TestExpState := True;
if not Peer1^.NoAutoFree then
Dispose(Peer1);
if not Peer2^.NoAutoFree then
Dispose(Peer2);
end;
function ExpN(ExpStart, ExpEnd: Integer; ExpType: TSynMarkupIfdefNodeTypeTest;
ExpState: TSynMarkupIfdefNodeStateEx;
Peer1: PPeerExpect = nil; Peer2: PPeerExpect = nil): TNodeExpect;
begin
Result := ExpN(ExpStart, ExpEnd, 0, ExpType, ExpState, Peer1, Peer2);
end;
function ExpN(ExpStart: Integer; ExpEnd: Integer = -1;
ExpEndLineOffs: Integer = 0; // Default to check for same line end
ExpType: TSynMarkupIfdefNodeTypeTest = idnSkipTest;
Peer1: PPeerExpect = nil; Peer2: PPeerExpect = nil): TNodeExpect;
begin
Result := ExpN(ExpStart, ExpEnd, ExpEndLineOffs, ExpType, idnUnknown, Peer1, Peer2);
Result.TestExpState := False;
end;
function ExpN(ExpStart, ExpEnd: Integer; ExpType: TSynMarkupIfdefNodeTypeTest;
Peer1: PPeerExpect = nil; Peer2: PPeerExpect = nil): TNodeExpect;
begin
Result := ExpN(ExpStart, ExpEnd, 0, ExpType, Peer1, Peer2);
end;
function ExpN(ExpStart, ExpEnd: Integer; ExpEndLineOffs: Integer;
Peer1: PPeerExpect; Peer2: PPeerExpect = nil): TNodeExpect;
begin
Result := ExpN(ExpStart, ExpEnd, ExpEndLineOffs, idnSkipTest, Peer1, Peer2);
end;
function ExpN(ExpStart, ExpEnd: Integer; Peer1: PPeerExpect; Peer2: PPeerExpect = nil): TNodeExpect;
begin
Result := ExpN(ExpStart, ExpEnd, 0, idnSkipTest, Peer1, Peer2);
end;
function ExpN(ExpStart: Integer; Peer1: PPeerExpect; Peer2: PPeerExpect = nil): TNodeExpect;
begin
Result := ExpN(ExpStart, -1, 0, idnSkipTest, Peer1, Peer2);
end;
procedure TTestMarkupIfDef.CheckNodes(AName: String; ALine: Integer;
AExp: array of TNodeExpect);
var
Node: TSynMarkupHighIfDefEntry;
procedure CheckPeerNode(ExpPeer: TPeerExpect; APeerType: TSynMarkupIfdefPeerType);
var
PName: String;
TestPeer: TSynMarkupHighIfDefEntry;
begin
if ExpPeer.PeerType = idnSkipTest then
exit;
PName := '';
WriteStr(PName, AName, ' ', ExpPeer.PeerType);
case APeerType of
idpOpeningPeer: TestPeer := Node.OpeningPeer;
idpClosingPeer: TestPeer := Node.ClosingPeer;
end;
if ExpPeer.PeerType = idnMustBeNil then begin
AssertTrue(PName + 'NO Peer', TestPeer = nil);
exit;
end;
if ExpPeer.PeerY = -99 then begin // special check for existence only
AssertTrue(PName + ' Has Peer', TestPeer <> nil);
AssertTrue(PName+' PeerType', ExpPeer.PeerType = NodeTypeMap[TestPeer.NodeType]);
end
else
if ExpPeer.PeerY < 0 then begin
AssertTrue(PName + 'NO Peer', TestPeer = nil);
end
else begin
AssertTrue(PName + ' Has Peer', TestPeer <> nil);
AssertTrue(PName+' PeerType', ExpPeer.PeerType = NodeTypeMap[TestPeer.NodeType]);
AssertEquals(PName + 'Peer.Y', ExpPeer.PeerY, TestPeer.Line.GetPosition);
if ExpPeer.PeerX >= 0 then
AssertEquals(PName + 'Peer.X', ExpPeer.PeerX, TestPeer.StartColumn);
end;
end;
var
i, c: Integer;
LineNode: TSynMarkupHighIfDefLinesNodeInfo;
ExpNode: TNodeExpect;
begin
AName := Format('%s - %s L=%d', [BaseTestName, AName, ALine]);
LineNode := FTestTree.FindNodeAtPosition(ALine, afmNil);
c := length(AExp);
if (c = 0) and (not LineNode.HasNode) then
exit;
AssertTrue(AName + 'HasNode', LineNode.HasNode);
AssertEquals(AName + 'EntryCount', c, LineNode.EntryCount);
for i := 0 to c - 1 do begin
ExpNode := AExp[i];
Node := LineNode.Entry[i];
AssertTrue('Node.Line = LineNode', Node.Line = LineNode.Node);
AssertEquals(AName+'StartCol', ExpNode.ExpStart, Node.StartColumn);
if ExpNode.ExpEnd >= 0 then
AssertEquals(AName+'EndCol', ExpNode.ExpEnd, Node.EndColumn);
if ExpNode.ExpEndLineOffs >= 0 then begin
AssertEquals(AName+'EndLineOffs', ExpNode.ExpEndLineOffs, LineNode.LastEntryEndLineOffs);
// AssertTrue(AName+'EndLineOffs flag', idnMultiLineTag in Node.NodeFlags);
end;
if ExpNode.ExpType <> idnSkipTest then
AssertTrue(AName+'NodeTypeflag', NodeTypeMap[Node.NodeType] = ExpNode.ExpType);
if ExpNode.TestExpState then
AssertTrue(AName+'NodeState', Node.NodeState = ExpNode.ExpState);
if ExpNode.OpenPeer.PeerType <> idnSkipTest then
CheckPeerNode(ExpNode.OpenPeer, idpOpeningPeer);
if ExpNode.ClosePeer.PeerType <> idnSkipTest then
CheckPeerNode(ExpNode.ClosePeer, idpClosingPeer);
end;
end;
procedure TTestMarkupIfDef.CheckNodesXY(AName: String; ALine: Integer;
AExp: array of Integer; // [Start, end, start, end, ....]
AExpEndOffs: Integer);
var
i, c: Integer;
n1: TSynMarkupHighIfDefLinesNodeInfo;
begin
AName := Format('%s - %s L=%d', [BaseTestName, AName, ALine]);
n1 := FTestTree.FindNodeAtPosition(ALine, afmNil);
c := length(AExp);
if (c = 0) and (not n1.HasNode) then
exit;
AssertTrue(AName + 'HasNode', n1.HasNode);
AssertEquals(AName + 'EntryCount', c div 2, n1.EntryCount);
for i := 0 to (c div 2) - 1 do begin
AssertTrue('Node.Line = LineNode', n1.Entry[i].Line = n1.Node);
AssertEquals(AName+'StartCol', AExp[i*2], n1.Entry[i].StartColumn);
AssertEquals(AName+'EndCol', AExp[i*2+1], n1.Entry[i].EndColumn);
end;
AssertEquals(AName+'EndLine', AExpEndOffs, n1.LastEntryEndLineOffs);
end;
//procedure TTestMarkupIfDef.CheckPeer(AName: String; ALine, ACol: Integer;
// AType: TSynMarkupIfdefNodeTypeTest; ExpLine, ExpCol: Integer);
//var
// n1: TSynMarkupHighIfDefLinesNodeInfo;
// p: TSynMarkupHighIfDefEntry;
//begin
// AName := Format('%s - %s L=%d Col=%d %s <=> %d, %d', [BaseTestName, AName, ALine, ACol, dbgs(AType), ExpLine, ExpCol]);
// n1 := FTestTree.FindNodeAtPosition(ALine, afmNil);
// AssertTrue(AName + 'HasNode', n1.HasNode);
// AssertTrue(AName + 'HasEntry', n1.EntryCount > ACol);
// case AType of
// idnIfdef: p := n1.Entry[ACol].IfDefPeer;
// idnElse: p := n1.Entry[ACol].ElsePeer;
// idnEndIf: p := n1.Entry[ACol].EndIfPeer;
// end;
// AssertTrue(AName + 'Peer', p <> nil);
// AssertEquals(AName + 'Peer.Y', ExpLine, p.Line.GetPosition);
// AssertTrue(AName + 'Peer.X (1)', p.Line.EntryCount > ExpCol);
// AssertTrue(AName + 'Peer.X (2)', p.Line.Entry[ExpCol] = p);
//end;
{ TTestMarkupIfDef }
function TTestMarkupIfDef.TestTextEmpty: TStringArray;
begin
SetLength(Result, 0);
end;
function TTestMarkupIfDef.TestTextNoIfDef: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
AddLine('//' );
AddLine('//' );
AddLine('//' );
AddLine('//' );
AddLine('//' );
AddLine('//' );
AddLine('//' );
AddLine('//' );
AddLine('//' );
end;
function TTestMarkupIfDef.TestTextIfDef: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine(' {$IFDEF b}' );
// 5
AddLine(' {$IFDEF cc}' );
AddLine('' );
AddLine(' {$IFDEF d}{$IFDEF eee}{$IFDEF ffff}' );
AddLine('' );
AddLine('{$IFDEF g' );
// 10
AddLine('}{$IFDEF h' );
AddLine('' );
AddLine(' }' );
AddLine('' );
AddLine('{$IFDEF i' );
// 15
AddLine(' }{$IFDEF h' );
AddLine('' );
AddLine(' }' );
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText1: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' ); // A >> else 29 / end 36 (1-11)
AddLine('' ); // |
AddLine(' // $ifdef' ); // |
// 5
AddLine(' {$IFDEF b}' ); // | B >> end 17 (3-13)
AddLine('' ); // | |
AddLine(' {$IFDEF c} F1; {$else} F2; {$endif} {$IFDEF d}' ); // | | --(5-15/20-27/32-40) // D >> 11 (43-53)
AddLine(' {$IFDEF e} {$IFDEF f} F1; {$else} F2; {$endif} '); // | | | e to 10 (7-17) // -- (19-29/34-41/46-54)
AddLine('' ); // | | | |
// 10
AddLine(' {$Endif}' ); // | | | e << from line 8 (7-15)
AddLine(' {$Endif}' ); // | | d << from line 7 (5-13)
AddLine('' ); // | |
AddLine(' {$IFDEF c2}' ); // | | c2 >> (5-16)
AddLine(' {$Endif}' ); // | | c2 << from 14 (5-13)
// 15
AddLine(' {$IFDEF x} {$endif} ' ); // | | -- (5-15/16-24)
AddLine('' ); // | |
AddLine(' {$Endif}' ); // | close b from line 5 (3-11)
AddLine('' ); // |
AddLine(' {$IFDEF b2}' ); // | b2 >> else 21 / end 27 (3-14)
// 20
AddLine('' ); // | |
AddLine(' {$Else}' ); // | else b2 from 19 to 27 (3-10)
AddLine('' ); // | |
AddLine(' {$IFDEF H}' ); // | | H >> (5-15)
AddLine('' ); // | | |
// 25
AddLine(' {$Endif}' ); // | | H << (5-13)
AddLine(' {$IFDEF Y} {$endif} ' ); // | | -- (5-15/16-24)
AddLine(' {$Endif}' ); // | << b2 from 19 (else 21) (3-11)
AddLine('' ); // |
AddLine('{$Else}' ); // A else from 2 to 36 (1-8)
// 30
AddLine('' ); // |
AddLine(' {$IFDEF M}' ); // | M (3-13)
AddLine(' {$Else}' ); // | else M (3-10)
AddLine('' ); // | |
AddLine(' {$Endif}' ); // | close M (3-11)
// 35
AddLine('' ); // |
AddLine('{$Endif}' ); // A << from 1 / else 29 (1-9)
AddLine('' ); //
end;
function TTestMarkupIfDef.TestText2: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine('{$Endif}' );
// 5
AddLine('' );
AddLine('{$Endif}' ); // extra endif
AddLine('' );
AddLine('' );
AddLine('' );
//10
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine('{$else}' );
AddLine('' );
AddLine('{$else}' );
// 15
AddLine('' );
AddLine('{$Endif}' );
AddLine('' );
AddLine('' );
AddLine('' );
// 20
AddLine('{$IFDEF a}' );
AddLine('' );
// 1 - 9 11 - 21 22 - 29 30 - 37 38 - 46 48 - 56 58 - 68 69 - 77
AddLine('{$EndIf} {$IFDEF a} {$ELSE} {$ELSE} {$ENDIF} {$endif} {$IFDEF a} {$ENDIF} ');
AddLine('' );
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText3: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine('{$Endif}' );
// 5
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText3a: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a} {$IFDEF a}' );
AddLine('' );
AddLine('{$Endif} {$Endif}' );
// 5
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText4: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a} {$Endif}' );
AddLine('' );
AddLine('{$IFDEF a} {$Endif}' );
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText5: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine('{$elseif b}' );
// 5
AddLine('' );
AddLine('{$else}' );
AddLine('' );
AddLine('{$Endif}' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText6: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine('' );
// 5
AddLine('' );
AddLine(' {$IFDEF b}' );
AddLine('' );
AddLine('' );
AddLine('' );
// 10
AddLine(' {$IFDEF c}' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine(' {$Endif}' );
// 15
AddLine('' );
AddLine('' );
AddLine('' );
AddLine(' {$Endif}' );
AddLine('' );
// 20
AddLine('' );
end;
function TTestMarkupIfDef.TestText7: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine('{$Endif}' );
// 5
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine('' );
// 10
AddLine(' {$IFDEF a}' );
AddLine('' );
AddLine('' );
AddLine('' );
AddLine(' {$Endif}' );
// 15
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText8: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF A} {$IFDEF B} {$ENDIF} {$ENDIF}');
AddLine(' {$IFDEF XX}' );
AddLine('' );
// 5
AddLine('{$ENDIF}');
AddLine('' );
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText9: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine('{$Elseif}' );
// 5
AddLine('' );
AddLine('{$Elseif}' );
AddLine('' );
AddLine('' );
AddLine('{$Elseif}' );
// 10
AddLine('' );
AddLine('' );
AddLine(' {$IFDEF b}' );
AddLine('' );
AddLine(' {$Endif}' );
// 15
AddLine('' );
AddLine('' );
AddLine('{$Endif}' );
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText10: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine('{$IFDEF a}' );
AddLine('' );
AddLine('' );
// 5
AddLine('' );
AddLine('' );
AddLine('{$IFDEF a}' );
AddLine('//' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText11: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('//' );
AddLine(' {$if defined(cpu86)} ');
AddLine(' // a');
AddLine(' {$elseif defined(cpupowerpc)} ');
//5
AddLine(' // disabled ');
AddLine(' {$elseif defined(cpupowerpc)} ');
AddLine(' // enabled (invalid) ');
AddLine(' {$elseif defined(cpuarm)} ');
AddLine(' // enabled (invalid) ');
// 10
AddLine(' {$elseif defined(CPUX86_64)} ');
AddLine(' // enabled (invalid) ');
AddLine(' {$else} ');
AddLine(' // enabled (invalid) ');
AddLine(' {$ifend} ');
//16
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText11a: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('{$if defined(cpu86)}' ); // level 0
AddLine(' {$if defined(cpu86)} '); // level 1
AddLine(' // a');
AddLine(' {$elseif defined(cpupowerpc)} '); // level 1
//5
AddLine(' // disabled ');
AddLine(' {$elseif defined(cpupowerpc)} '); // level 1
AddLine(' // enabled (invalid) ');
AddLine(' {$elseif defined(cpuarm)} '); // level 1
AddLine(' {$if defined(cpu86)}// enabled (invalid) ');
// 10
AddLine(' {$ifend}{$if defined(cpu86)}' ); // level 2
AddLine(' {$ifend}{$elseif defined(CPUX86_64)} '); // level 1 (close lvl 2)
AddLine(' // enabled (invalid) ');
AddLine(' {$if defined(cpu86)}' ); // level 2
AddLine(' {$ifend}{$if defined(cpu86)}' ); // level 2 <> 2
// 15
AddLine(' // nested ');
AddLine(' {$elseif defined(cpuarm)} '); // level 2
AddLine(' // nested ');
AddLine(' {$else} '); // level 2
AddLine(' // nested ');
// 20
AddLine(' {$ifend} '); // level 2
AddLine(' {$else} '); // level 1
AddLine(' // enabled (invalid) ');
AddLine(' {$if defined(cpu86)}' );
AddLine(' // nested ');
// 25
AddLine(' {$ifend}{$if defined(cpu86)}' );
AddLine(' // nested ');
AddLine(' {$elseif defined(cpuarm)} ');
AddLine(' // nested ');
AddLine(' {$else} ');
// 30
AddLine(' // nested ');
AddLine(' {$ifend} ');
AddLine(' {$ifend} ');
AddLine('' );
AddLine(' {$ifend} ');
// 35
AddLine('' );
AddLine('' );
AddLine('' );
end;
function TTestMarkupIfDef.TestText12: TStringArray;
procedure AddLine(s: String);
begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := s;
end;
begin
// 1
AddLine('program project1;');
AddLine('');
AddLine('{$mode objfpc}{$H+}');
AddLine('');
// 5
AddLine('uses {$IFDEF UNIX} {$IFDEF UseCThreads}');
AddLine(' cthreads, {$ENDIF} {$ENDIF} {$ifdef LCLWinCE}');
AddLine(' WinCEInt, {$endif}');
AddLine(' Interfaces, // this includes the LCL widgetset');
AddLine(' Windows,');
AddLine(' SysUtils,');
AddLine(' Forms;');
AddLine('');
end;
procedure TTestMarkupIfDef.CheckOpenCloseCount(AName: String; ALine: Integer; AExpOpenCnt,
AExpCloseCnt: Integer);
var
LineNode: TSynMarkupHighIfDefLinesNodeInfo;
begin
AName := Format('%s - %s L=%d', [BaseTestName, AName, ALine]);
LineNode := FTestTree.FindNodeAtPosition(ALine, afmNil);
AssertTrue(AName + 'HasNode', LineNode.HasNode);
AssertEquals(AName + ' DisabledEntryOpenCount', AExpOpenCnt, LineNode.Node.DisabledEntryOpenCount);
AssertEquals(AName + ' DisabledEntryCloseCount', AExpCloseCnt, LineNode.Node.DisabledEntryCloseCount);
end;
function TTestMarkupIfDef.CreateTheHighLighter: TSynCustomFoldHighlighter;
begin
Result := TSynPasSyn.Create(nil);
end;
procedure TTestMarkupIfDef.ReCreateEditForTreeTest(Lines: array of String);
begin
FreeAndNil(FTestTree);
FTestTree.DiscardOpeningList(FOpenings);
FOpenings := nil;;
ReCreateEdit;
TSynPasSyn(SynEdit.Highlighter).NestedComments := FUseNestedComments;
SetLines(Lines);
FTestTree := TSynMarkupHighIfDefLinesTree.Create;
FTestTree.Lines := SynEdit.ViewedTextBuffer;
FTestTree.Highlighter := TSynPasSyn(SynEdit.Highlighter);
FOpenings := FTestTree.CreateOpeningList;
end;
procedure TTestMarkupIfDef.TestIfDefTreeMoveOnEdit;
procedure DoTest;
var
n: String;
begin
FTestTree := nil;
n := 'No modification';
ReCreateEditForTreeTest(TestTextIfDef);
FTestTree.ValidateRange(1, 14, FOpenings);
CheckNodesXY(n+'', 1, [], 0);
CheckNodesXY(n+'', 2, [1, 11], 0);
CheckNodesXY(n+'', 3, [], 0);
CheckNodesXY(n+'', 4, [2, 12], 0);
CheckNodesXY(n+'', 5, [3, 14], 0);
CheckNodes(n+'', 5, [ExpN(3,14, idnIfdef)]);
{%region one line edit}
ReCreateEditForTreeTest(TestTextIfDef);
FTestTree.ValidateRange(1, 10, FOpenings);
n := 'Remove Space AT line-start, Node after space';
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
SynEdit.TextBetweenPoints[point(1, 7),point(2, 7)] := '';
CheckNodesXY(n+'', 7, [1,11, 11,23, 23,36], 0);
n := 'Insert Space AT line-start, Node after space';
SynEdit.TextBetweenPoints[point(1, 7),point(1, 7)] := ' ';
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
n := 'Replace Space AT line-start, Node after space';
SynEdit.TextBetweenPoints[point(1, 7),point(2, 7)] := #9;
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
n := 'Insert Space AT line-start, node later on line';
SynEdit.TextBetweenPoints[point(1, 7),point(1, 7)] := ' ';
CheckNodesXY(n+'', 7, [3,13, 13,25, 25,38], 0);
n := 'Insert Space before first node on line';
SynEdit.TextBetweenPoints[point(3, 7),point(3, 7)] := ' ';
CheckNodesXY(n+'', 7, [4,14, 14,26, 26,39], 0);
n := 'Remove Space before first node on line';
SynEdit.TextBetweenPoints[point(3, 7),point(4, 7)] := '';
CheckNodesXY(n+'', 7, [3,13, 13,25, 25,38], 0);
n := 'Insert Space between first and 2nd node on line';
SynEdit.TextBetweenPoints[point(13, 7),point(13, 7)] := ' ';
CheckNodesXY(n+'', 7, [3,13, 14,26, 26,39], 0);
n := 'Remove Space between first and 2nd node on line';
SynEdit.TextBetweenPoints[point(13, 7),point(14, 7)] := '';
CheckNodesXY(n+'', 7, [3,13, 13,25, 25,38], 0);
n := 'Insert Space after last node on line';
SynEdit.TextBetweenPoints[point(38, 7),point(38, 7)] := ' ';
CheckNodesXY(n+'', 7, [3,13, 13,25, 25,38], 0);
n := 'Remove Space after last node on line';
SynEdit.TextBetweenPoints[point(38, 7),point(39, 7)] := '';
CheckNodesXY(n+'', 7, [3,13, 13,25, 25,38], 0);
// Edit in node
ReCreateEditForTreeTest(TestTextIfDef);
FTestTree.ValidateRange(1, 19, FOpenings);
n := 'Insert Space INSIDE node (1st node on line)';
SynEdit.TextBetweenPoints[point(3, 7),point(3, 7)] := ' ';
CheckNodesXY(n+'', 7, [2,13, 13,25, 25,38], 0);
n := 'REMOVE Space INSIDE node (1st node on line)';
SynEdit.TextBetweenPoints[point(3, 7),point(4, 7)] := '';
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
n := 'Insert Space INSIDE node end (1st node on line)';
SynEdit.TextBetweenPoints[point(11, 7),point(11, 7)] := ' ';
CheckNodesXY(n+'', 7, [2,13, 13,25, 25,38], 0);
n := 'REMOVE Space INSIDE node end (1st node on line)';
SynEdit.TextBetweenPoints[point(11, 7),point(12, 7)] := '';
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
n := 'Insert Space INSIDE node (last node on line)';
SynEdit.TextBetweenPoints[point(26, 7),point(26, 7)] := ' ';
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,38], 0);
n := 'REMOVE Space INSIDE node (last node on line)';
SynEdit.TextBetweenPoints[point(26, 7),point(27, 7)] := '';
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
n := 'Insert Space INSIDE node (last node on line, multiline)';
SynEdit.TextBetweenPoints[point(3, 14),point(3, 14)] := ' ';
CheckNodesXY(n+'', 14, [1,6], 1);
n := 'REMOVE Space INSIDE node (last node on line, multiline)';
SynEdit.TextBetweenPoints[point(3, 14),point(4, 14)] := '';
CheckNodesXY(n+'', 14, [1,6], 1);
// test 1,12 modify previous node
n := 'Insert Space INSIDE node (last node on line, multiline, on end line)';
SynEdit.TextBetweenPoints[point(1, 12),point(1, 12)] := ' ';
CheckNodesXY(n+'', 10, [2,4], 2);
n := 'REMOVE Space INSIDE node (last node on line, multiline, on end line)';
SynEdit.TextBetweenPoints[point(1, 12),point(2, 12)] := '';
CheckNodesXY(n+'', 10, [2,3], 2);
// test 1,15 modify previous and current node
n := 'Insert Space INSIDE node (last node on line, multiline, on end line with NEXT open)';
SynEdit.TextBetweenPoints[point(2, 15),point(2, 15)] := ' ';
CheckNodesXY(n+'', 14, [1, 7], 1);
CheckNodesXY(n+'', 15, [7,13], 2);
n := 'REMOVE Space INSIDE node (last node on line, multiline, on end line with NEXT open)';
SynEdit.TextBetweenPoints[point(2, 15),point(3, 15)] := '';
CheckNodesXY(n+'', 14, [1, 6], 1);
CheckNodesXY(n+'', 15, [6,13], 2);
n := 'Insert Space Between node (last node on line, multiline, on end line with NEXT open)';
SynEdit.TextBetweenPoints[point(6, 15),point(6, 15)] := ' ';
CheckNodesXY(n+'', 14, [1, 6], 1);
CheckNodesXY(n+'', 15, [7,13], 2);
n := 'REMOVE Space Between node (last node on line, multiline, on end line with NEXT open)';
SynEdit.TextBetweenPoints[point(6, 15),point(7, 15)] := '';
CheckNodesXY(n+'', 14, [1, 6], 1);
CheckNodesXY(n+'', 15, [6,13], 2);
n := 'Insert Space at end of node (IN node) (last node on line, multiline, on end line with NEXT open)';
SynEdit.TextBetweenPoints[point(5, 15),point(5, 15)] := ' ';
CheckNodesXY(n+'', 14, [1, 7], 1);
CheckNodesXY(n+'', 15, [7,13], 2);
// delete an entire node
n := 'Delete full node';
SynEdit.TextBetweenPoints[point(10, 7),point(27, 7)] := '';
FTestTree.DebugPrint(true);
CheckNodesXY(n+'', 7, [2,10, 10,20], 0);
{%endregion one line}
{%region Line Breaks }
n := 'not modified';
ReCreateEditForTreeTest(TestTextIfDef);
FTestTree.ValidateRange(1, 19, FOpenings);
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
n := 'Insert LineBreak at line start nodes';
SynEdit.TextBetweenPoints[point(1, 7),point(1, 7)] := LineEnding;
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [], 0);
CheckNodesXY(n+'', 8, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 9, [], 0);
CheckNodesXY(n+'',10, [1,2], 1);
n := 'Remove LineBreak at line start nodes';
SynEdit.TextBetweenPoints[point(1, 7),point(1, 8)] := '';
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
n := 'Insert LineBreak before nodes';
SynEdit.TextBetweenPoints[point(2, 7),point(2, 7)] := LineEnding;
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [], 0);
CheckNodesXY(n+'', 8, [1,11, 11,23, 23,36], 0);
CheckNodesXY(n+'', 9, [], 0);
CheckNodesXY(n+'',10, [1,2], 1);
n := 'Remove LineBreak before nodes';
SynEdit.TextBetweenPoints[point(2, 7),point(1, 8)] := '';
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
n := 'Insert LineBreak between nodes';
SynEdit.TextBetweenPoints[point(24, 7),point(24, 7)] := LineEnding;
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24], 0);
CheckNodesXY(n+'', 8, [1,14], 0);
CheckNodesXY(n+'', 9, [], 0);
CheckNodesXY(n+'',10, [1,2], 1);
n := 'Remove LineBreak between nodes';
SynEdit.TextBetweenPoints[point(24, 7),point(1, 8)] := '';
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
n := 'Insert LineBreak after nodes';
SynEdit.TextBetweenPoints[point(37, 7),point(37, 7)] := LineEnding;
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [], 0);
CheckNodesXY(n+'',10, [1,2], 1);
n := 'Remove LineBreak after nodes';
SynEdit.TextBetweenPoints[point(37, 7),point(1, 8)] := '';
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
n := 'Insert LineBreak INSIDE nodes';
SynEdit.TextBetweenPoints[point(13, 7),point(13, 7)] := LineEnding;
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,12], 1);
CheckNodesXY(n+'', 8, [12,25], 0);
CheckNodesXY(n+'', 9, [], 0);
CheckNodesXY(n+'',10, [1,2], 1);
n := 'Remove LineBreak INSIDE nodes';
SynEdit.TextBetweenPoints[point(13, 7),point(1, 8)] := '';
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
n := 'Insert LineBreak INSIDE nodes (last node 1 line)';
SynEdit.TextBetweenPoints[point(23, 7),point(23, 7)] := LineEnding;
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,2], 1);
CheckNodesXY(n+'', 8, [2,15], 0);
CheckNodesXY(n+'', 9, [], 0);
CheckNodesXY(n+'',10, [1,2], 1);
n := 'Remove LineBreak INSIDE nodes (last node 1 line)';
SynEdit.TextBetweenPoints[point(23, 7),point(1, 8)] := '';
CheckNodesXY(n+'', 6, [], 0);
CheckNodesXY(n+'', 7, [2,12, 12,24, 24,37], 0);
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
n := 'Insert LineBreak INSIDE nodes (last node multi line)';
SynEdit.TextBetweenPoints[point(9, 10),point(9, 10)] := LineEnding;
CheckNodesXY(n+'', 9, [1,2], 1);
CheckNodesXY(n+'', 10, [2,3], 3);
CheckNodesXY(n+'', 14, [], 0);
CheckNodesXY(n+'', 15, [1,6], 1);
n := 'Remove LineBreak INSIDE nodes (last node multi line)';
SynEdit.TextBetweenPoints[point(9, 10),point(1, 11)] := '';
CheckNodesXY(n+'', 9, [1,2], 1);
CheckNodesXY(n+'', 10, [2,3], 2);
CheckNodesXY(n+'', 13, [], 0);
CheckNodesXY(n+'', 14, [1,6], 1);
n := 'Insert LineBreak INSIDE nodes (last node multi line)';
SynEdit.TextBetweenPoints[point(2, 14),point(2, 14)] := LineEnding;
CheckNodesXY(n+'', 14, [1,6], 2);
n := 'Remove LineBreak INSIDE nodes (last node multi line)';
SynEdit.TextBetweenPoints[point(2, 14),point(1, 15)] := '';
CheckNodesXY(n+'', 14, [1,6], 1);
n := 'Insert LineBreak INSIDE nodes (previous node multi line)';
SynEdit.TextBetweenPoints[point(1, 10),point(1, 10)] := LineEnding;
CheckNodesXY(n+'', 9, [1,2], 2);
CheckNodesXY(n+'', 10, [], 0);
CheckNodesXY(n+'', 11, [2,3], 2);
n := 'Remove LineBreak INSIDE nodes (previous node multi line)';
SynEdit.TextBetweenPoints[point(1, 10),point(1, 11)] := '';
CheckNodesXY(n+'', 9, [1,2], 1);
CheckNodesXY(n+'', 10, [2,3], 2);
n := 'Insert LineBreak INSIDE nodes (last node multi line - no next)';
SynEdit.TextBetweenPoints[point(1, 17),point(1, 17)] := LineEnding;
CheckNodesXY(n+'', 14, [1, 6], 1);
CheckNodesXY(n+'', 15, [6,13], 3);
CheckNodesXY(n+'', 16, [], 0);
CheckNodesXY(n+'', 17, [], 0);
CheckNodesXY(n+'', 18, [], 0);
n := 'Remove LineBreak INSIDE nodes (last node multi line - no next)';
SynEdit.TextBetweenPoints[point(1, 17),point(1, 18)] := '';
CheckNodesXY(n+'', 14, [1, 6], 1);
CheckNodesXY(n+'', 15, [6,13], 2);
CheckNodesXY(n+'', 16, [], 0);
CheckNodesXY(n+'', 17, [], 0);
CheckNodesXY(n+'', 18, [], 0);
n := 'Insert LineBreak INSIDE nodes (mid last node multi line - no next)';
SynEdit.TextBetweenPoints[point(7, 16),point(7, 16)] := LineEnding;
CheckNodesXY(n+'', 14, [1, 6], 1);
CheckNodesXY(n+'', 15, [6,13], 3);
CheckNodesXY(n+'', 16, [], 0);
CheckNodesXY(n+'', 17, [], 0);
CheckNodesXY(n+'', 18, [], 0);
n := 'Remove LineBreak INSIDE nodes (mid last node multi line - no next)';
SynEdit.TextBetweenPoints[point(7, 16),point(1, 17)] := '';
CheckNodesXY(n+'', 14, [1, 6], 1);
CheckNodesXY(n+'', 15, [6,13], 2);
CheckNodesXY(n+'', 16, [], 0);
CheckNodesXY(n+'', 17, [], 0);
CheckNodesXY(n+'', 18, [], 0);
n := 'Remove LineBreak INSIDE nodes EndOffs';
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
CheckNodesXY(n+'',10, [2,3], 2);
CheckNodesXY(n+'',11, [], 0);
CheckNodesXY(n+'',12, [], 0);
SynEdit.TextBetweenPoints[point(10, 9),point(1, 10)] := '';
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,11, 11,3], 2);
CheckNodesXY(n+'',10, [], 0);
CheckNodesXY(n+'',11, [], 0);
CheckNodesXY(n+'',12, [], 0);
n := 'Insert LineBreak INSIDE nodes EndOffs';
SynEdit.TextBetweenPoints[point(10, 9),point(10, 9)] := LineEnding;
CheckNodesXY(n+'', 8, [], 0);
CheckNodesXY(n+'', 9, [1,2], 1);
CheckNodesXY(n+'',10, [2,3], 2);
CheckNodesXY(n+'',11, [], 0);
CheckNodesXY(n+'',12, [], 0);
{%endregion Line Breaks }
ReCreateEditForTreeTest(TestTextIfDef);
FTestTree.ValidateRange(1, 14, FOpenings);
CheckNodesXY('', 1, [], 0);
CheckNodesXY('', 2, [1, 11], 0);
CheckNodesXY('', 3, [], 0);
CheckNodesXY('', 4, [2, 12], 0);
CheckNodesXY('', 5, [3, 14], 0);
// no modification
SynEdit.TextBetweenPoints[point(1,1),point(1,2)] := LineEnding;
CheckNodesXY('', 1, [], 0);
CheckNodesXY('', 2, [1, 11], 0);
CheckNodesXY('', 3, [], 0);
CheckNodesXY('', 4, [2, 12], 0);
CheckNodesXY('', 5, [3, 14], 0);
SynEdit.TextBetweenPoints[point(1,1),point(1,1)] := LineEnding;
CheckNodesXY('', 1, [], 0);
CheckNodesXY('', 2, [], 0);
CheckNodesXY('', 3, [1, 11], 0);
CheckNodesXY('', 4, [], 0);
CheckNodesXY('', 5, [2, 12], 0);
CheckNodesXY('', 6, [3, 14], 0);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := ' ';
CheckNodesXY('', 1, [], 0);
CheckNodesXY('', 2, [], 0);
CheckNodesXY('', 3, [2, 12], 0);
CheckNodesXY('', 4, [], 0);
CheckNodesXY('', 5, [2, 12], 0);
CheckNodesXY('', 6, [3, 14], 0);
SynEdit.TextBetweenPoints[point(1, 3),point(2, 3)] := '';
CheckNodesXY('', 1, [], 0);
CheckNodesXY('', 2, [], 0);
CheckNodesXY('', 3, [1, 11], 0);
CheckNodesXY('', 4, [], 0);
CheckNodesXY('', 5, [2, 12], 0);
CheckNodesXY('', 6, [3, 14], 0);
{%region Delete line with node}
ReCreateEditForTreeTest(TestText7);
FTestTree.ValidateRange( 1, 5, FOpenings);
FTestTree.ValidateRange(10, 10, FOpenings);
FTestTree.ValidateRange(14, 14, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef ) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf ) ]);
CheckNodes(n,10, [ ExpN( 2,12, idnIfdef ) ]);
CheckNodes(n,14, [ ExpN( 2,10, idnEndIf ) ]);
SynEdit.TextBetweenPoints[point(1, 4),point(1, 5)] := '';
FOpenings.Clear;
FTestTree.ValidateRange(3, 5, FOpenings); // only validate deleted line
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef) ]);
CheckNodes(n, 3, [ ]);
CheckNodes(n, 4, [ ]);
CheckNodes(n, 5, [ ]);
CheckNodes(n, 9, [ ExpN( 2,12, idnIfdef) ]);
CheckNodes(n,13, [ ExpN( 2,10, idnEndIf) ]);
SynEdit.TextBetweenPoints[point(1, 4),point(1, 4)] := '{$ENDIF}' + LineEnding;
FTestTree.ValidateRange(3, 5, FOpenings); // only validate deleted line
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef ) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf ) ]);
CheckNodes(n,10, [ ExpN( 2,12, idnIfdef ) ]);
CheckNodes(n,14, [ ExpN( 2,10, idnEndIf ) ]);
{%endregion }
// Insert IFDEF into empty text
ReCreateEditForTreeTest(TestTextNoIfDef);
FTestTree.ValidateRange(1, 5, FOpenings);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := '{$IFDEF a}';
FTestTree.ValidateRange(1, 5, FOpenings);
CheckNodesXY('Insert IFDEF into empty text', 3, [1,11], 0);
FTestTree.DiscardOpeningList(FOpenings);
FOpenings := nil;;
FTestTree.Free;
end;
begin
FUseNestedComments := False;
DoTest;
FUseNestedComments := True;
DoTest;
end;
procedure TTestMarkupIfDef.TestIfDefTreePeerConnect;
procedure DoTest;
var
n: String;
i, i2, i3, i4: Integer;
epMaybeIf: PPeerExpect;
begin
FTestTree := nil;
{%region peers}
n := 'Peers, TestText1: Validate all';
ReCreateEditForTreeTest(TestText1);
FTestTree.ValidateRange(1, 36, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(29, 1)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(17, 3)) ]);
CheckNodes(n, 7, [ ExpN( 5,15, idnIfdef, EpSkip, EpElse(7, 20)),
ExpN(20,27, idnElse, EpIf(7, 5), EpEnd(7, 32)),
ExpN(32,40, idnEndIf, EpElse(7, 20)),
ExpN(43,53, idnIfdef, EpSkip, EpEnd(11, 5)) ]);
CheckNodes(n, 8, [ ExpN( 7,17, idnIfdef, EpSkip, EpEnd(10, 7)),
ExpN(19,29, idnIfdef, EpSkip, EpElse(8, 34)),
ExpN(34,41, idnElse, EpIf(8, 19), EpEnd(8, 46)),
ExpN(46,54, idnEndIf, EpElse(8, 34)) ]);
CheckNodes(n,10, [ ExpN( 7,15, idnEndIf, EpIf(8, 7)) ]);
CheckNodes(n,11, [ ExpN( 5,13, idnEndIf, EpIf(7, 43)) ]);
CheckNodes(n,13, [ ExpN( 5,16, idnIfdef, EpSkip, EpEnd(14, 5)) ]);
CheckNodes(n,14, [ ExpN( 5,13, idnEndIf, EpIf(13, 5)) ]);
CheckNodes(n,15, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(15, 16)),
ExpN(16,24, idnEndIf, EpIf(15, 5)) ]);
CheckNodes(n,17, [ ExpN( 3,11, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,19, [ ExpN( 3,14, idnIfdef, EpSkip, EpElse(21, 3)) ]);
CheckNodes(n,21, [ ExpN( 3,10, idnElse, EpIf(19, 3), EpEnd(27, 3)) ]);
CheckNodes(n,23, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(25, 5)) ]);
CheckNodes(n,25, [ ExpN( 5,13, idnEndIf, EpIf(23, 5)) ]);
CheckNodes(n,26, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(26, 16)),
ExpN(16,24, idnEndIf, EpIf(26, 5)) ]);
CheckNodes(n,27, [ ExpN( 3,11, idnEndIf, EpElse(21, 3)) ]);
CheckNodes(n,29, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(36,1)) ]);
CheckNodes(n,31, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(32, 3)) ]);
CheckNodes(n,32, [ ExpN( 3,10, idnElse, EpIf(31, 3), EpEnd(34,3)) ]);
CheckNodes(n,34, [ ExpN( 3,11, idnEndIf, EpElse(32, 3)) ]);
CheckNodes(n,36, [ ExpN( 1, 9, idnEndIf, EpElse(29, 1)) ]);
n := 'Peers, TestText1: Validate 8 - 36';
ReCreateEditForTreeTest(TestText1);
FTestTree.ValidateRange(8, 36, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(29, 1)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(17, 3)) ]);
CheckNodes(n, 7, [ ExpN( 5,15, idnIfdef ),
ExpN(20,27, idnElse ),
ExpN(32,40, idnEndIf ),
ExpN(43,53, idnIfdef, EpSkip, EpEnd(11, 5)) ]);
CheckNodes(n, 8, [ ExpN( 7,17, idnIfdef, EpSkip, EpEnd(10, 7)),
ExpN(19,29, idnIfdef, EpSkip, EpElse(8, 34)),
ExpN(34,41, idnElse, EpIf(8, 19), EpEnd(8, 46)),
ExpN(46,54, idnEndIf, EpElse(8, 34)) ]);
CheckNodes(n,10, [ ExpN( 7,15, idnEndIf, EpIf(8, 7)) ]);
CheckNodes(n,11, [ ExpN( 5,13, idnEndIf, EpIf(7, 43)) ]);
CheckNodes(n,13, [ ExpN( 5,16, idnIfdef, EpSkip, EpEnd(14, 5)) ]);
CheckNodes(n,14, [ ExpN( 5,13, idnEndIf, EpIf(13, 5)) ]);
CheckNodes(n,15, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(15, 16)),
ExpN(16,24, idnEndIf, EpIf(15, 5)) ]);
CheckNodes(n,17, [ ExpN( 3,11, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,19, [ ExpN( 3,14, idnIfdef, EpSkip, EpElse(21, 3)) ]);
CheckNodes(n,21, [ ExpN( 3,10, idnElse, EpIf(19, 3), EpEnd(27, 3)) ]);
CheckNodes(n,23, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(25, 5)) ]);
CheckNodes(n,25, [ ExpN( 5,13, idnEndIf, EpIf(23, 5)) ]);
CheckNodes(n,26, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(26, 16)),
ExpN(16,24, idnEndIf, EpIf(26, 5)) ]);
CheckNodes(n,27, [ ExpN( 3,11, idnEndIf, EpElse(21, 3)) ]);
CheckNodes(n,29, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(36,1)) ]);
CheckNodes(n,31, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(32, 3)) ]);
CheckNodes(n,32, [ ExpN( 3,10, idnElse, EpIf(31, 3), EpEnd(34,3)) ]);
CheckNodes(n,34, [ ExpN( 3,11, idnEndIf, EpElse(32, 3)) ]);
CheckNodes(n,36, [ ExpN( 1, 9, idnEndIf, EpElse(29, 1)) ]);
n := 'Peers, TestText1: Validate 33 - 36';
ReCreateEditForTreeTest(TestText1);
FTestTree.ValidateRange(33, 36, FOpenings);
AssertTrue('Scan start node Node at empty line', FTestTree.FindNodeAtPosition(33, afmNil).HasNode);
CheckNodes(n,33, [ ]);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(29, 1)) ]);
CheckNodes(n,29, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(36,1)) ]);
CheckNodes(n,31, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(32, 3)) ]);
CheckNodes(n,32, [ ExpN( 3,10, idnElse, EpIf(31, 3), EpEnd(34,3)) ]);
CheckNodes(n,34, [ ExpN( 3,11, idnEndIf, EpElse(32, 3)) ]);
CheckNodes(n,36, [ ExpN( 1, 9, idnEndIf, EpElse(29, 1)) ]);
//
n := 'Peers, TestText1: Validate all AFTER 33-36';
FTestTree.ValidateRange(1, 36, FOpenings);
AssertFalse('Scan start node Node at empty line gone', FTestTree.FindNodeAtPosition(33, afmNil).HasNode);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(29, 1)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(17, 3)) ]);
CheckNodes(n, 7, [ ExpN( 5,15, idnIfdef, EpSkip, EpElse(7, 20)),
ExpN(20,27, idnElse, EpIf(7, 5), EpEnd(7, 32)),
ExpN(32,40, idnEndIf, EpElse(7, 20)),
ExpN(43,53, idnIfdef, EpSkip, EpEnd(11, 5)) ]);
CheckNodes(n, 8, [ ExpN( 7,17, idnIfdef, EpSkip, EpEnd(10, 7)),
ExpN(19,29, idnIfdef, EpSkip, EpElse(8, 34)),
ExpN(34,41, idnElse, EpIf(8, 19), EpEnd(8, 46)),
ExpN(46,54, idnEndIf, EpElse(8, 34)) ]);
CheckNodes(n,10, [ ExpN( 7,15, idnEndIf, EpIf(8, 7)) ]);
CheckNodes(n,11, [ ExpN( 5,13, idnEndIf, EpIf(7, 43)) ]);
CheckNodes(n,13, [ ExpN( 5,16, idnIfdef, EpSkip, EpEnd(14, 5)) ]);
CheckNodes(n,14, [ ExpN( 5,13, idnEndIf, EpIf(13, 5)) ]);
CheckNodes(n,15, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(15, 16)),
ExpN(16,24, idnEndIf, EpIf(15, 5)) ]);
CheckNodes(n,17, [ ExpN( 3,11, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,19, [ ExpN( 3,14, idnIfdef, EpSkip, EpElse(21, 3)) ]);
CheckNodes(n,21, [ ExpN( 3,10, idnElse, EpIf(19, 3), EpEnd(27, 3)) ]);
CheckNodes(n,23, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(25, 5)) ]);
CheckNodes(n,25, [ ExpN( 5,13, idnEndIf, EpIf(23, 5)) ]);
CheckNodes(n,26, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(26, 16)),
ExpN(16,24, idnEndIf, EpIf(26, 5)) ]);
CheckNodes(n,27, [ ExpN( 3,11, idnEndIf, EpElse(21, 3)) ]);
CheckNodes(n,29, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(36,1)) ]);
CheckNodes(n,31, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(32, 3)) ]);
CheckNodes(n,32, [ ExpN( 3,10, idnElse, EpIf(31, 3), EpEnd(34,3)) ]);
CheckNodes(n,34, [ ExpN( 3,11, idnEndIf, EpElse(32, 3)) ]);
CheckNodes(n,36, [ ExpN( 1, 9, idnEndIf, EpElse(29, 1)) ]);
n := 'Peers, TestText1: 32-36';
ReCreateEditForTreeTest(TestText1);
FTestTree.ValidateRange(32, 36, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(29, 1)) ]);
CheckNodes(n,29, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(36,1)) ]);
CheckNodes(n,31, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(32, 3)) ]);
CheckNodes(n,32, [ ExpN( 3,10, idnElse, EpIf(31, 3), EpEnd(34,3)) ]);
CheckNodes(n,34, [ ExpN( 3,11, idnEndIf, EpElse(32, 3)) ]);
CheckNodes(n,36, [ ExpN( 1, 9, idnEndIf, EpElse(29, 1)) ]);
//
n := 'Peers, TestText1: 16-20 AFTER 32-36';
FTestTree.ValidateRange(16, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(29, 1)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(17, 3)) ]);
CheckNodes(n,17, [ ExpN( 3,11, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,19, [ ExpN( 3,14, idnIfdef) ]);
CheckNodes(n,29, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(36,1)) ]);
CheckNodes(n,31, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(32, 3)) ]);
CheckNodes(n,32, [ ExpN( 3,10, idnElse, EpIf(31, 3), EpEnd(34,3)) ]);
CheckNodes(n,34, [ ExpN( 3,11, idnEndIf, EpElse(32, 3)) ]);
CheckNodes(n,36, [ ExpN( 1, 9, idnEndIf, EpElse(29, 1)) ]);
//
n := 'Peers, TestText1: all AFTER 16-20 AFTER 32-36';
FTestTree.ValidateRange(1, 36, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(29, 1)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(17, 3)) ]);
CheckNodes(n, 7, [ ExpN( 5,15, idnIfdef, EpSkip, EpElse(7, 20)),
ExpN(20,27, idnElse, EpIf(7, 5), EpEnd(7, 32)),
ExpN(32,40, idnEndIf, EpElse(7, 20)),
ExpN(43,53, idnIfdef, EpSkip, EpEnd(11, 5)) ]);
CheckNodes(n, 8, [ ExpN( 7,17, idnIfdef, EpSkip, EpEnd(10, 7)),
ExpN(19,29, idnIfdef, EpSkip, EpElse(8, 34)),
ExpN(34,41, idnElse, EpIf(8, 19), EpEnd(8, 46)),
ExpN(46,54, idnEndIf, EpElse(8, 34)) ]);
CheckNodes(n,10, [ ExpN( 7,15, idnEndIf, EpIf(8, 7)) ]);
CheckNodes(n,11, [ ExpN( 5,13, idnEndIf, EpIf(7, 43)) ]);
CheckNodes(n,13, [ ExpN( 5,16, idnIfdef, EpSkip, EpEnd(14, 5)) ]);
CheckNodes(n,14, [ ExpN( 5,13, idnEndIf, EpIf(13, 5)) ]);
CheckNodes(n,15, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(15, 16)),
ExpN(16,24, idnEndIf, EpIf(15, 5)) ]);
CheckNodes(n,17, [ ExpN( 3,11, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,19, [ ExpN( 3,14, idnIfdef, EpSkip, EpElse(21, 3)) ]);
CheckNodes(n,21, [ ExpN( 3,10, idnElse, EpIf(19, 3), EpEnd(27, 3)) ]);
CheckNodes(n,23, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(25, 5)) ]);
CheckNodes(n,25, [ ExpN( 5,13, idnEndIf, EpIf(23, 5)) ]);
CheckNodes(n,26, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(26, 16)),
ExpN(16,24, idnEndIf, EpIf(26, 5)) ]);
CheckNodes(n,27, [ ExpN( 3,11, idnEndIf, EpElse(21, 3)) ]);
CheckNodes(n,29, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(36,1)) ]);
CheckNodes(n,31, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(32, 3)) ]);
CheckNodes(n,32, [ ExpN( 3,10, idnElse, EpIf(31, 3), EpEnd(34,3)) ]);
CheckNodes(n,34, [ ExpN( 3,11, idnEndIf, EpElse(32, 3)) ]);
CheckNodes(n,36, [ ExpN( 1, 9, idnEndIf, EpElse(29, 1)) ]);
n := 'scan plain text, after closed node: step 1: node';
ReCreateEditForTreeTest(TestText3);
FTestTree.ValidateRange(3, 5, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
n := 'scan plain text, after closed node: step 2: empty';
FTestTree.ValidateRange(8, 9, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
n := 'scan plain text, after closed node (overlap): step 1: node';
ReCreateEditForTreeTest(TestText3);
FTestTree.ValidateRange(3, 8, FOpenings); // ensure node is valid to begin-of-plain-line-scan
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
n := 'scan plain text, after closed node (overlap): step 2: empty';
FTestTree.ValidateRange(7, 9, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
n := 'scan plain text, after closed node (not scanned end): step 1: node';
ReCreateEditForTreeTest(TestText3);
FTestTree.ValidateRange(3, 3, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef) ]);
n := 'scan plain text, after closed node (not scanned end): step 2: empty';
FTestTree.ValidateRange(8, 9, FOpenings);
n := 'Peers, TestText5: elseif';
ReCreateEditForTreeTest(TestText5);
FTestTree.ValidateRange(1, 9, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElseIf(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1,12, idnElseIf,EpIf(2, 1), EpElse(6, 1)) ]);
CheckNodes(n, 6, [ ExpN( 1, 8, idnElse, EpElseIf(4, 1), EpEnd(8, 1)) ]);
CheckNodes(n, 8, [ ExpN( 1, 9, idnEndIf, EpElse(6, 1)) ]);
{%endregion peers}
{%region peers + editing}
n := 'Peers, TestText1: Before Edit';
ReCreateEditForTreeTest(TestText1);
FTestTree.ValidateRange(1, 36, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(29, 1)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(17, 3)) ]);
CheckNodes(n, 7, [ ExpN( 5,15, idnIfdef, EpSkip, EpElse(7, 20)),
ExpN(20,27, idnElse, EpIf(7, 5), EpEnd(7, 32)),
ExpN(32,40, idnEndIf, EpElse(7, 20)),
ExpN(43,53, idnIfdef, EpSkip, EpEnd(11, 5)) ]);
CheckNodes(n, 8, [ ExpN( 7,17, idnIfdef, EpSkip, EpEnd(10, 7)),
ExpN(19,29, idnIfdef, EpSkip, EpElse(8, 34)),
ExpN(34,41, idnElse, EpIf(8, 19), EpEnd(8, 46)),
ExpN(46,54, idnEndIf, EpElse(8, 34)) ]);
CheckNodes(n,10, [ ExpN( 7,15, idnEndIf, EpIf(8, 7)) ]);
CheckNodes(n,11, [ ExpN( 5,13, idnEndIf, EpIf(7, 43)) ]);
CheckNodes(n,13, [ ExpN( 5,16, idnIfdef, EpSkip, EpEnd(14, 5)) ]);
CheckNodes(n,14, [ ExpN( 5,13, idnEndIf, EpIf(13, 5)) ]);
CheckNodes(n,15, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(15, 16)),
ExpN(16,24, idnEndIf, EpIf(15, 5)) ]);
CheckNodes(n,17, [ ExpN( 3,11, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,19, [ ExpN( 3,14, idnIfdef, EpSkip, EpElse(21, 3)) ]);
CheckNodes(n,21, [ ExpN( 3,10, idnElse, EpIf(19, 3), EpEnd(27, 3)) ]);
CheckNodes(n,23, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(25, 5)) ]);
CheckNodes(n,25, [ ExpN( 5,13, idnEndIf, EpIf(23, 5)) ]);
CheckNodes(n,26, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(26, 16)),
ExpN(16,24, idnEndIf, EpIf(26, 5)) ]);
CheckNodes(n,27, [ ExpN( 3,11, idnEndIf, EpElse(21, 3)) ]);
CheckNodes(n,29, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(36,1)) ]);
CheckNodes(n,31, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(32, 3)) ]);
CheckNodes(n,32, [ ExpN( 3,10, idnElse, EpIf(31, 3), EpEnd(34,3)) ]);
CheckNodes(n,34, [ ExpN( 3,11, idnEndIf, EpElse(32, 3)) ]);
CheckNodes(n,36, [ ExpN( 1, 9, idnEndIf, EpElse(29, 1)) ]);
SynEdit.TextBetweenPoints[point(1, 9),point(1, 9)] := LineEnding;
n := 'Peers, TestText1: Line inserted at 9';
FTestTree.ValidateRange(1, 37, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpElse(30, 1)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(18, 3)) ]);
CheckNodes(n, 7, [ ExpN( 5,15, idnIfdef, EpSkip, EpElse(7, 20)),
ExpN(20,27, idnElse, EpIf(7, 5), EpEnd(7, 32)),
ExpN(32,40, idnEndIf, EpElse(7, 20)),
ExpN(43,53, idnIfdef, EpSkip, EpEnd(12, 5)) ]);
CheckNodes(n, 8, [ ExpN( 7,17, idnIfdef, EpSkip, EpEnd(11, 7)),
ExpN(19,29, idnIfdef, EpSkip, EpElse(8, 34)),
ExpN(34,41, idnElse, EpIf(8, 19), EpEnd(8, 46)),
ExpN(46,54, idnEndIf, EpElse(8, 34)) ]);
CheckNodes(n,11, [ ExpN( 7,15, idnEndIf, EpIf(8, 7)) ]);
CheckNodes(n,12, [ ExpN( 5,13, idnEndIf, EpIf(7, 43)) ]);
CheckNodes(n,14, [ ExpN( 5,16, idnIfdef, EpSkip, EpEnd(15, 5)) ]);
CheckNodes(n,15, [ ExpN( 5,13, idnEndIf, EpIf(14, 5)) ]);
CheckNodes(n,16, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(16, 16)),
ExpN(16,24, idnEndIf, EpIf(16, 5)) ]);
CheckNodes(n,18, [ ExpN( 3,11, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,20, [ ExpN( 3,14, idnIfdef, EpSkip, EpElse(22, 3)) ]);
CheckNodes(n,22, [ ExpN( 3,10, idnElse, EpIf(20, 3), EpEnd(28, 3)) ]);
CheckNodes(n,24, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(26, 5)) ]);
CheckNodes(n,26, [ ExpN( 5,13, idnEndIf, EpIf(24, 5)) ]);
CheckNodes(n,27, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(27, 16)),
ExpN(16,24, idnEndIf, EpIf(27, 5)) ]);
CheckNodes(n,28, [ ExpN( 3,11, idnEndIf, EpElse(22, 3)) ]);
CheckNodes(n,30, [ ExpN( 1, 8, idnElse, EpIf(2, 1), EpEnd(37,1)) ]);
CheckNodes(n,32, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(33, 3)) ]);
CheckNodes(n,33, [ ExpN( 3,10, idnElse, EpIf(32, 3), EpEnd(35,3)) ]);
CheckNodes(n,35, [ ExpN( 3,11, idnEndIf, EpElse(33, 3)) ]);
CheckNodes(n,37, [ ExpN( 1, 9, idnEndIf, EpElse(30, 1)) ]);
SynEdit.TextBetweenPoints[point(1, 9),point(1, 9)] := '{$EndIf}';
n := 'Peers, TestText1: ENDIF inserted at 9';
FTestTree.ValidateRange(1, 37, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(18, 3)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(12, 5)) ]);
CheckNodes(n, 7, [ ExpN( 5,15, idnIfdef, EpSkip, EpElse(7, 20)),
ExpN(20,27, idnElse, EpIf(7, 5), EpEnd(7, 32)),
ExpN(32,40, idnEndIf, EpElse(7, 20)),
ExpN(43,53, idnIfdef, EpSkip, EpEnd(11, 7)) ]);
CheckNodes(n, 8, [ ExpN( 7,17, idnIfdef, EpSkip, EpEnd(9, 1)),
ExpN(19,29, idnIfdef, EpSkip, EpElse(8, 34)),
ExpN(34,41, idnElse, EpIf(8, 19), EpEnd(8, 46)),
ExpN(46,54, idnEndIf, EpElse(8, 34)) ]);
CheckNodes(n,11, [ ExpN( 7,15, idnEndIf, EpIf(7, 43)) ]);
CheckNodes(n,12, [ ExpN( 5,13, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,14, [ ExpN( 5,16, idnIfdef, EpSkip, EpEnd(15, 5)) ]);
CheckNodes(n,15, [ ExpN( 5,13, idnEndIf, EpIf(14, 5)) ]);
CheckNodes(n,16, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(16, 16)),
ExpN(16,24, idnEndIf, EpIf(16, 5)) ]);
CheckNodes(n,18, [ ExpN( 3,11, idnEndIf, EpIf(2, 1)) ]);
CheckNodes(n,20, [ ExpN( 3,14, idnIfdef, EpSkip, EpElse(22, 3)) ]);
CheckNodes(n,22, [ ExpN( 3,10, idnElse, EpIf(20, 3), EpEnd(28, 3)) ]);
CheckNodes(n,24, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(26, 5)) ]);
CheckNodes(n,26, [ ExpN( 5,13, idnEndIf, EpIf(24, 5)) ]);
CheckNodes(n,27, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(27, 16)),
ExpN(16,24, idnEndIf, EpIf(27, 5)) ]);
CheckNodes(n,28, [ ExpN( 3,11, idnEndIf, EpElse(22, 3)) ]);
CheckNodes(n,30, [ ExpN( 1, 8, idnElse, EpNil, EpEnd(37,1)) ]);
CheckNodes(n,32, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(33, 3)) ]);
CheckNodes(n,33, [ ExpN( 3,10, idnElse, EpIf(32, 3), EpEnd(35,3)) ]);
CheckNodes(n,35, [ ExpN( 3,11, idnEndIf, EpElse(33, 3)) ]);
CheckNodes(n,37, [ ExpN( 1, 9, idnEndIf, EpElse(30, 1)) ]);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := '{$Else}';
FTestTree.ValidateRange(1, 37, FOpenings);
//SynEdit.TextBetweenPoints[point(1, 3),point(1, 8)] := '';
SynEdit.TextBetweenPoints[point(1, 3),point(8, 3)] := '';
FTestTree.ValidateRange(1, 37, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(18, 3)) ]);
CheckNodes(n, 5, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(12, 5)) ]);
CheckNodes(n, 7, [ ExpN( 5,15, idnIfdef, EpSkip, EpElse(7, 20)),
ExpN(20,27, idnElse, EpIf(7, 5), EpEnd(7, 32)),
ExpN(32,40, idnEndIf, EpElse(7, 20)),
ExpN(43,53, idnIfdef, EpSkip, EpEnd(11, 7)) ]);
CheckNodes(n, 8, [ ExpN( 7,17, idnIfdef, EpSkip, EpEnd(9, 1)),
ExpN(19,29, idnIfdef, EpSkip, EpElse(8, 34)),
ExpN(34,41, idnElse, EpIf(8, 19), EpEnd(8, 46)),
ExpN(46,54, idnEndIf, EpElse(8, 34)) ]);
CheckNodes(n,11, [ ExpN( 7,15, idnEndIf, EpIf(7, 43)) ]);
CheckNodes(n,12, [ ExpN( 5,13, idnEndIf, EpIf(5, 3)) ]);
CheckNodes(n,14, [ ExpN( 5,16, idnIfdef, EpSkip, EpEnd(15, 5)) ]);
CheckNodes(n,15, [ ExpN( 5,13, idnEndIf, EpIf(14, 5)) ]);
CheckNodes(n,16, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(16, 16)),
ExpN(16,24, idnEndIf, EpIf(16, 5)) ]);
CheckNodes(n,18, [ ExpN( 3,11, idnEndIf, EpIf(2, 1)) ]);
CheckNodes(n,20, [ ExpN( 3,14, idnIfdef, EpSkip, EpElse(22, 3)) ]);
CheckNodes(n,22, [ ExpN( 3,10, idnElse, EpIf(20, 3), EpEnd(28, 3)) ]);
CheckNodes(n,24, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(26, 5)) ]);
CheckNodes(n,26, [ ExpN( 5,13, idnEndIf, EpIf(24, 5)) ]);
CheckNodes(n,27, [ ExpN( 5,15, idnIfdef, EpSkip, EpEnd(27, 16)),
ExpN(16,24, idnEndIf, EpIf(27, 5)) ]);
CheckNodes(n,28, [ ExpN( 3,11, idnEndIf, EpElse(22, 3)) ]);
CheckNodes(n,30, [ ExpN( 1, 8, idnElse, EpNil, EpEnd(37,1)) ]);
CheckNodes(n,32, [ ExpN( 3,13, idnIfdef, EpSkip, EpElse(33, 3)) ]);
CheckNodes(n,33, [ ExpN( 3,10, idnElse, EpIf(32, 3), EpEnd(35,3)) ]);
CheckNodes(n,35, [ ExpN( 3,11, idnEndIf, EpElse(33, 3)) ]);
CheckNodes(n,37, [ ExpN( 1, 9, idnEndIf, EpElse(30, 1)) ]);
{%region remove endif by edit // Test nodes delete => resolve peer}
n := 'remove endif by edit / edit endif (one endif in line)';
ReCreateEditForTreeTest(TestText3);
FTestTree.ValidateRange(1, 8, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
SynEdit.TextBetweenPoints[point(3, 4),point(3, 4)] := ' ';
FTestTree.ValidateRange(1, 8, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil) ]);
CheckNodes(n, 4, [ ]);
n := 'remove endif by edit / edit endif (two endif in line, edit first)';
ReCreateEditForTreeTest(TestText3a);
FTestTree.ValidateRange(1, 8, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4,10)),
ExpN(12,22, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2,12)),
ExpN(10,18, idnEndIf, EpIf(2, 1)) ]);
SynEdit.TextBetweenPoints[point(3, 4),point(3, 4)] := ' ';
FTestTree.ValidateRange(1, 8, FOpenings);
//FTestTree.DebugPrint(true);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil),
ExpN(12,22, idnIfdef, EpSkip, EpEnd(4,11)) ]);
CheckNodes(n, 4, [ ExpN(11,19, idnEndIf, EpIf(2, 12)) ]);
n := 'remove endif by edit / edit endif (two endif in line, edit 2nd)';
ReCreateEditForTreeTest(TestText3a);
FTestTree.ValidateRange(1, 8, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4,10)),
ExpN(12,22, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2,12)),
ExpN(10,18, idnEndIf, EpIf(2, 1)) ]);
SynEdit.TextBetweenPoints[point(13,4),point(13,4)] := ' ';
FTestTree.ValidateRange(1, 8, FOpenings);
FTestTree.DebugPrint(true);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil),
ExpN(12,22, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2,12)) ]);
{%endregion}
{%region Add outer lines by removing endif}
// No outer lines to begin
n := 'Extend outer lines by removing endif - BUT new peer for new outer ifdef is PAST visible (not scanned)';
ReCreateEditForTreeTest(TestText7);
FTestTree.ValidateRange(1, 16, FOpenings); // scan all, so the nodes to exist
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
CheckNodes(n,10, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd(14, 2)) ]);
CheckNodes(n,14, [ ExpN( 2,10, idnEndIf, EpIf(10, 2)) ]);
SynEdit.TextBetweenPoints[point(4,4),point(4,4)] := ' '; // remove ifdef (leaving invalid node)
FOpenings.Clear;
FTestTree.ValidateRange(6, 8, FOpenings); // scan empty text
// Expect outer node to be changed
// This is siped by markup
//CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil) ]);
n := 'Extend outer lines by removing endif - new endif in visible range';
ReCreateEditForTreeTest(TestText7);
FTestTree.ValidateRange(1, 16, FOpenings); // scan all, so the nodes to exist
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
CheckNodes(n,10, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd(14, 2)) ]);
CheckNodes(n,14, [ ExpN( 2,10, idnEndIf, EpIf(10, 2)) ]);
SynEdit.TextBetweenPoints[point(4,10),point(4,10)] := ' '; // remove ifdef so we have an extra endif
FOpenings.Clear;
FTestTree.ValidateRange(1, 16, FOpenings); // scan all, so the nodes to exist
FTestTree.DebugPrint(true);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
CheckNodes(n,10, [ ]);
CheckNodes(n,14, [ ExpN( 2,10, idnEndIf, EpNil) ]);
SynEdit.TextBetweenPoints[point(4,4),point(4,4)] := ' '; // remove ifdef (leaving invalid node)
FOpenings.Clear;
FTestTree.ValidateRange(6, 16, FOpenings); // scan empty text
FTestTree.DebugPrint(true);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(14, 2)) ]);
// CheckNodes(n, 4, [ ]);
CheckNodes(n,10, [ ]);
CheckNodes(n,14, [ ExpN( 2,10, idnEndIf, EpIf(2, 1)) ]);
{%endregion}
{%endregion peers + edit}
{%region UNMATCHED PEERS}
// NO EDIT
n := 'Peers, TestText2: Bad nodes';
ReCreateEditForTreeTest(TestText2);
FTestTree.ValidateRange(1, 18, FOpenings);
// ONe and only one of the 2 ends should have a peer
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(4, 1)) ]);
CheckNodes(n, 4, [ ExpN( 1, 9, idnEndIf, EpIf(2, 1)) ]);
CheckNodes(n, 6, [ ExpN( 1, 9, idnEndIf, EpNil) ]); // must not have a peer
// One and only one else may be connected to if and one (but maybe the other) to endif
CheckNodes(n,10, [ ExpN( 1,11, idnIfdef) ]); // EpElse(12, 1) // or 14
CheckNodes(n,12, [ ExpN( 1, 8, idnElse) ]);
CheckNodes(n,14, [ ExpN( 1, 8, idnElse) ]);
CheckNodes(n,16, [ ExpN( 1, 9, idnEndIf, EpElse(14, 1)) ]);
{%region Insert If/end to create invalid peering, that must be resolved }
n := 'Peers, TestText6: Resolve left-over binding: ' +
'Insert Ifdef in visible part, with node inbetween';
ReCreateEditForTreeTest(TestText6);
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd(18, 2)) ]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 6, 2)) ]);
SynEdit.TextBetweenPoints[point(1, 8),point(1, 8)] := ' {$IfDef X}';
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 8, [ ExpN( 4,14, idnIfdef, EpSkip, EpEnd(18, 2)) ]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 8, 4)) ]);
n := n + ' Remove again';
SynEdit.TextBetweenPoints[point(1, 8),point(14, 8)] := '';
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd(18, 2)) ]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 6, 2)) ]);
{%endregion Insert If/end to create invalid peering, that must be resolved }
{%region Insert If/end to create invalid peering, that must be resolved }
n := 'Peers, TestText6: Resolve left-over binding: ' +
'Insert EndIf in visible part, with node inbetween';
ReCreateEditForTreeTest(TestText6);
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd(18, 2)) ]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 6, 2)) ]);
SynEdit.TextBetweenPoints[point(1, 8),point(1, 8)] := ' {$Endif}';
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(18, 2)) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd( 8, 4)) ]);
CheckNodes(n, 8, [ ExpN( 4,12, idnEndIf, EpIf( 6, 2)) ]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 2, 1)) ]);
n := n + ' Remove again';
SynEdit.TextBetweenPoints[point(1, 8),point(14, 8)] := '';
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd(18, 2)) ]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 6, 2)) ]);
{%endregion Insert If/end to create invalid peering, that must be resolved }
{%region Insert If/end to create invalid peering, that must be resolved }
n := 'Peers, TestText6: Relosve left-over binding: ' +
'Insert Ifdef in visible part, with node inbetween AT end of outer ifdef';
ReCreateEditForTreeTest(TestText6);
FTestTree.ValidateRange(1, 20, FOpenings);
SynEdit.TextBetweenPoints[point(12, 6),point(12, 6)] := ' {$IfDef X}';
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpNil ),
ExpN(15,25, idnIfdef, EpSkip, EpEnd(18, 2))
]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 6, 15)) ]);
n := n + ' Remove again';
SynEdit.TextBetweenPoints[point(12, 6),point(25, 6)] := '';
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd(18, 2)) ]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 6, 2)) ]);
{%endregion Insert If/end to create invalid peering, that must be resolved }
{%region Insert If/end to create invalid peering, that must be resolved }
n := 'Peers, TestText6: Relosve left-over binding: ' +
'Insert EndIf in visible part, with node inbetween AT end of outer ifdef';
ReCreateEditForTreeTest(TestText6);
FTestTree.ValidateRange(1, 20, FOpenings);
SynEdit.TextBetweenPoints[point(12, 6),point(12, 6)] := ' {$EndIf}';
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpEnd(18, 2) ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd( 6,15) ),
ExpN(15,23, idnEndIf, EpIf( 6, 2))
]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 2, 1)) ]);
n := n + ' Remove again';
SynEdit.TextBetweenPoints[point(12, 6),point(25, 6)] := '';
FTestTree.ValidateRange(1, 20, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, EpSkip, EpNil ) ]);
CheckNodes(n, 6, [ ExpN( 2,12, idnIfdef, EpSkip, EpEnd(18, 2)) ]);
CheckNodes(n,10, [ ExpN( 3,13, idnIfdef, EpSkip, EpEnd(14, 3)) ]);
CheckNodes(n,14, [ ExpN( 3,11, idnEndIf, EpIf(10, 3)) ]);
CheckNodes(n,18, [ ExpN( 2,10, idnEndIf, EpIf( 6, 2)) ]);
{%endregion Insert If/end to create invalid peering, that must be resolved }
{%region ELSE WITHOUT IFDEF and DOUBLE ELSE }
// TODO: Else and ifdef on same line
for i := 0 to 2 do begin
for i2 := 0 to 7 do
for i3 := 0 to 2 do // ifdef
for i4 := 0 to 1 do // endif TODO
begin
case i of
0: begin
PushBaseName('Scan empty, then add else at line 3 (after scan-start-marker)');
ReCreateEditForTreeTest(TestTextNoIfDef);
FTestTree.ValidateRange(1, 9, FOpenings);
end;
1: begin
PushBaseName('Scan empty (form 3), then add else at line 3 (AT scan-start-marker)');
ReCreateEditForTreeTest(TestTextNoIfDef);
FTestTree.ValidateRange(3, 9, FOpenings);
end;
2:begin
PushBaseName('Add else (before first scan) at line 3');
ReCreateEditForTreeTest(TestTextNoIfDef);
end;
end;
//debugln(['# ', i, ' ', i2, ' ', i3, ' ', i4]);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := ' {$ELSE} //';
FTestTree.ValidateRange(1, 9, FOpenings);
CheckNodes(n, 3, [ ExpN(21,28, idnElse, EpNil, EpNil ) ]);
SynEdit.TextBetweenPoints[point(1, 3),point(28, 3)] := '';
FTestTree.ValidateRange(1, 9, FOpenings);
CheckNodes(n+'undone', 3, [ ]);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := ' {$ELSE} //';
FTestTree.ValidateRange(1, 9, FOpenings);
CheckNodes(n+'redone', 3, [ ExpN(21,28, idnElse, EpNil, EpNil ) ]);
n := '['+IntToStr(i2)+']';
// Maybe ifdef
epMaybeIf := EpNil;
epMaybeIf^.NoAutoFree := True;
if i3 >= 1 then begin
n := n + 'Insert leading IFDEF';
SynEdit.TextBetweenPoints[point(1, 1),point(1, 1)] := '{$IFDEF a}';
if i4 = 2 then begin
n := n + '(scanned)';
FTestTree.ValidateRange(1, 9, FOpenings);
CheckNodes(n+'ifdef', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(3,21) ) ]);
CheckNodes(n+'ifdef', 3, [ ExpN(21,28, idnElse, EpIf(1,1), EpNil ) ]);
end;
Dispose(epMaybeIf);
epMaybeIf := EpIf(1,1);
epMaybeIf^.NoAutoFree := True;
end;
if (i2 and 1) = 0 then begin
// 2nd before first
SynEdit.TextBetweenPoints[point(1, 2),point(1, 2)] := ' {$ELSE}';
FTestTree.ValidateRange(1, 9, FOpenings);
if i3 >= 1 then
CheckNodes(n+'2nd else before 1st', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(2,2) ) ]);
CheckNodes(n+'2nd else before 1st', 2, [ ExpN( 2, 9, idnElse, epMaybeIf, EpNil ) ]);
CheckNodes(n+'2nd else before 1st', 3, [ ExpN(21,28, idnElse, EpNil, EpNil ) ]);
SynEdit.TextBetweenPoints[point(1, 2),point(9, 2)] := '';
FTestTree.ValidateRange(1, 9, FOpenings);
if i3 >= 1 then
CheckNodes(n+'undone 2nd before 1st', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(3,21) ) ]);
CheckNodes(n+'undone 2nd before 1st', 2, [ ]);
CheckNodes(n+'undone 2nd before 1st', 3, [ ExpN(21,28, idnElse, epMaybeIf, EpNil ) ]);
end;
if (i2 and 2) = 0 then begin
// 2nd after first
SynEdit.TextBetweenPoints[point(1, 4),point(1, 4)] := ' {$ELSE}';
FTestTree.ValidateRange(1, 9, FOpenings);
if i3 >= 1 then
CheckNodes(n+'2nd after 1st', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(3,21) ) ]);
CheckNodes(n+'2nd else after 1st', 3, [ ExpN(21,28, idnElse, epMaybeIf, EpNil ) ]);
CheckNodes(n+'2nd else after 1st', 4, [ ExpN( 2, 9, idnElse, EpNil, EpNil ) ]);
SynEdit.TextBetweenPoints[point(1, 4),point(9, 4)] := '';
FTestTree.ValidateRange(1, 9, FOpenings);
if i3 >= 1 then
CheckNodes(n+'undone 2nd after 1st', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(3,21) ) ]);
CheckNodes(n+'undone 2nd after 1st', 3, [ ExpN(21,28, idnElse, epMaybeIf, EpNil ) ]);
CheckNodes(n+'undone 2nd after 1st', 4, [ ]);
end;
if (i2 and 3) = 0 then begin
// 2nd before first (same line)
SynEdit.TextBetweenPoints[point(11, 3),point(18, 3)] := '{$ELSE}';
FTestTree.ValidateRange(1, 9, FOpenings);
if i3 >= 1 then
CheckNodes(n+'2nd before 1st (same line)', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(3,11) ) ]);
CheckNodes(n+'2nd else before 1st (same line)', 3, [
ExpN(11,18, idnElse, epMaybeIf, EpNil ),
ExpN(21,28, idnElse, EpNil, EpNil )
]);
SynEdit.TextBetweenPoints[point(11, 3),point(18, 3)] := ' ';
FTestTree.ValidateRange(1, 9, FOpenings);
if i3 >= 1 then
CheckNodes(n+'undone 2nd before 1st (same line)', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(3,21) ) ]);
CheckNodes(n+'undone 2nd before 1st (same line)', 3, [ ExpN(21,28, idnElse, epMaybeIf, EpNil ) ]);
end;
// 2nd after first (same line)
SynEdit.TextBetweenPoints[point(31, 3),point(38, 3)] := '{$ELSE}';
FTestTree.ValidateRange(1, 9, FOpenings);
if i3 >= 1 then
CheckNodes(n+'2nd after 1st (same line)', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(3,21) ) ]);
CheckNodes(n+'2nd else after 1st (same line)', 3, [
ExpN(21,28, idnElse, epMaybeIf, EpNil ),
ExpN(31,38, idnElse, EpNil, EpNil )
]);
SynEdit.TextBetweenPoints[point(31, 3),point(38, 3)] := ' ';
FTestTree.ValidateRange(1, 9, FOpenings);
if i3 >= 1 then
CheckNodes(n+'undone 2nd after 1st (same line)', 1, [ ExpN( 1,11, idnIfdef, EpNil, EpElse(3,21) ) ]);
CheckNodes(n+'undone 2nd after 1st (same line)', 3, [ ExpN(21,28, idnElse, epMaybeIf, EpNil ) ]);
Dispose(epMaybeIf);
PopBaseName;
end;
end;
{%endregion ELSE WITHOUT IFDEF and DOUBLE ELSE }
{%region }
n := 'P';
ReCreateEditForTreeTest(TestText2);
FTestTree.ValidateRange(1, 24, FOpenings);
FTestTree.ValidateRange(1, 24, FOpenings);
{%endregion }
{%endregion UNMATCHED PEERS}
{%region }
n := 'scan new unfinished node, next node will be comment';
ReCreateEditForTreeTest(TestText4);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := LineEnding;
FTestTree.ValidateRange(1, 6, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
CheckNodes(n, 5, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := ' {$IFDEF ';
FTestTree.ValidateRange(3, 4, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
if FUseNestedComments
then CheckNodes(n, 3, [ ExpN( 4, 0, 4, idnIfdef) ]) // end-column does not exist
else CheckNodes(n, 3, [ ExpN( 4,11, 2, idnIfdef) ]); // end-column does not exist
{%endregion }
{%region }
n := 'scan new unfinished node, next node will be comment';
ReCreateEditForTreeTest(TestText4);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := LineEnding;
FTestTree.ValidateRange(1, 6, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
CheckNodes(n, 5, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := ' {$IFDEF ';
FTestTree.ValidateRange(1, 4, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
if FUseNestedComments
then CheckNodes(n, 3, [ ExpN( 4, 0, 4, idnIfdef) ]) // end-column does not exist
else CheckNodes(n, 3, [ ExpN( 4,11, 2, idnIfdef) ]); // end-column does not exist
{%endregion }
{%region }
n := 'scan new unfinished node, next node will be comment';
ReCreateEditForTreeTest(TestText4);
FTestTree.ValidateRange(1, 6, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
CheckNodes(n, 4, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := ' {$IFDEF ';
FTestTree.ValidateRange(1, 3, FOpenings);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
if FUseNestedComments
then CheckNodes(n, 3, [ ExpN( 4, 0, 3, idnIfdef) ]) // end-column does not exist
else CheckNodes(n, 3, [ ExpN( 4,11, 1, idnIfdef) ]); // end-column does not exist
{%endregion }
{%region }
n := 'multi elseif open';
ReCreateEditForTreeTest(TestText9);
FTestTree.ValidateRange(1, 18, FOpenings);
//CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
//n := '';
ReCreateEditForTreeTest(TestText9);
FTestTree.ValidateRange(11, 18, FOpenings);
//CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
{%endregion }
{%region }
n := '';
ReCreateEditForTreeTest(TestText10);
FTestTree.ValidateRange(1, 9, FOpenings);
FTestTree.SetNodeState(7, 1, idnDisabled);
//CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef), ExpN(13,21, idnEndIf) ]);
SynEdit.TextBetweenPoints[point(1, 4),point(1, 4)] := '{$endi';
FTestTree.ValidateRange(1, 9, FOpenings);
SynEdit.TextBetweenPoints[point(7, 4),point(7, 4)] := 'f';
FTestTree.ValidateRange(1, 9, FOpenings);
SynEdit.TextBetweenPoints[point(12, 4),point(12, 4)] := '} ';
FTestTree.ValidateRange(1, 9, FOpenings);
{%endregion }
{%region }
for i := 1 to 34 do begin
n := 'TestText11a elseif ' + IntToStr(i);
ReCreateEditForTreeTest(TestText11a);
FTestTree.ValidateRange(i, 35, FOpenings);
n := 'TestText11a elseif ' + IntToStr(i);
ReCreateEditForTreeTest(TestText11a);
FTestTree.ValidateRange(i, i+1, FOpenings);
n := 'TestText11a elseif ' + IntToStr(i);
ReCreateEditForTreeTest(TestText11a);
FTestTree.ValidateRange(i, i+2, FOpenings);
end;
n := 'TestText11a elseif 12-30';
ReCreateEditForTreeTest(TestText11a);
FTestTree.ValidateRange(11, 30, FOpenings);
CheckNodes(n, 1, [ ExpN( 1,21, idnIfdef)]);
//CheckNodes(n, 2, [ ExpN( 1,21, idnIfdef)]);
CheckNodes(n, 11, [ ExpN( 3,11, idnEndIf, EpIf(10,13), EpNil),
ExpN(11,39, idnElseIf, EpElseIf(8, 3), EpElse(21,3)) ]);
{%endregion }
{%region issue 0025811 }
n := 'issue 0025811';
ReCreateEditForTreeTest(TestText12);
FTestTree.ValidateRange( 7, 10, FOpenings);
CheckNodes(n, 6, [ ExpN( 13,21, idnSkipTest), ExpN(22,30, idnSkipTest),
ExpN(31, 48, idnIfdef, EpNil, EpEnd(7, 13)) ]);
CheckNodes(n, 7, [ ExpN( 13,21, idnEndIf, EpIf(6, 31), EpNil) ]);
ReCreateEditForTreeTest(TestText12);
FTestTree.ValidateRange( 5, 10, FOpenings);
CheckNodes(n, 5, [ ExpN( 6,19, idnIfdef, EpNil, EpEnd(6,22)),
ExpN(20,40, idnIfdef, EpNil, EpEnd(6,13)) ]);
CheckNodes(n, 6, [ ExpN(13,21, idnEndIf, EpIf(5,20), EpNil),
ExpN(22,30, idnEndIf, EpIf(5, 6), EpNil),
ExpN(31, 48, idnIfdef, EpNil, EpEnd(7, 13)) ]);
CheckNodes(n, 7, [ ExpN( 13,21, idnEndIf, EpIf(6, 31), EpNil) ]);
ReCreateEditForTreeTest(TestText12);
FTestTree.ValidateRange( 6, 10, FOpenings);
CheckNodes(n, 5, [ ExpN( 6,19, idnIfdef, EpNil, EpEnd(6,22)),
ExpN(20,40, idnIfdef, EpNil, EpEnd(6,13)) ]);
CheckNodes(n, 6, [ ExpN(13,21, idnEndIf, EpIf(5,20), EpNil),
ExpN(22,30, idnEndIf, EpIf(5, 6), EpNil),
ExpN(31, 48, idnIfdef, EpNil, EpEnd(7, 13)) ]);
CheckNodes(n, 7, [ ExpN( 13,21, idnEndIf, EpIf(6, 31), EpNil) ]);
ReCreateEditForTreeTest(TestText12);
FTestTree.ValidateRange( 8, 10, FOpenings);
{%endregion }
FTestTree.DiscardOpeningList(FOpenings);
FOpenings := nil;
FTestTree.Free;
end;
begin
FUseNestedComments := False;
DoTest;
FUseNestedComments := True;
DoTest;
end;
function TTestMarkupIfDef.TesTNodeStateHandler(Sender: TObject; LinePos, XStartPos: Integer;
CurrentState: TSynMarkupIfdefNodeStateEx): TSynMarkupIfdefNodeState;
var
n, v: String;
begin
n := Format('%d/%d', [LinePos, XStartPos]);
v := FNodeStateRequests.Values[n];
v := IntToStr(StrToIntDef(v, 0) + 1);
FNodeStateRequests.Values[n] := v;
v := FNodeStateResponses.Values[n];
if v = '' then
Result := idnInvalid
else
Result := TSynMarkupIfdefNodeState(StrToIntDef(v, 0));
//DebugLn('# TesTNodeStateHandler ', n, ' # ', v, ' ', dbgs(Result));
end;
procedure TTestMarkupIfDef.TestIfDefTreeNodeState;
procedure ClearData;
begin
FNodeStateResponses.Clear;
FNodeStateRequests.Clear;
end;
procedure AddResponses(R: Array of integer);
var
i: Integer;
begin
for i := 0 to (length(R) div 3) - 1 do
FNodeStateResponses.Values[Format('%d/%d', [R[i*3], R[I*3+1]])] := IntToStr(R[I*3+2]);
end;
procedure CheckReq(n: String; R: Array of integer);
var
i: Integer;
s, s2: String;
begin
AssertEquals(n + 'count requests ' , length(R) div 3, FNodeStateRequests.Count);
for i := 0 to (length(R) div 3) - 1 do begin
s := Format('%d/%d', [R[i*3], R[I*3+1]]);
s2 := IntToStr(R[I*3+2]);
if R[I*3+2] = 0 then s2 := '';
AssertEquals(n + 'Got reqest for '+s , s2, FNodeStateRequests.Values[s]);
end;
end;
procedure SetupTest(Lines: Array of String);
begin
ReCreateEditForTreeTest(Lines);
FTestTree.OnNodeStateRequest := @TesTNodeStateHandler;
end;
var
n: String;
begin
FTestTree := nil;
FNodeStateResponses := TStringList.Create;
FNodeStateRequests := TStringList.Create;
{%region Simple Ifdef + edit: get node request }
SetupTest(TestText3);
// *** Scan
n := 'TestText3 scan;';
ClearData;
AddResponses([ 2, 1, ord(idnEnabled) ]);
FTestTree.ValidateRange(1, 10, FOpenings);
CheckReq(n, [ 2, 1, 1 ]);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, idnEnabled) ]);
// *** Edit Node, trigger new request
n := 'TestText3 edit existing ifdef;';
ClearData;
AddResponses([ 2, 1, ord(idnDisabled) ]);
SynEdit.TextBetweenPoints[point(9, 2),point(9, 2)] := 'x';
FTestTree.ValidateRange(1, 10, FOpenings);
CheckReq(n, [ 2, 1, 1 ]);
CheckNodes(n, 2, [ ExpN( 1,12, idnIfdef, idnDisabled) ]);
// Add ELSE node
n := 'TestText3 add ELSE;';
ClearData;
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := '{$Else}';
FTestTree.ValidateRange(1, 10, FOpenings);
CheckReq(n, []);
CheckNodes(n, 2, [ ExpN( 1,12, idnIfdef, idnDisabled) ]);
CheckNodes(n, 3, [ ExpN( 1, 8, idnElse, idnEnabled) ]);
n := 'Comment entire text';
ClearData;
SynEdit.TextBetweenPoints[point(1, 1),point(1, 1)] := '(*';
FTestTree.ValidateRange(1, 10, FOpenings);
CheckReq(n, []);
CheckNodes(n, 2, [ ExpN( 1,12, idnCommentedIfdef, idnDisabled) ]);
CheckNodes(n, 3, []);
CheckNodes(n, 4, []);
n := 'Edit Commented-ifdef line (append)';
ClearData;
SynEdit.TextBetweenPoints[point(2, 12),point(2, 12)] := '//';
FTestTree.ValidateRange(1, 10, FOpenings);
CheckReq(n, []);
CheckNodes(n, 2, [ ExpN( 1,12, idnCommentedIfdef, idnDisabled) ]);
CheckNodes(n, 3, []);
CheckNodes(n, 4, []);
n := 'UN-Comment entire text';
ClearData;
SynEdit.TextBetweenPoints[point(1, 1),point(3, 1)] := '';
FTestTree.ValidateRange(1, 10, FOpenings);
CheckReq(n, []);
CheckNodes(n, 2, [ ExpN( 1,12, idnIfdef, idnDisabled) ]);
CheckNodes(n, 3, [ ExpN( 1, 8, idnElse, idnEnabled) ]);
{%endregion Simple Ifdef + edit: get node request }
{%region 2 one line Ifdef + edit: get node request, change with SetNodeState }
n := 'TestText4 scan;';
SetupTest(TestText4);
ClearData;
AddResponses([ 2, 1, ord(idnEnabled),
4, 1, ord(idnDisabled) ]);
FTestTree.ValidateRange(1, 6, FOpenings);
CheckReq(n, [ 2, 1, 1,
4, 1, 1 ]);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, idnEnabled), ExpN(13,21, idnEndIf, idnEnabled ) ]);
CheckNodes(n, 4, [ ExpN( 1,11, idnIfdef, idnDisabled), ExpN(13,21, idnEndIf, idnDisabled ) ]);
ClearData;
FTestTree.SetNodeState(2,1, idnNotInCode);
CheckReq(n, []);
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, idnNotInCode), ExpN(13,21, idnEndIf ) ]);
CheckNodes(n, 4, [ ExpN( 1,11, idnIfdef, idnDisabled), ExpN(13,21, idnEndIf, idnDisabled ) ]);
{%endregion 2 one line Ifdef + edit: get node request, change with SetNodeState }
{%region Insert IFDEF into empty text }
SetupTest(TestTextNoIfDef);
ClearData;
FTestTree.ValidateRange(1, 5, FOpenings);
CheckReq(n, []); // empty text, no request
SynEdit.TextBetweenPoints[point(1, 3),point(1, 3)] := '{$IFDEF a}';
FTestTree.ValidateRange(1, 5, FOpenings);
//FTestTree.DebugPrint(true);DebugLn;
CheckReq(n, [ 3, 1, 1 ]);
CheckNodesXY('Insert IFDEF into empty text', 3, [1,11], 0);
{%endregion Insert IFDEF into empty text }
{%region }
n := '';
ReCreateEditForTreeTest(TestText8);
FTestTree.SetNodeState( 2, 1,idnDisabled);
FTestTree.SetNodeState( 2,12,idnInvalid);
FTestTree.SetNodeState( 3, 2,idnEnabled);
FTestTree.DebugPrint(true);DebugLn('-----');
FTestTree.ValidateRange( 1, 11, FOpenings);
FTestTree.DebugPrint(true);DebugLn('-----');
CheckNodes(n, 2, [ ExpN( 1,11, idnIfdef, idnDisabled, EpNil, EpEnd(2, 35)),
ExpN(12,22, idnIfdef, idnInvalid, EpNil, EpEnd(2, 26)),
ExpN(26,34, idnEndIf, idnUnknown, EpIf(2,12), EpNil),
ExpN(35,43, idnEndIf, idnDisabled, EpIf(2, 1), EpNil)
]);
CheckOpenCloseCount(n, 2, 1, 1);
CheckNodes(n, 3, [ ExpN( 2,13, idnIfdef, idnEnabled, EpNil, EpEnd( 5, 1)) ]);
CheckOpenCloseCount(n, 3, 0, 0);
CheckNodes(n, 5, [ ExpN( 1, 9, idnEndIf, idnEnabled, EpIf( 3, 2)) ]);
CheckOpenCloseCount(n, 5, 0, 0);
SynEdit.TextBetweenPoints[point(10,2),point(10,2)] := LineEnding;
FTestTree.DebugPrint(true);DebugLn('-----');
CheckNodes(n, 2, [ ExpN( 1, 2, 1, idnIfdef, idnUnknown, EpNil, EpEnd(3, 26)) ]);
CheckNodes(n, 3, [ ExpN( 3,13, idnIfdef, idnInvalid, EpNil, EpEnd(3, 17)),
ExpN(17,25, idnEndIf, idnUnknown, EpIf(3, 3), EpNil),
ExpN(26,34, idnEndIf, idnUnknown, EpIf(2, 1), EpNil)
]);
CheckOpenCloseCount(n, 2, 0, 0);
CheckOpenCloseCount(n, 3, 0, 0);
SynEdit.TextBetweenPoints[point(14,2),point(1, 3)] := '';
{%endregion }
{%region }
n := '';
ReCreateEditForTreeTest(TestText11);
FTestTree.ValidateRange( 1, 16, FOpenings);
FTestTree.SetNodeState( 2, 3, idnEnabled);
FTestTree.SetNodeState( 4, 3, idnDisabled);
FTestTree.SetNodeState( 6, 3, idnInvalid);
FTestTree.SetNodeState( 8, 3, idnInvalid);
FTestTree.ValidateRange( 1, 16, FOpenings);
//FTestTree.DebugPrint(true);DebugLn('-----');
//SynEdit.TextBetweenPoints[point( 7,3),point( 1,4)] := ''; // JOIN LINES
SynEdit.TestTypeText(1, 4, #8, true);
FTestTree.ValidateRange( 1, 16, FOpenings);
FTestTree.SetNodeState( 2, 3, idnEnabled);
//FTestTree.SetNodeState( 4, 3, idnDisabled);
FTestTree.SetNodeState( 5, 3, idnInvalid);
FTestTree.SetNodeState( 7, 3, idnInvalid);
FTestTree.ValidateRange( 1, 16, FOpenings);
SynEdit.Undo; // RESTORE LINEBREAK
SynEdit.SimulatePaintText;
DebugLn('----- undone');FTestTree.DebugPrint(true);DebugLn('-----');
FTestTree.ValidateRange( 1, 16, FOpenings);
DebugLn('----- valid');FTestTree.DebugPrint(true);DebugLn('-----');
FTestTree.SetNodeState( 2, 3, idnEnabled);
FTestTree.DebugPrint(true);DebugLn('-----');
FTestTree.SetNodeState( 4, 3, idnDisabled);
DebugLn('----- disabled');FTestTree.DebugPrint(true);DebugLn('-----');
FTestTree.SetNodeState( 6, 3, idnInvalid);
FTestTree.SetNodeState( 8, 3, idnInvalid);
FTestTree.ValidateRange( 1, 16, FOpenings);
//FTestTree.DebugPrint(true);DebugLn('-----');
SynEdit.TextBetweenPoints[point( 1,4),point( 1,5)] := '';
FTestTree.ValidateRange( 1, 16, FOpenings);
{%endregion }
FTestTree.DiscardOpeningList(FOpenings);
FOpenings := nil;
FTestTree.Free;
FreeAndNil(FNodeStateResponses);
FreeAndNil(FNodeStateRequests);
end;
initialization
RegisterTest(TTestMarkupIfDef);
end.