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;