mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-17 05:29:32 +01:00
708 lines
27 KiB
ObjectPascal
708 lines
27 KiB
ObjectPascal
unit TestFoldedView;
|
|
|
|
(* TODO:
|
|
- test without highlighter / not-folding-highlighter (CalculateMaps must still work)
|
|
- Need a hook, to see which lines are invalidated
|
|
|
|
*)
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, testregistry, TestBase, TestHighlightPas, Forms, LCLProc,
|
|
SynEdit, SynHighlighterPas, SynEditFoldedView, SynEditHighlighterFoldBase,
|
|
SynGutterCodeFolding;
|
|
|
|
type
|
|
|
|
{ TTestFoldedView }
|
|
|
|
TTestFoldedView = class(TTestBaseHighlighterPas)
|
|
private
|
|
FoldedView: TSynEditFoldedView;
|
|
DoAutoFoldDescTests: Boolean;
|
|
DoAllowScrollPastEof: Boolean;
|
|
EnableDebug: Boolean;
|
|
|
|
procedure TestFoldedText(AName: String; ALines: Array of Integer);
|
|
procedure SetLines(AText: Array of String); reintroduce;
|
|
protected
|
|
procedure SetUp; override;
|
|
procedure ReCreateEdit; reintroduce;
|
|
function TestText: TStringArray;
|
|
function TestText2: TStringArray;
|
|
function TestText3: TStringArray;
|
|
function TestTextPasHl(AIfCol: Integer): TStringArray;
|
|
function TestText4: TStringArray;
|
|
function TestText5: TStringArray;
|
|
function TestTextHide(ALen: Integer): TStringArray;
|
|
function TestTextHide2(ALen: Integer): TStringArray;
|
|
function TestTextHide3: TStringArray;
|
|
function TestTextHide4: TStringArray;
|
|
published
|
|
procedure TestFold;
|
|
procedure TestFoldStateFromText;
|
|
procedure TestFoldStateDesc;
|
|
end;
|
|
|
|
implementation
|
|
|
|
procedure TTestFoldedView.TestFoldedText(AName: String; ALines: array of Integer);
|
|
var
|
|
ExpTxt: String;
|
|
i: Integer;
|
|
tmp: String;
|
|
function GetFoldedText: String;
|
|
var I: Integer;
|
|
begin
|
|
Result := '';
|
|
for i := 0 to FoldedView.Count - 1 do Result := Result + FoldedView[i] + LineEnding;
|
|
end;
|
|
begin
|
|
PushBaseName(AName);
|
|
//if EnableDebug then FoldedView.debug;
|
|
ExpTxt := '';
|
|
for i := 0 to high(ALines) do ExpTxt := ExpTxt + SynEdit.Lines[ALines[i]] + LineEnding;
|
|
TestCompareString('', ExpTxt, GetFoldedText);
|
|
|
|
FoldedView.FixFoldingAtTextIndex(0, SynEdit.Lines.Count-1);
|
|
TestCompareString('after FixFolding', ExpTxt, GetFoldedText);
|
|
|
|
if DoAutoFoldDescTests then begin
|
|
tmp := FoldedView.GetFoldDescription(0, 1, -1, -1, False, False);
|
|
//debugln(MyDbg(tmp));
|
|
FoldedView.UnfoldAll;
|
|
FoldedView.ApplyFoldDescription(0,1,-1,-1, PChar(tmp), length(tmp), False);
|
|
TestCompareString('Restore FoldDesc (NOT AsText, Not Ext)', ExpTxt, GetFoldedText);
|
|
|
|
tmp := FoldedView.GetFoldDescription(0, 1, -1, -1, False, True);
|
|
//debugln(MyDbg(tmp));
|
|
FoldedView.UnfoldAll;
|
|
FoldedView.ApplyFoldDescription(0,1,-1,-1, PChar(tmp), length(tmp), False);
|
|
TestCompareString('Restore FoldDesc (NOT AsText, Ext)', ExpTxt, GetFoldedText);
|
|
|
|
tmp := FoldedView.GetFoldDescription(0, 1, -1, -1, True, False);
|
|
//debugln(MyDbg(tmp));
|
|
FoldedView.UnfoldAll;
|
|
FoldedView.ApplyFoldDescription(0,1,-1,-1, PChar(tmp), length(tmp), True);
|
|
TestCompareString('Restore FoldDesc (AsText, Not Ext)', ExpTxt, GetFoldedText);
|
|
|
|
tmp := FoldedView.GetFoldDescription(0, 1, -1, -1, True, True);
|
|
//debugln(MyDbg(tmp));
|
|
FoldedView.UnfoldAll;
|
|
FoldedView.ApplyFoldDescription(0,1,-1,-1, PChar(tmp), length(tmp), True);
|
|
TestCompareString('Restore FoldDesc (AsText, Ext)', ExpTxt, GetFoldedText);
|
|
end;
|
|
PopBaseName;
|
|
end;
|
|
|
|
procedure TTestFoldedView.SetLines(AText: Array of String);
|
|
begin
|
|
inherited SetLines(AText);
|
|
FoldedView.TopLine := 1;
|
|
FoldedView.LinesInWindow := Length(AText) + 2;
|
|
end;
|
|
|
|
procedure TTestFoldedView.SetUp;
|
|
begin
|
|
DoAllowScrollPastEof := False;
|
|
DoAutoFoldDescTests := False;
|
|
inherited SetUp;
|
|
end;
|
|
|
|
procedure TTestFoldedView.ReCreateEdit;
|
|
begin
|
|
inherited ReCreateEdit;
|
|
FoldedView := SynEdit.TextView;
|
|
if DoAllowScrollPastEof then SynEdit.Options := SynEdit.Options + [eoScrollPastEof];
|
|
EnableFolds([cfbtBeginEnd.. cfbtNone], [cfbtSlashComment]);
|
|
end;
|
|
|
|
function TTestFoldedView.TestText: TStringArray;
|
|
begin
|
|
SetLength(Result, 6);
|
|
Result[0] := 'program Foo;';
|
|
Result[1] := 'procedure a;';
|
|
Result[2] := 'begin';
|
|
Result[3] := 'writeln()';
|
|
Result[4] := 'end;';
|
|
Result[5] := '';
|
|
end;
|
|
|
|
function TTestFoldedView.TestText2: TStringArray;
|
|
begin
|
|
SetLength(Result, 13);
|
|
Result[0] := 'program Foo;';
|
|
Result[1] := 'procedure a; procedure b;'; // 2 folds open on one line
|
|
Result[2] := ' begin';
|
|
Result[3] := ' end;';
|
|
Result[4] := '{%region} {%endregion} begin'; // begin end on same line (in front of 2nd begin
|
|
Result[5] := ' if b then begin';
|
|
Result[6] := ' writeln(1)';
|
|
Result[7] := ' end else begin'; // close/open line
|
|
Result[8] := ' writeln(2)';
|
|
Result[9] := ' if c then begin x; end; end;'; // begin end on same line (in front of 2nd end
|
|
Result[10]:= 'end;';
|
|
Result[11]:= '{$note}';
|
|
Result[12]:= '';
|
|
end;
|
|
|
|
function TTestFoldedView.TestText3: TStringArray;
|
|
begin
|
|
SetLength(Result, 13);
|
|
Result[0] := 'program Foo;';
|
|
Result[1] := '{$IFDEF x}';
|
|
Result[2] := 'procedure a;';
|
|
Result[3] := '{$ENDIF}'; // overlapping
|
|
Result[4] := 'begin';
|
|
Result[5] := '{%region} if a then begin';
|
|
Result[6] := ' writeln(1)';
|
|
Result[7] := '{%endregion} end else begin'; //semi-overlapping: endregion, hides start-line of "else begin"
|
|
Result[8] := ' writeln(2)';
|
|
Result[9] := ' end';
|
|
Result[10]:= 'end;';
|
|
Result[11]:= '//';
|
|
Result[12]:= '';
|
|
end;
|
|
|
|
function TTestFoldedView.TestTextPasHl(AIfCol: Integer): TStringArray;
|
|
begin
|
|
// various mixed of pascal and ifdef blocks => actually a test for pascal highlighter
|
|
SetLength(Result, 8);
|
|
Result[0] := 'program p;';
|
|
Result[1] := 'procedure A;';
|
|
case AIfCol of
|
|
0: Result[2] := '{$IFDEF} begin if a then begin';
|
|
1: Result[2] := 'begin {$IFDEF} if a then begin';
|
|
2: Result[2] := 'begin if a then begin {$IFDEF}';
|
|
end;
|
|
Result[3] := ' end; // 2';
|
|
Result[4] := 'end; // 1';
|
|
Result[5] := '{$ENDIF}';
|
|
Result[6] := '//';
|
|
Result[7] := '';
|
|
end;
|
|
|
|
function TTestFoldedView.TestText4: TStringArray;
|
|
begin
|
|
SetLength(Result, 8);
|
|
Result[0] := 'program Foo; procedure a; begin';
|
|
Result[1] := 'if a then begin';
|
|
Result[2] := 'end;';
|
|
Result[3] := 'if b then begin'; // consecutive begin-end
|
|
Result[4] := 'end;';
|
|
Result[5] := 'if b then begin'; // consecutive begin-end
|
|
Result[6] := 'end;';
|
|
Result[7] := '';
|
|
end;
|
|
|
|
function TTestFoldedView.TestText5: TStringArray;
|
|
begin
|
|
SetLength(Result, 5000);
|
|
Result[0] := 'program Foo; procedure a; begin';
|
|
Result[1] := 'if a then begin';
|
|
Result[2] := 'end;';
|
|
// for fold-desc text, this should force a new ' p' node
|
|
Result[4900] := 'if b then begin'; // consecutive begin-end => long lines down
|
|
Result[4901] := 'end;';
|
|
Result[7] := '';
|
|
end;
|
|
|
|
function TTestFoldedView.TestTextHide(ALen: Integer): TStringArray;
|
|
begin
|
|
SetLength(Result, 3+ALen);
|
|
Result[0] := 'program Foo;';
|
|
|
|
Result[1+ALen] := 'begin end';
|
|
Result[2+ALen] := '';
|
|
|
|
while ALen > 0 do begin
|
|
Result[ALen] := '//'+IntToStr(ALen);
|
|
dec(ALen);
|
|
end;
|
|
end;
|
|
|
|
function TTestFoldedView.TestTextHide2(ALen: Integer): TStringArray;
|
|
begin
|
|
SetLength(Result, 2+ALen);
|
|
Result[ALen] := 'program foo;';
|
|
Result[1+ALen] := '';
|
|
while ALen > 0 do begin;
|
|
Result[ALen-1] := '// '+IntToStr(ALen); // hide first line
|
|
dec(ALen);
|
|
end;
|
|
end;
|
|
|
|
function TTestFoldedView.TestTextHide3: TStringArray;
|
|
begin
|
|
SetLength(Result, 3);
|
|
Result[0] := '// test'; // hide ALL
|
|
Result[1] := '// FOO';
|
|
Result[2] := '';
|
|
end;
|
|
|
|
function TTestFoldedView.TestTextHide4: TStringArray;
|
|
begin
|
|
SetLength(Result, 13);
|
|
Result[0] := '{ABC}'; // hide individual blocks, following each other
|
|
Result[1] := '{def}';
|
|
Result[2] := '{XYZ}';
|
|
Result[3] := '{foo}';
|
|
Result[4] := '//abc';
|
|
Result[5] := '{foo';
|
|
Result[6] := '}';
|
|
Result[7] := '{bar';
|
|
Result[8] := '-';
|
|
Result[9] := '}';
|
|
Result[10]:= '{foo';
|
|
Result[11]:= '}';
|
|
Result[12]:= '';
|
|
|
|
end;
|
|
|
|
|
|
procedure TTestFoldedView.TestFold;
|
|
|
|
procedure TstSetText(AName: String; AText: TStringArray);
|
|
begin
|
|
PopBaseName;
|
|
ReCreateEdit;
|
|
SetLines(AText);
|
|
PushBaseName(AName);
|
|
end;
|
|
|
|
procedure TstFold(AName: String; AFoldAtIndex: integer; AExpectedLines: Array of Integer);
|
|
begin
|
|
FoldedView.FoldAtTextIndex(AFoldAtIndex);
|
|
TestFoldedText(AName, AExpectedLines);
|
|
end;
|
|
procedure TstFold(AName: String; AFoldAtIndex, AFoldAtColum: integer; AExpectedLines: Array of Integer);
|
|
begin
|
|
FoldedView.FoldAtTextIndex(AFoldAtIndex, AFoldAtColum);
|
|
TestFoldedText(AName, AExpectedLines);
|
|
end;
|
|
procedure TstFold(AName: String; AFoldAtIndex, AFoldAtColum, AFoldAtColCnt: integer;
|
|
AExpectedLines: Array of Integer);
|
|
begin
|
|
FoldedView.FoldAtTextIndex(AFoldAtIndex, AFoldAtColum, AFoldAtColCnt);
|
|
TestFoldedText(AName, AExpectedLines);
|
|
end;
|
|
procedure TstFold(AName: String; AFoldAtIndex, AFoldAtColum, AFoldAtColCnt: integer;
|
|
AFoldAtSkip: Boolean; AExpectedLines: Array of Integer);
|
|
begin
|
|
FoldedView.FoldAtTextIndex(AFoldAtIndex, AFoldAtColum, AFoldAtColCnt, AFoldAtSkip);
|
|
TestFoldedText(AName, AExpectedLines);
|
|
end;
|
|
procedure TstFold(AName: String; AFoldAtIndex, AFoldAtColum, AFoldAtColCnt: integer;
|
|
AFoldAtSkip: Boolean; AVisibleLines: Integer; AExpectedLines: Array of Integer);
|
|
begin
|
|
FoldedView.FoldAtTextIndex(AFoldAtIndex, AFoldAtColum, AFoldAtColCnt, AFoldAtSkip, AVisibleLines);
|
|
TestFoldedText(AName, AExpectedLines);
|
|
end;
|
|
|
|
procedure TstUnFoldAtCaret(AName: String; X, Y: integer; AExpectedLines: Array of Integer);
|
|
begin
|
|
SynEdit.CaretXY := Point(X, Y);
|
|
TestFoldedText('UnfoldCaret - '+AName, AExpectedLines);
|
|
end;
|
|
|
|
// ViewPos is 1 based
|
|
procedure TstTxtIndexToViewPos(AName: String; AExpectedPairs: Array of Integer; ADoReverse: Boolean = false);
|
|
var i: Integer;
|
|
begin
|
|
i := 0;
|
|
while i < high(AExpectedPairs)-1 do begin
|
|
AssertEquals(AName+' TxtIdx('+IntToStr( AExpectedPairs[i])+') to ViewPos[1-based]('+IntToStr( AExpectedPairs[i+1])+') ',
|
|
AExpectedPairs[i+1], FoldedView.TextIndexToViewPos(AExpectedPairs[i]));
|
|
if ADoReverse then
|
|
AssertEquals(AName+' ViewPos[1-based]('+IntToStr( AExpectedPairs[i+1])+') to TxtIdx('+IntToStr( AExpectedPairs[i])+') [R]',
|
|
AExpectedPairs[i], FoldedView.ViewPosToTextIndex(AExpectedPairs[i+1]));
|
|
inc(i, 2);
|
|
end;
|
|
end;
|
|
// ViewPos is 1 based // Reverse of the above
|
|
procedure TstViewPosToTextIndex(AName: String; AExpectedPairs: Array of Integer; ADoReverse: Boolean = false);
|
|
var i: Integer;
|
|
begin
|
|
i := 0;
|
|
while i < high(AExpectedPairs)-1 do begin
|
|
AssertEquals(AName+' ViewPos[1-based]('+IntToStr( AExpectedPairs[i])+') to TxtIdx('+IntToStr( AExpectedPairs[i+1])+')',
|
|
AExpectedPairs[i+1], FoldedView.ViewPosToTextIndex(AExpectedPairs[i]));
|
|
if ADoReverse then
|
|
AssertEquals(AName+' TxtIdx('+IntToStr( AExpectedPairs[i+1])+') to ViewPos[1-based]('+IntToStr( AExpectedPairs[i])+') [R]',
|
|
AExpectedPairs[i], FoldedView.TextIndexToViewPos(AExpectedPairs[i+1]));
|
|
inc(i, 2);
|
|
end;
|
|
end;
|
|
|
|
// ScreenLine is 0 based
|
|
procedure TstTextIndexToScreenLine(AName: String; AExpectedPairs: Array of Integer; ADoReverse: Boolean = false);
|
|
var i: Integer;
|
|
begin
|
|
i := 0;
|
|
while i < high(AExpectedPairs)-1 do begin
|
|
AssertEquals(AName+' TxtIdx('+IntToStr( AExpectedPairs[i])+') to ScreenLine[0-based]('+IntToStr( AExpectedPairs[i+1])+') ',
|
|
AExpectedPairs[i+1], FoldedView.TextIndexToScreenLine(AExpectedPairs[i]));
|
|
if ADoReverse then
|
|
AssertEquals(AName+' ScreenLine[0-based]('+IntToStr( AExpectedPairs[i+1])+') to TxtIdx('+IntToStr( AExpectedPairs[i])+') [R]',
|
|
AExpectedPairs[i], FoldedView.ScreenLineToTextIndex(AExpectedPairs[i+1]));
|
|
inc(i, 2);
|
|
end;
|
|
end;
|
|
// ScreenLine is 0 based // Reverse of the above
|
|
procedure TstScreenLineToTextIndex(AName: String; AExpectedPairs: Array of Integer; ADoReverse: Boolean = false);
|
|
var i: Integer;
|
|
begin
|
|
i := 0;
|
|
while i < high(AExpectedPairs)-1 do begin
|
|
AssertEquals(AName+' ScreenLine[0-based]('+IntToStr( AExpectedPairs[i])+') to TxtIdx('+IntToStr( AExpectedPairs[i+1])+') ',
|
|
AExpectedPairs[i+1], FoldedView.ScreenLineToTextIndex(AExpectedPairs[i]));
|
|
if ADoReverse then
|
|
AssertEquals(AName+' TxtIdx('+IntToStr( AExpectedPairs[i+1])+') to ScreenLine[0-based]('+IntToStr( AExpectedPairs[i])+') [R]',
|
|
AExpectedPairs[i], FoldedView.TextIndexToScreenLine(AExpectedPairs[i+1]));
|
|
inc(i, 2);
|
|
end;
|
|
end;
|
|
|
|
procedure RunTest;
|
|
begin
|
|
PushBaseName('');
|
|
|
|
{%region 'simple folds'}
|
|
TstSetText('Prg Prc Beg (1)', TestText);
|
|
TstFold('fold Prg', 0, [0]);
|
|
//IsFoldedAtTextIndex
|
|
|
|
TstSetText('Prg Prc Beg (2)', TestText);
|
|
TstFold('fold Prc', 1, [0, 1]);
|
|
TstFold('fold Prg', 0, [0]);
|
|
|
|
TstSetText('Prg Prc Beg (3)', TestText);
|
|
TstFold('fold Beg', 2, [0, 1, 2]);
|
|
TstFold('fold Prg', 0, [0]);
|
|
|
|
TstSetText('Prg Prc Beg (4)', TestText);
|
|
TstFold('fold Beg', 2, [0, 1, 2]);
|
|
TstFold('fold Prc', 1, [0, 1]);
|
|
TstFold('fold Prg', 0, [0]);
|
|
{%endregion}
|
|
|
|
{%region 'lines with many folds starting/ending'}
|
|
// Fold at column (positive ColIndex)
|
|
TstSetText('Text2 (a)', TestText2);
|
|
TstFold('fold PrcB (col 1)', 1, 1, [0, 1, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstFold('fold PrcA (col 0)', 1, 0, [0, 1, 11]);
|
|
|
|
// Fold at column (negative ColIndex)
|
|
TstSetText('Text2 (b)', TestText2);
|
|
TstFold('fold PrcB (col -1)', 1, -1, [0, 1, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstFold('again PrcB (col -1, NO skip)', 1, -1, [0, 1, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstFold('fold PrcA (col -1, skip)', 1, -1, 1, True, [0, 1, 11]);
|
|
|
|
// Fold at column, Cnt=2 (negative ColIndex)
|
|
TstSetText('Text2 (b)', TestText2);
|
|
TstFold('fold Prc (col -1, Cnt=2)', 1, -1, 2, True, [0, 1, 11]);
|
|
|
|
// Fold at column, after same line open/close (positive ColIndex)
|
|
TstSetText('Text2 (c)', TestText2);
|
|
TstFold('fold BegB (col 0)', 4, 0, [0, 1, 2, 3, 4, 11]);
|
|
//DebugLn(MyDbg(SynEdit.FoldState));
|
|
|
|
// Fold at column, after same line open/close (negative ColIndex)
|
|
TstSetText('Text2 (d)', TestText2);
|
|
TstFold('fold BegB (col -1)', 4, -1, [0, 1, 2, 3, 4, 11]);
|
|
|
|
// Fold block with end on re-opening line
|
|
TstSetText('Text2 (e)', TestText2);
|
|
TstFold('fold Beg', 5, [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11]);
|
|
{%endregion}
|
|
|
|
{%region 'Overlaps / Semi overlaps'}
|
|
TstSetText('Text3 (a)', TestText3);
|
|
TstFold('fold ifdef', 1, [0, 1, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
TstFold('fold Beg', 4, [0, 1, 4, 11]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
|
|
TstSetText('Text3 (b, overlap)', TestText3);
|
|
TstFold('fold Prc', 2, [0, 1, 2, 11]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
TstFold('fold ifdef', 1, [0, 1, 11]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
|
|
TstSetText('Text3 (c, NO semi-overlap)', TestText3);
|
|
TstFold('fold Else', 7, [0, 1, 2, 3, 4, 5, 6, 7, 10, 11]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
TstFold('fold Beg', 5,1, [0, 1, 2, 3, 4, 5, 7, 10, 11]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
|
|
TstSetText('Text3 (d, semi-overlap)', TestText3);
|
|
TstFold('fold Else', 7, [0, 1, 2, 3, 4, 5, 6, 7, 10, 11]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
TstFold('fold Region', 5,0, [0, 1, 2, 3, 4, 5, 10, 11]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
TstTxtIndexToViewPos('', [0,1, 1,2, 2,3, 3,4, 4,5, 5,6, 10,7, 11,8], True);
|
|
|
|
TstUnFoldAtCaret('Unfold Else', 1,8+1, [0, 1, 2, 3, 4, 5, 8, 9, 10, 11]);
|
|
|
|
TstSetText('Text3 (e, semi-overlap)', TestText3);
|
|
TstFold('fold Else', 7, [0, 1, 2, 3, 4, 5, 6, 7, 10, 11]);
|
|
TstFold('fold Region', 5,0, [0, 1, 2, 3, 4, 5, 10, 11]);
|
|
TstUnFoldAtCaret('Unfold Else 2', 1,9+1, [0, 1, 2, 3, 4, 5, 8, 9, 10, 11]);
|
|
|
|
TstSetText('Text3 (f, semi-overlap)', TestText3);
|
|
TstFold('fold Else', 7, [0, 1, 2, 3, 4, 5, 6, 7, 10, 11]);
|
|
TstFold('fold Region', 5,0, [0, 1, 2, 3, 4, 5, 10, 11]);
|
|
TstUnFoldAtCaret('Unfold Region', 1,6+1, [0, 1, 2, 3, 4, 5, 6, 7, 10, 11]);
|
|
|
|
TstSetText('Text3 (g, semi-overlap)', TestText3);
|
|
TstFold('fold Else', 7, [0, 1, 2, 3, 4, 5, 6, 7, 10, 11]);
|
|
TstFold('fold Region', 5,0, [0, 1, 2, 3, 4, 5, 10, 11]);
|
|
TstUnFoldAtCaret('Unfold Region 2', 1,7+1, [0, 1, 2, 3, 4, 5, 6, 7, 10, 11]);
|
|
{%endregion}
|
|
|
|
{%region 'Mixed pascal and ifdef in opening line'}
|
|
TstSetText('Text4 PasIfDef (0)', TestTextPasHl(0));
|
|
TstFold('fold IfDef(0)', 2, 0, [0, 1, 2, 6]);
|
|
TstSetText('Text4 PasIfDef (0)', TestTextPasHl(0));
|
|
TstFold('fold Begin(1)', 2, 1, [0, 1, 2, 5, 6]);
|
|
TstSetText('Text4 PasIfDef (0)', TestTextPasHl(0));
|
|
TstFold('fold Begin(2)', 2, 2, [0, 1, 2, 4, 5, 6]);
|
|
|
|
TstSetText('Text4 PasIfDef (1)', TestTextPasHl(1));
|
|
TstFold('fold Begin(0)', 2, 0, [0, 1, 2, 5, 6]);
|
|
TstSetText('Text4 PasIfDef (1)', TestTextPasHl(1));
|
|
TstFold('fold Ifdef(1)', 2, 1, [0, 1, 2, 6]);
|
|
TstSetText('Text4 PasIfDef (1)', TestTextPasHl(1));
|
|
TstFold('fold Begin(2)', 2, 2, [0, 1, 2, 4, 5, 6]);
|
|
|
|
TstSetText('Text4 PasIfDef (2)', TestTextPasHl(2));
|
|
TstFold('fold Begin(0)', 2, 0, [0, 1, 2, 5, 6]);
|
|
TstSetText('Text4 PasIfDef (2)', TestTextPasHl(2));
|
|
TstFold('fold Begin(1)', 2, 1, [0, 1, 2, 4, 5, 6]);
|
|
TstSetText('Text4 PasIfDef (2)', TestTextPasHl(2));
|
|
TstFold('fold IfDef(2)', 2, 2, [0, 1, 2, 6]);
|
|
{%endregion}
|
|
|
|
{%region 'Hide'}
|
|
{%region 'Hide in middle of source'}
|
|
TstSetText('Text5 Hide 1', TestTextHide(1));
|
|
TstFold('fold //)', 1, 0, 1, False, 0, [0, 2]);
|
|
|
|
TstSetText('Text5 Hide 2', TestTextHide(2));
|
|
TstFold('fold //(2)', 1, 0, 1, False, 0, [0, 3]);
|
|
|
|
TstSetText('Text5 Hide 3', TestTextHide(3));
|
|
TstFold('fold //(3)', 1, 0, 1, False, 0, [0, 4]);
|
|
TstTxtIndexToViewPos ('', [0,1, 4,2 ], True); // 0-base => 1 base
|
|
TstTextIndexToScreenLine('', [0,0, 4,1 ], True); // 0-base => 0 base
|
|
TstScreenLineToTextIndex('', [-1,-1, 5,-1 ]); // 0-base => 0-base
|
|
SynEdit.Options := SynEdit.Options + [eoScrollPastEof];
|
|
SynEdit.TopLine := 5; // now the visible TxtIdx=0 line, is just before the screen [-1]
|
|
AssertEquals('FoldView.topline', 2, FoldedView.TopLine);
|
|
TstTextIndexToScreenLine('TopLine=2', [0,-1, 4,0 ], True); // 0-base => 0 base
|
|
TstScreenLineToTextIndex('TopLine=2', [-1,0, 4,-1 ]); // 0-base => 0-base
|
|
|
|
{%endregion}
|
|
|
|
{%region 'Hide at very begin of source'}
|
|
ReCreateEdit;
|
|
TstSetText('Text6 Hide 1st line', TestTextHide2(1)); // *** one line at the top
|
|
TstFold('fold //)', 0, 0, 1, False, 0, [1]);
|
|
AssertEquals('FoldedView.TextIndex 0', 1, FoldedView.TextIndex[0]);
|
|
AssertEquals('FoldedView.TextIndex -1', -1, FoldedView.TextIndex[-1]);
|
|
|
|
TstTxtIndexToViewPos ('', [1,1 ], True); // 0-base => 1 base
|
|
TstTextIndexToScreenLine('', [1,0 ], True); // 0-base => 0 base
|
|
TstScreenLineToTextIndex('', [-1,-1, 0,1, 1,-1 ]); // 0-base => 0-base
|
|
|
|
AssertEquals('FoldedView.FoldedAtTextIndex 0', True, FoldedView.FoldedAtTextIndex[0]);
|
|
AssertEquals('FoldedView.FoldedAtTextIndex 1', False, FoldedView.FoldedAtTextIndex[1]);
|
|
//TODO check FoldedView.FoldType;
|
|
{%endregion}
|
|
|
|
{%region 'Hide full text'}
|
|
TstSetText('Hide all', TestTextHide3);
|
|
TstFold('fold //)', 0, 0, 1, False, 0, []);
|
|
{%endregion}
|
|
|
|
{%region 'Hide, none-foldable'}
|
|
TstSetText('Hide //', TestTextHide(2));
|
|
EnableFolds([cfbtBeginEnd..cfbtNone], [cfbtBorCommand, cfbtAnsiComment, cfbtSlashComment], [cfbtBeginEnd..cfbtNone]);
|
|
TstFold('fold //)', 1, 0, 1, False, 0, [0, 3]);
|
|
TstSetText('Hide {} one line', TestTextHide4);
|
|
EnableFolds([cfbtBeginEnd..cfbtNone], [cfbtBorCommand, cfbtAnsiComment, cfbtSlashComment], [cfbtBeginEnd..cfbtNone]);
|
|
TstFold('fold {})', 3, 0, 1, False, 0, [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstSetText('Hide {} multi line', TestTextHide4);
|
|
EnableFolds([cfbtBeginEnd..cfbtNone], [cfbtBorCommand, cfbtAnsiComment, cfbtSlashComment], [cfbtBeginEnd..cfbtNone]);
|
|
TstFold('fold {})', 7, 0, 1, False, 0, [0, 1, 2, 3, 4, 5, 6, 10, 11]);
|
|
{%endregion}
|
|
|
|
{%region 'Hide consecutive individual folds'}
|
|
TstSetText('Hide consecutive', TestTextHide4);
|
|
EnableFolds([cfbtBeginEnd..cfbtNone], [cfbtBorCommand, cfbtAnsiComment, cfbtSlashComment]);
|
|
TstFold('fold 3)', 3, 0, 1, False, 0, [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstFold('fold 2)', 2, 0, 1, False, 0, [0, 1, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstFold('fold 1)', 1, 0, 1, False, 0, [0, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
{%endregion}
|
|
|
|
{%endregion}
|
|
|
|
{%region}
|
|
// consecutive begin-end
|
|
// for text desc
|
|
TstSetText('Text4 consecutive begin (all)', TestText4);
|
|
TstFold('fold 1st', 1, [0, 1, 3, 4, 5, 6]);
|
|
TstFold('fold 2nd', 3, [0, 1, 3, 5, 6]);
|
|
TstFold('fold 3rd', 5, [0, 1, 3, 5]);
|
|
|
|
TstSetText('Text4 consecutive begin (1,3)', TestText4);
|
|
TstFold('fold 1st', 1, [0, 1, 3, 4, 5, 6]);
|
|
TstFold('fold 3rd', 5, [0, 1, 3, 4, 5]);
|
|
|
|
TstSetText('Text4 consecutive begin (2,3)', TestText4);
|
|
TstFold('fold 2nd', 3, [0, 1, 2, 3, 5, 6]);
|
|
TstFold('fold 3rd', 5, [0, 1, 2, 3, 5]);
|
|
|
|
TstSetText('Text5 consecutive begin (long distance)', TestText5);
|
|
AssertEquals(FoldedView.Count, 4999);
|
|
FoldedView.FoldAtTextIndex(1);
|
|
FoldedView.FoldAtTextIndex(4900);
|
|
AssertEquals(FoldedView.Count, 4999-2);
|
|
{%endregion}
|
|
|
|
end;
|
|
|
|
begin
|
|
DoAllowScrollPastEof := False;
|
|
DoAutoFoldDescTests := False;
|
|
RunTest;
|
|
|
|
DoAutoFoldDescTests:= True;
|
|
RunTest;
|
|
|
|
DoAllowScrollPastEof := True;
|
|
RunTest;
|
|
end;
|
|
|
|
procedure TTestFoldedView.TestFoldStateFromText;
|
|
procedure TstSetText(AName: String; AText: TStringArray);
|
|
begin
|
|
PopBaseName;
|
|
ReCreateEdit;
|
|
SetLines(AText);
|
|
PushBaseName(AName);
|
|
end;
|
|
|
|
procedure TstFoldState(AName, AFoldDesc: String; AExpectedLines: Array of Integer);
|
|
begin
|
|
// Use to test text-desc as stored in IDE xml session files
|
|
FoldedView.UnfoldAll;
|
|
SynEdit.FoldState := AFoldDesc;
|
|
TestFoldedText('FoldState - '+AName, AExpectedLines);
|
|
end;
|
|
|
|
begin
|
|
DoAutoFoldDescTests := False;
|
|
|
|
TstSetText('Prg Prc Beg (1)', TestText);
|
|
TstFoldState('fold Prg', ' TA004,', [0]); // from ide session xml
|
|
|
|
TstSetText('Prg Prc Beg (2)', TestText);
|
|
TstFoldState('fold Prc', ' T3103M', [0, 1]); // from ide session xml
|
|
TstFoldState('fold Prg', ' TA004 T3103#', [0]); // from ide session xml
|
|
|
|
TstSetText('Prg Prc Beg (3)', TestText);
|
|
TstFoldState('fold Beg', ' T1202E', [0, 1, 2]); // from ide session xml
|
|
TstFoldState('fold Prg', ' TA004 T12025', [0]); // from ide session xml
|
|
|
|
TstSetText('Prg Prc Beg (4)', TestText);
|
|
TstFoldState('fold Beg', ' T1202E', [0, 1, 2]); // from ide session xml
|
|
TstFoldState('fold Prc', ' T3103 T1202{', [0,1]); // from ide session xml
|
|
TstFoldState('fold Prg', ' TA004 T3103 T1202Y', [0]); // from ide session xml
|
|
|
|
TstSetText('Text2 (a)', TestText2);
|
|
TstFoldState('fold PrcB (col 1)', ' T31D21', [0, 1, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstFoldState('fold PrcA+B (col 0)', ' T31091a', [0, 1, 11]);
|
|
TstFoldState('fold BegB (col 0)', ' T14N69', [0, 1, 2, 3, 4, 11]);
|
|
TstFoldState('fold Beg', ' T05C1''', [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11]);
|
|
|
|
TstSetText('Text3 (a)', TestText3);
|
|
TstFoldState('fold ifdef', ' TI122;', [0, 1, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstFoldState('fold Beg', ' TI122 T1406e', [0, 1, 4, 11]);
|
|
|
|
TstSetText('Text3 (b, overlap)', TestText3);
|
|
TstFoldState('fold Prc', ' T3208Y', [0, 1, 2, 11]);
|
|
// TstFoldState('fold ifdef', ' TI129 T3208$', [0, 1, 11]); // TODO
|
|
|
|
TstSetText('Text3 (c, NO semi-overlap)', TestText3);
|
|
TstFoldState('fold Else', ' T07N2O', [0, 1, 2, 3, 4, 5, 6, 7, 10, 11]);
|
|
TstFoldState('fold Beg', ' T05L11K', [0, 1, 2, 3, 4, 5, 7, 10, 11]);
|
|
|
|
TstSetText('Text2 (a) without region', TestText2);
|
|
PasHighLighter.FoldConfig[ord(cfbtRegion)].Enabled := False;
|
|
TstFoldState('fold PrcB (col 1)', ' T31D21', [0, 1, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
TstFoldState('fold PrcA+B (col 0)', ' T31091a', [0, 1, 11]);
|
|
TstFoldState('fold BegB (col 0)', ' T14N69', [0, 1, 2, 3, 4, 11]);
|
|
TstFoldState('fold Beg', ' T05C1''', [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11]);
|
|
|
|
TstSetText('Text4 consecutive begin (all)', TestText4);
|
|
TstFoldState('fold 3rd', ' T01A12q', [0, 1, 3, 5]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
|
|
TstSetText('Text4 consecutive begin (1,3)', TestText4);
|
|
TstFoldState('fold 3rd', ' T01A1011p', [0, 1, 3, 4, 5]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
|
|
TstSetText('Text4 consecutive begin (2,3)', TestText4);
|
|
TstFoldState('fold 3rd', ' T03A11r', [0, 1, 2, 3, 5]);
|
|
DebugLn(MyDbg(SynEdit.FoldState));
|
|
|
|
TstSetText('Text5 consecutive begin (long distance)', TestText5);
|
|
AssertEquals(FoldedView.Count, 4999);
|
|
SynEdit.FoldState := ' T01A1 p0j*eA1i';
|
|
AssertEquals(FoldedView.Count, 4999-2);
|
|
end;
|
|
|
|
procedure TTestFoldedView.TestFoldStateDesc;
|
|
begin
|
|
(* - The values returned by GetFoldDescription can change in future versions
|
|
Therefore there is only a limited number of tests.
|
|
Test should only ensure that there are different results depending on text/extended flags
|
|
|
|
- If they do for the not-extended-text, then new results should be added to TestFoldStateFromText
|
|
(as ide will save new results / old result must still be supported for reading)
|
|
*)
|
|
ReCreateEdit;
|
|
SetLines(TestText);
|
|
FoldedView.FoldAtLine(2);
|
|
FoldedView.FoldAtLine(0);
|
|
//DebugLn(MyDbg(FoldedView.GetFoldDescription(0,1,-1,-1, False, False)));
|
|
//DebugLn(MyDbg(FoldedView.GetFoldDescription(0,1,-1,-1, True, False)));
|
|
//DebugLn(MyDbg(FoldedView.GetFoldDescription(0,1,-1,-1, False, True)));
|
|
//DebugLn(MyDbg(FoldedView.GetFoldDescription(0,1,-1,-1, True, True)));
|
|
TestCompareString('FoldDesc (NOT txt / NOT ext)',
|
|
#$00#$00#$00#$00#$00#$00#$00#$00#$07#$00#$00#$00#$04#$00#$00#$00#$04#$00#$00#$00#$04#$00#$00#$00#$0A#$00#$00#$00#$04#$00#$00#$00#$02#$00#$00#$00#$00#$00#$00#$00#$05#$00#$00#$00#$04#$00#$00#$00#$00#$00#$00#$00#$03#$00#$00#$00#$01#$00#$00#$00#$02#$00#$00#$00,
|
|
FoldedView.GetFoldDescription(0,1,-1,-1, False, False)
|
|
);
|
|
TestCompareString('FoldDesc (txt / NOT ext)', ' TA004 T12025',
|
|
FoldedView.GetFoldDescription(0,1,-1,-1, True, False)
|
|
);
|
|
// TODO: Extended is not yet implemented
|
|
//TestCompareString('FoldDesc (NOT txt / ext)',
|
|
// #$00#$00#$00#$00#$00#$00#$00#$00#$07#$00#$00#$00#$04#$00#$00#$00#$00#$00#$00#$00#$03#$00#$00#$00#$0A#$00#$00#$00#$02#$00#$00#$00#$00#$00#$00#$00#$05#$00#$00#$00#$04#$00#$00#$00#$00#$00#$00#$00#$03#$00#$00#$00#$01#$00#$00#$00,
|
|
// FoldedView.GetFoldDescription(0,1,-1,-1, False, True)
|
|
// );
|
|
//TestCompareString('FoldDesc (txt / ext)', ' TA004 T12025',
|
|
// FoldedView.GetFoldDescription(0,1,-1,-1, True, True)
|
|
// );
|
|
end;
|
|
|
|
initialization
|
|
|
|
RegisterTest(TTestFoldedView);
|
|
end.
|
|
|