SynEdit tests

git-svn-id: trunk@39083 -
This commit is contained in:
martin 2012-10-14 19:48:15 +00:00
parent 3b90468c10
commit ad7aed810e
4 changed files with 796 additions and 432 deletions

1
.gitattributes vendored
View File

@ -2820,6 +2820,7 @@ components/synedit/test/testhighlightmulti.pas svneol=native#text/pascal
components/synedit/test/testhighlightpas.pas svneol=native#text/pascal components/synedit/test/testhighlightpas.pas svneol=native#text/pascal
components/synedit/test/testhighlightxml.pas svneol=native#text/pascal components/synedit/test/testhighlightxml.pas svneol=native#text/pascal
components/synedit/test/testmarkupwordgroup.pas svneol=native#text/pascal components/synedit/test/testmarkupwordgroup.pas svneol=native#text/pascal
components/synedit/test/testnavigation.pas svneol=native#text/pascal
components/synedit/test/testsearch.pas svneol=native#text/pascal components/synedit/test/testsearch.pas svneol=native#text/pascal
components/synedit/test/testsynbeautifier.pas svneol=native#text/pascal components/synedit/test/testsynbeautifier.pas svneol=native#text/pascal
components/synedit/test/testsyncroedit.pas svneol=native#text/pascal components/synedit/test/testsyncroedit.pas svneol=native#text/pascal

View File

@ -4,7 +4,7 @@ program SynTest;
uses uses
Interfaces, Forms, GuiTestRunner, TestBase, Interfaces, Forms, GuiTestRunner, TestBase,
TestBasicSynEdit, TestSynSelection, TestBlockIndent, TestBookMarks, TestBasicSynEdit, TestNavigation, TestSynSelection, TestBlockIndent, TestBookMarks,
TestSearch, TestSynBeautifier, TestTrimSpace, TestSyncroEdit, TestSynTextArea, TestSearch, TestSynBeautifier, TestTrimSpace, TestSyncroEdit, TestSynTextArea,
TestHighlightPas, TestHighlightXml, TestHighlightMulti, TestHighlightPas, TestHighlightXml, TestHighlightMulti,
TestMarkupwordGroup, TestFoldedView, TestSynSharedEdits, TestHighlighterLfm, TestMarkupwordGroup, TestFoldedView, TestSynSharedEdits, TestHighlighterLfm,

View File

