1 unit TestBasicSynEdit;
2
3 (* TODO:
4 - TestEditEmpty:
5 Test with different sets of VirtualViews (with/without trimming (enabled/module present at all)
6 *)
7
8 {$mode objfpc}{$H+}
9
10 interface
11
12 uses
13 Classes, SysUtils, testregistry, LCLProc, LCLType, Forms, TestBase, SynEdit,
14 SynEditTextTrimmer, SynEditKeyCmds, LazSynEditText, SynEditPointClasses,
15 SynEditMiscClasses, SynEditTypes, SynEditMiscProcs;
16
17 type
18
19 { TTestBasicSynEdit }
20
21 TTestBasicSynEdit = class(TTestBase)
22 private
23 InsertFlag: Boolean;
24 TrimType: TSynEditStringTrimmingType;
25 TrimEnabled: Boolean;
26 private
27 AllowPastEOL, FPersistSel: Boolean;
28 FDoInit: procedure of object;
TStringArraynull29 FTestLines: function: TStringArray of object;
30 Procedure DoInit1;
TestLines1null31 function TestLines1: TStringArray;
TestLines2null32 function TestLines2: TStringArray;
33 private
34 FTestCommand:TSynEditorCommand;
35 procedure TestCommand(Name:String; X, Y: Integer;
36 ExpX1, ExpY1: Integer; Repl: Array of const);
37 procedure TestCommand(Name:String; X, Y, X2, Y2: Integer;
38 ExpX1, ExpY1, ExpX2, ExpY2: Integer;
39 Repl: Array of const);
40 procedure TestCommand(Name:String; X, Y: Integer;
41 ExpX1, ExpY1: Integer; Repl: Array of const;
42 ExpX2, ExpY2: Integer; Repl2: Array of const);
43 protected
TestMaxLeftProcnull44 function TestMaxLeftProc: Integer;
45 procedure ReCreateEdit; reintroduce;
46 published
47 procedure TestEditEmpty;
48 procedure TestEditTabs;
49 procedure TestEditEcChar;
50 procedure TestPhysicalLogical; // TODO adjust to char tests
51 procedure TestPhysicalLogicalCaretMove;
52 procedure TestLogicalAdjust;
53 procedure TestCaretObject;
54 procedure TestCaretAutoMove;
55 procedure TestCaretEcDeleteWord;
56 procedure TestCaretEcDeleteLastWord;
57 procedure TestCaretEcDeleteEOL;
58 procedure TestWordBreaker;
59 procedure TestSearchReplace;
60 procedure TestMoveLineUpDown;
61 end;
62
63 implementation
64
65 procedure TTestBasicSynEdit.DoInit1;
66 begin
67 InsertFlag := False;
68 TrimEnabled := False;;
69 ReCreateEdit;
70 if AllowPastEOL
71 then SynEdit.Options := SynEdit.Options + [eoScrollPastEol]
72 else SynEdit.Options := SynEdit.Options - [eoScrollPastEol];
73 if FPersistSel
74 then SynEdit.Options2 := SynEdit.Options2 + [eoPersistentBlock]
75 else SynEdit.Options2 := SynEdit.Options2 - [eoPersistentBlock];
76 SynEdit.TabWidth := 7;
77 SetLines(FTestLines());
78 end;
79
TestLines1null80 function TTestBasicSynEdit.TestLines1: TStringArray;
81 begin
82 SetLength(Result, 16);
83 // 1 6 11 14
84 Result[0] := 'Some text to test'; //1
85 // 1 5 9
86 Result[1] := 'Foo bar abc'; // 2
87 // 8 14 19 24
88 Result[2] := #9'Other line with tab'; // 3
89 // 1 8 11 15
90 Result[3] := 'tab'#9'in the middle'; // 4
91 // 1 9 12 16 23 28
92 Result[4] := 'tab'#9' in the middle with space'; // 5
93 // 1 9 13 16
94 Result[5] := 'umlaute äää in text'; // 6
95 Result[6] := 'normal line';
96 // 4 14 21 28 32
97 Result[7] := ' untrimmed spaces around line '; // 8
98 Result[8] := 'normal line';
99 // 8 15 22 26
100 Result[9] := #9'tab'#9'only'#9'line'#9; // 10
101 // 1 8
102 Result[10] := 'normal line';
103 Result[11] := ''; // 12 (empty)
104 Result[12] := 'normal line';
105 Result[13] := ' '; // space only empty line // 14
106 Result[14] := 'normal line';
107 Result[15] := '';
108 end;
109
TestLines2null110 function TTestBasicSynEdit.TestLines2: TStringArray;
111 begin
112 SetLength(Result, 7);
113 // 1 6 11 14
114 Result[0] := 'abc def ghi'; // 1
115 Result[1] := 'ABC DEF GHI'; // 2
116 Result[2] := '123 456 789'; // 3
117 Result[3] := 'mno pqr stu'; // 4
118 Result[4] := 'MNO PQR STU'; //5
119 Result[5] := 'xyz XYZ vw';
120 Result[6] := '';
121 end;
122
123 procedure TTestBasicSynEdit.TestCommand(Name: String; X, Y: Integer; ExpX1,
124 ExpY1: Integer; Repl: array of const);
125 begin
126 FDoInit();
127 SetCaretPhys(X,Y);
128 SynEdit.CommandProcessor(FTestCommand, '', nil);
129 TestIsCaretPhys(Name + '(1st)', ExpX1, ExpY1);
130 TestIsFullText(Name + '(1st)', FTestLines(), Repl);
131 end;
132
133 procedure TTestBasicSynEdit.TestCommand(Name: String; X, Y, X2, Y2: Integer;
134 ExpX1, ExpY1, ExpX2, ExpY2: Integer; Repl: array of const);
135 begin
136 FDoInit();
137 SetCaretAndSel(X,Y, x2,y2);
138 SynEdit.CommandProcessor(FTestCommand, '', nil);
139 TestIsCaretAndSel(Name + '(1st)', ExpX1, ExpY1, ExpX2, ExpY2);
140 TestIsFullText(Name + '(1st)', FTestLines(), Repl);
141 end;
142
143 procedure TTestBasicSynEdit.TestCommand(Name: String; X, Y: Integer; ExpX1,
144 ExpY1: Integer; Repl: array of const; ExpX2, ExpY2: Integer;
145 Repl2: array of const);
146 begin
147 TestCommand(Name, X, Y, ExpX1, ExpY1, Repl);
148 SynEdit.CommandProcessor(FTestCommand, '', nil);
149 TestIsCaretPhys(Name + '(2nd)', ExpX2, ExpY2);
150 TestIsFullText(Name + '(2nd)', FTestLines(), Repl2);
151 end;
152
TestMaxLeftProcnull153 function TTestBasicSynEdit.TestMaxLeftProc: Integer;
154 begin
155 Result := 6000;
156 end;
157
158 procedure TTestBasicSynEdit.ReCreateEdit;
159 begin
160 inherited ReCreateEdit;
161 SynEdit.InsertMode := InsertFlag;
162 SynEdit.TrimSpaceType := TrimType;
163 if TrimEnabled then
164 SynEdit.Options := SynEdit.Options + [eoTrimTrailingSpaces]
165 else
166 SynEdit.Options := SynEdit.Options - [eoTrimTrailingSpaces];
167
168 end;
169
170 procedure TTestBasicSynEdit.TestEditEmpty;
171 procedure CheckText(aName: String; ExpText: String; ExpLines: Integer);
172 var
173 s: String;
174 begin
175 AssertEquals(BaseTestName + aName+' Count', ExpLines, SynEdit.Lines.Count);
176 // TestIsText (without Views => just real text)
177 // TestIsFullText (with Views => eg trimmed spaces)
178 s:='';
179 if ExpLines > 0 then
180 s := LineEnding;
181 TestIsText(aName+' Text', ExpText+s);
182 end;
183 procedure DoChecks;
184 begin
185 ReCreateEdit;
186 CheckText('Empty', '', 0);
187 SynEdit.CommandProcessor(ecChar, 'x', nil);
188 CheckText('After Insert "x"', 'x', 1);
189
190 ReCreateEdit;
191 SynEdit.CommandProcessor(ecChar, ' ', nil);
192 if TrimEnabled then begin
193 CheckText('After Insert <space>', '', 1);
194 if TrimType = settIgnoreAll then begin
195 TestIsFullText('After Insert <space> (FullText)', ''+LineEnding);
196 TestIsCaret('After Insert <space>', 2,1);
197 end else begin
198 TestIsFullText('After Insert <space> (FullText)', ' '+LineEnding);
199 TestIsCaret('After Insert <space>', 2,1);
200 end;
201 end else begin
202 CheckText('After Insert <space>', ' ', 1);
203 TestIsFullText('After Insert <space> (FullText)', ' '+LineEnding);
204 TestIsCaret('After Insert <space>', 2,1);
205 end;
206
207 ReCreateEdit;
208 CheckText('Empty', '', 0);
209 SynEdit.CommandProcessor(ecDeleteChar, '', nil);
210 CheckText('After ecDeleteChar', '', 0);
211
212 ReCreateEdit;
213 SynEdit.CommandProcessor(ecDeleteLastChar, '', nil);
214 CheckText('After ecDeleteLastChar', '', 0);
215
216 ReCreateEdit;
217 SynEdit.CommandProcessor(ecDeleteWord, '', nil);
218 CheckText('After ecDeleteWord', '', 0);
219
220 ReCreateEdit;
221 SynEdit.CommandProcessor(ecDeleteLastWord, '', nil);
222 CheckText('After ecDeleteLastWord', '', 0);
223
224 ReCreateEdit;
225 SynEdit.CommandProcessor(ecInsertLine, '', nil);
226 CheckText('After ecInsertLine', LineEnding, 2);
227
228 ReCreateEdit;
229 SynEdit.CommandProcessor(ecLineBreak, '', nil);
230 CheckText('After ecLineBreak', LineEnding, 2);
231
232 end;
233 begin
234 FPersistSel := False;
235 TrimEnabled := True;
236 TrimType := settEditLine;
237 PushBaseName('Trim=EditLine');
238 PushBaseName('InsertMode');
239 InsertFlag := True;
240 DoChecks;
241 PopPushBaseName('OverwriteMode');
242 InsertFlag := False;
243 DoChecks;
244 PopBaseName;
245
246 TrimType := settIgnoreAll;
247 PopPushBaseName('Trim=IgnoreAll');
248 PushBaseName('InsertMode');
249 InsertFlag := True;
250 DoChecks;
251 PopPushBaseName('OverwriteMode');
252 InsertFlag := False;
253 DoChecks;
254 PopBaseName;
255
256 TrimEnabled := False;
257 PopPushBaseName('Trim=Disabled');
258 PushBaseName('InsertMode');
259 InsertFlag := True;
260 DoChecks;
261 PopPushBaseName('OverwriteMode');
262 InsertFlag := False;
263 DoChecks;
264 PopBaseName;
265
266 end;
267
268 procedure TTestBasicSynEdit.TestEditTabs;
269 begin
270 FPersistSel := False;
271 ReCreateEdit;
272 // witout eoAutoIndent
273 SynEdit.Options := SynEdit.Options
274 - [eoTabIndent, eoTabsToSpaces, eoSpacesToTabs, eoAutoIndent, eoSmartTabs, eoSmartTabDelete];
275 SynEdit.TabWidth := 4;
276 SetLines([' abc', #9'abcde', '']);
277 SetCaret(2, 2); // after tab
278 TestIsCaretPhys('Before delete tab', 5, 2);
279 SynEdit.CommandProcessor(ecDeleteLastChar, '', nil);
280
281 TestIsCaret('After delete tab', 1, 2);
282 TestIsCaretPhys('After delete tab', 1, 2);
283 TestIsText('After delete tab', [' abc', 'abcde', '']);
284
285 ReCreateEdit;
286 // with eoAutoIndent
287 SynEdit.Options := SynEdit.Options + [eoSmartTabs, eoSmartTabDelete, eoAutoIndent]
288 - [eoTabIndent, eoTabsToSpaces, eoSpacesToTabs];
289 SynEdit.TabWidth := 4;
290 SetLines([' abc', #9'abcde', '']);
291 SetCaret(2, 2); // after tab
292 TestIsCaretPhys('Before delete tab', 5, 2);
293 SynEdit.CommandProcessor(ecDeleteLastChar, '', nil);
294
295 // reuqired indent is filled up with spaces
296 TestIsCaret('After delete tab (smart)', 3, 2);
297 TestIsCaretPhys('After delete tab (smart)', 3, 2);
298 TestIsText('After delete tab (smart)', [' abc', ' abcde', '']);
299
300 end;
301
302 procedure TTestBasicSynEdit.TestEditEcChar;
303 var
304 CaretPEol: Boolean;
305
TestText1null306 function TestText1: TStringArray;
307 begin
308 SetLength(Result, 4);
309 Result[0] := 'abc';
310 Result[1] := 'öbc';
311 Result[2] := #9'abc';
312 Result[3] := '';
313 end;
314 procedure InitEdit;
315 begin
316 ReCreateEdit;
317 SynEdit.Options := [];
318 if CaretPEol then SynEdit.Options := SynEdit.Options + [eoScrollPastEol];
319 SynEdit.TabWidth := 6;
320 SetLines(TestText1);
321 end;
322
323 // All Logical pos
324 Procedure DoTest(ATestName: String; StartX, StartY: Integer;
325 Char1: String; ExpX1, ExpY1: Integer; Repl1: Array of const;
326 Char2: String; ExpX2, ExpY2: Integer; Repl2: Array of const;
327 AStartIsPhys: Boolean = False
328 );
329 begin
330 BaseTestName := Format('%s -Ins=%s - PastEol=%s - StartXY=(%d,%d) - ',
331 [ATestName, dbgs(InsertFlag), dbgs(CaretPEol), StartX, StartY]);
332 InitEdit;
333
334 if AStartIsPhys
335 then SetCaretPhys(StartX, StartY)
336 else SetCaret(StartX, StartY);
337
338 SynEdit.TestTypeText(Char1);
339 TestIsCaret('After Char 1', ExpX1, ExpY1);
340 TestIsText ('After Char 1', TestText1, Repl1);
341
342 SynEdit.TestTypeText(Char2);
343 TestIsCaret('After Char 2', ExpX2, ExpY2);
344 TestIsText ('After Char 2', TestText1, Repl2);
345
346 SynEdit.Undo;
347 TestIsCaret('Undo 1', ExpX1, ExpY1);
348 TestIsText ('Undo 1', TestText1, Repl1);
349
350 SynEdit.Redo;
351 TestIsCaret('Redo 1', ExpX2, ExpY2);
352 TestIsText ('Redo 1', TestText1, Repl2);
353
354 SynEdit.Undo;
355 TestIsCaret('Undo 2a', ExpX1, ExpY1);
356 TestIsText ('Undo 2a', TestText1, Repl1);
357
358 SynEdit.Undo;
359 if AStartIsPhys
360 then TestIsCaretPhys('Undo 2b', StartX, StartY)
361 else TestIsCaret('Undo 2b', StartX, StartY);
362 TestIsText ('Undo 2b', TestText1);
363
364 SynEdit.Redo;
365 TestIsCaret('Redo 2a', ExpX1, ExpY1);
366 TestIsText ('Redo 2a', TestText1, Repl1);
367
368 SynEdit.Redo;
369 TestIsCaret('Redo 2b', ExpX2, ExpY2);
370 TestIsText ('Redo 2b', TestText1, Repl2);
371
372 InitEdit;
373
374 if AStartIsPhys
375 then SetCaretPhys(StartX, StartY)
376 else SetCaret(StartX, StartY);
377 SynEdit.TestTypeText(Char1);
378 SynEdit.TestTypeText(Char2);
379 TestIsCaret('After Char 1+2', ExpX2, ExpY2);
380 TestIsText ('After Char 1+2', TestText1, Repl2);
381
382 end;
383 begin
384 FPersistSel := False;
385 TrimEnabled := False; // Trim has its own test
386
387 // Testing ecChar. Tab is ecTab, so not included
388
389 {%region Normal Line}
390 {%region Normal Line -- Normal Char}
391 InsertFlag := True;
392 CaretPEol := False;
393 DoTest('normal line - BOL', 1, 1, 'X', 2, 1, [1,'Xabc'], 'Y', 3,1, [1,'XYabc']);
394 DoTest('normal line - mid', 2, 1, 'X', 3, 1, [1,'aXbc'], 'Y', 4,1, [1,'aXYbc']);
395 DoTest('normal line - EOL', 4, 1, 'X', 5, 1, [1,'abcX'], 'Y', 6,1, [1,'abcXY']);
396 CaretPEol := True;
397 DoTest('normal line - EOL', 4, 1, 'X', 5, 1, [1,'abcX'], 'Y', 6,1, [1,'abcXY']);
398 DoTest('normal line - Past', 6, 1, 'X', 7, 1, [1,'abc X'], 'Y', 8,1, [1,'abc XY']);
399
400 InsertFlag := False;
401 CaretPEol := False;
402 DoTest('normal line - BOL', 1, 1, 'X', 2, 1, [1,'Xbc'], 'Y', 3,1, [1,'XYc']);
403 DoTest('normal line - mid', 2, 1, 'X', 3, 1, [1,'aXc'], 'Y', 4,1, [1,'aXY']);
404 DoTest('normal line - mid', 3, 1, 'X', 4, 1, [1,'abX'], 'Y', 5,1, [1,'abXY']);
405 DoTest('normal line - EOL', 4, 1, 'X', 5, 1, [1,'abcX'], 'Y', 6,1, [1,'abcXY']);
406 CaretPEol := True;
407 DoTest('normal line - EOL', 4, 1, 'X', 5, 1, [1,'abcX'], 'Y', 6,1, [1,'abcXY']);
408 DoTest('normal line - Past', 6, 1, 'X', 7, 1, [1,'abc X'], 'Y', 8,1, [1,'abc XY']);
409 {%endregion}
410
411 {%region Normal Line -- Space (and char)}
412 InsertFlag := True;
413 CaretPEol := False;
414 DoTest('normal line - space,char - BOL', 1, 1, ' ', 2, 1, [1,' abc'], 'Y', 3,1, [1,' Yabc']);
415 DoTest('normal line - space,char - mid', 2, 1, ' ', 3, 1, [1,'a bc'], 'Y', 4,1, [1,'a Ybc']);
416 DoTest('normal line - space,char - EOL', 4, 1, ' ', 5, 1, [1,'abc '], 'Y', 6,1, [1,'abc Y']);
417 CaretPEol := True;
418 DoTest('normal line - space,char - EOL', 4, 1, ' ', 5, 1, [1,'abc '], 'Y', 6,1, [1,'abc Y']);
419 DoTest('normal line - space,char - Past', 6, 1, ' ', 7, 1, [1,'abc '], 'Y', 8,1, [1,'abc Y']);
420
421 InsertFlag := False;
422 CaretPEol := False;
423 DoTest('normal line - space,char - BOL', 1, 1, ' ', 2, 1, [1,' bc'], 'Y', 3,1, [1,' Yc']);
424 DoTest('normal line - space,char - mid', 2, 1, ' ', 3, 1, [1,'a c'], 'Y', 4,1, [1,'a Y']);
425 DoTest('normal line - space,char - mid', 3, 1, ' ', 4, 1, [1,'ab '], 'Y', 5,1, [1,'ab Y']);
426 DoTest('normal line - space,char - EOL', 4, 1, ' ', 5, 1, [1,'abc '], 'Y', 6,1, [1,'abc Y']);
427 CaretPEol := True;
428 DoTest('normal line - space,char - EOL', 4, 1, ' ', 5, 1, [1,'abc '], 'Y', 6,1, [1,'abc Y']);
429 DoTest('normal line - space,char - Past', 6, 1, ' ', 7, 1, [1,'abc '], 'Y', 8,1, [1,'abc Y']);
430 {%endregion}
431
432 {%region Normal Line -- Space}
433 InsertFlag := True;
434 CaretPEol := False;
435 DoTest('normal line - space - BOL', 1, 1, ' ', 2, 1, [1,' abc'], ' ', 3,1, [1,' abc']);
436 DoTest('normal line - space - mid', 2, 1, ' ', 3, 1, [1,'a bc'], ' ', 4,1, [1,'a bc']);
437 DoTest('normal line - space - EOL', 4, 1, ' ', 5, 1, [1,'abc '], ' ', 6,1, [1,'abc ']);
438 CaretPEol := True;
439 DoTest('normal line - space - EOL', 4, 1, ' ', 5, 1, [1,'abc '], ' ', 6,1, [1,'abc ']);
440 DoTest('normal line - space - Past', 6, 1, ' ', 7, 1, [1,'abc '], ' ', 8,1, [1,'abc ']);
441
442 InsertFlag := False;
443 CaretPEol := False;
444 DoTest('normal line - space - BOL', 1, 1, ' ', 2, 1, [1,' bc'], ' ', 3,1, [1,' c']);
445 DoTest('normal line - space - mid', 2, 1, ' ', 3, 1, [1,'a c'], ' ', 4,1, [1,'a ']);
446 DoTest('normal line - space - mid', 3, 1, ' ', 4, 1, [1,'ab '], ' ', 5,1, [1,'ab ']);
447 DoTest('normal line - space - EOL', 4, 1, ' ', 5, 1, [1,'abc '], ' ', 6,1, [1,'abc ']);
448 CaretPEol := True;
449 DoTest('normal line - space - EOL', 4, 1, ' ', 5, 1, [1,'abc '], ' ', 6,1, [1,'abc ']);
450 DoTest('normal line - space - Past', 6, 1, ' ', 7, 1, [1,'abc '], ' ', 8,1, [1,'abc ']);
451 {%endregion}
452
453 {%region Normal Line -- utf8 2 byte Char}
454 InsertFlag := True;
455 CaretPEol := False;
456 DoTest('normal line - 2byte utf8 - BOL', 1, 1, 'Ä', 3, 1, [1,'Äabc'], 'Ü', 5,1, [1,'ÄÜabc']);
457 DoTest('normal line - 2byte utf8 - mid', 2, 1, 'Ä', 4, 1, [1,'aÄbc'], 'Ü', 6,1, [1,'aÄÜbc']);
458 DoTest('normal line - 2byte utf8 - EOL', 4, 1, 'Ä', 6, 1, [1,'abcÄ'], 'Ü', 8,1, [1,'abcÄÜ']);
459 CaretPEol := True;
460 DoTest('normal line - 2byte utf8 - EOL', 4, 1, 'Ä', 6, 1, [1,'abcÄ'], 'Ü', 8,1, [1,'abcÄÜ']);
461 DoTest('normal line - 2byte utf8 - Past', 6, 1, 'Ä', 8, 1, [1,'abc Ä'], 'Ü',10,1, [1,'abc ÄÜ']);
462
463 InsertFlag := False;
464 CaretPEol := False;
465 DoTest('normal line - 2byte utf8 - BOL', 1, 1, 'Ä', 3, 1, [1,'Äbc'], 'Ü', 5,1, [1,'ÄÜc']);
466 DoTest('normal line - 2byte utf8 - mid', 2, 1, 'Ä', 4, 1, [1,'aÄc'], 'Ü', 6,1, [1,'aÄÜ']);
467 DoTest('normal line - 2byte utf8 - mid', 3, 1, 'Ä', 5, 1, [1,'abÄ'], 'Ü', 7,1, [1,'abÄÜ']);
468 DoTest('normal line - 2byte utf8 - EOL', 4, 1, 'Ä', 6, 1, [1,'abcÄ'], 'Ü', 8,1, [1,'abcÄÜ']);
469 CaretPEol := True;
470 DoTest('normal line - 2byte utf8 - EOL', 4, 1, 'Ä', 6, 1, [1,'abcÄ'], 'Ü', 8,1, [1,'abcÄÜ']);
471 DoTest('normal line - 2byte utf8 - Past', 6, 1, 'Ä', 8, 1, [1,'abc Ä'], 'Ü',10,1, [1,'abc ÄÜ']);
472 {%endregion}
473
474 {%region Normal Line -- full width Char - 3 bytes}
475 // May change in future. overwrite only one char
476 InsertFlag := True;
477 CaretPEol := False;
478 DoTest('normal line - 3 byte full witdh - BOL', 1, 1, 'あ', 4, 1, [1,'あabc'], '吾', 7,1, [1,'あ吾abc']);
479 DoTest('normal line - 3 byte full witdh - mid', 2, 1, 'あ', 5, 1, [1,'aあbc'], '吾', 8,1, [1,'aあ吾bc']);
480 DoTest('normal line - 3 byte full witdh - EOL', 4, 1, 'あ', 7, 1, [1,'abcあ'], '吾',10,1, [1,'abcあ吾']);
481 CaretPEol := True;
482 DoTest('normal line - 3 byte full witdh - EOL', 4, 1, 'あ', 7, 1, [1,'abcあ'], '吾',10,1, [1,'abcあ吾']);
483 DoTest('normal line - 3 byte full witdh - Past', 6, 1, 'あ', 9, 1, [1,'abc あ'], '吾',12,1, [1,'abc あ吾']);
484
485 InsertFlag := False;
486 CaretPEol := False;
487 DoTest('normal line - 3 byte full witdh - BOL', 1, 1, 'あ', 4, 1, [1,'あbc'], '吾', 7,1, [1,'あ吾c']);
488 DoTest('normal line - 3 byte full witdh - mid', 2, 1, 'あ', 5, 1, [1,'aあc'], '吾', 8,1, [1,'aあ吾']);
489 DoTest('normal line - 3 byte full witdh - mid', 3, 1, 'あ', 6, 1, [1,'abあ'], '吾', 9,1, [1,'abあ吾']);
490 DoTest('normal line - 3 byte full witdh - EOL', 4, 1, 'あ', 7, 1, [1,'abcあ'], '吾',10,1, [1,'abcあ吾']);
491 CaretPEol := True;
492 DoTest('normal line - 3 byte full witdh - EOL', 4, 1, 'あ', 7, 1, [1,'abcあ'], '吾',10,1, [1,'abcあ吾']);
493 DoTest('normal line - 3 byte full witdh - Past', 6, 1, 'あ', 9, 1, [1,'abc あ'], '吾',12,1, [1,'abc あ吾']);
494 {%endregion}
495 {%endregion}
496
497 {%region Line with utf8 at start}
498 {%region Normal Char}
499 InsertFlag := True;
500 CaretPEol := False;
501 DoTest('utf8 at start - BOL', 1, 2, 'X', 2, 2, [2,'Xöbc'], 'Y', 3,2, [2,'XYöbc']);
502 DoTest('utf8 at start - mid', 3, 2, 'X', 4, 2, [2,'öXbc'], 'Y', 5,2, [2,'öXYbc']);
503 DoTest('utf8 at start - EOL', 5, 2, 'X', 6, 2, [2,'öbcX'], 'Y', 7,2, [2,'öbcXY']);
504 CaretPEol := True;
505 DoTest('utf8 at start - EOL', 5, 2, 'X', 6, 2, [2,'öbcX'], 'Y', 7,2, [2,'öbcXY']);
506 DoTest('utf8 at start - Past', 7, 2, 'X', 8, 2, [2,'öbc X'], 'Y', 9,2, [2,'öbc XY']);
507
508 InsertFlag := False;
509 CaretPEol := False;
510 DoTest('utf8 at start - BOL', 1, 2, 'X', 2, 2, [2,'Xbc'], 'Y', 3,2, [2,'XYc']);
511 DoTest('utf8 at start - mid', 3, 2, 'X', 4, 2, [2,'öXc'], 'Y', 5,2, [2,'öXY']);
512 DoTest('utf8 at start - mid', 4, 2, 'X', 5, 2, [2,'öbX'], 'Y', 6,2, [2,'öbXY']);
513 DoTest('utf8 at start - EOL', 5, 2, 'X', 6, 2, [2,'öbcX'], 'Y', 7,2, [2,'öbcXY']);
514 CaretPEol := True;
515 DoTest('utf8 at start - EOL', 5, 2, 'X', 6, 2, [2,'öbcX'], 'Y', 7,2, [2,'öbcXY']);
516 DoTest('utf8 at start - Past', 7, 2, 'X', 8, 2, [2,'öbc X'], 'Y', 9,2, [2,'öbc XY']);
517 {%endregion}
518
519 {%region utf8 2 byte Char}
520 InsertFlag := True;
521 CaretPEol := False;
522 DoTest('utf8 at start - 2byte utf8 - BOL', 1, 2, 'Ä', 3, 2, [2,'Äöbc'], 'Ü', 5,2, [2,'ÄÜöbc']);
523 DoTest('utf8 at start - 2byte utf8 - mid', 3, 2, 'Ä', 5, 2, [2,'öÄbc'], 'Ü', 7,2, [2,'öÄÜbc']);
524 DoTest('utf8 at start - 2byte utf8 - EOL', 5, 2, 'Ä', 7, 2, [2,'öbcÄ'], 'Ü', 9,2, [2,'öbcÄÜ']);
525 CaretPEol := True;
526 DoTest('utf8 at start - 2byte utf8 - EOL', 5, 2, 'Ä', 7, 2, [2,'öbcÄ'], 'Ü', 9,2, [2,'öbcÄÜ']);
527 DoTest('utf8 at start - 2byte utf8 - Past', 7, 2, 'Ä', 9, 2, [2,'öbc Ä'], 'Ü',11,2, [2,'öbc ÄÜ']);
528
529 InsertFlag := False;
530 CaretPEol := False;
531 DoTest('utf8 at start - 2byte utf8 - BOL', 1, 2, 'Ä', 3, 2, [2,'Äbc'], 'Ü', 5,2, [2,'ÄÜc']);
532 DoTest('utf8 at start - 2byte utf8 - mid', 3, 2, 'Ä', 5, 2, [2,'öÄc'], 'Ü', 7,2, [2,'öÄÜ']);
533 DoTest('utf8 at start - 2byte utf8 - mid', 4, 2, 'Ä', 6, 2, [2,'öbÄ'], 'Ü', 8,2, [2,'öbÄÜ']);
534 DoTest('utf8 at start - 2byte utf8 - EOL', 5, 2, 'Ä', 7, 2, [2,'öbcÄ'], 'Ü', 9,2, [2,'öbcÄÜ']);
535 CaretPEol := True;
536 DoTest('utf8 at start - 2byte utf8 - EOL', 5, 2, 'Ä', 7, 2, [2,'öbcÄ'], 'Ü', 9,2, [2,'öbcÄÜ']);
537 DoTest('utf8 at start - 2byte utf8 - Past', 7, 2, 'Ä', 9, 2, [2,'öbc Ä'], 'Ü',11,2, [2,'öbc ÄÜ']);
538 {%endregion}
539
540 {%endregion}
541
542 {%region Line with tab at start}
543 {%region Normal Char}
544 InsertFlag := True;
545 CaretPEol := False;
546 // Phys start pos
547 DoTest('tab at start - BOL', 1, 3, 'X', 2, 3, [3,'X'#9'abc'], 'Y', 3,3, [3,'XY'#9'abc'], True);
548 DoTest('tab at start - after tab', 7, 3, 'X', 3, 3, [3,#9'Xabc'], 'Y', 4,3, [3,#9'XYabc'], True);
549 DoTest('tab at start - in tab', 3, 3, 'X', 2, 3, [3,'X'#9'abc'], 'Y', 3,3, [3,'XY'#9'abc'], True);
550
551 InsertFlag := False;
552 CaretPEol := False;
553 DoTest('tab at start - BOL', 1, 3, 'X', 2, 3, [3,'Xabc'], 'Y', 3,3, [3,'XYbc'], True);
554 DoTest('tab at start - after tab', 7, 3, 'X', 3, 3, [3,#9'Xbc'], 'Y', 4,3, [3,#9'XYc'], True);
555 DoTest('tab at start - in tab', 3, 3, 'X', 2, 3, [3,'Xabc'], 'Y', 3,3, [3,'XYbc'], True);
556 {%endregion}
557 {%endregion}
558
559 // TODO: 2 byte at EOL
560 // TODO Overwrite selection
561 end;
562
563 procedure TTestBasicSynEdit.TestPhysicalLogical;
564
LogPhysConvnull565 function LogPhysConv: TSynLogicalPhysicalConvertor;
566 begin
567 Result := SynEdit.ViewedTextBuffer.LogPhysConvertor;
568 end;
569
570 procedure TestPhysLog(name: string; y, x: integer;
571 expX: integer; expCol: integer = -1;
572 expXcsRight: integer = -1; expColCsRight: integer = -1;
573 expXcsLtr: integer = -1; expColCsLtr: integer = -1;
574 expXcsRtl: integer = -1; expColCsRtl: integer = -1);
575 var
576 gotX, gotCol: Integer;
577 expDef: Integer;
578 begin
579 name := name + ' y='+inttostr(y)+' x='+inttostr(x);
580
581 expDef := expX;
582 if expXcsLtr >= 0 then expDef := expXcsLtr;
583
584 gotX := SynEdit.PhysicalToLogicalPos(Point(x, y)).x;
585 AssertEquals(name+' PhysicalToLogicalPos', expDef, gotX);
586
587 gotX := SynEdit.PhysicalToLogicalCol(SynEdit.Lines[y-1], y-1, x);
588 AssertEquals(name+' PhysicalToLogicalCol', expDef, gotX);
589
590
591
592 gotX := LogPhysConv.PhysicalToLogical(y-1, x, gotCol, cspLeft);
593 AssertEquals(name+' c.PhysicalToLogical', expX, gotX);
594 if expCol >= 0 then
595 AssertEquals(name+' c.PhysicalToLogical COL', expCol, gotCol);
596
597
598 if expXcsRight >= 0 then begin
599 gotX := LogPhysConv.PhysicalToLogical(y-1, x, gotCol, cspRight);
600 AssertEquals(name+' c.PhysicalToLogical csRight', expXcsRight, gotX);
601 if expColCsRight >= 0 then
602 AssertEquals(name+' c.PhysicalToLogical csRight COL', expColCsRight, gotCol);
603 end;
604
605
606 if expXcsLtr >= 0 then begin
607 gotX := LogPhysConv.PhysicalToLogical(y-1, x, gotCol, cspFollowLtr);
608 AssertEquals(name+' c.PhysicalToLogical csLtr', expXcsLtr, gotX);
609 if expColCsLtr >= 0 then
610 AssertEquals(name+' c.PhysicalToLogical csLtr COL', expColCsLtr, gotCol);
611 end;
612
613
614 if expXcsRtl >= 0 then begin
615 gotX := LogPhysConv.PhysicalToLogical(y-1, x, gotCol, cspFollowRtl);
616 AssertEquals(name+' c.PhysicalToLogical csRtl', expXcsRtl, gotX);
617 if expColCsRtl >= 0 then
618 AssertEquals(name+' c.PhysicalToLogical csRtl COL', expColCsRtl, gotCol);
619 end;
620 end;
621
622 procedure TestLogPhys(name: string; y, x, aCol: integer;
623 expX: integer; expXcsAfter: integer = -1; expXcsLtr: integer = -1; expXcsRtl: integer = -1);
624 var gotX: Integer;
625 expDef: Integer;
626 begin
627 name := name + ' y='+inttostr(y)+' x='+inttostr(x)+' c='+IntToStr(aCol);
628
629 if aCol = 0 then begin
630 expDef := expX;
631 if expXcsLtr >= 0 then expDef := expXcsLtr; // default is now cslFollowLtr
632
633 gotX := SynEdit.LogicalToPhysicalPos(Point(x, y)).x;
634 AssertEquals(name+' LogicalToPhysicalPos', expDef, gotX);
635
636 gotX := SynEdit.LogicalToPhysicalCol(SynEdit.Lines[y-1], y-1, x);
637 AssertEquals(name+' LogicalToPhysicalCol', expDef, gotX);
638 end;
639
640 gotX := LogPhysConv.LogicalToPhysical(y-1, x, aCol, cslBefore);
641 AssertEquals(name+' c.LogicalToPhysical', expX, gotX);
642
643 if expXcsAfter >= 0 then begin
644 gotX := LogPhysConv.LogicalToPhysical(y-1, x, aCol, cslAfter);
645 AssertEquals(name+' c.LogicalToPhysical cslAfter', expXcsAfter, gotX);
646 end;
647
648 if expXcsLtr >= 0 then begin
649 gotX := LogPhysConv.LogicalToPhysical(y-1, x, aCol, cslFollowLtr);
650 AssertEquals(name+' c.LogicalToPhysical cslFollowLtr', expXcsLtr, gotX);
651 end;
652
653 if expXcsRtl >= 0 then begin
654 gotX := LogPhysConv.LogicalToPhysical(y-1, x, aCol, cslFollowRtl);
655 AssertEquals(name+' c.LogicalToPhysical cslFollowRtl', expXcsRtl, gotX);
656 end;
657 end;
658
659 begin
660 FPersistSel := False;
661 ReCreateEdit;
662 SynEdit.TabWidth := 6;
663
664 // Todo Log2Phys: test column is cut off
665
666 SetLines(['abc', ' ääX', #9'mn', 'abc'#9'de', #9'Xää.', 'ab'#9, 'あ吾' ]);
667
668 TestLogPhys('simple line (abc)', 1, 1, 0, 1);
669 TestLogPhys('simple line (abc)', 1, 2, 0, 2);
670 TestLogPhys('simple line (abc)', 1, 4, 0, 4);
671 TestLogPhys('simple line (abc)', 1, 5, 0, 5);
672 TestLogPhys('simple line (abc)', 1, 6, 0, 6);
673 TestLogPhys('line with 2byte-char', 2, 1, 0, 1);
674 TestLogPhys('line with 2byte-char', 2, 2, 0, 2);
675 TestLogPhys('line with 2byte-char', 2, 4, 0, 3); // after ae
676 TestLogPhys('line with 2byte-char', 2, 6, 0, 4);
677 TestLogPhys('line with 2byte-char', 2, 7, 0, 5);
678 TestLogPhys('line with 2byte-char', 2, 8, 0, 6);
679 TestLogPhys('line with 2byte-char', 2, 11, 0, 9);
680 TestLogPhys('line with tab (start)', 3, 1, 0, 1);
681 TestLogPhys('line with tab (start)', 3, 2, 0, 7);
682 TestLogPhys('line with tab (middle)', 4, 3, 0, 3);
683 TestLogPhys('line with tab (middle)', 4, 4, 0, 4); // before tab
684 TestLogPhys('line with tab (middle)', 4, 4, 1, 5); // inside tab
685 TestLogPhys('line with tab (middle)', 4, 4, 2, 6); // inside tab
686 TestLogPhys('line with tab (middle)', 4, 5, 0, 7); // after tab
687 TestLogPhys('line with tab (middle)', 4, 6, 0, 8);
688 TestLogPhys('line with tab (middle)', 4, 9, 0, 11);
689 TestLogPhys('line with tab (start) + 2bc', 5, 1, 0, 1);
690 TestLogPhys('line with tab (start) + 2bc', 5, 2, 0, 7);
691 TestLogPhys('line with tab (start) + 2bc', 5, 3, 0, 8);
692 TestLogPhys('line with tab (start) + 2bc', 5, 5, 0, 9);
693 TestLogPhys('line with tab (end)', 6, 3, 0, 3);
694 TestLogPhys('line with tab (end)', 6, 4, 0, 7);
695 TestLogPhys('line with tab (end)', 6, 5, 0, 8);
696 TestLogPhys('line with tab (end)', 6, 3, 1, 4);
697 TestLogPhys('line with tab (end)', 6, 3, 2, 5);
698 TestLogPhys('line with tab (end)', 6, 3, 3, 6);
699 TestLogPhys('line with double-width/3byte',7, 1, 0, 1);
700 TestLogPhys('line with double-width/3byte',7, 1, 1, 2);
701 TestLogPhys('line with double-width/3byte',7, 4, 0, 3);
702 TestLogPhys('line with double-width/3byte',7, 4, 1, 4);
703 TestLogPhys('line with double-width/3byte',7, 7, 0, 5);
704
705 TestPhysLog('simple line (abc)', 1, 1, 1);
706 TestPhysLog('simple line (abc)', 1, 2, 2);
707 TestPhysLog('simple line (abc)', 1, 4, 4);
708 TestPhysLog('simple line (abc)', 1, 5, 5);
709 TestPhysLog('simple line (abc)', 1, 6, 6);
710 TestPhysLog('line with 3byte-char', 2, 1, 1);
711 TestPhysLog('line with 3byte-char', 2, 2, 2);
712 TestPhysLog('line with 3byte-char', 2, 3, 4);
713 TestPhysLog('line with 3byte-char', 2, 4, 6);
714 TestPhysLog('line with 3byte-char', 2, 5, 7);
715 TestPhysLog('line with 3byte-char', 2, 6, 8);
716 TestPhysLog('line with 3byte-char', 2, 7, 9);
717 TestPhysLog('line with tab (start)', 3, 1, 1);
718 TestPhysLog('line with tab (start)', 3, 2, 1);
719 TestPhysLog('line with tab (start)', 3, 5, 1);
720 TestPhysLog('line with tab (start)', 3, 6, 1);
721 TestPhysLog('line with tab (start)', 3, 7, 2);
722 TestPhysLog('line with tab (start)', 3, 8, 3);
723 TestPhysLog('line with tab (start)', 3, 9, 4);
724 TestPhysLog('line with tab (start)', 3, 11, 6);
725 TestPhysLog('line with double-width/3byte', 7, 1, 1, 0);
726 TestPhysLog('line with double-width/3byte', 7, 2, 1, 1);
727 TestPhysLog('line with double-width/3byte', 7, 3, 4, 0);
728 TestPhysLog('line with double-width/3byte', 7, 4, 4, 1);
729 TestPhysLog('line with double-width/3byte', 7, 5, 7, 0);
730
731 //abc def ghi // 2bytes per char
732
733 (* Order in String "123" / Order on Screen "321"
734 LogicalToPhys
735 Log = 1
736 <|321 L2p (csLeft) => 1 // Log 1 is after it's LEFT neighbour (BOL)
737 321<| L2p (csRight) => 4 // Log 1 is before it's RIGHT neighbour (char "1") // logical right, byte order in string
738 Log = 4
739 |>321 L2p (csLeft) => 1 // Log 4 is after it's LEFT neighbour (char "3") // logical left, byte order in string
740 321|> L2p (csRight) => 4 // Log 4 is before it's RIGHT neighbour (EOL)
741
742 PhysToLog:
743 Phys = 1
744 <|321 L2p (csLeft) => 1
745 |>321 L2p (csRight) => 4
746 Phys = 4
747 321<| L2p (csLeft) => 1
748 321|> L2p (csRight) => 4
749
750 *)
751
752 SetLines(['شىه ايغ عتل', 'ABCشىه ايغ عتلDEF', 'abcشىه ايغ عتل', 'شىه ايغ عتلdef', '']);
753
754 // B, A, L, R
755 TestLogPhys('empty line', 5, 1, 0, 1, 1, 1, 1);
756 TestLogPhys('empty line', 5, 2, 0, 2, 2, 2, 2);
757
758 TestLogPhys('bidi line (arab only)', 1, 1, 0, 1, 12, 1, 12);
759 TestLogPhys('bidi line (arab only)', 1, 3, 0, 11, 11, 11, 11);
760 TestLogPhys('bidi line (arab only)', 1, 5, 0, 10, 10, 10, 10);
761 TestLogPhys('bidi line (arab only)', 1, 7, 0, 9, 9, 9, 9);
762 TestLogPhys('bidi line (arab only)', 1, 8, 0, 8, 8, 8, 8); // after space
763 TestLogPhys('bidi line (arab only)', 1, 15, 0, 4, 4, 4, 4); // after space
764 TestLogPhys('bidi line (arab only)', 1, 19, 0, 2, 2, 2, 2);
765 TestLogPhys('bidi line (arab only)', 1, 21, 0, 1, 12, 12, 1); // at EOL
766 TestLogPhys('bidi line (arab only)', 1, 22, 0, 13, 13, 13, 13); // past eol
767 TestLogPhys('bidi line (arab only)', 1, 23, 0, 14, 14, 14, 14);
768
769 TestLogPhys('bidi line (mixed arab/latin)', 2, 1, 0, 1, 1, 1, 1);
770 TestLogPhys('bidi line (mixed arab/latin)', 2, 4, 0, 4, 15, 4, 15); // after C
771 TestLogPhys('bidi line (mixed arab/latin)', 2, 6, 0, 14, 14, 14, 14); // 1 into arabic
772 TestLogPhys('bidi line (mixed arab/latin)', 2, 22, 0, 5, 5, 5, 5); // 1 before end arabic
773 TestLogPhys('bidi line (mixed arab/latin)', 2, 24, 0, 4, 15, 15, 4); // at end arabic
774 TestLogPhys('bidi line (mixed arab/latin)', 2, 25, 0, 16, 16, 16, 16); // after D
775 TestLogPhys('bidi line (mixed arab/latin)', 2, 27, 0, 18, 18, 18, 18); // at eol
776 TestLogPhys('bidi line (mixed arab/latin)', 2, 28, 0, 19, 19, 19, 19); // after eol
777
778 // Lft Rght LTR RTL
779 TestPhysLog('empty line', 5, 1, 1, 0, 1, 0, 1, 0, 1, 0);
780 TestPhysLog('empty line', 5, 2, 2, 0, 2, 0, 2, 0, 2, 0);
781
782 TestPhysLog('bidi line (arab only)', 1, 1, 1, 0, 21, 0, 1, 0, 21, 0);
783 TestPhysLog('bidi line (arab only)', 1, 2, 19, 0, 19, 0, 19, 0, 19, 0);
784 TestPhysLog('bidi line (arab only)', 1, 3, 17, 0, 17, 0, 17, 0, 17, 0);
785 TestPhysLog('bidi line (arab only)', 1, 4, 15, 0, 15, 0, 15, 0, 15, 0); // before space
786 TestPhysLog('bidi line (arab only)', 1, 5, 14, 0, 14, 0, 14, 0, 14, 0); // after space
787 TestPhysLog('bidi line (arab only)', 1, 10, 5, 0, 5, 0, 5, 0, 5, 0);
788 TestPhysLog('bidi line (arab only)', 1, 11, 3, 0, 3, 0, 3, 0, 3, 0);
789 TestPhysLog('bidi line (arab only)', 1, 12, 1, 0, 21, 0, 21, 0, 1, 0); // at eol
790 TestPhysLog('bidi line (arab only)', 1, 13, 22, 0, 22, 0, 22, 0, 22, 0);
791 TestPhysLog('bidi line (arab only)', 1, 14, 23, 0, 23, 0, 23, 0, 23, 0);
792
793 TestPhysLog('bidi line (mixed arab/latin)',2, 1, 1, 0, 1, 0, 1, 0, 1, 0);
794 TestPhysLog('bidi line (mixed arab/latin)',2, 4, 4, 0, 24, 0, 4, 0, 24, 0);
795 TestPhysLog('bidi line (mixed arab/latin)',2, 15, 4, 0, 24, 0, 24, 0, 4, 0);
796 end;
797
798 procedure TTestBasicSynEdit.TestPhysicalLogicalCaretMove;
799 begin
800 SetLines([
801 '//',
802 '// X あsf//',
803 '//X あsf//',
804 '//',
805 ''
806 ]);
807
808 SynEdit.Options := SynEdit.Options + [eoKeepCaretX] - [eoScrollPastEol];
809
810 SetCaretPhys(8, 2);
811 TestIsCaretPhys('(1st)', 8, 2);
812 TestIsCaret('(1st)', 9, 2);
813
814 SynEdit.CommandProcessor(ecDown, '', nil);
815 TestIsCaretPhys('(1st)', 7, 3);
816 TestIsCaret('(1st)', 9, 3);
817 SynEdit.CommandProcessor(ecDown, '', nil);
818 TestIsCaretPhys('(1st)', 3, 4);
819
820 SynEdit.CommandProcessor(ecUp, '', nil);
821 TestIsCaretPhys('(1st)', 7, 3);
822 TestIsCaret('(1st)', 9, 3);
823 SynEdit.CommandProcessor(ecUp, '', nil);
824 TestIsCaretPhys('(1st)', 8, 2);
825 TestIsCaret('(1st)', 9, 2);
826
827
828 end;
829
830 procedure TTestBasicSynEdit.TestLogicalAdjust;
831 var
832 tb: TSynEditStrings;
833 begin
834 FPersistSel := False;
835 tb := SynEdit.TextBuffer;
836 // #$CC#$81 Combining
837 AssertEquals('LogicPosIsAtChar 1 ', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 1)); // a
838 AssertEquals('LogicPosIsAtChar 2 ', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 2)); // ü
839 AssertEquals('LogicPosIsAtChar 3 ', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 3)); // mid ü
840 AssertEquals('LogicPosIsAtChar 4 ', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 4)); // b
841 AssertEquals('LogicPosIsAtChar 5 ', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 5)); // AT Combining
842 AssertEquals('LogicPosIsAtChar 6 ', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 6)); // mid Combining
843 AssertEquals('LogicPosIsAtChar 7 ', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 7)); // c
844
845 AssertEquals('LogicPosIsAtChar 1 C', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 1, [lpStopAtCodePoint])); // a
846 AssertEquals('LogicPosIsAtChar 2 C', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 2, [lpStopAtCodePoint])); // ü
847 AssertEquals('LogicPosIsAtChar 3 C', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 3, [lpStopAtCodePoint])); // mid ü
848 AssertEquals('LogicPosIsAtChar 4 C', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 4, [lpStopAtCodePoint])); // b
849 AssertEquals('LogicPosIsAtChar 5 C', True ,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 5, [lpStopAtCodePoint])); // AT Combining
850 AssertEquals('LogicPosIsAtChar 6 C', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 6, [lpStopAtCodePoint])); // mid Combining
851 AssertEquals('LogicPosIsAtChar 7 C', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 7, [lpStopAtCodePoint])); // c
852
853 // broken text
854 AssertEquals('LogicPosIsAtChar 1 Comb', True, tb.LogicPosIsAtChar(#$CC#$81'c', 1, []));
855 AssertEquals('LogicPosIsAtChar 1 Comb C', True, tb.LogicPosIsAtChar(#$CC#$81'c', 1, [lpStopAtCodePoint]));
856
857
858 AssertEquals('LogicPosAdjustToChar 1 ', 1, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 1)); // a
859 AssertEquals('LogicPosAdjustToChar 2 ', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 2)); // ü
860 AssertEquals('LogicPosAdjustToChar 3 ', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 3)); // mid ü
861 AssertEquals('LogicPosAdjustToChar 4 ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 4)); // b
862 AssertEquals('LogicPosAdjustToChar 5 ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 5)); // AT Combining
863 AssertEquals('LogicPosAdjustToChar 6 ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 6)); // mid Combining
864 AssertEquals('LogicPosAdjustToChar 7 ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 7)); // c
865
866 AssertEquals('LogicPosAdjustToChar 1N ', 1, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 1, [lpAdjustToNext])); // a
867 AssertEquals('LogicPosAdjustToChar 2N ', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 2, [lpAdjustToNext])); // ü
868 AssertEquals('LogicPosAdjustToChar 3N ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 3, [lpAdjustToNext])); // mid ü
869 AssertEquals('LogicPosAdjustToChar 4N ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 4, [lpAdjustToNext])); // b
870 AssertEquals('LogicPosAdjustToChar 5N ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 5, [lpAdjustToNext])); // AT Combining
871 AssertEquals('LogicPosAdjustToChar 6N ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 6, [lpAdjustToNext])); // mid Combining
872 AssertEquals('LogicPosAdjustToChar 7N ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 7, [lpAdjustToNext])); // ü
873 AssertEquals('LogicPosAdjustToChar 8N ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 8, [lpAdjustToNext])); // mid ü
874 AssertEquals('LogicPosAdjustToChar 8NE', 9, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 8, [lpAdjustToNext, lpAllowPastEol])); // mid ü
875
876 AssertEquals('LogicPosAdjustToChar 1 C', 1, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 1, [lpStopAtCodePoint])); // a
877 AssertEquals('LogicPosAdjustToChar 2 C', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 2, [lpStopAtCodePoint])); // ü
878 AssertEquals('LogicPosAdjustToChar 3 C', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 3, [lpStopAtCodePoint])); // mid ü
879 AssertEquals('LogicPosAdjustToChar 4 C', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 4, [lpStopAtCodePoint])); // b
880 AssertEquals('LogicPosAdjustToChar 5 C', 5, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 5, [lpStopAtCodePoint])); // AT Combining
881 AssertEquals('LogicPosAdjustToChar 6 C', 5, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 6, [lpStopAtCodePoint])); // mid Combining
882 AssertEquals('LogicPosAdjustToChar 7 C', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 7, [lpStopAtCodePoint])); // c
883
884 AssertEquals('LogicPosAdjustToChar 1N C', 1, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 1, [lpStopAtCodePoint, lpAdjustToNext])); // a
885 AssertEquals('LogicPosAdjustToChar 2N C', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 2, [lpStopAtCodePoint, lpAdjustToNext])); // ü
886 AssertEquals('LogicPosAdjustToChar 3N C', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 3, [lpStopAtCodePoint, lpAdjustToNext])); // mid ü
887 AssertEquals('LogicPosAdjustToChar 4N C', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 4, [lpStopAtCodePoint, lpAdjustToNext])); // b
888 AssertEquals('LogicPosAdjustToChar 5N C', 5, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 5, [lpStopAtCodePoint, lpAdjustToNext])); // AT Combining
889 AssertEquals('LogicPosAdjustToChar 6N C', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 6, [lpStopAtCodePoint, lpAdjustToNext])); // mid Combining
890 AssertEquals('LogicPosAdjustToChar 7N C', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 7, [lpStopAtCodePoint, lpAdjustToNext])); // ü
891 AssertEquals('LogicPosAdjustToChar 8N C', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 8, [lpStopAtCodePoint, lpAdjustToNext])); // mid ü
892 AssertEquals('LogicPosAdjustToChar 8NE C', 9, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 8, [lpStopAtCodePoint, lpAdjustToNext, lpAllowPastEol])); // mid ü
893
894 // broken text
895 AssertEquals('LogicPosAdjustToChar 1 Comb', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 1, []));
896 AssertEquals('LogicPosAdjustToChar 2 Comb', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 2, []));
897 AssertEquals('LogicPosAdjustToChar 1 Comb N', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 1, [lpAdjustToNext]));
898 AssertEquals('LogicPosAdjustToChar 2 Comb N', 3, tb.LogicPosAdjustToChar(#$CC#$81'c', 2, [lpAdjustToNext]));
899 AssertEquals('LogicPosAdjustToChar 1 Comb', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 1, [lpStopAtCodePoint]));
900 AssertEquals('LogicPosAdjustToChar 2 Comb', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 2, [lpStopAtCodePoint]));
901 AssertEquals('LogicPosAdjustToChar 1 Comb N', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 1, [lpStopAtCodePoint, lpAdjustToNext]));
902 AssertEquals('LogicPosAdjustToChar 2 Comb N', 3, tb.LogicPosAdjustToChar(#$CC#$81'c', 2, [lpStopAtCodePoint, lpAdjustToNext]));
903
904
905 AssertEquals('LogicPosAddChars 1, 1 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, 1)); // a
906 AssertEquals('LogicPosAddChars 2, 1 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, 1)); // ü
907 AssertEquals('LogicPosAddChars 3, 1 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, 1)); // mid ü
908 AssertEquals('LogicPosAddChars 4, 1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, 1)); // b
909 AssertEquals('LogicPosAddChars 5, 1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, 1)); // comb
910 AssertEquals('LogicPosAddChars 6, 1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, 1)); // mid
911 AssertEquals('LogicPosAddChars 7, 1 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, 1)); // c
912 AssertEquals('LogicPosAddChars 8, 1 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 1)); // ü
913 AssertEquals('LogicPosAddChars 9, 1 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 1)); // mid ü
914 AssertEquals('LogicPosAddChars 10, 1 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 1)); // ü
915 AssertEquals('LogicPosAddChars 11, 1 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 1)); // mid ü
916 AssertEquals('LogicPosAddChars 10, 1 E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 1, [lpAllowPastEol])); // ü
917 AssertEquals('LogicPosAddChars 11, 1 E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 1, [lpAllowPastEol])); // mid ü
918
919 AssertEquals('LogicPosAddChars 1, 2 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, 2)); // a
920 AssertEquals('LogicPosAddChars 2, 2 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, 2)); // ü
921 AssertEquals('LogicPosAddChars 3, 2 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, 2)); // mid ü
922 AssertEquals('LogicPosAddChars 4, 2 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, 2)); // b
923 AssertEquals('LogicPosAddChars 5, 2 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, 2)); // comb
924 AssertEquals('LogicPosAddChars 6, 2 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, 2)); // mid
925 AssertEquals('LogicPosAddChars 7, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, 2)); // c
926 AssertEquals('LogicPosAddChars 8, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 2)); // ü
927 AssertEquals('LogicPosAddChars 9, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 2)); // mid ü
928 AssertEquals('LogicPosAddChars 10, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 2)); // ü
929 AssertEquals('LogicPosAddChars 11, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 2)); // mid ü
930 AssertEquals('LogicPosAddChars 8, 2 E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 2, [lpAllowPastEol])); // ü
931 AssertEquals('LogicPosAddChars 9, 2 E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 2, [lpAllowPastEol])); // mid ü
932 AssertEquals('LogicPosAddChars 10, 2 E',13, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 2, [lpAllowPastEol])); // ü
933 AssertEquals('LogicPosAddChars 11, 2 E',13, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 2, [lpAllowPastEol])); // mid ü
934
935 AssertEquals('LogicPosAddChars 1, -1 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, -1)); // a
936 AssertEquals('LogicPosAddChars 2, -1 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, -1)); // ü
937 //AssertEquals('LogicPosAddChars 3, -1 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, -1)); // mid ü
938 AssertEquals('LogicPosAddChars 4, -1 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, -1)); // b
939 //AssertEquals('LogicPosAddChars 5, -1 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, -1)); // comb
940 //AssertEquals('LogicPosAddChars 6, -1 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, -1)); // mid
941 AssertEquals('LogicPosAddChars 7, -1 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, -1)); // c
942 AssertEquals('LogicPosAddChars 8, -1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, -1)); // ü
943 //AssertEquals('LogicPosAddChars 9, -1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, -1)); // mid ü
944 AssertEquals('LogicPosAddChars 10, -1 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, -1)); // ü
945 //AssertEquals('LogicPosAddChars 11, -1 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, -1)); // mid ü
946
947 AssertEquals('LogicPosAddChars 1, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, -2)); // a
948 AssertEquals('LogicPosAddChars 2, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, -2)); // ü
949 //AssertEquals('LogicPosAddChars 3, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, -2)); // mid ü
950 AssertEquals('LogicPosAddChars 4, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, -2)); // b
951 //AssertEquals('LogicPosAddChars 5, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, -2)); // comb
952 //AssertEquals('LogicPosAddChars 6, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, -2)); // mid
953 AssertEquals('LogicPosAddChars 7, -2 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, -2)); // c
954 AssertEquals('LogicPosAddChars 8, -2 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, -2)); // ü
955 //AssertEquals('LogicPosAddChars 9, -2 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, -2)); // mid ü
956 AssertEquals('LogicPosAddChars 10, -2 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, -2)); // ü
957 //AssertEquals('LogicPosAddChars 11, -2 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, -2)); // mid ü
958
959
960 AssertEquals('LogicPosAddChars 1, 1C ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, 1, [lpStopAtCodePoint])); // a
961 AssertEquals('LogicPosAddChars 2, 1C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, 1, [lpStopAtCodePoint])); // ü
962 AssertEquals('LogicPosAddChars 3, 1C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, 1, [lpStopAtCodePoint])); // mid ü
963 AssertEquals('LogicPosAddChars 4, 1C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, 1, [lpStopAtCodePoint])); // b
964 AssertEquals('LogicPosAddChars 5, 1C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, 1, [lpStopAtCodePoint])); // comb
965 AssertEquals('LogicPosAddChars 6, 1C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, 1, [lpStopAtCodePoint])); // mid
966 AssertEquals('LogicPosAddChars 7, 1C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, 1, [lpStopAtCodePoint])); // c
967 AssertEquals('LogicPosAddChars 8, 1C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 1, [lpStopAtCodePoint])); // ü
968 AssertEquals('LogicPosAddChars 9, 1C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 1, [lpStopAtCodePoint])); // mid ü
969 AssertEquals('LogicPosAddChars 10, 1C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 1, [lpStopAtCodePoint])); // ü
970 AssertEquals('LogicPosAddChars 11, 1C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 1, [lpStopAtCodePoint])); // mid ü
971 AssertEquals('LogicPosAddChars 10, 1C E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 1, [lpAllowPastEol, lpStopAtCodePoint])); // ü
972 AssertEquals('LogicPosAddChars 11, 1C E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 1, [lpAllowPastEol, lpStopAtCodePoint])); // mid ü
973
974 AssertEquals('LogicPosAddChars 1, 2C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, 2, [lpStopAtCodePoint])); // a
975 AssertEquals('LogicPosAddChars 2, 2C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, 2, [lpStopAtCodePoint])); // ü
976 AssertEquals('LogicPosAddChars 3, 2C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, 2, [lpStopAtCodePoint])); // mid ü
977 AssertEquals('LogicPosAddChars 4, 2C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, 2, [lpStopAtCodePoint])); // b
978 AssertEquals('LogicPosAddChars 5, 2C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, 2, [lpStopAtCodePoint])); // comb
979 AssertEquals('LogicPosAddChars 6, 2C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, 2, [lpStopAtCodePoint])); // mid
980 AssertEquals('LogicPosAddChars 7, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, 2, [lpStopAtCodePoint])); // c
981 AssertEquals('LogicPosAddChars 8, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 2, [lpStopAtCodePoint])); // ü
982 AssertEquals('LogicPosAddChars 9, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 2, [lpStopAtCodePoint])); // mid ü
983 AssertEquals('LogicPosAddChars 10, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 2, [lpStopAtCodePoint])); // ü
984 AssertEquals('LogicPosAddChars 11, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 2, [lpStopAtCodePoint])); // mid ü
985 AssertEquals('LogicPosAddChars 8, 2C E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 2, [lpAllowPastEol, lpStopAtCodePoint])); // ü
986 AssertEquals('LogicPosAddChars 9, 2C E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 2, [lpAllowPastEol, lpStopAtCodePoint])); // mid ü
987 AssertEquals('LogicPosAddChars 10, 2C E',13, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 2, [lpAllowPastEol, lpStopAtCodePoint])); // ü
988 AssertEquals('LogicPosAddChars 11, 2C E',13, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 2, [lpAllowPastEol, lpStopAtCodePoint])); // mid ü
989
990 AssertEquals('LogicPosAddChars 1, -1C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, -1, [lpStopAtCodePoint])); // a
991 AssertEquals('LogicPosAddChars 2, -1C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, -1, [lpStopAtCodePoint])); // ü
992 //AssertEquals('LogicPosAddChars 3, -1C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, -1, [lpStopAtCodePoint])); // mid ü
993 AssertEquals('LogicPosAddChars 4, -1C ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, -1, [lpStopAtCodePoint])); // b
994 AssertEquals('LogicPosAddChars 5, -1C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, -1, [lpStopAtCodePoint])); // comb
995 //AssertEquals('LogicPosAddChars 6, -1C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, -1, [lpStopAtCodePoint])); // mid
996 AssertEquals('LogicPosAddChars 7, -1C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, -1, [lpStopAtCodePoint])); // c
997 AssertEquals('LogicPosAddChars 8, -1C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, -1, [lpStopAtCodePoint])); // ü
998 //AssertEquals('LogicPosAddChars 9, -1C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, -1, [lpStopAtCodePoint])); // mid ü
999 AssertEquals('LogicPosAddChars 10, -1C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, -1, [lpStopAtCodePoint])); // ü
1000 //AssertEquals('LogicPosAddChars 11, -1C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, -1, [lpStopAtCodePoint])); // mid ü
1001
1002 AssertEquals('LogicPosAddChars 1, -2C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, -2, [lpStopAtCodePoint])); // a
1003 AssertEquals('LogicPosAddChars 2, -2C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, -2, [lpStopAtCodePoint])); // ü
1004 //AssertEquals('LogicPosAddChars 3, -2C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, -2, [lpStopAtCodePoint])); // mid ü
1005 AssertEquals('LogicPosAddChars 4, -2C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, -2, [lpStopAtCodePoint])); // b
1006 AssertEquals('LogicPosAddChars 5, -2C ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, -2, [lpStopAtCodePoint])); // comb
1007 //AssertEquals('LogicPosAddChars 6, -2C ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, -2, [lpStopAtCodePoint])); // mid
1008 AssertEquals('LogicPosAddChars 7, -2C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, -2, [lpStopAtCodePoint])); // c
1009 AssertEquals('LogicPosAddChars 8, -2C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, -2, [lpStopAtCodePoint])); // ü
1010 //AssertEquals('LogicPosAddChars 9, -2C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, -2, [lpStopAtCodePoint])); // mid ü
1011 AssertEquals('LogicPosAddChars 10, -2C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, -2, [lpStopAtCodePoint])); // ü
1012 //AssertEquals('LogicPosAddChars 11, -2C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, -2, [lpStopAtCodePoint])); // mid ü
1013
1014
1015
1016 end;
1017
1018 procedure TTestBasicSynEdit.TestCaretObject;
1019 var
1020 TestCaret, TestCaret2: TSynEditCaret;
1021 TestOrder: Integer;
1022 UseAdjustToNextChar, UseIncAdjustToNextChar: Boolean;
1023 UseAllowPastEOL, UseIncAllowPastEOL: Boolean;
1024 UseKeepCaretX: Boolean;
1025 UseLock: Boolean;
1026 UseChangeOnTouch: Boolean;
1027 UseIncAutoMoveOnEdit: Boolean;
1028 UseSkipTabs: Boolean;
1029 UseMaxLeft: Boolean;
1030
1031
1032 procedure CheckPhys(AName: String; ExpY, ExpX: Integer);
1033 procedure CheckEach;
1034 begin
1035 AssertEquals(AName + 'Phys.Y', ExpY, TestCaret.LinePos);
1036 AssertEquals(AName + 'Phys.X', ExpX, TestCaret.CharPos);
1037 end;
1038 procedure CheckPoint;
1039 begin
1040 AssertEquals(AName + 'Phys.XY.Y', ExpY, TestCaret.LineCharPos.Y);
1041 AssertEquals(AName + 'Phys.XY.X', ExpX, TestCaret.LineCharPos.x);
1042 end;
1043 begin
1044 if ExpX <= 0 then exit;
1045 AName := BaseTestName + ' ' + AName;
1046 if (TestOrder and 1) = 0 then begin
1047 CheckEach;
1048 CheckPoint;
1049 end else begin
1050 CheckPoint;
1051 CheckEach;
1052 end;
1053 end;
1054 procedure CheckIsAtChar(AName: String; ExpY, ExpX: Integer);
1055 begin
1056 if ExpX <= 0 then exit;
1057 AName := BaseTestName + ' ' + AName;
1058 if (TestOrder and 1) = 1 then exit; // Only one order
1059 AssertEquals(AName + 'IsAtLineChar', True, TestCaret.IsAtLineChar(point(ExpX, ExpY)));
1060 AssertEquals(AName + 'NOT IsAtLineChar', False, TestCaret.IsAtLineChar(point(ExpX+1, ExpY)));
1061 end;
1062
1063 procedure CheckLog(AName: String; ExpY, ExpX, ExpOffs: Integer);
1064 procedure CheckEach;
1065 begin
1066 AssertEquals(AName + 'Log.Y', ExpY, TestCaret.LinePos);
1067 AssertEquals(AName + 'Log.X', ExpX, TestCaret.BytePos);
1068 AssertEquals(AName + 'Log.Offs', ExpOffs, TestCaret.BytePosOffset);
1069 end;
1070 procedure CheckPoint;
1071 begin
1072 AssertEquals(AName + 'Log.XY.Y', ExpY, TestCaret.LineBytePos.y);
1073 AssertEquals(AName + 'Log.XY.X', ExpX, TestCaret.LineBytePos.x);
1074 end;
1075 begin
1076 if ExpX <= 0 then exit;
1077 AName := BaseTestName + ' ' + AName;
1078 AName := BaseTestName + ' ' + AName;
1079 if (TestOrder and 1) = 0 then begin
1080 CheckEach;
1081 CheckPoint;
1082 end else begin
1083 CheckPoint;
1084 CheckEach;
1085 end;
1086 end;
1087 procedure CheckIsAtByte(AName: String; ExpY, ExpX, ExpOffs: Integer);
1088 begin
1089 if ExpX <= 0 then exit;
1090 AName := BaseTestName + ' ' + AName;
1091 if (TestOrder and 1) = 1 then exit; // Only one order
1092 AssertEquals(AName + 'IsAtLineChar', True, TestCaret.IsAtLineByte(point(ExpX, ExpY), ExpOffs));
1093 AssertEquals(AName + 'NOT IsAtLineByte', False, TestCaret.IsAtLineByte(point(ExpX+1, ExpY), ExpOffs));
1094 if ExpOffs = 0 then begin
1095 AssertEquals(AName + 'IsAtLineChar', True, TestCaret.IsAtLineByte(point(ExpX, ExpY)));
1096 AssertEquals(AName + 'NOT IsAtLineByte', False, TestCaret.IsAtLineByte(point(ExpX+1, ExpY)));
1097 AssertEquals(AName + 'NOT IsAtLineByte', False, TestCaret.IsAtLineByte(point(ExpX, ExpY), 1));
1098 end;
1099 end;
1100
1101
1102 procedure CheckLogPhys(AName: String; ExpY, ExpX, ExpLogX, ExpOffs: Integer);
1103 procedure CheckAtPos;
1104 procedure CheckAtPosChar;
1105 begin
1106 TestCaret2.LineBytePos := point(1, 1);
1107 TestCaret2.LineCharPos := point(ExpX, ExpY);
1108 AssertTrue(AName + 'IsAtPos(Char)', TestCaret.IsAtPos(TestCaret2));
1109 TestCaret2.LineCharPos := point(1, ExpY-1);
1110 AssertFalse(AName + 'not IsAtPos(Char)', TestCaret.IsAtPos(TestCaret2));
1111 end;
1112 procedure CheckAtPosByte;
1113 begin
1114 TestCaret2.LineCharPos := point(1, 1);
1115 TestCaret2.LineBytePos := point(ExpLogX, ExpY);
1116 //TestCaret2.BytePosOffset := ExpOffs;
1117 if ExpOffs = 0 then // TODO
1118 AssertTrue(AName + 'IsAtPos(Byte)', TestCaret.IsAtPos(TestCaret2));
1119 TestCaret2.LineBytePos := point(1, ExpY-1);
1120 AssertFalse(AName + 'not IsAtPos(Byte)', TestCaret.IsAtPos(TestCaret2));
1121 end;
1122 begin
1123 if ((TestOrder and 1) = 0) and (ExpX > 0) then CheckAtPosChar;
1124 if (ExpLogX > 0) then CheckAtPosByte;
1125 if ((TestOrder and 1) = 1) and (ExpX > 0) then CheckAtPosChar;
1126 end;
1127 procedure CheckPos;
1128 begin
1129 if (TestOrder and 2) = 0 then begin
1130 if ExpX > 0 then CheckPhys(AName, ExpY, ExpX);
1131 if ExpLogX > 0 then CheckLog (AName, ExpY, ExpLogX, ExpOffs);
1132 end else begin
1133 if ExpLogX > 0 then CheckLog (AName, ExpY, ExpLogX, ExpOffs);
1134 if ExpX > 0 then CheckPhys(AName, ExpY, ExpX);
1135 end;
1136 end;
1137 begin
1138 if (TestOrder and 8) = 8 then
1139 CheckAtPos;
1140
1141 if (TestOrder and 4) = 4 then
1142 CheckPos;
1143
1144 if (TestOrder and 2) = 2 then begin
1145 CheckIsAtChar(AName, ExpY, ExpX);
1146 CheckIsAtByte(AName, ExpY, ExpLogX, ExpOffs);
1147 end else begin
1148 CheckIsAtByte(AName, ExpY, ExpLogX, ExpOffs);
1149 CheckIsAtChar(AName, ExpY, ExpX);
1150 end;
1151
1152 if (TestOrder and 4) = 0 then
1153 CheckPos;
1154
1155 if (TestOrder and 8) = 0 then
1156 CheckAtPos;
1157 end;
1158
1159
1160 Procedure DoOneTest(AName: String; AY, AX, ALogX, ALogOffs: Integer;
1161 ExpY, ExpX, ExpLogX, ExpLogOffs: Integer;
1162 // X,LogX,LogOffs, [X,LogX,LogOffs]
1163 AMoveHorizNext: array of integer; AMoveHorizPrev: array of integer;
1164 ExpMoveHorizFalse: Boolean = False;
1165 ALineForKeepX: Integer = -1; ExpNotKeptX: Integer = -1; ExpNotKeptLogX: Integer = -1
1166 );
1167 procedure DoOneSetLine(Y: Integer);
1168 begin
1169 if UseLock then TestCaret.Lock;
1170 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1171 TestCaret.LinePos := Y;
1172 if UseLock then TestCaret.Unlock;
1173 end;
1174 procedure DoOneSetChar(Y, X: Integer; ChangeToLine: Integer = -1);
1175 begin
1176 if UseLock then TestCaret.Lock;
1177 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1178 TestCaret.LineCharPos := point(X, Y);
1179 if ChangeToLine > 0 then TestCaret.LinePos := ChangeToLine;
1180 if UseLock then TestCaret.Unlock;
1181 end;
1182 procedure DoOneSetByte(Y, X, {%H-}O: Integer; ChangeToLine: Integer = -1);
1183 begin
1184 if UseLock then TestCaret.Lock;
1185 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1186 TestCaret.LineBytePos := point(X, Y);
1187 //TestCaret.BytePosOffset := O;
1188 if ChangeToLine > 0 then TestCaret.LinePos := ChangeToLine;
1189 if UseLock then TestCaret.Unlock;
1190 end;
1191 procedure DoOneMoveHoriz(C: Integer);
1192 begin
1193 if UseLock then TestCaret.Lock;
1194 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1195 AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(C));
1196 if UseLock then TestCaret.Unlock;
1197 end;
1198 procedure DoOneMoveHorizFromChar(C, Y, X: Integer);
1199 begin
1200 if UseLock then TestCaret.Lock;
1201 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1202 TestCaret.LineCharPos := point(X, Y);
1203 AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(C));
1204 if UseLock then TestCaret.Unlock;
1205 end;
1206 procedure DoOneMoveHorizFromByte(C, Y, X, {%H-}O: Integer);
1207 begin
1208 if UseLock then TestCaret.Lock;
1209 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1210 TestCaret.LineBytePos := point(X, Y);
1211 //TestCaret.BytePosOffset := O;
1212 AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(C));
1213 if UseLock then TestCaret.Unlock;
1214 end;
1215 begin
1216 DoOneSetChar(AY, AX);
1217 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1218
1219 // KeepX
1220 if (ALineForKeepX > 0) and UseKeepCaretX then begin
1221 if (TestOrder and 4) = 4 then begin
1222 TestCaret.LineCharPos := point(1, 1);
1223 if (TestOrder and 6) = 4 then
1224 TestCaret.LineCharPos := point(AX, AY);
1225 end;
1226
1227 if (TestOrder and 6) = 6
1228 then DoOneSetChar(AY, AX, ALineForKeepX)
1229 else DoOneSetLine(ALineForKeepX);
1230 CheckLogPhys(AName + ' from CharPos', ALineForKeepX, ExpNotKeptX, ExpNotKeptLogX, 0);
1231 if ExpNotKeptX < 0 then AssertFalse(AName + '(char) keepx moved (c)', ExpX = TestCaret.CharPos);
1232 if ExpNotKeptLogX < 0 then AssertFalse(AName + '(char) keepx moved (b)', ExpLogX = TestCaret.BytePos);
1233
1234 DoOneSetLine(AY);
1235 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1236 end;
1237
1238 if length(AMoveHorizNext) >= 3 then begin
1239 DoOneMoveHorizFromChar(1, AY, AX);
1240 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[0], AMoveHorizNext[1], AMoveHorizNext[2]);
1241
1242 if not ExpMoveHorizFalse then begin
1243 DoOneMoveHoriz(-1);
1244 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1245 end;
1246 end;
1247 if length(AMoveHorizNext) >= 6 then begin
1248 TestCaret.LineCharPos := point(AX, AY);
1249 if UseLock then TestCaret.Lock;
1250 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1251 AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(1));
1252 AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(1));
1253 if UseLock then TestCaret.Unlock;
1254 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[3], AMoveHorizNext[4], AMoveHorizNext[5]);
1255
1256 if not ExpMoveHorizFalse then begin
1257 DoOneMoveHoriz(-1);
1258 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[0], AMoveHorizNext[1], AMoveHorizNext[2]);
1259 DoOneMoveHoriz(-1);
1260 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1261
1262 TestCaret.LineCharPos := point(AX, AY);
1263 DoOneMoveHoriz(2);
1264 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[3], AMoveHorizNext[4], AMoveHorizNext[5]);
1265 end;
1266 end;
1267
1268 if length(AMoveHorizPrev) >= 3 then begin
1269 DoOneMoveHorizFromChar(-1, AY, AX);
1270 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[0], AMoveHorizPrev[1], AMoveHorizPrev[2]);
1271
1272 if not ExpMoveHorizFalse then begin
1273 DoOneMoveHoriz(1);
1274 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1275 end;
1276 end;
1277 if length(AMoveHorizPrev) >= 6 then begin
1278 TestCaret.LineCharPos := point(AX, AY);
1279 if UseLock then TestCaret.Lock;
1280 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1281 AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(-1));
1282 AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(-1));
1283 if UseLock then TestCaret.Unlock;
1284 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[3], AMoveHorizPrev[4], AMoveHorizPrev[5]);
1285
1286 if not ExpMoveHorizFalse then begin
1287 DoOneMoveHoriz(1);
1288 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[0], AMoveHorizPrev[1], AMoveHorizPrev[2]);
1289 DoOneMoveHoriz(1);
1290 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1291
1292 TestCaret.LineCharPos := point(AX, AY);
1293 DoOneMoveHoriz(-2);
1294 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[3], AMoveHorizPrev[4], AMoveHorizPrev[5]);
1295 end;
1296 end;
1297
1298
1299
1300 // Logical
1301 if ALogOffs <> 0 then exit; // TODO;
1302 if ALogX > 0 then begin
1303 DoOneSetByte(AY, ALogX, ALogOffs);
1304 CheckLogPhys(AName + ' from BytePos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1305
1306 // KeepX
1307 if (ALineForKeepX > 0) and UseKeepCaretX then begin
1308 if (TestOrder and 4) = 4 then begin
1309 TestCaret.LineBytePos := point(1, 1);
1310 if (TestOrder and 6) = 4 then
1311 TestCaret.LineBytePos := point(ALogX, AY);
1312 end;
1313
1314 if (TestOrder and 6) = 6
1315 then DoOneSetByte(AY, ALogX, ALogOffs, ALineForKeepX)
1316 else DoOneSetLine(ALineForKeepX);
1317 CheckLogPhys(AName + ' from CharPos', ALineForKeepX, ExpNotKeptX, ExpNotKeptLogX, 0);
1318 if ExpNotKeptX < 0 then AssertFalse(AName + '(char) keepx moved (c)', ExpX = TestCaret.CharPos);
1319 if ExpNotKeptLogX < 0 then AssertFalse(AName + '(char) keepx moved (b)', ExpLogX = TestCaret.BytePos);
1320
1321 DoOneSetLine(AY);
1322 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1323 end;
1324
1325 if length(AMoveHorizNext) >= 3 then begin
1326 DoOneMoveHorizFromByte(1, AY, ALogX, ALogOffs);
1327 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[0], AMoveHorizNext[1], AMoveHorizNext[2]);
1328
1329 if not ExpMoveHorizFalse then begin
1330 DoOneMoveHoriz(-1);
1331 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1332 end;
1333 end;
1334 if length(AMoveHorizNext) >= 6 then begin
1335 TestCaret.LineBytePos := point(ALogX, AY);
1336 if UseLock then TestCaret.Lock;
1337 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1338 TestCaret.MoveHoriz(1);
1339 TestCaret.MoveHoriz(1);
1340 if UseLock then TestCaret.Unlock;
1341 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[3], AMoveHorizNext[4], AMoveHorizNext[5]);
1342
1343 if not ExpMoveHorizFalse then begin
1344 DoOneMoveHoriz(-1);
1345 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[0], AMoveHorizNext[1], AMoveHorizNext[2]);
1346 DoOneMoveHoriz(-1);
1347 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1348
1349 TestCaret.LineBytePos := point(ALogX, AY);
1350 DoOneMoveHoriz(2);
1351 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[3], AMoveHorizNext[4], AMoveHorizNext[5]);
1352 end;
1353 end;
1354
1355 if length(AMoveHorizPrev) >= 3 then begin
1356 DoOneMoveHorizFromByte(-1, AY, ALogX, ALogOffs);
1357 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[0], AMoveHorizPrev[1], AMoveHorizPrev[2]);
1358
1359 if not ExpMoveHorizFalse then begin
1360 DoOneMoveHoriz(1);
1361 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1362 end;
1363 end;
1364 if length(AMoveHorizPrev) >= 6 then begin
1365 TestCaret.LineBytePos := point(ALogX, AY);
1366 if UseLock then TestCaret.Lock;
1367 if UseChangeOnTouch then TestCaret.ChangeOnTouch;
1368 TestCaret.MoveHoriz(-1);
1369 TestCaret.MoveHoriz(-1);
1370 if UseLock then TestCaret.Unlock;
1371 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[3], AMoveHorizPrev[4], AMoveHorizPrev[5]);
1372
1373 if not ExpMoveHorizFalse then begin
1374 DoOneMoveHoriz(1);
1375 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[0], AMoveHorizPrev[1], AMoveHorizPrev[2]);
1376 DoOneMoveHoriz(1);
1377 CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
1378
1379 TestCaret.LineBytePos := point(ALogX, AY);
1380 DoOneMoveHoriz(-2);
1381 CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[3], AMoveHorizPrev[4], AMoveHorizPrev[5]);
1382 end;
1383 end;
1384
1385 end;
1386
1387 end;
1388
1389 procedure DoTests;
1390 begin
1391 if (TestOrder >= 4) and (UseIncAllowPastEOL or UseIncAdjustToNextChar) then
1392 exit;
1393
1394 ReCreateEdit;
1395 SynEdit.TabWidth := 6;
1396 SetLines(['x',
1397 StringOfChar('x', 40),
1398 ' äääbc', // EOL = 7, 10
1399 'X嗚呼あ嗚呼嗚呼あ嗚呼嗚呼あ嗚呼嗚呼あ',
1400 '嗚呼嗚呼あ嗚呼嗚呼あ嗚呼嗚呼あ嗚呼嗚呼あ',
1401 ' '#9#9#9'mn',
1402 '',
1403 'X ab',
1404 '']);
1405 try
1406 PushBaseName(Format('UseLock=%s, AdjustToNextChar=%s, IncAdjustToNextChar=%s,'+
1407 ' AllowPastEOL=%s, IncAllowPastEOL=%s, KeepCaretX=%s,' +
1408 ' ChangeOnTouch=%s, IncAutoMoveOnEdit=%s, SkipTabs=%s' +
1409 ' MaxLeft=%s',
1410 [dbgs(UseLock), dbgs(UseAdjustToNextChar), dbgs(UseIncAdjustToNextChar),
1411 dbgs(UseAllowPastEOL), dbgs(UseIncAllowPastEOL),
1412 dbgs(UseKeepCaretX), dbgs(UseChangeOnTouch),
1413 dbgs(UseIncAutoMoveOnEdit), dbgs(UseSkipTabs), dbgs(UseMaxLeft)
1414 ]));
1415
1416 //debugln(BaseTestName);
1417
1418 TestCaret := TSynEditCaret.Create;
1419 TestCaret.Lines := SynEdit.ViewedTextBuffer;
1420
1421 TestCaret.AdjustToNextChar := UseAdjustToNextChar;
1422 if UseIncAdjustToNextChar then TestCaret.IncForceAdjustToNextChar;
1423
1424 TestCaret.AllowPastEOL := UseAllowPastEOL;
1425 if UseIncAllowPastEOL then TestCaret.IncForcePastEOL;
1426
1427 TestCaret.KeepCaretX := UseKeepCaretX;
1428 if UseIncAutoMoveOnEdit then TestCaret.IncAutoMoveOnEdit;
1429 TestCaret.SkipTabs := UseSkipTabs;
1430 if UseMaxLeft then
1431 TestCaret.MaxLeftChar := @TestMaxLeftProc; // 6000
1432
1433 TestCaret2 := TSynEditCaret.Create;
1434 TestCaret2.Lines := SynEdit.ViewedTextBuffer;
1435
1436
1437
1438 if UseAdjustToNextChar or UseIncAdjustToNextChar
1439 then DoOneTest('Basic', 2, 3, 3, 0, 2, 3, 3, 0,
1440 [4,4,0, 5,5,0], [2,2,0, 1,1,0], False, // MoveHoriz
1441 4, 4, 5 // KeepX
1442 )
1443 else DoOneTest('Basic', 2, 3, 3, 0, 2, 3, 3, 0,
1444 [4,4,0, 5,5,0], [2,2,0, 1,1,0], False, // MoveHoriz
1445 4, 2, 2 // KeepX
1446 );
1447
1448 // past EOL
1449 if UseAllowPastEOL or UseIncAllowPastEOL
1450 then DoOneTest('past EOL', 8, 9, 9, 0, 8, 9, 9, 0,
1451 [10,10,0], [8,8,0])
1452 else DoOneTest('past EOL', 8, 9, 9, 0, 8, 5, 5, 0,
1453 [5,5,0, 5,5,0],[], True);
1454 // BOL
1455 DoOneTest('at BOL', 8, 1, 1, 0, 8, 1, 1, 0,
1456 [],[1,1,0, 1,1,0], True);
1457
1458 // one past EOL
1459 if UseAllowPastEOL or UseIncAllowPastEOL
1460 then DoOneTest('one past EOL', 3, 8,11, 0, 3, 8,11, 0,
1461 [ 9,12,0, 10,13,0], [7,10,0, 6,9,0])
1462 else DoOneTest('one past EOL', 3, 8,11, 0, 3, 7,10, 0,
1463 [7,10,0, 7,10,0], [], True);
1464
1465 // MaxLeftChar 6000 (5999 char / EOL = 6000)
1466 if UseAllowPastEOL or UseIncAllowPastEOL
1467 then if UseMaxLeft
1468 then DoOneTest('past EOL', 3, 6001, 6004, 0, 3, 6000, 6003, 0,
1469 [6000, 6003, 0], [], True)
1470 else DoOneTest('past EOL', 3, 6001, 6004, 0, 3, 6001, 6004, 0,
1471 [], [])
1472 else DoOneTest('past EOL', 3, 6001, 6004, 0, 3, 7,10, 0,
1473 [],[]
1474 );
1475
1476
1477 // ' äääbc'
1478 if UseAdjustToNextChar or UseIncAdjustToNextChar
1479 then DoOneTest('LogPhys', 3, 4, 6, 0, 3, 4, 6, 0,
1480 [5,8,0, 6,9,0], [3,4,0, 2,2,0], False,
1481 5, 5, 7
1482 )
1483 else DoOneTest('LogPhys', 3, 4, 6, 0, 3, 4, 6, 0,
1484 [5,8,0, 6,9,0], [3,4,0, 2,2,0], False,
1485 5, 3, 4
1486 );
1487
1488 // 'X嗚呼あ' // skip "from byte"
1489 if UseAdjustToNextChar or UseIncAdjustToNextChar
1490 then DoOneTest('Mid Dbl-Width', 4, 3, -3, 0, 4, 4, 5, 0,
1491 [6,8,0], [2,2,0], False,
1492 5, 5, 7
1493 )
1494 else DoOneTest('Mid Dbl-Width', 4, 3, -3, 0, 4, 2, 2, 0,
1495 [4,5,0], [1,1,0], False,
1496 5, 1, 1
1497 );
1498
1499 // ' '#9#9#9'mn' // skip "from byte" TODO
1500 if UseSkipTabs
1501 then if UseAdjustToNextChar or UseIncAdjustToNextChar
1502 then DoOneTest('Mid Tab', 6, 8, -3, 1, 6,13, 4, 0,
1503 [19,5,0, 20,6,0], [7,3,0, 2,2,0], False
1504 //7,1,1
1505 )
1506 else if UseAllowPastEOL or UseIncAllowPastEOL
1507 then DoOneTest('Mid Tab', 6, 8, -3, 1, 6, 7, 3, 0,
1508 [13,4,0, 19,5,0], [2,2,0, 1,1,0], False
1509 )
1510 else DoOneTest('Mid Tab', 6, 8, -3, 1, 6, 7, 3, 0,
1511 [13,4,0, 19,5,0], [2,2,0, 1,1,0], False,
1512 7,1,1
1513 )
1514 else if UseAllowPastEOL or UseIncAllowPastEOL
1515 then DoOneTest('Mid Tab', 6, 8, -3, 1, 6, 8, 3, 1,
1516 [9,3,2, 10,3,3], [7,3,0, 6,2,4], False
1517 )
1518 else DoOneTest('Mid Tab', 6, 8, -3, 1, 6, 8, 3, 1,
1519 [9,3,2, 10,3,3], [7,3,0, 6,2,4], False,
1520 7,1,1
1521 );
1522
1523
1524
1525 finally
1526 PopBaseName;
1527 FreeAndNil(TestCaret);
1528 FreeAndNil(TestCaret2);
1529 end;
1530 end;
1531
1532 begin
1533 FPersistSel := False;
1534 //(*
1535 TestOrder := 6;
1536 UseLock := True;
1537 UseAdjustToNextChar := False;
1538 UseIncAdjustToNextChar := False;
1539 UseAllowPastEOL := False;
1540 UseIncAllowPastEOL := False;
1541 UseKeepCaretX := True;
1542 UseChangeOnTouch := False;
1543 UseIncAutoMoveOnEdit := False;
1544 UseSkipTabs := False;
1545 UseMaxLeft := False;
1546 DoTests;
1547 exit;
1548 //*)
1549
1550 for TestOrder := 0 to 11 do // CheckAtPos (8) only runs first 4
1551 for UseLock := low(Boolean) to high(Boolean) do
1552 for UseAdjustToNextChar := low(Boolean) to high(Boolean) do
1553 for UseIncAdjustToNextChar := low(Boolean) to high(Boolean) do
1554 for UseAllowPastEOL := low(Boolean) to high(Boolean) do
1555 for UseIncAllowPastEOL := low(Boolean) to high(Boolean) do
1556 for UseKeepCaretX := low(Boolean) to high(Boolean) do
1557 for UseChangeOnTouch := low(Boolean) to high(Boolean) do
1558 for UseIncAutoMoveOnEdit := low(Boolean) to high(Boolean) do
1559 for UseSkipTabs := low(Boolean) to high(Boolean) do
1560 for UseMaxLeft := low(Boolean) to high(Boolean) do
1561 // OldPos, MoveHoriz
1562 // IsAtPos /
1563 DoTests;
1564
1565 end;
1566
1567 procedure TTestBasicSynEdit.TestCaretAutoMove;
1568
1569 procedure DoTest(name: string; y, x, insertY, insertX, InsertY2, InsertX2: integer;
1570 txt: string; expY, expX: Integer);
1571 begin
1572 name := name + ' y='+inttostr(y)+' x='+inttostr(x);
1573 if y > 0 then begin
1574 ReCreateEdit;
1575 SynEdit.TabWidth := 6;
1576 SetLines(['x', 'abc', ' ääX', #9'mn', 'abc'#9'de', #9'Xää.']);
1577 SynEdit.CaretXY := Point(x, y);
1578 end;
1579
1580 SynEdit.TextBetweenPointsEx[Point(insertX, insertY), point(insertX2, InsertY2), scamAdjust]
1581 := txt;
1582 debugln(dbgstr(SynEdit.Text));
1583 TestIsCaretPhys(name, expX, expY);
1584 end;
1585
1586 const
1587 cr = LineEnding;
1588 begin
1589 FPersistSel := False;
1590
1591 DoTest('simple insert', 2,2, 2,1, 2,1, 'X', 2,3);
1592 DoTest('simple insert CR', 2,2, 2,1, 2,1, 'X'+cr, 3,2);
1593 DoTest('simple insert CR+', 2,2, 2,1, 2,1, cr+'X', 3,3);
1594 DoTest('simple delete', 2,2, 2,1, 2,2, '', 2,1);
1595 DoTest('simple delete CR', 2,2, 1,2, 2,1, '', 1,3);
1596 DoTest('+simple delete CR', 2,2, 1,1, 2,1, '', 1,2);
1597
1598 DoTest('simple insert (eol)', 2,4, 2,1, 2,1, 'X', 2,5);
1599 DoTest('simple insert (past eol)', 2,7, 2,1, 2,1, 'X', 2,8);
1600
1601 DoTest('insert with tab', 4,8, 4,1, 4,1, 'X', 4,8);
1602 DoTest('insert with tab (cont)', -4,8, 4,2, 4,2, 'Y', 4,8);
1603 DoTest('insert with tab (cont)', -4,8, 4,3, 4,3, 'abc', 4,8);
1604 DoTest('insert with tab (cont)', -4,8, 4,6, 4,6, 'Z', 4,14);
1605 DoTest('insert with tab (cont)', -4,8, 4,7, 4,7, '.', 4,14);
1606 DoTest('delete with tab (cont)', -4,8, 4,1, 4,2, '', 4,14);
1607 DoTest('delete with tab (cont)', -4,8, 4,1, 4,2, '', 4,8);
1608 DoTest('delete with tab (cont)', -4,8, 4,1, 4,2, '', 4,8);
1609 DoTest('delete with tab (cont)', -4,8, 4,1, 4,2, '', 4,8);
1610
1611
1612 SynEdit.CaretObj.IncAutoMoveOnEdit;
1613 DoTest('insert with tab (am-block)', 4,8, 4,1, 4,1, 'X', 4,8);
1614 DoTest('insert with tab (am-block) (cont)', -4,8, 4,2, 4,2, 'Y', 4,8);
1615 DoTest('insert with tab (am-block) (cont)', -4,8, 4,3, 4,3, 'abc', 4,8);
1616 DoTest('insert with tab (am-block) (cont)', -4,8, 4,6, 4,6, 'Z', 4,14);
1617 DoTest('insert with tab (am-block) (cont)', -4,8, 4,7, 4,7, '.', 4,14);
1618 DoTest('delete with tab (cont)', -4,8, 4,1, 4,2, '', 4,14);
1619 DoTest('delete with tab (cont)', -4,8, 4,1, 4,2, '', 4,8);
1620 DoTest('delete with tab (cont)', -4,8, 4,1, 4,2, '', 4,8);
1621 DoTest('delete with tab (cont)', -4,8, 4,1, 4,2, '', 4,8);
1622 SynEdit.CaretObj.DecAutoMoveOnEdit;
1623
1624 end;
1625
1626 procedure TTestBasicSynEdit.TestCaretEcDeleteWord;
1627 begin
1628 FPersistSel := False;
1629 FDoInit := @DoInit1;
1630 FTestLines := @TestLines1;
1631 FTestCommand := ecDeleteWord;
1632 AllowPastEOL := True;
1633 PushBaseName('ecDeleteWord');
1634
1635 // if in middle of word, keep spaces after
1636 TestCommand('simple "te|xt"', 8, 1, 8, 1, [1,'Some te to test'],
1637 8, 1, [1,'Some teto test']);
1638 // if at end of word, just del spaces after
1639 TestCommand('simple EOW "text|"', 10, 1, 10, 1, [1,'Some textto test'],
1640 10, 1, [1,'Some text test']);
1641 // if at start of word, do NOT keep spaces after
1642 TestCommand('simple BOW "|text"', 6, 1, 6, 1, [1,'Some to test'],
1643 6, 1, [1,'Some test']);
1644 TestCommand('simple EOT "li|ne"', 10,15, 10,15, [15,'normal li'],
1645 10,15, [15,'normal li']);
1646 TestCommand('simple > EOL, next line "te|st"', 16, 1, 16, 1, [1,'Some text to te'],
1647 16, 1, [1, 1,'Some text to teFoo bar abc']);
1648
1649 TestCommand('tab "li|ne"', 16, 3, 16, 3, [3, #9'Other li with tab'],
1650 16, 3, [3, #9'Other liwith tab']);
1651 TestCommand('tab EOW "line|"', 18, 3, 18, 3, [3, #9'Other linewith tab'],
1652 18, 3, [3, #9'Other line tab']);
1653 TestCommand('tab BOW "|line"', 14, 3, 14, 3, [3, #9'Other with tab'],
1654 14, 3, [3, #9'Other tab']);
1655 TestCommand('tab > EOL, next-line', 25, 3, 25, 3, [3, #9'Other line with t'],
1656 25, 3, [3, 3, #9'Other line with ttab'#9'in the middle']);
1657
1658 TestCommand('M-tab "t|ab"', 2, 4, 2, 4, [4, 't'#9'in the middle'],
1659 2, 4, [4, 'tin the middle']);
1660 TestCommand('M-tab "tab|"', 4, 4, 4, 4, [4, 'tabin the middle'],
1661 4, 4, [4, 'tab the middle']);
1662 TestCommand('M-tab > EOL, next-line-tab', 17, 4, 17, 4, [4, 'tab'#9'in the mi'],
1663 17, 4, [4, 4, 'tab'#9'in the mitab'#9' in the middle with space']);
1664
1665 //TestCommand('M-S-tab BOW "t|ab"', 2, 5, 9, 5,
1666 // 12, 5);
1667 //TestCommand('M-S-tab EOW "tab|"', 4, 5, 9, 5,
1668 // 12, 5);
1669 //TestCommand('M-S-tab BOW "|tab"', 1, 5, 9, 5,
1670 // 12, 5);
1671 //TestCommand('M-S-tab "tab#9| "', 5, 5, 9, 5,
1672 // 12, 5);
1673 //
1674 TestCommand('Umlaut "ää|ä"', 11, 6, 11, 6, [6, 'umlaute ää in text'],
1675 11, 6, [6, 'umlaute ääin text']);
1676 TestCommand('Umlaut EOW "äää|"', 12, 6, 12, 6, [6, 'umlaute äääin text'],
1677 12, 6, [6, 'umlaute äää text']);
1678 TestCommand('Umlaut BOW "|äää"', 9, 6, 9, 6, [6, 'umlaute in text'],
1679 9, 6, [6, 'umlaute text']);
1680 TestCommand('Umlaut "umlaute|"', 8, 6, 8, 6, [6, 'umlauteäää in text'],
1681 8, 6, [6, 'umlaute in text']);
1682 TestCommand('After Umlaut > EOL, next line', 18, 6, 18, 6, [6, 'umlaute äää in te'],
1683 18, 6, [6, 6, 'umlaute äää in te'+FTestLines()[6]]);
1684 // past eol
1685 TestCommand('Umlaut EOW "äää in text |"', 21, 6, 21, 6, [6, 6, 'umlaute äää in text normal line']);
1686
1687 //TestCommand('Before untrimmed > next', 12, 7, 4, 8,
1688 // 14, 8);
1689 //TestCommand('untrimmed > EOL, next', 30, 8, 35, 8,
1690 // 1, 9);
1691 //TestCommand('Before untrimmed tab > next', 12, 9, 8,10,
1692 // 15,10);
1693 //TestCommand('untrimmed tab > EOL, next', 24,10, 29,10,
1694 // 1,11);
1695 //
1696 //TestCommand('Before empty > next', 12,11, 1,12);
1697 //TestCommand('Before space empty > next', 12,13, 1,14,
1698 // 6, 14);
1699 end;
1700
1701 procedure TTestBasicSynEdit.TestCaretEcDeleteLastWord;
1702 begin
1703 FPersistSel := False;
1704 FDoInit := @DoInit1;
1705 FTestLines := @TestLines1;
1706 FTestCommand := ecDeleteLastWord;
1707 AllowPastEOL := True;
1708 PushBaseName('ecDeleteLastWord');
1709
1710 TestCommand('simple "te|st"', 16, 1, 14, 1, [1,'Some text to st'],
1711 11, 1, [1,'Some text st']);
1712 TestCommand('simple EOW "test|"', 18, 1, 14, 1, [1,'Some text to '],
1713 11, 1, [1,'Some text ']);
1714 TestCommand('simple BOW "|test"', 14, 1, 11, 1, [1,'Some text test'],
1715 6, 1, [1,'Some test']);
1716 TestCommand('simple > BOT "So|me"', 3, 1, 1, 1, [1,'me text to test'],
1717 1, 1, [1,'me text to test']);
1718 TestCommand('simple > prev-line "F|oo"', 2, 2, 1, 2, [2,'oo bar abc'],
1719 18, 1, [1, 1, 'Some text to testoo bar abc']);
1720 TestCommand('simple > prev-line "|Foo"', 1, 2, 18, 1, [1, 1, 'Some text to testFoo bar abc'],
1721 14, 1, [1, 1, 'Some text to Foo bar abc']);
1722
1723 TestCommand('tab "wi|th"', 21, 3, 19, 3, [3, #9'Other line th tab'],
1724 14, 3, [3, #9'Other th tab']);
1725 TestCommand('tab EOW "with|"', 23, 3, 19, 3, [3, #9'Other line tab'],
1726 14, 3, [3, #9'Other tab']);
1727 TestCommand('tab BOW "|with"', 19, 3, 14, 3, [3, #9'Other with tab'],
1728 8, 3, [3, #9'with tab']);
1729 TestCommand('tab > prev-line "O|ther"', 9, 3, 8, 3, [3, #9'ther line with tab'],
1730 12, 2, [2, 2, 'Foo bar abcther line with tab']);
1731
1732 TestCommand('M-tab "i|n"', 9, 4, 8, 4, [4, 'tab'#9'n the middle'],
1733 1, 4, [4, 'n the middle']);
1734 TestCommand('M-tab > prev-line-tab "ta|b"', 3, 4, 1, 4, [4, 'b'#9'in the middle'],
1735 27, 3, [3, 3, #9'Other line with tabb'#9'in the middle']);
1736
1737 //TestCommand('M-S-tab "i|n"', 10, 5, 9, 5,
1738 // 1, 5);
1739 //TestCommand('M-S-EOW tab "in|"', 11, 5, 9, 5,
1740 // 1, 5);
1741 //TestCommand('M-S-BOW tab "|in"', 9, 5, 1, 5,
1742 // 21, 4);
1743 //TestCommand('M-S-tab "#9| in"', 8, 5, 1, 5);
1744 //
1745 TestCommand('Umlaut "ää|ä"', 11, 6, 9, 6, [6, 'umlaute ä in text'],
1746 1, 6, [6, 'ä in text']);
1747 TestCommand('Umlaut EOW "äää|"', 12, 6, 9, 6, [6, 'umlaute in text'],
1748 1, 6, [6, ' in text']);
1749 TestCommand('Umlaut BOW "|äää"', 9, 6, 1, 6, [6, 'äää in text'],
1750 33, 5, [5, 5, FTestLines()[4]+'äää in text']);
1751 TestCommand('Umlaut "i|n"', 14, 6, 13, 6, [6, 'umlaute äää n text'],
1752 9, 6, [6, 'umlaute n text']);
1753 TestCommand('After Umlaut > prev line', 1, 7, 20, 6, [6, 6, 'umlaute äää in text'+FTestLines()[6]],
1754 16, 6, [6, 6, 'umlaute äää in '+FTestLines()[6]]);
1755
1756 //TestCommand('untrimmed "un|trimmed"', 6, 8, 4, 8,
1757 // 12, 7);
1758 //TestCommand('After untrimmed > prev', 1, 9, 35, 8,
1759 // 28, 8);
1760 //TestCommand('untrimmed tab "t|ab"', 9,10, 8,10,
1761 // 12, 9);
1762 //TestCommand('After untrimmed tab > prev', 1,11, 29,10,
1763 // 22,10);
1764 //
1765 //TestCommand('After empty > prev', 1,13, 1,12);
1766 //TestCommand('After space empty > prev', 1,15, 6,14);
1767 end;
1768
1769 procedure TTestBasicSynEdit.TestCaretEcDeleteEOL;
1770 begin
1771 FPersistSel := False;
1772 FDoInit := @DoInit1;
1773 FTestLines := @TestLines1;
1774 FTestCommand := ecDeleteEOL;
1775 AllowPastEOL := True;
1776 PushBaseName('ecDeleteEOL');
1777
1778 TestCommand('simple "te|xt"', 8, 1, 8, 1, [1,'Some te']);
1779 // if at end of line
1780 TestCommand('simple EOL "text|"', 18, 1, 18, 1, []);
1781 // if at start of line
1782 TestCommand('simple BOL "|text"', 1, 1, 1, 1, [1,'']);
1783
1784 // utf8
1785 TestCommand('utf8 "te|xt"', 10, 6, 10, 6, [6,'umlaute ä']);
1786 // if at end of line
1787 TestCommand('utf8 EOL "text|"', 20, 6, 20, 6, []);
1788 // if at start of line
1789 TestCommand('utf8 BOL "|text"', 1, 6, 1, 6, [6,'']);
1790
1791 //tab
1792 TestCommand('tab "te|#9xt"', 11, 10, 11, 10, [10,#9'tab']);
1793 TestCommand('tab "te#9|xt"', 15, 10, 15, 10, [10,#9'tab'#9]);
1794 // if at end of line
1795 TestCommand('tab EOL "text|"', 29, 10, 29, 10, []);
1796 // if at start of line
1797 TestCommand('tab BOL "|text"', 1, 10, 1, 10, [10,'']);
1798
1799 end;
1800
1801 procedure TTestBasicSynEdit.TestWordBreaker;
1802 var
1803 WBrker: TSynWordBreaker;
1804 begin
1805 FPersistSel := False;
1806 WBrker := TSynWordBreaker.Create;
1807 WBrker.IdentChars := ['a'..'z', 'A'..'Z', '0'..'9']; // not used
1808 WBrker.WhiteChars := [' ', #9];
1809 WBrker.WordBreakChars := [',', '.', '-', ';' ,':'];
1810
1811 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 1));
1812 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 2));
1813 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 3));
1814 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 4));
1815 AssertEquals('', False, WBrker.IsInWord('abc 123 ... aa', 5));
1816 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 6));
1817 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 7));
1818 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 9));
1819 AssertEquals('', False, WBrker.IsInWord('abc 123 ... aa', 10));
1820 AssertEquals('', False, WBrker.IsInWord('abc 123 ... aa', 11)); // before ...
1821 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 15)); // |aa
1822 AssertEquals('', True, WBrker.IsInWord('abc 123 ... aa', 17)); // at eol
1823 AssertEquals('', False, WBrker.IsInWord('abc 123 ... aa', 18));
1824 AssertEquals('', False, WBrker.IsInWord('abc 123 ... aa', 19));
1825 AssertEquals('', False, WBrker.IsInWord('abc 123 ... aa', 0));
1826 AssertEquals('', False, WBrker.IsInWord('abc 123 ... aa', -1));
1827 AssertEquals('', False, WBrker.IsInWord(' ', 1));
1828 AssertEquals('', False, WBrker.IsInWord(' ', 2));
1829 AssertEquals('', False, WBrker.IsInWord('', 1));
1830 AssertEquals('', False, WBrker.IsInWord('...', 1));
1831 AssertEquals('', False, WBrker.IsInWord('...', 2));
1832 AssertEquals('', False, WBrker.IsInWord('...', 4));
1833 AssertEquals('', False, WBrker.IsInWord('..aa', 2));
1834 AssertEquals('', True, WBrker.IsInWord('..aa', 3));
1835 AssertEquals('', True, WBrker.IsInWord('..aa', 4));
1836 AssertEquals('', True, WBrker.IsInWord('..aa', 5));
1837
1838
1839 AssertEquals('', True, WBrker.IsAtWordStart('abc 123 ... aa', 1));
1840 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 2));
1841 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 3));
1842 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 4));
1843 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 5));
1844 AssertEquals('', True, WBrker.IsAtWordStart('abc 123 ... aa', 6));
1845 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 7));
1846 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 9));
1847 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 10));
1848 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 11)); // before ...
1849 AssertEquals('', True, WBrker.IsAtWordStart('abc 123 ... aa', 15)); // |aa
1850 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 17)); // at eol
1851 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 18));
1852 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 19));
1853 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', 0));
1854 AssertEquals('', False, WBrker.IsAtWordStart('abc 123 ... aa', -1));
1855 AssertEquals('', False, WBrker.IsAtWordStart(' ', 1));
1856 AssertEquals('', False, WBrker.IsAtWordStart('', 1));
1857 AssertEquals('', False, WBrker.IsAtWordStart(' ', 2));
1858 AssertEquals('', False, WBrker.IsAtWordStart('...', 1));
1859 AssertEquals('', True, WBrker.IsAtWordStart('..aa', 3));
1860
1861 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 1));
1862 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 2));
1863 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 3));
1864 AssertEquals('', True, WBrker.IsAtWordEnd('abc 123 ... aa', 4));
1865 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 5));
1866 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 6));
1867 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 7));
1868 AssertEquals('', True, WBrker.IsAtWordEnd('abc 123 ... aa', 9));
1869 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 10));
1870 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 11)); // before ...
1871 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 15)); // |aa
1872 AssertEquals('', True, WBrker.IsAtWordEnd('abc 123 ... aa', 17)); // at eol
1873 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 18));
1874 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 19));
1875 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', 0));
1876 AssertEquals('', False, WBrker.IsAtWordEnd('abc 123 ... aa', -1));
1877 AssertEquals('', False, WBrker.IsAtWordEnd(' ', 1));
1878 AssertEquals('', False, WBrker.IsAtWordEnd(' ', 2));
1879 AssertEquals('', False, WBrker.IsAtWordEnd('', 1));
1880 AssertEquals('', False, WBrker.IsAtWordEnd('...', 1));
1881 AssertEquals('', False, WBrker.IsAtWordEnd('..aa', 3));
1882
1883 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 1, False));
1884 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 2, False));
1885 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 3, False));
1886 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 4, False)); // abc|
1887 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 5, False));
1888 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 6, False)); // |123
1889 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 7, False)); // 1|23
1890 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 8, False));
1891 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 9, False)); // 123|
1892 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 10, False));
1893 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 11, False)); // |...
1894 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 12, False));
1895 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 13, False));
1896 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 14, False)); // ...|
1897 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 15, False));
1898 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 16, False));
1899 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 17, False)); // at eol
1900 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 18, False));
1901 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 19, False));
1902 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 0, False));
1903 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', -1, False));
1904 AssertEquals('',-1, WBrker.NextWordStart('', 1, False));
1905 AssertEquals('',-1, WBrker.NextWordStart(' ', 1, False));
1906 AssertEquals('',-1, WBrker.NextWordStart(' ', 2, False));
1907 AssertEquals('',3, WBrker.NextWordStart('..aa', 1, False));
1908 AssertEquals('',3, WBrker.NextWordStart('..aa', 2, False));
1909 AssertEquals('',-1, WBrker.NextWordStart('..aa', 3, False));
1910 AssertEquals('',-1, WBrker.NextWordStart('..aa', 4, False));
1911 AssertEquals('', 3, WBrker.NextWordStart('a a 1', 1, False));
1912 AssertEquals('', 3, WBrker.NextWordStart('a a 1', 2, False));
1913 AssertEquals('', 5, WBrker.NextWordStart('a a 1', 3, False));
1914 AssertEquals('', 5, WBrker.NextWordStart('a a 1', 4, False));
1915 AssertEquals('',-1, WBrker.NextWordStart('a a 1', 5, False));
1916 AssertEquals('',-1, WBrker.NextWordStart('a a 1', 6, False));
1917 AssertEquals('', 2, WBrker.NextWordStart(' a ', 1, False));
1918 AssertEquals('',-1, WBrker.NextWordStart(' a ', 2, False));
1919 AssertEquals('',-1, WBrker.NextWordStart(' a ', 3, False));
1920 AssertEquals('',-1, WBrker.NextWordStart(' a ', 4, False));
1921
1922 AssertEquals('', 1, WBrker.NextWordStart('abc 123 ... aa', 1, True));
1923 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 2, True));
1924 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 3, True));
1925 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 4, True)); // abc|
1926 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 5, True));
1927 AssertEquals('', 6, WBrker.NextWordStart('abc 123 ... aa', 6, True)); // |123
1928 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 7, True)); // 1|23
1929 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 8, True));
1930 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 9, True)); // 123|
1931 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 10, True));
1932 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 11, True)); // |...
1933 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 12, True));
1934 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 13, True));
1935 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 14, True)); // ...|
1936 AssertEquals('',15, WBrker.NextWordStart('abc 123 ... aa', 15, True));
1937 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 16, True));
1938 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 17, True)); // at eol
1939 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 18, True));
1940 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 19, True));
1941 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', 0, True));
1942 AssertEquals('',-1, WBrker.NextWordStart('abc 123 ... aa', -1, True));
1943 AssertEquals('',-1, WBrker.NextWordStart('', 1, True));
1944 AssertEquals('',-1, WBrker.NextWordStart(' ', 1, True));
1945 AssertEquals('',-1, WBrker.NextWordStart(' ', 2, True));
1946 AssertEquals('',3, WBrker.NextWordStart('..aa', 1, True));
1947 AssertEquals('',3, WBrker.NextWordStart('..aa', 2, True));
1948 AssertEquals('',3, WBrker.NextWordStart('..aa', 3, True));
1949 AssertEquals('',-1, WBrker.NextWordStart('..aa', 4, True));
1950 AssertEquals('', 1, WBrker.NextWordStart('a a 1', 1, True));
1951 AssertEquals('', 3, WBrker.NextWordStart('a a 1', 2, True));
1952 AssertEquals('', 3, WBrker.NextWordStart('a a 1', 3, True));
1953 AssertEquals('', 5, WBrker.NextWordStart('a a 1', 4, True));
1954 AssertEquals('', 5, WBrker.NextWordStart('a a 1', 5, True));
1955 AssertEquals('',-1, WBrker.NextWordStart('a a 1', 6, True));
1956 AssertEquals('', 2, WBrker.NextWordStart(' a ', 1, True));
1957 AssertEquals('', 2, WBrker.NextWordStart(' a ', 2, True));
1958 AssertEquals('',-1, WBrker.NextWordStart(' a ', 3, True));
1959 AssertEquals('',-1, WBrker.NextWordStart(' a ', 4, True));
1960
1961 AssertEquals('', 4, WBrker.NextWordEnd('abc 123 ... aa', 1, False));
1962 AssertEquals('', 4, WBrker.NextWordEnd('abc 123 ... aa', 2, False));
1963 AssertEquals('', 4, WBrker.NextWordEnd('abc 123 ... aa', 3, False));
1964 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 4, False)); // abc|
1965 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 5, False));
1966 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 6, False)); // |123
1967 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 7, False)); // 1|23
1968 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 8, False));
1969 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 9, False)); // 123|
1970 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 10, False));
1971 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 11, False)); // |...
1972 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 12, False));
1973 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 13, False));
1974 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 14, False)); // ...|
1975 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 15, False));
1976 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 16, False));
1977 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', 17, False)); // at eol
1978 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', 18, False));
1979 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', 19, False));
1980 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', 0, False));
1981 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', -1, False));
1982 AssertEquals('',-1, WBrker.NextWordEnd('', 1, False));
1983 AssertEquals('',-1, WBrker.NextWordEnd(' ', 1, False));
1984 AssertEquals('',-1, WBrker.NextWordEnd(' ', 2, False));
1985 AssertEquals('',5, WBrker.NextWordEnd('..aa', 1, False));
1986 AssertEquals('',5, WBrker.NextWordEnd('..aa', 2, False));
1987 AssertEquals('',5, WBrker.NextWordEnd('..aa', 3, False));
1988 AssertEquals('',5, WBrker.NextWordEnd('..aa', 4, False));
1989 AssertEquals('',-1, WBrker.NextWordEnd('..aa', 5, False));
1990 AssertEquals('', 2, WBrker.NextWordEnd('a a 1', 1, False));
1991 AssertEquals('', 4, WBrker.NextWordEnd('a a 1', 2, False));
1992 AssertEquals('', 4, WBrker.NextWordEnd('a a 1', 3, False));
1993 AssertEquals('', 6, WBrker.NextWordEnd('a a 1', 4, False));
1994 AssertEquals('', 6, WBrker.NextWordEnd('a a 1', 5, False));
1995 AssertEquals('',-1, WBrker.NextWordEnd('a a 1', 6, False));
1996 AssertEquals('', 3, WBrker.NextWordEnd(' a ', 1, False));
1997 AssertEquals('', 3, WBrker.NextWordEnd(' a ', 2, False));
1998 AssertEquals('',-1, WBrker.NextWordEnd(' a ', 3, False));
1999 AssertEquals('',-1, WBrker.NextWordEnd(' a ', 4, False));
2000
2001 AssertEquals('', 4, WBrker.NextWordEnd('abc 123 ... aa', 1, True));
2002 AssertEquals('', 4, WBrker.NextWordEnd('abc 123 ... aa', 2, True));
2003 AssertEquals('', 4, WBrker.NextWordEnd('abc 123 ... aa', 3, True));
2004 AssertEquals('', 4, WBrker.NextWordEnd('abc 123 ... aa', 4, True)); // abc|
2005 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 5, True));
2006 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 6, True)); // |123
2007 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 7, True)); // 1|23
2008 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 8, True));
2009 AssertEquals('', 9, WBrker.NextWordEnd('abc 123 ... aa', 9, True)); // 123|
2010 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 10, True));
2011 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 11, True)); // |...
2012 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 12, True));
2013 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 13, True));
2014 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 14, True)); // ...|
2015 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 15, True));
2016 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 16, True));
2017 AssertEquals('',17, WBrker.NextWordEnd('abc 123 ... aa', 17, True)); // at eol
2018 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', 18, True));
2019 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', 19, True));
2020 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', 0, True));
2021 AssertEquals('',-1, WBrker.NextWordEnd('abc 123 ... aa', -1, True));
2022 AssertEquals('',-1, WBrker.NextWordEnd('', 1, True));
2023 AssertEquals('',-1, WBrker.NextWordEnd(' ', 1, True));
2024 AssertEquals('',-1, WBrker.NextWordEnd(' ', 2, True));
2025 AssertEquals('',5, WBrker.NextWordEnd('..aa', 1, True));
2026 AssertEquals('',5, WBrker.NextWordEnd('..aa', 2, True));
2027 AssertEquals('',5, WBrker.NextWordEnd('..aa', 3, True));
2028 AssertEquals('',5, WBrker.NextWordEnd('..aa', 4, True));
2029 AssertEquals('',5, WBrker.NextWordEnd('..aa', 5, True));
2030 AssertEquals('', 2, WBrker.NextWordEnd('a a 1', 1, True));
2031 AssertEquals('', 2, WBrker.NextWordEnd('a a 1', 2, True));
2032 AssertEquals('', 4, WBrker.NextWordEnd('a a 1', 3, True));
2033 AssertEquals('', 4, WBrker.NextWordEnd('a a 1', 4, True));
2034 AssertEquals('', 6, WBrker.NextWordEnd('a a 1', 5, True));
2035 AssertEquals('', 6, WBrker.NextWordEnd('a a 1', 6, True));
2036 AssertEquals('', 3, WBrker.NextWordEnd(' a ', 1, True));
2037 AssertEquals('', 3, WBrker.NextWordEnd(' a ', 2, True));
2038 AssertEquals('', 3, WBrker.NextWordEnd(' a ', 3, True));
2039 AssertEquals('',-1, WBrker.NextWordEnd(' a ', 4, True));
2040
2041 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', 1, False));
2042 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 2, False));
2043 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 3, False));
2044 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 4, False)); // abc|
2045 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 5, False));
2046 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 6, False)); // |123
2047 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 7, False)); // 1|23
2048 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 8, False));
2049 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 9, False)); // 123|
2050 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 10, False));
2051 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 11, False)); // |...
2052 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 12, False));
2053 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 13, False));
2054 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 14, False)); // ...|
2055 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 15, False));
2056 AssertEquals('',15, WBrker.PrevWordStart('abc 123 ... aa', 16, False));
2057 AssertEquals('',15, WBrker.PrevWordStart('abc 123 ... aa', 17, False)); // at eol
2058 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', 18, False));
2059 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', 19, False));
2060 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', 0, False));
2061 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', -1, False));
2062 AssertEquals('',-1, WBrker.PrevWordStart('', 1, False));
2063 AssertEquals('',-1, WBrker.PrevWordStart(' ', 1, False));
2064 AssertEquals('',-1, WBrker.PrevWordStart(' ', 2, False));
2065 AssertEquals('',-1, WBrker.PrevWordStart('..aa', 1, False));
2066 AssertEquals('',-1, WBrker.PrevWordStart('..aa', 2, False));
2067 AssertEquals('',-1, WBrker.PrevWordStart('..aa', 3, False));
2068 AssertEquals('', 3, WBrker.PrevWordStart('..aa', 4, False));
2069 AssertEquals('', 3, WBrker.PrevWordStart('..aa', 5, False));
2070 AssertEquals('',-1, WBrker.PrevWordStart('a a 1', 1, False));
2071 AssertEquals('', 1, WBrker.PrevWordStart('a a 1', 2, False));
2072 AssertEquals('', 1, WBrker.PrevWordStart('a a 1', 3, False));
2073 AssertEquals('', 3, WBrker.PrevWordStart('a a 1', 4, False));
2074 AssertEquals('', 3, WBrker.PrevWordStart('a a 1', 5, False));
2075 AssertEquals('', 5, WBrker.PrevWordStart('a a 1', 6, False));
2076 AssertEquals('',-1, WBrker.PrevWordStart(' a ', 1, False));
2077 AssertEquals('',-1, WBrker.PrevWordStart(' a ', 2, False));
2078 AssertEquals('', 2, WBrker.PrevWordStart(' a ', 3, False));
2079 AssertEquals('', 2, WBrker.PrevWordStart(' a ', 4, False));
2080
2081 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 1, True));
2082 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 2, True));
2083 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 3, True));
2084 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 4, True)); // abc|
2085 AssertEquals('', 1, WBrker.PrevWordStart('abc 123 ... aa', 5, True));
2086 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 6, True)); // |123
2087 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 7, True)); // 1|23
2088 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 8, True));
2089 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 9, True)); // 123|
2090 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 10, True));
2091 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 11, True)); // |...
2092 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 12, True));
2093 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 13, True));
2094 AssertEquals('', 6, WBrker.PrevWordStart('abc 123 ... aa', 14, True)); // ...|
2095 AssertEquals('',15, WBrker.PrevWordStart('abc 123 ... aa', 15, True));
2096 AssertEquals('',15, WBrker.PrevWordStart('abc 123 ... aa', 16, True));
2097 AssertEquals('',15, WBrker.PrevWordStart('abc 123 ... aa', 17, True)); // at eol
2098 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', 18, True));
2099 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', 19, True));
2100 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', 0, True));
2101 AssertEquals('',-1, WBrker.PrevWordStart('abc 123 ... aa', -1, True));
2102 AssertEquals('',-1, WBrker.PrevWordStart('', 1, True));
2103 AssertEquals('',-1, WBrker.PrevWordStart(' ', 1, True));
2104 AssertEquals('',-1, WBrker.PrevWordStart(' ', 2, True));
2105 AssertEquals('',-1, WBrker.PrevWordStart('..aa', 1, True));
2106 AssertEquals('',-1, WBrker.PrevWordStart('..aa', 2, True));
2107 AssertEquals('', 3, WBrker.PrevWordStart('..aa', 3, True));
2108 AssertEquals('', 3, WBrker.PrevWordStart('..aa', 4, True));
2109 AssertEquals('', 3, WBrker.PrevWordStart('..aa', 5, True));
2110 AssertEquals('', 1, WBrker.PrevWordStart('a a 1', 1, True));
2111 AssertEquals('', 1, WBrker.PrevWordStart('a a 1', 2, True));
2112 AssertEquals('', 3, WBrker.PrevWordStart('a a 1', 3, True));
2113 AssertEquals('', 3, WBrker.PrevWordStart('a a 1', 4, True));
2114 AssertEquals('', 5, WBrker.PrevWordStart('a a 1', 5, True));
2115 AssertEquals('', 5, WBrker.PrevWordStart('a a 1', 6, True));
2116 AssertEquals('',-1, WBrker.PrevWordStart(' a ', 1, True));
2117 AssertEquals('', 2, WBrker.PrevWordStart(' a ', 2, True));
2118 AssertEquals('', 2, WBrker.PrevWordStart(' a ', 3, True));
2119 AssertEquals('', 2, WBrker.PrevWordStart(' a ', 4, True));
2120
2121 AssertEquals('', -1, WBrker.PrevWordEnd('abc 123 ... aa', 1, False));
2122 AssertEquals('', -1, WBrker.PrevWordEnd('abc 123 ... aa', 2, False));
2123 AssertEquals('', -1, WBrker.PrevWordEnd('abc 123 ... aa', 3, False));
2124 AssertEquals('', -1, WBrker.PrevWordEnd('abc 123 ... aa', 4, False)); // abc|
2125 AssertEquals('', 4, WBrker.PrevWordEnd('abc 123 ... aa', 5, False));
2126 AssertEquals('',4, WBrker.PrevWordEnd('abc 123 ... aa', 6, False)); // |123
2127 AssertEquals('',4, WBrker.PrevWordEnd('abc 123 ... aa', 7, False)); // 1|23
2128 AssertEquals('',4, WBrker.PrevWordEnd('abc 123 ... aa', 8, False));
2129 AssertEquals('',4, WBrker.PrevWordEnd('abc 123 ... aa', 9, False)); // 123|
2130 AssertEquals('',9, WBrker.PrevWordEnd('abc 123 ... aa', 10, False));
2131 AssertEquals('',9, WBrker.PrevWordEnd('abc 123 ... aa', 11, False)); // |...
2132 AssertEquals('',9, WBrker.PrevWordEnd('abc 123 ... aa', 12, False));
2133 AssertEquals('',9, WBrker.PrevWordEnd('abc 123 ... aa', 13, False));
2134 AssertEquals('',9, WBrker.PrevWordEnd('abc 123 ... aa', 14, False)); // ...|
2135 AssertEquals('',9, WBrker.PrevWordEnd('abc 123 ... aa', 15, False));
2136 AssertEquals('',9, WBrker.PrevWordEnd('abc 123 ... aa', 16, False));
2137 AssertEquals('',9, WBrker.PrevWordEnd('abc 123 ... aa', 17, False)); // at eol
2138 AssertEquals('',-1, WBrker.PrevWordEnd('abc 123 ... aa', 18, False));
2139 AssertEquals('',-1, WBrker.PrevWordEnd('abc 123 ... aa', 19, False));
2140 AssertEquals('',-1, WBrker.PrevWordEnd('abc 123 ... aa', 0, False));
2141 AssertEquals('',-1, WBrker.PrevWordEnd('abc 123 ... aa', -1, False));
2142 AssertEquals('',-1, WBrker.PrevWordEnd('', 1, False));
2143 AssertEquals('',-1, WBrker.PrevWordEnd(' ', 1, False));
2144 AssertEquals('',-1, WBrker.PrevWordEnd(' ', 2, False));
2145 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 1, False));
2146 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 2, False));
2147 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 3, False));
2148 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 4, False));
2149 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 5, False));
2150 AssertEquals('',-1, WBrker.PrevWordEnd('a a 1', 1, False));
2151 AssertEquals('',-1, WBrker.PrevWordEnd('a a 1', 2, False));
2152 AssertEquals('', 2, WBrker.PrevWordEnd('a a 1', 3, False));
2153 AssertEquals('', 2, WBrker.PrevWordEnd('a a 1', 4, False));
2154 AssertEquals('', 4, WBrker.PrevWordEnd('a a 1', 5, False));
2155 AssertEquals('', 4, WBrker.PrevWordEnd('a a 1', 6, False));
2156 AssertEquals('',-1, WBrker.PrevWordEnd(' a ', 1, False));
2157 AssertEquals('',-1, WBrker.PrevWordEnd(' a ', 2, False));
2158 AssertEquals('',-1, WBrker.PrevWordEnd(' a ', 3, False));
2159 AssertEquals('', 3, WBrker.PrevWordEnd(' a ', 4, False));
2160
2161 AssertEquals('', -1, WBrker.PrevWordEnd('abc 123 ... aa', 1, True));
2162 AssertEquals('', -1, WBrker.PrevWordEnd('abc 123 ... aa', 2, True));
2163 AssertEquals('', -1, WBrker.PrevWordEnd('abc 123 ... aa', 3, True));
2164 AssertEquals('', 4, WBrker.PrevWordEnd('abc 123 ... aa', 4, True)); // abc|
2165 AssertEquals('', 4, WBrker.PrevWordEnd('abc 123 ... aa', 5, True));
2166 AssertEquals('', 4, WBrker.PrevWordEnd('abc 123 ... aa', 6, True)); // |123
2167 AssertEquals('', 4, WBrker.PrevWordEnd('abc 123 ... aa', 7, True)); // 1|23
2168 AssertEquals('', 4, WBrker.PrevWordEnd('abc 123 ... aa', 8, True));
2169 AssertEquals('', 9, WBrker.PrevWordEnd('abc 123 ... aa', 9, True)); // 123|
2170 AssertEquals('', 9, WBrker.PrevWordEnd('abc 123 ... aa', 10, True));
2171 AssertEquals('', 9, WBrker.PrevWordEnd('abc 123 ... aa', 11, True)); // |...
2172 AssertEquals('', 9, WBrker.PrevWordEnd('abc 123 ... aa', 12, True));
2173 AssertEquals('', 9, WBrker.PrevWordEnd('abc 123 ... aa', 13, True));
2174 AssertEquals('', 9, WBrker.PrevWordEnd('abc 123 ... aa', 14, True)); // ...|
2175 AssertEquals('', 9, WBrker.PrevWordEnd('abc 123 ... aa', 15, True));
2176 AssertEquals('', 9, WBrker.PrevWordEnd('abc 123 ... aa', 16, True));
2177 AssertEquals('',17, WBrker.PrevWordEnd('abc 123 ... aa', 17, True)); // at eol
2178 AssertEquals('',-1, WBrker.PrevWordEnd('abc 123 ... aa', 18, True));
2179 AssertEquals('',-1, WBrker.PrevWordEnd('abc 123 ... aa', 19, True));
2180 AssertEquals('',-1, WBrker.PrevWordEnd('abc 123 ... aa', 0, True));
2181 AssertEquals('',-1, WBrker.PrevWordEnd('abc 123 ... aa', -1, True));
2182 AssertEquals('',-1, WBrker.PrevWordEnd('', 1, True));
2183 AssertEquals('',-1, WBrker.PrevWordEnd(' ', 1, True));
2184 AssertEquals('',-1, WBrker.PrevWordEnd(' ', 2, True));
2185 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 1, True));
2186 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 2, True));
2187 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 3, True));
2188 AssertEquals('',-1, WBrker.PrevWordEnd('..aa', 4, True));
2189 AssertEquals('', 5, WBrker.PrevWordEnd('..aa', 5, True));
2190 AssertEquals('',-1, WBrker.PrevWordEnd('a a 1', 1, True));
2191 AssertEquals('', 2, WBrker.PrevWordEnd('a a 1', 2, True));
2192 AssertEquals('', 2, WBrker.PrevWordEnd('a a 1', 3, True));
2193 AssertEquals('', 4, WBrker.PrevWordEnd('a a 1', 4, True));
2194 AssertEquals('', 4, WBrker.PrevWordEnd('a a 1', 5, True));
2195 AssertEquals('', 6, WBrker.PrevWordEnd('a a 1', 6, True));
2196 AssertEquals('',-1, WBrker.PrevWordEnd(' a ', 1, True));
2197 AssertEquals('',-1, WBrker.PrevWordEnd(' a ', 2, True));
2198 AssertEquals('', 3, WBrker.PrevWordEnd(' a ', 3, True));
2199 AssertEquals('', 3, WBrker.PrevWordEnd(' a ', 4, True));
2200
2201
2202 AssertEquals('', 4, WBrker.NextBoundary('abc 123 ... aa', 1, False));
2203 AssertEquals('', 4, WBrker.NextBoundary('abc 123 ... aa', 2, False));
2204 AssertEquals('', 4, WBrker.NextBoundary('abc 123 ... aa', 3, False));
2205 AssertEquals('', 6, WBrker.NextBoundary('abc 123 ... aa', 4, False)); // abc|
2206 AssertEquals('', 6, WBrker.NextBoundary('abc 123 ... aa', 5, False));
2207 AssertEquals('', 9, WBrker.NextBoundary('abc 123 ... aa', 6, False)); // |123
2208 AssertEquals('', 9, WBrker.NextBoundary('abc 123 ... aa', 7, False)); // 1|23
2209 AssertEquals('', 9, WBrker.NextBoundary('abc 123 ... aa', 8, False));
2210 AssertEquals('',11, WBrker.NextBoundary('abc 123 ... aa', 9, False)); // 123|
2211 AssertEquals('',11, WBrker.NextBoundary('abc 123 ... aa', 10, False));
2212 AssertEquals('',14, WBrker.NextBoundary('abc 123 ... aa', 11, False)); // |...
2213 AssertEquals('',14, WBrker.NextBoundary('abc 123 ... aa', 12, False));
2214 AssertEquals('',14, WBrker.NextBoundary('abc 123 ... aa', 13, False));
2215 AssertEquals('',15, WBrker.NextBoundary('abc 123 ... aa', 14, False)); // ...|
2216 AssertEquals('',17, WBrker.NextBoundary('abc 123 ... aa', 15, False));
2217 AssertEquals('',17, WBrker.NextBoundary('abc 123 ... aa', 16, False));
2218 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', 17, False)); // at eol
2219 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', 18, False));
2220 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', 19, False));
2221 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', 0, False));
2222 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', -1, False));
2223 AssertEquals('',-1, WBrker.NextBoundary('', 1, False));
2224 AssertEquals('',-1, WBrker.NextBoundary(' ', 1, False));
2225 AssertEquals('',-1, WBrker.NextBoundary(' ', 2, False));
2226 AssertEquals('',3, WBrker.NextBoundary('..aa', 1, False));
2227 AssertEquals('',3, WBrker.NextBoundary('..aa', 2, False));
2228 AssertEquals('',5, WBrker.NextBoundary('..aa', 3, False));
2229 AssertEquals('',5, WBrker.NextBoundary('..aa', 4, False));
2230 AssertEquals('',-1, WBrker.NextBoundary('..aa', 5, False));
2231 AssertEquals('', 2, WBrker.NextBoundary('a a 1', 1, False));
2232 AssertEquals('', 3, WBrker.NextBoundary('a a 1', 2, False));
2233 AssertEquals('', 4, WBrker.NextBoundary('a a 1', 3, False));
2234 AssertEquals('', 5, WBrker.NextBoundary('a a 1', 4, False));
2235 AssertEquals('', 6, WBrker.NextBoundary('a a 1', 5, False));
2236 AssertEquals('',-1, WBrker.NextBoundary('a a 1', 6, False));
2237 AssertEquals('', 2, WBrker.NextBoundary(' a ', 1, False));
2238 AssertEquals('', 3, WBrker.NextBoundary(' a ', 2, False));
2239 AssertEquals('',-1, WBrker.NextBoundary(' a ', 3, False));
2240 AssertEquals('',-1, WBrker.NextBoundary(' a ', 4, False));
2241
2242 AssertEquals('', 1, WBrker.NextBoundary('abc 123 ... aa', 1, True));
2243 AssertEquals('', 4, WBrker.NextBoundary('abc 123 ... aa', 2, True));
2244 AssertEquals('', 4, WBrker.NextBoundary('abc 123 ... aa', 3, True));
2245 AssertEquals('', 4, WBrker.NextBoundary('abc 123 ... aa', 4, True)); // abc|
2246 AssertEquals('', 6, WBrker.NextBoundary('abc 123 ... aa', 5, True));
2247 AssertEquals('', 6, WBrker.NextBoundary('abc 123 ... aa', 6, True)); // |123
2248 AssertEquals('', 9, WBrker.NextBoundary('abc 123 ... aa', 7, True)); // 1|23
2249 AssertEquals('', 9, WBrker.NextBoundary('abc 123 ... aa', 8, True));
2250 AssertEquals('', 9, WBrker.NextBoundary('abc 123 ... aa', 9, True)); // 123|
2251 AssertEquals('',11, WBrker.NextBoundary('abc 123 ... aa', 10, True));
2252 AssertEquals('',11, WBrker.NextBoundary('abc 123 ... aa', 11, True)); // |...
2253 AssertEquals('',14, WBrker.NextBoundary('abc 123 ... aa', 12, True));
2254 AssertEquals('',14, WBrker.NextBoundary('abc 123 ... aa', 13, True));
2255 AssertEquals('',14, WBrker.NextBoundary('abc 123 ... aa', 14, True)); // ...|
2256 AssertEquals('',15, WBrker.NextBoundary('abc 123 ... aa', 15, True));
2257 AssertEquals('',17, WBrker.NextBoundary('abc 123 ... aa', 16, True));
2258 AssertEquals('',17, WBrker.NextBoundary('abc 123 ... aa', 17, True)); // at eol
2259 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', 18, True));
2260 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', 19, True));
2261 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', 0, True));
2262 AssertEquals('',-1, WBrker.NextBoundary('abc 123 ... aa', -1, True));
2263 AssertEquals('',-1, WBrker.NextBoundary('', 1, True));
2264 AssertEquals('',-1, WBrker.NextBoundary(' ', 1, True));
2265 AssertEquals('',-1, WBrker.NextBoundary(' ', 2, True));
2266 AssertEquals('',1, WBrker.NextBoundary('..aa', 1, True));
2267 AssertEquals('',3, WBrker.NextBoundary('..aa', 2, True));
2268 AssertEquals('',3, WBrker.NextBoundary('..aa', 3, True));
2269 AssertEquals('',5, WBrker.NextBoundary('..aa', 4, True));
2270 AssertEquals('',5, WBrker.NextBoundary('..aa', 5, True));
2271 AssertEquals('', 1, WBrker.NextBoundary('a a 1', 1, True));
2272 AssertEquals('', 2, WBrker.NextBoundary('a a 1', 2, True));
2273 AssertEquals('', 3, WBrker.NextBoundary('a a 1', 3, True));
2274 AssertEquals('', 4, WBrker.NextBoundary('a a 1', 4, True));
2275 AssertEquals('', 5, WBrker.NextBoundary('a a 1', 5, True));
2276 AssertEquals('', 6, WBrker.NextBoundary('a a 1', 6, True));
2277 AssertEquals('', 2, WBrker.NextBoundary(' a ', 1, True));
2278 AssertEquals('', 2, WBrker.NextBoundary(' a ', 2, True));
2279 AssertEquals('', 3, WBrker.NextBoundary(' a ', 3, True));
2280 AssertEquals('',-1, WBrker.NextBoundary(' a ', 4, True));
2281
2282 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', 1, False));
2283 AssertEquals('', 1, WBrker.PrevBoundary('abc 123 ... aa', 2, False));
2284 AssertEquals('', 1, WBrker.PrevBoundary('abc 123 ... aa', 3, False));
2285 AssertEquals('', 1, WBrker.PrevBoundary('abc 123 ... aa', 4, False)); // abc|
2286 AssertEquals('', 4, WBrker.PrevBoundary('abc 123 ... aa', 5, False));
2287 AssertEquals('', 4, WBrker.PrevBoundary('abc 123 ... aa', 6, False)); // |123
2288 AssertEquals('', 6, WBrker.PrevBoundary('abc 123 ... aa', 7, False)); // 1|23
2289 AssertEquals('', 6, WBrker.PrevBoundary('abc 123 ... aa', 8, False));
2290 AssertEquals('', 6, WBrker.PrevBoundary('abc 123 ... aa', 9, False)); // 123|
2291 AssertEquals('', 9, WBrker.PrevBoundary('abc 123 ... aa', 10, False));
2292 AssertEquals('', 9, WBrker.PrevBoundary('abc 123 ... aa', 11, False)); // |...
2293 AssertEquals('',11, WBrker.PrevBoundary('abc 123 ... aa', 12, False));
2294 AssertEquals('',11, WBrker.PrevBoundary('abc 123 ... aa', 13, False));
2295 AssertEquals('',11, WBrker.PrevBoundary('abc 123 ... aa', 14, False)); // ...|
2296 AssertEquals('',14, WBrker.PrevBoundary('abc 123 ... aa', 15, False));
2297 AssertEquals('',15, WBrker.PrevBoundary('abc 123 ... aa', 16, False));
2298 AssertEquals('',15, WBrker.PrevBoundary('abc 123 ... aa', 17, False)); // at eol
2299 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', 18, False));
2300 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', 19, False));
2301 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', 0, False));
2302 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', -1, False));
2303 AssertEquals('',-1, WBrker.PrevBoundary('', 1, False));
2304 AssertEquals('',-1, WBrker.PrevBoundary(' ', 1, False));
2305 AssertEquals('',-1, WBrker.PrevBoundary(' ', 2, False));
2306 AssertEquals('',-1, WBrker.PrevBoundary('..aa', 1, False));
2307 AssertEquals('',1, WBrker.PrevBoundary('..aa', 2, False));
2308 AssertEquals('',1, WBrker.PrevBoundary('..aa', 3, False));
2309 AssertEquals('',3, WBrker.PrevBoundary('..aa', 4, False));
2310 AssertEquals('',3, WBrker.PrevBoundary('..aa', 5, False));
2311 AssertEquals('',-1, WBrker.PrevBoundary('a a 1', 1, False));
2312 AssertEquals('', 1, WBrker.PrevBoundary('a a 1', 2, False));
2313 AssertEquals('', 2, WBrker.PrevBoundary('a a 1', 3, False));
2314 AssertEquals('', 3, WBrker.PrevBoundary('a a 1', 4, False));
2315 AssertEquals('', 4, WBrker.PrevBoundary('a a 1', 5, False));
2316 AssertEquals('', 5, WBrker.PrevBoundary('a a 1', 6, False));
2317 AssertEquals('',-1, WBrker.PrevBoundary(' a ', 1, False));
2318 AssertEquals('',-1, WBrker.PrevBoundary(' a ', 2, False));
2319 AssertEquals('', 2, WBrker.PrevBoundary(' a ', 3, False));
2320 AssertEquals('', 3, WBrker.PrevBoundary(' a ', 4, False));
2321
2322 AssertEquals('', 1, WBrker.PrevBoundary('abc 123 ... aa', 1, True));
2323 AssertEquals('', 1, WBrker.PrevBoundary('abc 123 ... aa', 2, True));
2324 AssertEquals('', 1, WBrker.PrevBoundary('abc 123 ... aa', 3, True));
2325 AssertEquals('', 4, WBrker.PrevBoundary('abc 123 ... aa', 4, True)); // abc|
2326 AssertEquals('', 4, WBrker.PrevBoundary('abc 123 ... aa', 5, True));
2327 AssertEquals('', 6, WBrker.PrevBoundary('abc 123 ... aa', 6, True)); // |123
2328 AssertEquals('', 6, WBrker.PrevBoundary('abc 123 ... aa', 7, True)); // 1|23
2329 AssertEquals('', 6, WBrker.PrevBoundary('abc 123 ... aa', 8, True));
2330 AssertEquals('', 9, WBrker.PrevBoundary('abc 123 ... aa', 9, True)); // 123|
2331 AssertEquals('', 9, WBrker.PrevBoundary('abc 123 ... aa', 10, True));
2332 AssertEquals('',11, WBrker.PrevBoundary('abc 123 ... aa', 11, True)); // |...
2333 AssertEquals('',11, WBrker.PrevBoundary('abc 123 ... aa', 12, True));
2334 AssertEquals('',11, WBrker.PrevBoundary('abc 123 ... aa', 13, True));
2335 AssertEquals('',14, WBrker.PrevBoundary('abc 123 ... aa', 14, True)); // ...|
2336 AssertEquals('',15, WBrker.PrevBoundary('abc 123 ... aa', 15, True));
2337 AssertEquals('',15, WBrker.PrevBoundary('abc 123 ... aa', 16, True));
2338 AssertEquals('',17, WBrker.PrevBoundary('abc 123 ... aa', 17, True)); // at eol
2339 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', 18, True));
2340 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', 19, True));
2341 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', 0, True));
2342 AssertEquals('',-1, WBrker.PrevBoundary('abc 123 ... aa', -1, True));
2343 AssertEquals('',-1, WBrker.PrevBoundary('', 1, True));
2344 AssertEquals('',-1, WBrker.PrevBoundary(' ', 1, True));
2345 AssertEquals('',-1, WBrker.PrevBoundary(' ', 2, True));
2346 AssertEquals('',1, WBrker.PrevBoundary('..aa', 1, True));
2347 AssertEquals('',1, WBrker.PrevBoundary('..aa', 2, True));
2348 AssertEquals('',3, WBrker.PrevBoundary('..aa', 3, True));
2349 AssertEquals('',3, WBrker.PrevBoundary('..aa', 4, True));
2350 AssertEquals('',5, WBrker.PrevBoundary('..aa', 5, True));
2351 AssertEquals('', 1, WBrker.PrevBoundary('a a 1', 1, True));
2352 AssertEquals('', 2, WBrker.PrevBoundary('a a 1', 2, True));
2353 AssertEquals('', 3, WBrker.PrevBoundary('a a 1', 3, True));
2354 AssertEquals('', 4, WBrker.PrevBoundary('a a 1', 4, True));
2355 AssertEquals('', 5, WBrker.PrevBoundary('a a 1', 5, True));
2356 AssertEquals('', 6, WBrker.PrevBoundary('a a 1', 6, True));
2357 AssertEquals('',-1, WBrker.PrevBoundary(' a ', 1, True));
2358 AssertEquals('', 2, WBrker.PrevBoundary(' a ', 2, True));
2359 AssertEquals('', 3, WBrker.PrevBoundary(' a ', 3, True));
2360 AssertEquals('', 3, WBrker.PrevBoundary(' a ', 4, True));
2361
2362
2363 FreeAndNil(WBrker);
2364 end;
2365
2366 procedure TTestBasicSynEdit.TestSearchReplace;
TestText1null2367 function TestText1: TStringArray;
2368 begin
2369 SetLength(Result, 9);
2370 Result[0] := 'aaaa';
2371 Result[1] := 'xx11';
2372 Result[2] := 'cccc';
2373 Result[3] := '1 1 x';
2374 Result[4] := '9';
2375 Result[5] := '1 1 x';
2376 Result[6] := '9';
2377 Result[7] := '';
2378 Result[8] := '';
2379 end;
2380
2381 type
2382 TCaretBlockCoordinates = record x,y, BBx, BBy, BEx, BEy: Integer end;
2383
expCnull2384 function expC(ExpCaretX, ExpCaretY, ExpBBX, ExpBBY, ExpBEX, ExpBEY : Integer): TCaretBlockCoordinates;
2385 begin
2386 with result do begin
2387 x := ExpCaretX; y := ExpCaretY;
2388 BBx := ExpBBX; BBy := ExpBBY;
2389 BEx := ExpBEX; BEy := ExpBEY;
2390 end;
2391 end;
expCnull2392 function expC(ExpCaretX, ExpCaretY: Integer; ExpBBX : Integer = -1): TCaretBlockCoordinates;
2393 begin
2394 Result := ExpC(ExpCaretX, ExpCaretY, ExpBBX, -1, -1, -1);
2395 end;
expCnull2396 function expC(ExpBBX, ExpBBY, ExpBEX, ExpBEY: Integer): TCaretBlockCoordinates;
2397 begin
2398 with result do begin
2399 x := -1; y := -1;
2400 BBx := ExpBBX; BBy := ExpBBY;
2401 BEx := ExpBEX; BEy := ExpBEY;
2402 end;
2403 end;
expCNonull2404 function expCNo(ExpCaretX, ExpCaretY: Integer): TCaretBlockCoordinates; // no solection
2405 begin
2406 Result := expC(ExpCaretX, ExpCaretY, -2);
2407 end;
expCFwnull2408 function expCFw(ExpBBX, ExpBBY, ExpBEX, ExpBEY: Integer): TCaretBlockCoordinates;
2409 begin // Forward selection
2410 with result do begin
2411 x := ExpBEX; y := ExpBEY;
2412 BBx := ExpBBX; BBy := ExpBBY;
2413 BEx := ExpBEX; BEy := ExpBEY;
2414 end;
2415 end;
expCBwnull2416 function expCBw(ExpBBX, ExpBBY, ExpBEX, ExpBEY: Integer): TCaretBlockCoordinates;
2417 begin // Backward selection
2418 with result do begin
2419 x := ExpBBX; y := ExpBBY;
2420 BBx := ExpBBX; BBy := ExpBBY;
2421 BEx := ExpBEX; BEy := ExpBEY;
2422 end;
2423 end;
2424
nextSelnull2425 function nextSel(ExpBBX, ExpBBY, ExpBEX, ExpBEY: Integer): TCaretBlockCoordinates;
2426 begin
2427 Result := expC(ExpBBX, ExpBBY, ExpBEX, ExpBEY);
2428 end;
2429
2430 var
2431 TheTestText: TStringArray;
2432 NextTestSetSelection: TCaretBlockCoordinates;
2433
2434 procedure TestCoord(Name: String; ExpCoord: TCaretBlockCoordinates);
2435 begin
2436 if ExpCoord.x > 0 then
2437 TestIsCaret(Name+' Caret ', ExpCoord.x, ExpCoord.y);
2438 if ExpCoord.BBx > 0 then
2439 TestIsSelection(Name+' Selection ', ExpCoord.BBx, ExpCoord.BBy, ExpCoord.BEx, ExpCoord.BEy);
2440 if ExpCoord.BBx = -2 then
2441 TestIsSelection(Name+' NO Selection ', SynEdit.LogicalCaretXY.x, SynEdit.CaretY, SynEdit.LogicalCaretXY.x, SynEdit.CaretY);
2442 end;
2443
2444 procedure TestSearch(Name, Find, Repl: String; SrcOpts: TSynSearchOptions;
2445 CaretX, CaretY: Integer;
2446 ExpCnt: Integer; ExpTxt: Array of const;
2447 ExpSearchCoord, ExpReplCoord: TCaretBlockCoordinates
2448 );
2449 var
2450 got: Integer;
2451 begin
2452 ReCreateEdit;
2453 SynEdit.Options := SynEdit.Options + [eoScrollPastEol];
2454 Name := ' - ' + Name;
2455
2456 PushBaseName('Search');
2457 SetLines(TheTestText);
2458 if NextTestSetSelection.BBx > 0 then
2459 with NextTestSetSelection do SetCaretAndSel(BBx, BBy, BEx, BEy)
2460 else
2461 SetCaret(CaretX, CaretY);
2462 got := SynEdit.SearchReplace(Find, '', SrcOpts - [ssoReplace, ssoReplaceAll]);
2463 AssertEquals(BaseTestName + Name + 'Result Count', Min(ExpCnt,1), got);
2464 TestCoord(Name, ExpSearchCoord);
2465 PopBaseName;
2466
2467 PushBaseName('Search ssoRegExprMultiLine');
2468 SetLines(TheTestText);
2469 if NextTestSetSelection.BBx > 0 then
2470 with NextTestSetSelection do SetCaretAndSel(BBx, BBy, BEx, BEy)
2471 else
2472 SetCaret(CaretX, CaretY);
2473 got := SynEdit.SearchReplace(Find, '', SrcOpts - [ssoReplace, ssoReplaceAll]+[ssoRegExprMultiLine]);
2474 AssertEquals(BaseTestName + Name + 'Result Count', Min(ExpCnt,1), got);
2475 TestCoord(Name, ExpSearchCoord);
2476 PopBaseName;
2477
2478 if (SrcOpts * [ssoReplace, ssoReplaceAll]) = [] then exit;
2479
2480 PushBaseName('Replace');
2481 SetLines(TheTestText);
2482 if NextTestSetSelection.BBx > 0 then
2483 with NextTestSetSelection do SetCaretAndSel(BBx, BBy, BEx, BEy)
2484 else
2485 SetCaret(CaretX, CaretY);
2486 got := SynEdit.SearchReplace(Find, Repl, SrcOpts);
2487 AssertEquals(BaseTestName + Name + 'Result Count', ExpCnt, got);
2488 TestIsText(Name + 'Result Text', TheTestText, ExpTxt);
2489 TestCoord(Name, ExpReplCoord);
2490 PopBaseName;
2491
2492 PushBaseName('Replace ssoRegExprMultiLine');
2493 SetLines(TheTestText);
2494 if NextTestSetSelection.BBx > 0 then
2495 with NextTestSetSelection do SetCaretAndSel(BBx, BBy, BEx, BEy)
2496 else
2497 SetCaret(CaretX, CaretY);
2498 got := SynEdit.SearchReplace(Find, Repl, SrcOpts+[ssoRegExprMultiLine]);
2499 AssertEquals(BaseTestName + Name + 'Result Count', ExpCnt, got);
2500 TestIsText(Name + 'Result Text', TheTestText, ExpTxt);
2501 TestCoord(Name, ExpReplCoord);
2502 PopBaseName;
2503
2504 NextTestSetSelection := expCNo(-1,-1);
2505 end;
2506
2507 procedure TestSearch(Name, Find, Repl: String; SrcOpts: TSynSearchOptions;
2508 CaretX, CaretY: Integer; ExpCnt: Integer; ExpTxt: Array of const);
2509 begin
2510 TestSearch(Name, Find, Repl, SrcOpts, CaretX, CaretY, ExpCnt, ExpTxt, ExpC(-1,-1), ExpC(-1,-1));
2511 end;
2512 procedure TestSearch(Name, Find, Repl: String; Opts: TSynSearchOptions;
2513 ExpCnt: Integer; ExpTxt: Array of const);
2514 begin
2515 if ssoBackwards in Opts
2516 then TestSearch(Name, Find, Repl, Opts, 1,length(TheTestText)-1, ExpCnt, ExpTxt)
2517 else TestSearch(Name, Find, Repl, Opts, 1,1, ExpCnt, ExpTxt);
2518 end;
2519 procedure TestSearch(Name, Find, Repl: String; Opts: TSynSearchOptions;
2520 ExpCnt: Integer; ExpTxt: Array of const; ExpSearchCoord, ExpReplCoord: TCaretBlockCoordinates);
2521 begin
2522 if ssoBackwards in Opts
2523 then TestSearch(Name, Find, Repl, Opts, 1,length(TheTestText)-1, ExpCnt, ExpTxt, ExpSearchCoord, ExpReplCoord)
2524 else TestSearch(Name, Find, Repl, Opts, 1,1, ExpCnt, ExpTxt, ExpSearchCoord, ExpReplCoord);
2525 end;
2526
2527 const
2528 LE = LineEnding;
2529 optAllAll: TSynSearchOptions = [ssoEntireScope, ssoReplace, ssoReplaceAll];
2530 optAllAllB: TSynSearchOptions = [ssoEntireScope, ssoReplace, ssoReplaceAll, ssoBackwards];
2531 optSelAll: TSynSearchOptions = [ssoSelectedOnly, ssoReplace, ssoReplaceAll];
2532 optSelAllB: TSynSearchOptions = [ssoSelectedOnly, ssoReplace, ssoReplaceAll, ssoBackwards];
2533 var f, r: String;
2534 var txl: Integer;
2535 begin
2536 FPersistSel := False;
2537 TheTestText := TestText1;
2538 txl := length(TheTestText)-1;
2539 NextTestSetSelection := nextSel(0,0, 0,0);
2540
2541 PushBaseName('Find single line term ');
2542 PushBaseName('no match ');
2543 f := '11xx';
2544 r := '2222';
2545 TestSearch('', f, r, optAllAll, 0, [], expCNo(1,1), expCNo(1,1) );
2546 TestSearch('backward', f, r, optAllAllB, 0, [], expCNo(1,txl), expCNo(1,txl) );
2547
2548 PopPushBaseName('match - full line');
2549 f := 'xx11';
2550 r := '2222';
2551 TestSearch('', f, r, optAllAll, 1, [2, '2222'], expCFw(1,2, 5,2), expCFw(1,2, 5,2) );
2552 TestSearch('backward', f, r, optAllAllB, 1, [2, '2222'], expCBw(1,2, 5,2), expCBw(1,2, 5,2) );
2553
2554 r := '';
2555 TestSearch('repl-empty ', f, r, optAllAll, 1, [2, ''], expCFw(1,2, 5,2), expCNo(1,2) );
2556 TestSearch('repl-empty backward', f, r, optAllAllB, 1, [2, ''], expCBw(1,2, 5,2), expCNo(1,2) );
2557
2558 r := LE;
2559 TestSearch('repl-CR ', f, r, optAllAll, 1, [2, '', ''], expCFw(1,2, 5,2), expCFw(1,2, 1,3) );
2560 TestSearch('repl-CR backward', f, r, optAllAllB, 1, [2, '', ''], expCBw(1,2, 5,2), expCBw(1,2, 1,3) );
2561
2562 PopPushBaseName('match - part line (end)');
2563 f := 'x11';
2564 r := '22';
2565 TestSearch('repl-shorter ', f, r, optAllAll, 1, [2, 'x22'], expCFw(2,2, 5,2), expCFw(2,2, 4,2) );
2566 TestSearch('repl-shorter backward', f, r, optAllAllB, 1, [2, 'x22'], expCBw(2,2, 5,2), expCBw(2,2, 4,2) );
2567
2568 r := '2222';
2569 TestSearch('repl-longer ', f, r, optAllAll, 1, [2, 'x2222'], expCFw(2,2, 5,2), expCFw(2,2, 6,2) );
2570 TestSearch('repl-longer backward', f, r, optAllAllB, 1, [2, 'x2222'], expCBw(2,2, 5,2), expCBw(2,2, 6,2) );
2571
2572 r := LE;
2573 TestSearch('repl-CR ', f, r, optAllAll, 1, [2, 'x', ''], expCFw(2,2, 5,2), expCFw(2,2, 1,3) );
2574 TestSearch('repl-CR backward', f, r, optAllAllB, 1, [2, 'x', ''], expCBw(2,2, 5,2), expCBw(2,2, 1,3) );
2575
2576 PopPushBaseName('match in selection');
2577 f := '1';
2578 r := 'N';
2579 NextTestSetSelection := nextSel(1,4, 2,6);
2580 TestSearch('repl-at-end ', f, r, optSelAll, 3, [4,'N N x', 6,'N 1 x'], expCFw(1,4, 2,4), expCFw(1,6, 2,6) );
2581 NextTestSetSelection := nextSel(1,4, 2,6);
2582 TestSearch('repl-at-end backward', f, r, optSelAllB, 3, [4,'N N x', 6,'N 1 x'], expCBw(1,6, 2,6), expCBw(1,4, 2,4) );
2583
2584 NextTestSetSelection := nextSel(1,4, 3,6);
2585 TestSearch('no-repl-after-end ', f, r, optSelAll, 3, [4,'N N x', 6,'N 1 x'], expCFw(1,4, 2,4), expCFw(1,6, 2,6) );
2586 NextTestSetSelection := nextSel(1,4, 3,6);
2587 TestSearch('no-repl-after-end backward', f, r, optSelAllB, 3, [4,'N N x', 6,'N 1 x'], expCBw(1,6, 2,6), expCBw(1,4, 2,4) );
2588
2589 NextTestSetSelection := nextSel(1,4, 1,6);
2590 TestSearch('no-repl-after-end(BOL) ', f, r, optSelAll, 2, [4,'N N x'], expCFw(1,4, 2,4), expCFw(3,4, 4,4) );
2591 NextTestSetSelection := nextSel(1,4, 1,6);
2592 TestSearch('no-repl-after-end(BOL) backward', f, r, optSelAllB, 2, [4,'N N x'], expCBw(3,4, 4,4), expCBw(1,4, 2,4) );
2593
2594 PopPushBaseName('match in selection, repl-SHORTER - to empty');
2595 r := '';
2596 NextTestSetSelection := nextSel(1,4, 4,6);
2597 TestSearch('repl-at-end ', f, r, optSelAll, 4, [4,' x', 6,' x'], expCFw(1,4, 2,4), expCNo(2,6) );
2598 NextTestSetSelection := nextSel(1,4, 4,6);
2599 TestSearch('repl-at-end backward', f, r, optSelAllB, 4, [4,' x', 6,' x'], expCBw(3,6, 4,6), expCNo(1,4) );
2600
2601 NextTestSetSelection := nextSel(1,4, 3,6);
2602 TestSearch('no-repl-after-end ', f, r, optSelAll, 3, [4,' x', 6,' 1 x'], expCFw(1,4, 2,4), expCNo(1,6) );
2603 NextTestSetSelection := nextSel(1,4, 3,6);
2604 TestSearch('no-repl-after-end backward', f, r, optSelAllB, 3, [4,' x', 6,' 1 x'], expCBw(1,6, 2,6), expCNo(1,4) );
2605
2606 PopPushBaseName('match in selection, repl-LONGER');
2607 r := 'NN';
2608 NextTestSetSelection := nextSel(1,4, 4,6);
2609 TestSearch('repl-at-end ', f, r, optSelAll, 4, [4,'NN NN x', 6,'NN NN x'], expCFw(1,4, 2,4), expCFw(4,6, 6,6) );
2610 NextTestSetSelection := nextSel(1,4, 4,6);
2611 TestSearch('repl-at-end backward', f, r, optSelAllB, 4, [4,'NN NN x', 6,'NN NN x'], expCBw(3,6, 4,6), expCBw(1,4, 3,4) );
2612
2613 NextTestSetSelection := nextSel(1,4, 3,6);
2614 TestSearch('no-repl-after-end ', f, r, optSelAll, 3, [4,'NN NN x', 6,'NN 1 x'], expCFw(1,4, 2,4), expCFw(1,6, 3,6) );
2615 NextTestSetSelection := nextSel(1,4, 3,6);
2616 TestSearch('no-repl-after-end backward', f, r, optSelAllB, 3, [4,'NN NN x', 6,'NN 1 x'], expCBw(1,6, 2,6), expCBw(1,4, 3,4) );
2617
2618 PopPushBaseName('match in selection, repl-CR');
2619 r := LE;
2620 NextTestSetSelection := nextSel(1,4, 4,6);
2621 TestSearch('repl-at-end ', f, r, optSelAll, 4, [4,'',' ',' x', 8,'',' ',' x'], expCFw(1,4, 2,4), expCFw(2,9, 1,10) );
2622 NextTestSetSelection := nextSel(1,4, 4,6);
2623 TestSearch('repl-at-end backward', f, r, optSelAllB, 4, [4,'',' ',' x', 8,'',' ',' x'], expCBw(3,6, 4,6), expCBw(1,4, 1,5) );
2624
2625 NextTestSetSelection := nextSel(1,4, 3,6);
2626 TestSearch('no-repl-after-end ', f, r, optSelAll, 3, [4,'',' ',' x', 8,'',' 1 x'], expCFw(1,4, 2,4), expCFw(1,8, 1,9) );
2627 NextTestSetSelection := nextSel(1,4, 3,6);
2628 TestSearch('no-repl-after-end backward', f, r, optSelAllB, 3, [4,'',' ',' x', 8,'',' 1 x'], expCBw(1,6, 2,6), expCBw(1,4, 1,5) );
2629
2630 PopBaseName;
2631
2632
2633 PopPushBaseName('Find with trailing CR ');
2634 PushBaseName('no match ');
2635 f := 'xx'+LE;
2636 r := '11'+LE;
2637 TestSearch('', f, r, optSelAll, 0, [], expCNo(1,1), expCNo(1,1) );
2638 TestSearch('backward', f, r, optSelAllB, 0, [], expCNo(1,txl), expCNo(1,txl) );
2639
2640 PopPushBaseName('match ');
2641 f := '11'+LE;
2642 r := 'bb'+LE;
2643 TestSearch('', f, r, optSelAll, 1, [2, 'xxbb'], expCFw(3,2, 1,3), expCFw(3,2, 1,3) );
2644 TestSearch('backward', f, r, optSelAllB, 1, [2, 'xxbb'], expCBw(3,2, 1,3), expCBw(3,2, 1,3) );
2645 PopBaseName;
2646
2647 PopPushBaseName('Find with leading CR ');
2648 PushBaseName('no match ');
2649 f := LE+'11';
2650 r := LE+'xx';
2651 TestSearch('', f, r, optSelAll, 0, [], expCNo(1,1), expCNo(1,1) );
2652 TestSearch('backward', f, r, optSelAllB, 0, [], expCNo(1,txl), expCNo(1,txl) );
2653
2654 PopPushBaseName('match ');
2655 f := LE+'xx';
2656 r := LE+'bb';
2657 TestSearch('', f, r, optSelAll, 1, [2, 'bb11'], expCFw(5,1, 3,2), expCFw(5,1, 3,2) );
2658 TestSearch('backward', f, r, optSelAllB, 1, [2, 'bb11'], expCBw(5,1, 3,2), expCBw(5,1, 3,2) );
2659 PopBaseName;
2660
2661 PopBaseName;
2662 end;
2663
2664 procedure TTestBasicSynEdit.TestMoveLineUpDown;
2665 begin
2666 FDoInit := @DoInit1;
2667 FPersistSel := False;
2668 FTestLines := @TestLines2;
2669
2670 FTestCommand := ecMoveLineUp;
2671 TestCommand('ecMoveLineUp - no sel', 1,3, 1,2, [2, '123 456 789', 3, 'ABC DEF GHI']);
2672 TestCommand('ecMoveLineUp - no sel', 4,3, 4,2, [2, '123 456 789', 3, 'ABC DEF GHI']);
2673 TestCommand('ecMoveLineUp - 1L part sel', 2,3, 4,3, 2,2, 4,2, [2, '123 456 789', 3, 'ABC DEF GHI']);
2674 TestCommand('ecMoveLineUp - 1L part sel', 2,3, 1,4, 2,2, 1,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2675 TestCommand('ecMoveLineUp - 1L full sel', 1,3, 1,4, 1,2, 1,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2676
2677 TestCommand('ecMoveLineUp - 2L part sel', 2,3, 3,4, 2,2, 3,3, [2, '123 456 789', 3, 'mno pqr stu', 4, 'ABC DEF GHI']);
2678 TestCommand('ecMoveLineUp - 2L part sel', 2,3, 1,5, 2,2, 1,4, [2, '123 456 789', 3, 'mno pqr stu', 4, 'ABC DEF GHI']);
2679 TestCommand('ecMoveLineUp - 2L full sel', 1,3, 1,5, 1,2, 1,4, [2, '123 456 789', 3, 'mno pqr stu', 4, 'ABC DEF GHI']);
2680
2681
2682 FTestCommand := ecMoveLineDown;
2683 TestCommand('ecMoveLineDown - no sel', 1,2, 1,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2684 TestCommand('ecMoveLineDown - no sel', 4,2, 4,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2685 TestCommand('ecMoveLineDown - 1L part sel', 2,2, 4,2, 2,3, 4,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2686 TestCommand('ecMoveLineDown - 1L part sel', 2,2, 1,3, 2,3, 1,4, [2, '123 456 789', 3, 'ABC DEF GHI']);
2687 TestCommand('ecMoveLineDown - 1L full sel', 1,2, 1,3, 1,3, 1,4, [2, '123 456 789', 3, 'ABC DEF GHI']);
2688
2689 TestCommand('ecMoveLineDown - 2L part sel', 2,2, 3,3, 2,3, 3,4, [2, 'mno pqr stu', 3, 'ABC DEF GHI', 4, '123 456 789']);
2690 TestCommand('ecMoveLineDown - 2L part sel', 2,2, 1,4, 2,3, 1,5, [2, 'mno pqr stu', 3, 'ABC DEF GHI', 4, '123 456 789']);
2691 TestCommand('ecMoveLineDown - 2L full sel', 1,2, 1,4, 1,3, 1,5, [2, 'mno pqr stu', 3, 'ABC DEF GHI', 4, '123 456 789']);
2692
2693
2694 FPersistSel := true;
2695
2696 FTestCommand := ecMoveLineUp;
2697 TestCommand('ecMoveLineUp - no sel', 1,3, 1,2, [2, '123 456 789', 3, 'ABC DEF GHI']);
2698 TestCommand('ecMoveLineUp - no sel', 4,3, 4,2, [2, '123 456 789', 3, 'ABC DEF GHI']);
2699 TestCommand('ecMoveLineUp - 1L part sel', 2,3, 4,3, 2,2, 4,2, [2, '123 456 789', 3, 'ABC DEF GHI']);
2700 TestCommand('ecMoveLineUp - 1L part sel', 2,3, 1,4, 2,2, 1,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2701 TestCommand('ecMoveLineUp - 1L full sel', 1,3, 1,4, 1,2, 1,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2702
2703 TestCommand('ecMoveLineUp - 2L part sel', 2,3, 3,4, 2,2, 3,3, [2, '123 456 789', 3, 'mno pqr stu', 4, 'ABC DEF GHI']);
2704 TestCommand('ecMoveLineUp - 2L part sel', 2,3, 1,5, 2,2, 1,4, [2, '123 456 789', 3, 'mno pqr stu', 4, 'ABC DEF GHI']);
2705 TestCommand('ecMoveLineUp - 2L full sel', 1,3, 1,5, 1,2, 1,4, [2, '123 456 789', 3, 'mno pqr stu', 4, 'ABC DEF GHI']);
2706
2707
2708 FTestCommand := ecMoveLineDown;
2709 TestCommand('ecMoveLineDown - no sel', 1,2, 1,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2710 TestCommand('ecMoveLineDown - no sel', 4,2, 4,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2711 TestCommand('ecMoveLineDown - 1L part sel', 2,2, 4,2, 2,3, 4,3, [2, '123 456 789', 3, 'ABC DEF GHI']);
2712 TestCommand('ecMoveLineDown - 1L part sel', 2,2, 1,3, 2,3, 1,4, [2, '123 456 789', 3, 'ABC DEF GHI']);
2713 TestCommand('ecMoveLineDown - 1L full sel', 1,2, 1,3, 1,3, 1,4, [2, '123 456 789', 3, 'ABC DEF GHI']);
2714
2715 TestCommand('ecMoveLineDown - 2L part sel', 2,2, 3,3, 2,3, 3,4, [2, 'mno pqr stu', 3, 'ABC DEF GHI', 4, '123 456 789']);
2716 TestCommand('ecMoveLineDown - 2L part sel', 2,2, 1,4, 2,3, 1,5, [2, 'mno pqr stu', 3, 'ABC DEF GHI', 4, '123 456 789']);
2717 TestCommand('ecMoveLineDown - 2L full sel', 1,2, 1,4, 1,3, 1,5, [2, 'mno pqr stu', 3, 'ABC DEF GHI', 4, '123 456 789']);
2718
2719 end;
2720
2721
2722
2723 initialization
2724
2725 RegisterTest(TTestBasicSynEdit);
2726 end.
2727
2728