diff --git a/components/synedit/synedithighlighterfoldbase.pas b/components/synedit/synedithighlighterfoldbase.pas
index e22254e299..3849e7197b 100644
--- a/components/synedit/synedithighlighterfoldbase.pas
+++ b/components/synedit/synedithighlighterfoldbase.pas
@@ -805,7 +805,7 @@ var
r: Pointer;
begin
Assert(CurrentRanges <> nil, 'TSynCustomFoldHighlighter.FoldBlockEndLevel requires CurrentRanges');
- if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
+ if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count - 1) then
exit(0);
r := CurrentRanges[ALineIndex];
if (r <> nil) and (r <> NullRange) then
@@ -820,7 +820,7 @@ var
r: Pointer;
begin
Assert(CurrentRanges <> nil, 'TSynCustomFoldHighlighter.FoldBlockMinLevelrequires CurrentRanges');
- if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
+ if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count - 1) then
exit(0);
r := CurrentRanges[ALineIndex];
if (r <> nil) and (r <> NullRange) then
diff --git a/components/synedit/test/testhighlightfoldbase.pas b/components/synedit/test/testhighlightfoldbase.pas
index 35d6518fee..cf79c13de8 100644
--- a/components/synedit/test/testhighlightfoldbase.pas
+++ b/components/synedit/test/testhighlightfoldbase.pas
@@ -12,6 +12,15 @@ type
// used by Fold / MarkupWord
+ TTestExpValuesForLine = record
+ Line: integer;
+ Exp: Array of integer;
+ end;
+
+ function ExpVLine(ALine: Integer; AExp: Array of integer): TTestExpValuesForLine;
+
+type
+
{ TTestBaseHighlighterPas }
{ TTestBaseHighlighterFoldBase }
@@ -25,6 +34,9 @@ type
procedure ReCreateEdit; reintroduce;
procedure CheckFoldOpenCounts(Name: String; Expected: Array of Integer);
+ procedure CheckFoldLengths(Name: String; Expected: Array of TTestExpValuesForLine);
+ procedure CheckFoldEndLines(Name: String; Expected: Array of TTestExpValuesForLine);
+
procedure CheckFoldInfoCounts(Name: String; Filter: TSynFoldActions; Expected: Array of Integer);
procedure CheckFoldInfoCounts(Name: String; Filter: TSynFoldActions; Group: Integer; Expected: Array of Integer);
@@ -34,6 +46,16 @@ type
implementation
+function ExpVLine(ALine: Integer; AExp: array of integer): TTestExpValuesForLine;
+var
+ i: Integer;
+begin
+ Result.Line := ALine;
+ SetLength(Result.Exp, Length(AExp));
+ for i := low(AExp) to high(AExp) do
+ Result.Exp[i] := AExp[i];
+end;
+
{ TTestBaseHighlighterFoldBase }
procedure TTestBaseHighlighterFoldBase.SetUp;
@@ -72,6 +94,28 @@ begin
AssertEquals(Name + 'OpenCount Line='+IntToStr(i), Expected[i], FTheHighLighter.FoldBlockOpeningCount(i));
end;
+procedure TTestBaseHighlighterFoldBase.CheckFoldLengths(Name: String;
+ Expected: array of TTestExpValuesForLine);
+var
+ i, j: Integer;
+begin
+ for i := 0 to high(Expected) do
+ for j := 0 to high(Expected[i].Exp) do
+ AssertEquals(Name + 'FoldLength Line='+IntToStr(Expected[i].Line) + ' idx='+IntToStr(j),
+ Expected[i].Exp[j], FTheHighLighter.FoldLineLength(Expected[i].Line, j));
+end;
+
+procedure TTestBaseHighlighterFoldBase.CheckFoldEndLines(Name: String;
+ Expected: array of TTestExpValuesForLine);
+var
+ i, j: Integer;
+begin
+ for i := 0 to high(Expected) do
+ for j := 0 to high(Expected[i].Exp) do
+ AssertEquals(Name + 'FoldEnd Line='+IntToStr(Expected[i].Line) + ' idx='+IntToStr(j),
+ Expected[i].Exp[j], FTheHighLighter.FoldEndLine(Expected[i].Line, j));
+end;
+
procedure TTestBaseHighlighterFoldBase.CheckFoldInfoCounts(Name: String;
Filter: TSynFoldActions; Expected: array of Integer);
begin
diff --git a/components/synedit/test/testhighlightxml.pas b/components/synedit/test/testhighlightxml.pas
index 7c2c704746..091e9b6576 100644
--- a/components/synedit/test/testhighlightxml.pas
+++ b/components/synedit/test/testhighlightxml.pas
@@ -5,19 +5,27 @@ unit TestHighlightXml;
interface
uses
- Classes, SysUtils, fpcunit, testregistry, TestBase, SynHighlighterXML;
+ Classes, SysUtils, fpcunit, testregistry, TestBase, TestHighlightFoldBase, SynHighlighterXML,
+ SynEditHighlighterFoldBase;
type
{ THighlightXml }
- THighlightXml = class(TTestBase)
+ THighlightXml = class(TTestBaseHighlighterFoldBase)
+ protected
+ function CreateTheHighLighter: TSynCustomFoldHighlighter; override;
published
procedure TestXml;
end;
implementation
+function THighlightXml.CreateTheHighLighter: TSynCustomFoldHighlighter;
+begin
+ Result := TSynXMLSyn.Create(nil);
+end;
+
procedure THighlightXml.TestXml;
function TestText: TStringArray;
begin
@@ -31,12 +39,35 @@ var
hl: TSynXMLSyn;
begin
ReCreateEdit;
- hl := TSynXMLSyn.Create(nil);
- SynEdit.Highlighter := hl;
SetLines(TestText);
- SynEdit.Highlighter := nil;
- hl.free;
+ CheckFoldOpenCounts('simple', [1,0,0]);
+ CheckFoldLengths ('simple', [ExpVLine(0,[2])]);
+ CheckFoldEndLines ('simple', [ExpVLine(0,[2])]);
+
+ SetLines(['', '', '', '', '', '']);
+ CheckFoldOpenCounts('nested', [1,2,0,0,0]);
+ CheckFoldLengths ('nested', [ExpVLine(0, [4]), ExpVLine(1, [3,1]) ]);
+ CheckFoldEndLines ('nested', [ExpVLine(0, [4]), ExpVLine(1, [4,2]) ]);
+
+ // c is not closed, and ended by b
+ SetLines(['', '', '', '', '', '']);
+ CheckFoldOpenCounts('bad nested', [1,2,0,0,0]);
+ CheckFoldLengths ('bad nested', [ExpVLine(0, [4]), ExpVLine(1, [3,3]) ]);
+ CheckFoldEndLines ('bad nested', [ExpVLine(0, [4]), ExpVLine(1, [4,4]) ]);
+
+ // a is not closed
+ SetLines(['', '', '', '', '', '']);
+ CheckFoldOpenCounts('open end', [1,2,0,0,0]);
+ CheckFoldLengths ('open end', [ExpVLine(0, [4]), ExpVLine(1, [3,1]) ]);
+ CheckFoldEndLines ('open end', [ExpVLine(0, [4]), ExpVLine(1, [4,2]) ]);
+
+ // a is not closed
+ SetLines(['', '']);
+ CheckFoldOpenCounts('open end (one line)', [0]);
+ //CheckFoldLengths ('open end (one line)', [ExpVLine(0, [0]) ]);
+ //CheckFoldEndLines ('open end (one line)', [ExpVLine(0, [0]) ]);
+
end;