@ -3,8 +3,6 @@ unit TestBasicSynEdit;
(* TODO: (* TODO:
- TestEditEmpty: - TestEditEmpty:
Test with different sets of VirtualViews (with/without trimming (enabled/module present at all) Test with different sets of VirtualViews (with/without trimming (enabled/module present at all)
Word Left/Right: Need tests with fold, trim, selection
*) *)
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
@ -31,8 +29,6 @@ type
procedure TestEditTabs; procedure TestEditTabs;
procedure TestPhysicalLogical; procedure TestPhysicalLogical;
procedure TestCaretAutoMove; procedure TestCaretAutoMove;
procedure TestEditHomeEnd;
procedure TestCaretMoveLeftRightWord;
procedure TestCaretDeleteWord_LastWord; procedure TestCaretDeleteWord_LastWord;
end; end;
@ -475,433 +471,6 @@ begin
end; end;
procedure TTestBasicSynEdit.TestEditHomeEnd;
procedure DoInit1;
begin
InsertFlag := False;
TrimType := settIgnoreAll;
ReCreateEdit;
SynEdit.TabWidth := 6;
SyneDit.Options := [];
SyneDit.Options2 := [];
SetLines(['', //1
'',
'test', // 3
'',
'',
' ',
'test', // 3
#9#9#9#9#9,
' spaced', // 9
'',
'',
' ',
' spaced',
#9#9#9#9#9,
#9'tabbed', // 15
'',
'',
' ',
#9'tabbed',
#9#9#9#9#9,
#9' tabbed spaced', // 21
'',
'',
' ',
#9' tabbed spaced',
#9#9#9#9#9,
' ', // 27 (space only)
'',
'',
' ',
#9' ',
#9#9#9#9#9,
' spaced 9 for tab', // 33
#9#9#9#9#9,
' X ', // 35
' X'#9, // 36
''
]);
end;
procedure TestHome(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer; ExpLTxTStartX: Integer = -1);
begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(1st home)', ExpX1,Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(2nd home)', ExpX2,Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(3rd home)', ExpX3,Y);
if ExpLTxTStartX > 0 then begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(1st line-text-start)', ExpLTxTStartX,Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(2nd line-text-start)', ExpLTxTStartX,Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(3rd line-text-start)', ExpLTxTStartX,Y);
end;
end;
procedure TestEnd(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer);
begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(1st end)', ExpX1,Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(2nd end)', ExpX2,Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(3rd end)', ExpX3,Y);
end;
begin
// None Smart-Home:
// Caret goes x=1, then x=indend
// Smart-Home:
// Caret goes x=indent, then 1, IF AFTER indent, or at x=1
// Caret goes x=1, then x=indend, IF at x=indent, or inside indent
// Both
// Caret does not go past eol, unless explicitly enabled
// if spaces/tab exist at start of otherwise empty line, caret will go to prev-line indent
{%region}
DoInit1;
PushBaseName('no smart / no past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4);
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoScrollPastEol];
PopPushBaseName('no smart / past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4);
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
TestHome('1st after space indented line (x)', 2,10, 1,4,1, 1);
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
TestHome('1st after tab indented line(x)', 2,16, 1,7,1, 1);
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoEnhanceHomeKey];
PopPushBaseName('smart home / no past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 7,1,7, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoEnhanceHomeKey, eoScrollPastEol];
PopPushBaseName('smart home / past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
TestHome('1st after tab indented line (x)', 2,16, 1,7,1, 1);
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
PopPushBaseName('NO smart end/ NO past-eol');
DoInit1;
TestEnd ('empty 1st line', 1,1, 1,1,1);
TestEnd ('end', 1,35, 6,3,6);
TestEnd ('end tab', 1,36, 7,3,7);
PopPushBaseName('smart end/ NO past-eol');
DoInit1;
SyneDit.Options2 := [eoEnhanceEndKey];
TestEnd ('end', 1,35, 3,6,3);
TestEnd ('end tab', 1,36, 3,7,3);
//SyneDit.Options := [eoScrollPastEol, eoEnhanceHomeKey];
//SyneDit.Options2 := [eoEnhanceEndKey];
end;
procedure TTestBasicSynEdit.TestCaretMoveLeftRightWord;
procedure DoInit;
begin
InsertFlag := False;
TrimEnabled := False;;
ReCreateEdit;
SynEdit.TabWidth := 7;
// 1 6 11 14
SetLines(['Some text to test', //1
// 1 5 9
'Foo bar abc', // 2
// 8 14 19 24
#9'Other line with tab', // 3
// 1 8 11 15
'tab'#9'in the middle', // 4
// 1 9 12 16 23 28
'tab'#9' in the middle with space', // 5
// 1 9 13 16
'umlaute äää in text', // 6
'normal line',
// 4 14 21 28 32
' untrimmed spaces around line ', // 8
'normal line',
// 8 15 22 26
#9'tab'#9'only'#9'line'#9, // 10
// 1 8
'normal line',
'', // 12 (empty)
'normal line',
' ', // space only empty line // 14
'normal line',
'',
'A B', // 17
'normal line', // 18
''
]);
end;
procedure TestWordLeft(Name:String; X, Y, ExpX1, ExpY1: Integer;
ExpX2: Integer = -1; ExpY2: Integer = -1);
begin
SetCaretPhys(X,Y);
SynEdit.CommandProcessor(ecWordLeft, '', nil);
TestIsCaretPhys(Name + '(1st WordLeft)', ExpX1, ExpY1);
if ExpY2 > 0 then begin
SynEdit.CommandProcessor(ecWordLeft, '', nil);
TestIsCaretPhys(Name + '(2nd WordLeft)', ExpX2, ExpY2);
end;
end;
procedure TestWordRight(Name:String; X, Y, ExpX1, ExpY1: Integer;
ExpX2: Integer = -1; ExpY2: Integer = -1);
begin
SetCaretPhys(X,Y);
SynEdit.CommandProcessor(ecWordRight, '', nil);
TestIsCaretPhys(Name + '(1st WordRight)', ExpX1, ExpY1);
if ExpY2 > 0 then begin
SynEdit.CommandProcessor(ecWordRight, '', nil);
TestIsCaretPhys(Name + '(2nd WordRight)', ExpX2, ExpY2);
end;
end;
begin
DoInit;
{%region word left}
TestWordLeft('simple "te|st"', 16, 1, 14, 1, 11, 1);
TestWordLeft('simple EOW "test|"', 18, 1, 14, 1, 11, 1);
TestWordLeft('simple BOW "|test"', 14, 1, 11, 1, 6, 1);
TestWordLeft('simple > BOT "So|me"', 3, 1, 1, 1, 1, 1);
TestWordLeft('simple > prev-line "F|oo"', 2, 2, 1, 2, 18, 1);
TestWordLeft('simple > prev-line "|Foo"', 1, 2, 18, 1, 14, 1);
TestWordLeft('tab "wi|th"', 21, 3, 19, 3, 14, 3);
TestWordLeft('tab EOW "with|"', 23, 3, 19, 3, 14, 3);
TestWordLeft('tab BOW "|with"', 19, 3, 14, 3, 8, 3);
TestWordLeft('tab > prev-line "O|ther"', 9, 3, 8, 3, 12, 2);
TestWordLeft('M-tab "i|n"', 9, 4, 8, 4, 1, 4);
TestWordLeft('M-tab > prev-line-tab "ta|b"', 3, 4, 1, 4, 27, 3);
TestWordLeft('M-S-tab "i|n"', 10, 5, 9, 5, 1, 5);
TestWordLeft('M-S-EOW tab "in|"', 11, 5, 9, 5, 1, 5);
TestWordLeft('M-S-BOW tab "|in"', 9, 5, 1, 5, 21, 4);
TestWordLeft('M-S-tab "#9| in"', 8, 5, 1, 5);
TestWordLeft('Umlaut "ää|ä"', 11, 6, 9, 6, 1, 6);
TestWordLeft('Umlaut EOW "äää|"', 12, 6, 9, 6, 1, 6);
TestWordLeft('Umlaut BOW "|äää"', 9, 6, 1, 6, 33, 5);
TestWordLeft('Umlaut "i|n"', 14, 6, 13, 6, 9, 6);
TestWordLeft('After Umlaut > prev line', 1, 7, 20, 6, 16, 6);
TestWordLeft('untrimmed "un|trimmed"', 6, 8, 4, 8, 12, 7);
TestWordLeft('After untrimmed > prev', 1, 9, 35, 8, 28, 8);
TestWordLeft('untrimmed tab "t|ab"', 9,10, 8,10, 12, 9);
TestWordLeft('After untrimmed tab > prev', 1,11, 29,10, 22,10);
TestWordLeft('After empty > prev', 1,13, 1,12);
TestWordLeft('After space empty > prev', 1,15, 6,14);
TestWordLeft('single char at eol "A B|"', 4,17, 3,17, 1,17);
{%endregion}
{%region word right}
TestWordRight('simple "te|xt"', 8, 1, 11, 1, 14, 1);
TestWordRight('simple EOW "text|"', 10, 1, 11, 1, 14, 1);
TestWordRight('simple BOW "|text"', 6, 1, 11, 1, 14, 1);
TestWordRight('simple EOT "li|ne"', 10,18, 12,18, 12,18);
TestWordRight('simple > EOL, next line "te|st"', 16, 1, 18, 1, 1, 2);
TestWordRight('tab "li|ne"', 16, 3, 19, 3, 24, 3);
TestWordRight('tab EOW "line|"', 18, 3, 19, 3, 24, 3);
TestWordRight('tab BOW "|line"', 14, 3, 19, 3, 24, 3);
TestWordRight('tab > EOL, next-line', 25, 3, 27, 3, 1, 4);
TestWordRight('M-tab "t|ab"', 2, 4, 8, 4, 11, 4);
TestWordRight('M-tab "tab|"', 4, 4, 8, 4, 11, 4);
TestWordRight('M-tab > EOL, next-line-tab', 17, 4, 21, 4, 1, 5);
TestWordRight('M-S-tab BOW "t|ab"', 2, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab EOW "tab|"', 4, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab BOW "|tab"', 1, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab "tab#9| "', 5, 5, 9, 5, 12, 5);
TestWordRight('Umlaut "ää|ä"', 11, 6, 13, 6, 16, 6);
TestWordRight('Umlaut EOW "äää|"', 12, 6, 13, 6, 16, 6);
TestWordRight('Umlaut BOW "|äää"', 9, 6, 13, 6, 16, 6);
TestWordRight('Umlaut "um|laute"', 2, 6, 9, 6, 13, 6);
TestWordRight('After Umlaut > EOL, next line', 18, 6, 20, 6, 1, 7);
TestWordRight('Before untrimmed > next', 12, 7, 4, 8, 14, 8);
TestWordRight('untrimmed > EOL, next', 30, 8, 35, 8, 1, 9);
TestWordRight('Before untrimmed tab > next', 12, 9, 8,10, 15,10);
TestWordRight('untrimmed tab > EOL, next', 24,10, 29,10, 1,11);
TestWordRight('Before empty > next', 12,11, 1,12);
TestWordRight('Before space empty > next', 12,13, 1,14, 6, 14);
{%endregion}
end;
procedure TTestBasicSynEdit.TestCaretDeleteWord_LastWord; procedure TTestBasicSynEdit.TestCaretDeleteWord_LastWord;
var var
AllowPastEOL: Boolean; AllowPastEOL: Boolean;

View File

@ -0,0 +1,794 @@
unit TestNavigation;
(* TODO:
Word Left/Right: Need tests with fold, trim, selection
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, testregistry, LCLProc, LCLType, Forms, TestBase,
SynEdit, SynEditTextTrimmer, SynEditKeyCmds, LazSynEditText;
type
{ TTestSynNavigation }
TTestSynNavigation = class(TTestBase)
published
procedure TestCaretHomeEnd;
procedure TestCaretLeftRight;
procedure TestCaretMoveLeftRightWord;
//procedure TestCaretMoveLeftRightPartWord;
end;
implementation
{ TTestSynNavigation }
procedure TTestSynNavigation.TestCaretHomeEnd;
procedure DoInit1;
begin
ReCreateEdit;
SynEdit.TabWidth := 6;
SyneDit.Options := [];
SyneDit.Options2 := [];
SetLines(['', //1
'',
'test', // 3
'',
'',
' ',
'test', // 3
#9#9#9#9#9,
' spaced', // 9
'',
'',
' ',
' spaced',
#9#9#9#9#9,
#9'tabbed', // 15
'',
'',
' ',
#9'tabbed',
#9#9#9#9#9,
#9' tabbed spaced', // 21
'',
'',
' ',
#9' tabbed spaced',
#9#9#9#9#9,
' ', // 27 (space only)
'',
'',
' ',
#9' ',
#9#9#9#9#9,
' spaced 9 for tab', // 33
#9#9#9#9#9,
' X ', // 35
' X'#9, // 36
''
]);
end;
procedure TestHome(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer; ExpLTxTStartX: Integer = -1);
begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(1st home)', ExpX1,Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(2nd home)', ExpX2,Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(3rd home)', ExpX3,Y);
if ExpLTxTStartX > 0 then begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(1st line-text-start)', ExpLTxTStartX,Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(2nd line-text-start)', ExpLTxTStartX,Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(3rd line-text-start)', ExpLTxTStartX,Y);
end;
end;
procedure TestEnd(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer);
begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(1st end)', ExpX1,Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(2nd end)', ExpX2,Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(3rd end)', ExpX3,Y);
end;
begin
// None Smart-Home:
// Caret goes x=1, then x=indend
// Smart-Home:
// Caret goes x=indent, then 1, IF AFTER indent, or at x=1
// Caret goes x=1, then x=indend, IF at x=indent, or inside indent
// Both
// Caret does not go past eol, unless explicitly enabled
// if spaces/tab exist at start of otherwise empty line, caret will go to prev-line indent
{%region}
DoInit1;
PushBaseName('no smart / no past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4);
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoScrollPastEol];
PopPushBaseName('no smart / past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4);
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
TestHome('1st after space indented line (x)', 2,10, 1,4,1, 1);
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
TestHome('1st after tab indented line(x)', 2,16, 1,7,1, 1);
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoEnhanceHomeKey];
PopPushBaseName('smart home / no past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 7,1,7, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoEnhanceHomeKey, eoScrollPastEol];
PopPushBaseName('smart home / past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
TestHome('1st after tab indented line (x)', 2,16, 1,7,1, 1);
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
PopPushBaseName('NO smart end/ NO past-eol');
DoInit1;
TestEnd ('empty 1st line', 1,1, 1,1,1);
TestEnd ('end', 1,35, 6,3,6);
TestEnd ('end tab', 1,36, 7,3,7);
PopPushBaseName('smart end/ NO past-eol');
DoInit1;
SyneDit.Options2 := [eoEnhanceEndKey];
TestEnd ('end', 1,35, 3,6,3);
TestEnd ('end tab', 1,36, 3,7,3);
//SyneDit.Options := [eoScrollPastEol, eoEnhanceHomeKey];
//SyneDit.Options2 := [eoEnhanceEndKey];
end;
procedure TTestSynNavigation.TestCaretLeftRight;
procedure SetTextLeftRight;
begin
ReCreateEdit;
SetLines([ 'ああああああああああああああああああああああ', // 1: Double width at odd pos (start at 1, then every 2)
' ああああああああああああああああああああああ', // 2: Double width at even pos
'', // 3: empty
#9#9#9#9#9#9#9#9, // 4: tabs
'abc'#9'def', // 5: text+tabs
'abc def üüü xyz', // 6: utf8 multibyte
'abc def ü'#9'üü xyz', // 7: utf8 multibyte + tabs
'abc あdefあ123', // 8: Double withs
'abc あdef'#9'あ'#9'123', // 9: Double withs + tabs
''
]);
end;
procedure TestLeftRight(AName: String; ALine: Integer; AStartPhysX: Integer; ACommand:TSynEditorCommand;
ExpPhysX, ExpLogX: Integer; ExpRepeatPhysX: Integer = -1; ExpRepeatLogX: Integer = -1;
DoReverse: Boolean = True; DoKeepXDWidth: Boolean = True;
ASelectXEnd: Integer = -1; ExpCaretY: integer = -1);
var
Name2: String;
TestLogFirst: Boolean;
procedure DoCmd;
begin
if ASelectXEnd < 0
then SetCaretPhys(AStartPhysX, ALine)
else SetCaretAndSelPhys(ASelectXEnd, ALine, AStartPhysX, ALine);
SynEdit.ExecuteCommand(ACommand, '', nil);
end;
procedure TestCmd;
begin
DoCmd;
if not TestLogFirst then
TestIsCaretPhys(Name2+'[1]', ExpPhysX, ExpCaretY);
TestIsCaret(Name2+'[1]', ExpLogX, ExpCaretY);
TestIsCaretPhys(Name2+'[1]', ExpPhysX, ExpCaretY);
end;
procedure DoCmdRepeat;
begin
if ExpRepeatPhysX < 0 then exit;
SynEdit.ExecuteCommand(ACommand, '', nil);
end;
procedure TestCmdRepeat;
begin
if ExpRepeatPhysX < 0 then exit;
DoCmdRepeat;
if not TestLogFirst then
TestIsCaretPhys(Name2+'[2]', ExpRepeatPhysX, ExpCaretY);
if ExpRepeatLogX > 0 then
TestIsCaret(Name2+'[2]', ExpRepeatLogX, ExpCaretY);
TestIsCaretPhys(Name2+'[2]', ExpRepeatPhysX, ExpCaretY);
end;
procedure DoCmdReverse(AfterRepeat: Boolean = false);
begin
if not DoReverse then exit;
if AfterRepeat and (ExpRepeatPhysX < 0) then exit; // was never repeated
if ACommand = ecLeft
then SynEdit.ExecuteCommand(ecRight, '', nil)
else SynEdit.ExecuteCommand(ecLeft, '', nil);
end;
procedure TestCmdReverse(AfterRepeat: Boolean = false);
begin
if not DoReverse then exit;
if AfterRepeat and (ExpRepeatPhysX < 0) then exit; // was never repeated
DoCmdReverse(AfterRepeat);
if AfterRepeat then begin
if not TestLogFirst then
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', ExpPhysX, ExpCaretY);
TestIsCaret(Name2, ExpLogX, ExpCaretY);
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', ExpPhysX, ExpCaretY);
end else begin
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', AStartPhysX, ALine);
end;
end;
procedure DoKeepXOnEmpty;
begin
if (ExpPhysX > 1) and not(eoScrollPastEol in SynEdit.Options) then begin
SynEdit.CaretObj.LinePos := 3; // empty line
SynEdit.CaretObj.LinePos := ExpCaretY;
end;
end;
procedure TestKeepXOnEmpty(TestBetween: Boolean = False);
begin
if (ExpPhysX > 1) and not(eoScrollPastEol in SynEdit.Options) then begin
SynEdit.CaretObj.LinePos := 3; // empty line
if TestBetween then
AssertEquals(Name2+'empty line at pos 1', 1, SynEdit.CaretObj.CharPos);
SynEdit.CaretObj.LinePos := ExpCaretY;
if eoKeepCaretX in SynEdit.Options
then AssertEquals(Name2+'after empty line at pos 1', ExpPhysX, SynEdit.CaretObj.CharPos)
else AssertEquals(Name2+'after empty line at pos 1', 1, SynEdit.CaretObj.CharPos);
end;
end;
procedure DoKeepXOnDWidth;
begin
if (ExpPhysX > 1) and DoKeepXDWidth then begin
if (ExpPhysX and 1) = 0
then SynEdit.CaretObj.LinePos := 1 // double width odd
else SynEdit.CaretObj.LinePos := 2; // double width even
SynEdit.CaretObj.LinePos := ExpCaretY;
end;
end;
procedure TestKeepXOnDWidth(TestBetween: Boolean = False);
begin
if (ExpPhysX > 1) and DoKeepXDWidth then begin
if (ExpPhysX and 1) = 0
then SynEdit.CaretObj.LinePos := 1 // double width odd
else SynEdit.CaretObj.LinePos := 2; // double width even
if TestBetween then
AssertFalse(Name2+'after dwidth line at pos 1', ExpPhysX = SynEdit.CaretObj.CharPos);
SynEdit.CaretObj.LinePos := ExpCaretY;
AssertTrue(Name2+'after dwidth line at pos 1',
(ExpPhysX = SynEdit.CaretObj.CharPos) = (eoKeepCaretX in SynEdit.Options));
end;
end;
var
s: string;
begin
if ExpCaretY < 0 then ExpCaretY := ALine;
EditorCommandToIdent(ACommand, s);
AName := Format('%s (%s Y=%d, X=%d) ', [AName, s, ALine, AStartPhysX]);
{%region NO eoKeepCaretX}
SynEdit.Options := SynEdit.Options - [eoKeepCaretX];
Name2 := AName + 'NO eoKeepCaretX: ';
TestLogFirst := False;
TestCmd;
TestCmdReverse;
TestCmd;
TestCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
DoCmd;
TestCmdReverse;
DoCmd;
DoCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
TestLogFirst := True;
TestCmd;
TestCmdReverse;
TestCmd;
TestCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
TestCmd;
TestKeepXOnEmpty(False);
TestCmd;
TestKeepXOnEmpty(True);
TestCmd;
TestKeepXOnDWidth(False);
TestCmd;
TestKeepXOnDWidth(True);
{%endregion NO eoKeepCaretX}
{%region WITH eoKeepCaretX}
SynEdit.Options := SynEdit.Options + [eoKeepCaretX];
Name2 := Name2 + 'WITH eoKeepCaretX: ';
TestLogFirst := False;
TestCmd;
TestCmdReverse;
TestCmd;
TestCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
DoCmd;
TestCmdReverse;
DoCmd;
DoCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
TestLogFirst := True;
TestCmd;
TestCmdReverse;
TestCmd;
TestCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
TestCmd;
TestKeepXOnEmpty(False);
if ASelectXEnd < 0 then
TestCmdReverse;
TestCmd;
TestKeepXOnEmpty(True);
if ASelectXEnd < 0 then
TestCmdReverse;
TestCmd;
TestKeepXOnEmpty(False);
TestCmdRepeat;
TestCmd;
TestKeepXOnDWidth(False);
if ASelectXEnd < 0 then
TestCmdReverse;
TestCmd;
TestKeepXOnDWidth(True);
if ASelectXEnd < 0 then
TestCmdReverse;
TestCmd;
TestKeepXOnDWidth(False);
TestCmdRepeat;
{%endregion WITH eoKeepCaretX}
end;
begin
SetTextLeftRight;
{%region ecRight}
PushBaseName('No opts');
SynEdit.TabWidth := 6;
SynEdit.MaxLeftChar := 200;
SynEdit.Options := [];
SynEdit.Options2 := [];
TestLeftRight('Simple right', 5, 2, ecRight, 3, 3, 4, 4);
TestLeftRight('After tab right', 5, 7, ecRight, 8, 6, 9, 7);
TestLeftRight('Before tab right', 5, 4, ecRight, 5, 4, 6, 4);
TestLeftRight('Mid tab right', 5, 5, ecRight, 6, 4, 7, 5);
TestLeftRight('tab to tab right', 4, 6, ecRight, 7, 2, 8, 2);
TestLeftRight('Umlaut right', 6, 9, ecRight, 10,11, 11,13);
TestLeftRight('Double W right', 8, 5, ecRight, 7, 8, 8, 9);
TestLeftRight('at EOL right', 5, 10, ecRight, 1, 1, 2, 2, True, True, -1 , 6);
PopPushBaseName('eoScrollPastEol');
SynEdit.Options := [eoScrollPastEol];
TestLeftRight('at EOL right', 5, 10, ecRight, 11, 9, 12,10);
TestLeftRight('at Max-left right', 5,199, ecRight, 200,198, 200,198, False, False);
PopPushBaseName('eoCaretSkipTab');
SynEdit.Options := [];
SynEdit.Options2 := [eoCaretSkipTab];
TestLeftRight('Simple right', 5, 2, ecRight, 3, 3, 4, 4);
TestLeftRight('After tab right', 5, 7, ecRight, 8, 6, 9, 7);
TestLeftRight('Before tab right', 5, 4, ecRight, 7, 5, 8, 6);
TestLeftRight('tab to tab right', 4, 7, ecRight, 13, 3, 19, 4);
PopPushBaseName('eoCaretSkipsSelection');
SynEdit.Options2 := [eoCaretSkipsSelection];
TestLeftRight('Selected right', 5, 2, ecRight, 8, 6, -1, -1, True, False, 8);
{%region ecRight}
{%region ecLeft}
SynEdit.Options := [];
SynEdit.Options2 := [];
TestLeftRight('Simple left', 5, 3, ecLeft, 2, 2, 1, 1);
TestLeftRight('After tab left', 5, 7, ecLeft, 6, 4, 5, 4);
TestLeftRight('Before tab left', 5, 4, ecLeft, 3, 3, 2, 2);
TestLeftRight('Mid tab left', 5, 5, ecLeft, 4, 4, 3, 3);
TestLeftRight('tab to tab left', 4, 8, ecLeft, 7, 2, 6, 1);
TestLeftRight('Umlaut left', 6, 10, ecLeft, 9, 9, 8, 8);
TestLeftRight('Double W left', 8, 7, ecLeft, 5, 5, 4, 4);
TestLeftRight('at BOL left', 6, 1, ecLeft, 10, 8, 9, 7, True, True, -1 , 5);
PopPushBaseName('eoScrollPastEol');
SynEdit.Options := [eoScrollPastEol];
TestLeftRight('at BOL left', 6, 1, ecLeft, 1, 1, 1, 1, False, False);
PopPushBaseName('eoCaretSkipTab');
SynEdit.Options := [];
SynEdit.Options2 := [eoCaretSkipTab];
TestLeftRight('Simple left', 5, 3, ecLeft, 2, 2, 1, 1);
TestLeftRight('After tab left', 5, 7, ecLeft, 4, 4, 3, 3);
TestLeftRight('tab to tab left', 4, 13, ecLeft, 7, 2, 1, 1);
PopPushBaseName('eoCaretSkipsSelection');
SynEdit.Options2 := [eoCaretSkipsSelection];
TestLeftRight('Selected left', 5, 8, ecLeft, 3, 3, -1, -1, True, False, 3);
{%endregion ecLeft}
PopBaseName;
end;
procedure TTestSynNavigation.TestCaretMoveLeftRightWord;
procedure DoInit;
begin
ReCreateEdit;
SynEdit.TabWidth := 7;
// 1 6 11 14
SetLines(['Some text to test', //1
// 1 5 9
'Foo bar abc', // 2
// 8 14 19 24
#9'Other line with tab', // 3
// 1 8 11 15
'tab'#9'in the middle', // 4
// 1 9 12 16 23 28
'tab'#9' in the middle with space', // 5
// 1 9 13 16
'umlaute äää in text', // 6
'normal line',
// 4 14 21 28 32
' untrimmed spaces around line ', // 8
'normal line',
// 8 15 22 26
#9'tab'#9'only'#9'line'#9, // 10
// 1 8
'normal line',
'', // 12 (empty)
'normal line',
' ', // space only empty line // 14
'normal line',
'',
'A B', // 17
'normal line', // 18
''
]);
end;
procedure TestWordLeft(Name:String; X, Y, ExpX1, ExpY1: Integer;
ExpX2: Integer = -1; ExpY2: Integer = -1);
begin
SetCaretPhys(X,Y);
SynEdit.CommandProcessor(ecWordLeft, '', nil);
TestIsCaretPhys(Name + '(1st WordLeft)', ExpX1, ExpY1);
if ExpY2 > 0 then begin
SynEdit.CommandProcessor(ecWordLeft, '', nil);
TestIsCaretPhys(Name + '(2nd WordLeft)', ExpX2, ExpY2);
end;
end;
procedure TestWordRight(Name:String; X, Y, ExpX1, ExpY1: Integer;
ExpX2: Integer = -1; ExpY2: Integer = -1);
begin
SetCaretPhys(X,Y);
SynEdit.CommandProcessor(ecWordRight, '', nil);
TestIsCaretPhys(Name + '(1st WordRight)', ExpX1, ExpY1);
if ExpY2 > 0 then begin
SynEdit.CommandProcessor(ecWordRight, '', nil);
TestIsCaretPhys(Name + '(2nd WordRight)', ExpX2, ExpY2);
end;
end;
begin
DoInit;
{%region word left}
TestWordLeft('simple "te|st"', 16, 1, 14, 1, 11, 1);
TestWordLeft('simple EOW "test|"', 18, 1, 14, 1, 11, 1);
TestWordLeft('simple BOW "|test"', 14, 1, 11, 1, 6, 1);
TestWordLeft('simple > BOT "So|me"', 3, 1, 1, 1, 1, 1);
TestWordLeft('simple > prev-line "F|oo"', 2, 2, 1, 2, 18, 1);
TestWordLeft('simple > prev-line "|Foo"', 1, 2, 18, 1, 14, 1);
TestWordLeft('tab "wi|th"', 21, 3, 19, 3, 14, 3);
TestWordLeft('tab EOW "with|"', 23, 3, 19, 3, 14, 3);
TestWordLeft('tab BOW "|with"', 19, 3, 14, 3, 8, 3);
TestWordLeft('tab > prev-line "O|ther"', 9, 3, 8, 3, 12, 2);
TestWordLeft('M-tab "i|n"', 9, 4, 8, 4, 1, 4);
TestWordLeft('M-tab > prev-line-tab "ta|b"', 3, 4, 1, 4, 27, 3);
TestWordLeft('M-S-tab "i|n"', 10, 5, 9, 5, 1, 5);
TestWordLeft('M-S-EOW tab "in|"', 11, 5, 9, 5, 1, 5);
TestWordLeft('M-S-BOW tab "|in"', 9, 5, 1, 5, 21, 4);
TestWordLeft('M-S-tab "#9| in"', 8, 5, 1, 5);
TestWordLeft('Umlaut "ää|ä"', 11, 6, 9, 6, 1, 6);
TestWordLeft('Umlaut EOW "äää|"', 12, 6, 9, 6, 1, 6);
TestWordLeft('Umlaut BOW "|äää"', 9, 6, 1, 6, 33, 5);
TestWordLeft('Umlaut "i|n"', 14, 6, 13, 6, 9, 6);
TestWordLeft('After Umlaut > prev line', 1, 7, 20, 6, 16, 6);
TestWordLeft('untrimmed "un|trimmed"', 6, 8, 4, 8, 12, 7);
TestWordLeft('After untrimmed > prev', 1, 9, 35, 8, 28, 8);
TestWordLeft('untrimmed tab "t|ab"', 9,10, 8,10, 12, 9);
TestWordLeft('After untrimmed tab > prev', 1,11, 29,10, 22,10);
TestWordLeft('After empty > prev', 1,13, 1,12);
TestWordLeft('After space empty > prev', 1,15, 6,14);
TestWordLeft('single char at eol "A B|"', 4,17, 3,17, 1,17);
{%endregion}
{%region word right}
TestWordRight('simple "te|xt"', 8, 1, 11, 1, 14, 1);
TestWordRight('simple EOW "text|"', 10, 1, 11, 1, 14, 1);
TestWordRight('simple BOW "|text"', 6, 1, 11, 1, 14, 1);
TestWordRight('simple EOT "li|ne"', 10,18, 12,18, 12,18);
TestWordRight('simple > EOL, next line "te|st"', 16, 1, 18, 1, 1, 2);
TestWordRight('tab "li|ne"', 16, 3, 19, 3, 24, 3);
TestWordRight('tab EOW "line|"', 18, 3, 19, 3, 24, 3);
TestWordRight('tab BOW "|line"', 14, 3, 19, 3, 24, 3);
TestWordRight('tab > EOL, next-line', 25, 3, 27, 3, 1, 4);
TestWordRight('M-tab "t|ab"', 2, 4, 8, 4, 11, 4);
TestWordRight('M-tab "tab|"', 4, 4, 8, 4, 11, 4);
TestWordRight('M-tab > EOL, next-line-tab', 17, 4, 21, 4, 1, 5);
TestWordRight('M-S-tab BOW "t|ab"', 2, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab EOW "tab|"', 4, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab BOW "|tab"', 1, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab "tab#9| "', 5, 5, 9, 5, 12, 5);
TestWordRight('Umlaut "ää|ä"', 11, 6, 13, 6, 16, 6);
TestWordRight('Umlaut EOW "äää|"', 12, 6, 13, 6, 16, 6);
TestWordRight('Umlaut BOW "|äää"', 9, 6, 13, 6, 16, 6);
TestWordRight('Umlaut "um|laute"', 2, 6, 9, 6, 13, 6);
TestWordRight('After Umlaut > EOL, next line', 18, 6, 20, 6, 1, 7);
TestWordRight('Before untrimmed > next', 12, 7, 4, 8, 14, 8);
TestWordRight('untrimmed > EOL, next', 30, 8, 35, 8, 1, 9);
TestWordRight('Before untrimmed tab > next', 12, 9, 8,10, 15,10);
TestWordRight('untrimmed tab > EOL, next', 24,10, 29,10, 1,11);
TestWordRight('Before empty > next', 12,11, 1,12);
TestWordRight('Before space empty > next', 12,13, 1,14, 6, 14);
{%endregion}
end;
initialization
RegisterTest(TTestSynNavigation);
end.