1 unit TestSynTextArea;
2
3 {$mode objfpc}{$H+}
4 {$INLINE OFF}
5
6 interface
7
8 uses
9 Classes, SysUtils, testregistry, TestBase, LazSynTextArea, SynEditTypes,
10 SynEditMarkupBracket, SynEdit, SynHighlighterPosition, SynEditMiscClasses,
11 Graphics;
12
13 type
14
15 { TTestSynTextArea }
16
17 TTestSynTextArea = class(TTestBase)
18 private
19 FTheHighLighter: TSynPositionHighlighter;
20 FtkRed, FtkGreen, FtkBlue, FtkYellow: TtkTokenKind;
21 protected
22 FTokenBreaker: TLazSynPaintTokenBreaker;
23
24 procedure ReCreateEdit; reintroduce;
CreateTheHighLighternull25 function CreateTheHighLighter: TSynPositionHighlighter;
26 procedure SetUp; override;
27 procedure TearDown; override;
28
29 procedure SetRealLinesText;
30 published
31 procedure TestPaintTokenBreaker;
32 end;
33
34 implementation
35
36
37 { TTestSynTextArea }
38
39 procedure TTestSynTextArea.ReCreateEdit;
40 begin
41 if Assigned(SynEdit) then
42 SynEdit.Highlighter := nil;
43 FreeAndNil(FTheHighLighter);
44 inherited ReCreateEdit;
45 FTheHighLighter := CreateTheHighLighter;
46 SynEdit.Highlighter := FTheHighLighter;
47 SynEdit.Color := clWhite;
48 SynEdit.Font.Color := clBlack;
49 SynEdit.SelectedColor.Foreground := clPurple;
50 FTokenBreaker.ForegroundColor := clBlack;
51 FTokenBreaker.BackgroundColor := clWhite;
52 end;
53
CreateTheHighLighternull54 function TTestSynTextArea.CreateTheHighLighter: TSynPositionHighlighter;
55 begin
56 Result := TSynPositionHighlighter.Create(nil);
57 FtkRed := Result.CreateTokenID('red', clRed, clDefault, []);
58 FtkGreen := Result.CreateTokenID('green', clGreen, clDefault, []);
59 FtkBlue := Result.CreateTokenID('blue', clBlue, clDefault, []);
60 FtkYellow := Result.CreateTokenID('yellow', clYellow, clDefault, []);
61 end;
62
63 procedure TTestSynTextArea.SetUp;
64 begin
65 inherited SetUp;
66 FTokenBreaker := TLazSynPaintTokenBreaker.Create;
67 end;
68
69 procedure TTestSynTextArea.TearDown;
70 begin
71 FTokenBreaker.Free;
72 inherited TearDown;
73 end;
74
75 procedure TTestSynTextArea.SetRealLinesText;
76 begin
77 ReCreateEdit;
78 SetLines(['unit foo;', // 1
79 'interface//', // Hl-token
80 'const',
81 ' test =''abcDEF'';',
82 ' testa=''a あアア F'';', // 5
83 ' testb=''aääDEF''; // föö bar',
84 #9'i=123;', // 7 // Hl-token
85 ' a'#9'=0;',
86 #9#9#9#9'end',
87 '', // 10
88 'شس',
89 'شس ي',
90 'ABشس يCD',
91 #9'i'#9'12'#9,
92 'ي'#9'شس', // 15
93 #9'('#9')',
94 '//شس يشس ي(شس ي',
95 'a ''شس''b',
96 'a ''شسقف',
97 'a ''شسقف', // 20
98 ''
99 ]);
100 end;
101
102 procedure TTestSynTextArea.TestPaintTokenBreaker;
103 var
104 BaseName, Name: String;
105 TkCnt: Integer;
106 Token: TLazSynDisplayTokenInfoEx;
107 UseViewTokenOnly: Boolean;
108 SkipPreFirst: Boolean;
109 type
110 TBoundExpectation = record
111 ExpPhys, ExpLog, ExpOffs: Integer;
112 WantOffs: Boolean;
113 end;
114
bnull115 function b(AExpPhys, AExpLog: Integer): TBoundExpectation;
116 begin
117 Result.ExpPhys := AExpPhys;
118 Result.ExpLog := AExpLog;
119 Result.WantOffs := False;
120 end;
121
bnull122 function b(AExpPhys, AExpLog, AExpOffs: Integer): TBoundExpectation;
123 begin
124 Result.ExpPhys := AExpPhys;
125 Result.ExpLog := AExpLog;
126 Result.ExpOffs := AExpOffs;
127 Result.WantOffs := True;
128 end;
129
130 procedure TestBound(AName: String; ABound: TLazSynDisplayTokenBound; AExpect: TBoundExpectation);
131 begin
132 AssertEquals(AName + ' Bound.Phys', AExpect.ExpPhys, ABound.Physical);
133 AssertEquals(AName + ' Bound.Log', AExpect.ExpLog, ABound.Logical);
134 if AExpect.WantOffs then
135 AssertEquals(AName + ' Bound.Offs', AExpect.ExpOffs, ABound.Offset);
136 end;
137
138 procedure TestStart(AName: String; ALine, AFirst, ALast: Integer; ExpRLine: Integer = -1);
139 // ALine, ExpRLine: 1-based
140 var
141 RLine: TLineIdx;
142 begin
143 BaseName := Format('%s::%s (Line=%d, F/L=%d-%d): ', [BaseTestName, AName, ALine, AFirst, ALast]);
144 Name := BaseName;
145 TkCnt := 0;
146 FTokenBreaker.Prepare(SynEdit.ViewedTextBuffer.DisplayView,
147 SynEdit.ViewedTextBuffer,
148 SynEdit.TextArea.MarkupManager,
149 AFirst, ALast);
150 FTokenBreaker.SetHighlighterTokensLine(ALine-1, RLine);
151 if ExpRLine >= 0 then
152 AssertEquals(Name+'Got RealLine', ExpRLine-1, RLine);
153
154 if not UseViewTokenOnly then
155 SynEdit.TextArea.MarkupManager.PrepareMarkupForRow(ALine);
156 end;
157
158 procedure TestPreFirst(ExpNext: TBoundExpectation; ExpNxtIsRtl: Boolean);
159 var
160 R: Boolean;
161 begin
162 if SkipPreFirst then exit;
163 Name := Format('%sL (Pre-First): ', [BaseName]);
164 R := FTokenBreaker.GetNextHighlighterTokenFromView(Token, -1, 1);
165
166 AssertTrue(Name + 'Got Token', R);
167 TestBound(Name + ' Next(BOL)', Token.NextPos, ExpNext);
168 AssertEquals(Name + 'Nxt IsRtl', ExpNxtIsRtl, Token.NextRtlInfo.IsRtl);
169 end;
170
171 procedure TestNext(ALimits: Array of Integer);
172 var
173 R: Boolean;
174 PhysLimit, LogLimit: Integer;
175 begin
176 inc(TkCnt);
177 PhysLimit := -1;
178 LogLimit := -1;
179 if Length(ALimits) > 0 then PhysLimit := ALimits[0];
180 if Length(ALimits) > 1 then LogLimit := ALimits[1];
181 Name := Format('%sL=%d (%d): ', [BaseName, PhysLimit, TkCnt]);
182 if UseViewTokenOnly
183 then R := FTokenBreaker.GetNextHighlighterTokenFromView(Token, PhysLimit, LogLimit)
184 else R := FTokenBreaker.GetNextHighlighterTokenEx(Token);
185
186 AssertTrue(Name + 'Got Token', R);
187 end;
188
189 procedure TestNext(ALimits: Array of Integer;
190 ExpStart, ExpEnd: TBoundExpectation;
191 ExpCharStart, ExpCharEnd: Integer; ExpClipStart, ExpClipEnd: Integer;
192 ExpIsRtl: Boolean; ExpText: String);
193 begin
194 TestNext(ALimits);
195
196 TestBound(Name + ' Start', Token.StartPos, ExpStart);
197 TestBound(Name + ' End', Token.EndPos, ExpEnd);
198 AssertEquals(Name + ' PhysicalCharStart', ExpCharStart, Token.PhysicalCharStart);
199 AssertEquals(Name + ' PhysicalCharEnd', ExpCharEnd, Token.PhysicalCharEnd);
200 AssertEquals(Name + ' PhysicalClipStart', ExpClipStart, Token.PhysicalClipStart);
201 AssertEquals(Name + ' PhysicalClipEnd', ExpClipEnd, Token.PhysicalClipEnd);
202 AssertEquals(Name + ' ExpIsRtl', ExpIsRtl, Token.RtlInfo.IsRtl);
203 AssertEquals(Name + ' Text', ExpText, copy(Token.Tk.TokenStart, 1, Token.Tk.TokenLength));
204 end;
205
206 procedure TestNext(ALimits: Array of Integer;
207 ExpStart, ExpEnd: TBoundExpectation;
208 ExpCharStart, ExpCharEnd: Integer; ExpClipStart, ExpClipEnd: Integer;
209 ExpIsRtl: Boolean; ExpText: String;
210 ExpFColor: TColor);
211 begin
212 TestNext(ALimits, ExpStart, ExpEnd, ExpCharStart, ExpCharEnd, ExpClipStart,
213 ExpClipEnd, ExpIsRtl, ExpText);
214
215 AssertEquals(Name + ' F-Color', ExpFColor, Token.Attr.Foreground);
216 end;
217
218 procedure TestNext(ALimits: Array of Integer;
219 ExpStart, ExpEnd: TBoundExpectation;
220 ExpCharStart, ExpCharEnd: Integer; ExpClipStart, ExpClipEnd: Integer;
221 ExpIsRtl: Boolean; ExpText: String;
222 ExpNext: TBoundExpectation; ExpNxtIsRtl: Boolean);
223 begin
224 TestNext(ALimits, ExpStart, ExpEnd, ExpCharStart, ExpCharEnd, ExpClipStart,
225 ExpClipEnd, ExpIsRtl, ExpText);
226
227 TestBound(Name + ' Next', Token.NextPos, ExpNext);
228 AssertEquals(Name + 'Nxt IsRtl', ExpNxtIsRtl, Token.NextRtlInfo.IsRtl);
229 end;
230
231 procedure TestNext(ALimits: Array of Integer;
232 ExpStart, ExpEnd: TBoundExpectation;
233 ExpCharStart, ExpCharEnd: Integer; ExpClipStart, ExpClipEnd: Integer;
234 ExpIsRtl: Boolean; ExpText: String;
235 ExpFColor: TColor;
236 ExpNext: TBoundExpectation; ExpNxtIsRtl: Boolean);
237 begin
238 TestNext(ALimits, ExpStart, ExpEnd, ExpCharStart, ExpCharEnd, ExpClipStart,
239 ExpClipEnd, ExpIsRtl, ExpText, ExpNext, ExpNxtIsRtl);
240
241 AssertEquals(Name + ' F-Color', ExpFColor, Token.Attr.Foreground);
242 end;
243
244 procedure TestEnd;
245 var
246 R: Boolean;
247 begin
248 inc(TkCnt);
249 Name := Format('%sL=(%d): ', [BaseName, TkCnt]);
250 if UseViewTokenOnly
251 then R := FTokenBreaker.GetNextHighlighterTokenFromView(Token)
252 else R := FTokenBreaker.GetNextHighlighterTokenEx(Token);
253 AssertFalse(Name + ' No further Token', R);
254 end;
255
256 procedure TestEnd(ExpStart: TBoundExpectation);
257 begin
258 TestEnd;
259 TestBound(Name + ' Start(EOL)', Token.StartPos, ExpStart);
260 end;
261
262 procedure DoTests;
263 begin
264 UseViewTokenOnly := True;
265 SetRealLinesText;
266 SynEdit.TabWidth := 4;
267 SynEdit.ViewedTextBuffer.DisplayView.InitHighlighterTokens(SynEdit.Highlighter);
268
269 FTheHighLighter.AddToken(2-1, 9, FtkBlue); // interface
270 FTheHighLighter.AddToken(7-1, 1, FtkYellow); // #9
271 FTheHighLighter.AddToken(7-1, 2, FtkGreen); // i
272 FTheHighLighter.AddToken(7-1, 3, FtkRed); // =
273 FTheHighLighter.AddToken(7-1, 6, FtkGreen); // 123
274 FTheHighLighter.AddToken(17-1, 2, FtkBlue); // //
275
276 FTheHighLighter.AddToken(18-1, 6, FtkGreen); // ' ' 6 spaces
277 FTheHighLighter.AddToken(18-1, 7, FtkYellow); // '
278 FTheHighLighter.AddToken(18-1,11, FtkBlue); // شس
279 FTheHighLighter.AddToken(18-1,12, FtkYellow); // '
280 FTheHighLighter.AddToken(18-1,13, FtkRed); // ,
281
282 FTheHighLighter.AddToken(19-1, 6, FtkGreen); // ' ' 6 spaces
283 FTheHighLighter.AddToken(19-1, 7, FtkYellow); // '
284 FTheHighLighter.AddToken(19-1,15, FtkBlue); // شس
285
286 FTheHighLighter.AddToken(20-1, 6, FtkGreen); // ' ' 6 spaces
287 FTheHighLighter.AddToken(20-1, 7, FtkYellow); // '
288 FTheHighLighter.AddToken(20-1,13, FtkRed); // شس 3 chars, ekcept last will be red
289 FTheHighLighter.AddToken(20-1,15, FtkBlue); // شس
290
291 {%region LTR only }
292 PushBaseName('LTR-Only');
293
294 {%region full line}
295 TestStart('Scan full line / hl-token', 2, 1, 100, 2);
296 TestNext([100], b( 1, 1, 0), b(10,10, 0), 1,10, 1,10, False, 'interface', clBlue, b(10,10, 0), False);
297 TestNext([100], b(10,10, 0), b(12,12, 0), 10,12, 10,12, False, '//', clBlack, b(12,12, 0), False);
298 TestEnd(b(12,12,0));
299
300 TestStart('Scan full line / hl-token', 2, 1, 100, 2);
301 TestPreFirst(b( 1, 1, 0), False);
302 TestNext([], b( 1, 1), b(10,10), 1,10, 1,10, False, 'interface', b(10,10, 0), False);
303 TestNext([], b(10,10), b(12,12), 10,12, 10,12, False, '//', b(12,12, 0), False);
304 TestEnd(b(12,12, 0));
305 {%endregion}
306
307 {%region cut off end of line}
308 TestStart('Cut off end', 2, 1, 5, 2);
309
310 TestNext([100], b( 1, 1), b( 5, 5), 1, 5, 1, 5, False, 'inte', b( 5, 5, 0), False);
311 TestEnd(b( 5, 5, 0));
312 {%endregion}
313
314 {%region cut off start of line}
315 TestStart('Cut off start', 2, 3, 100, 2);
316 TestNext([100], b( 3, 3), b(10,10), 3,10, 3,10, False, 'terface', b(10,10, 0), False);
317 TestNext([100], b(10,10), b(12,12), 10,12, 10,12, False, '//', b(12,12, 0), False);
318 TestEnd(b(12,12, 0));
319
320 TestStart('Cut off start 1 tok', 2, 10, 100, 2);
321 TestNext([100], b(10,10), b(12,12), 10,12, 10,12, False, '//', b(12,12, 0), False);
322 TestEnd(b(12,12, 0));
323
324 TestStart('Cut off start 1.5 tok', 2, 11, 100, 2);
325 TestNext([100], b(11,11), b(12,12), 11,12, 11,12, False, '/', b(12,12, 0), False);
326 TestEnd(b(12,12, 0));
327
328 TestStart('Cut off entire line', 2, 20, 50, 2);
329 AssertFalse(Name + 'Got NO Token', FTokenBreaker.GetNextHighlighterTokenFromView(Token, -1, 1));
330 TestBound(Name + ' Start(BOL)', Token.StartPos, b(12,12, 0));
331 {%endregion}
332
333 {%region cut off both}
334 TestStart('Cut off both', 2, 3, 10, 2);
335 TestNext([100], b( 3, 3), b(10,10), 3,10, 3,10, False, 'terface');
336 //TestNext([100], b(10,10), b(12,12), 10,12, 10,12, False, '//');
337 TestEnd;
338
339 TestStart('Cut off both - 2 token', 2, 3, 11, 2);
340 TestNext([100], b( 3, 3), b(10,10), 3,10, 3,10, False, 'terface');
341 TestNext([100], b(10,10), b(11,11), 10,11, 10,11, False, '/');
342 TestEnd;
343
344 TestStart('Cut off both - 1 token, skip 1st', 2, 10,11, 2);
345 TestNext([100], b(10,10), b(11,11), 10,11, 10,11, False, '/');
346 TestEnd;
347 {%endregion}
348
349 {%region 1 token 2 parts}
350 TestStart('1 token 2 parts', 2, 1, 100, 2);
351
352 TestNext([ 3], b( 1, 1, 0), b( 3, 3, 0), 1, 3, 1, 3, False, 'in',clBlue );
353 TestNext([100], b( 3, 3, 0), b(10,10, 0), 3,10, 3,10, False, 'terface', clBlue);
354 TestNext([100], b(10,10, 0), b(12,12, 0), 10,12, 10,12, False, '//', clBlack);
355 TestEnd;
356 {%endregion}
357
358 // part chars/tabs
359
360 {%region cut off PART of char }
361 // start at 1
362 TestStart('cut off PART of char (end)', 7, 1, 100, 7);
363 TestPreFirst(b( 1, 1, 0), False);
364 TestNext([ 3], b( 1, 1, 0), b( 3, 2,-2), 1, 5, 1, 3, False, #9, b( 3, 1, 2), False);
365 TestNext([100], b( 3, 1, 2), b( 5, 2, 0), 1, 5, 3, 5, False, #9, b( 5, 2, 0), False);
366 TestNext([100], b( 5, 2, 0), b( 6, 3, 0), 5, 6, 5, 6, False, 'i');
367
368 TestStart('cut off PART of char (end) next-limit', 7, 1, 100, 7);
369 TestPreFirst(b( 1, 1, 0), False);
370 TestNext([ 3], b( 1, 1), b( 3, 2), 1, 5, 1, 3, False, #9, b( 3, 1, 2), False);
371 TestNext([ 5], b( 3, 1), b( 5, 2), 1, 5, 3, 5, False, #9, b( 5, 2, 0), False);
372 TestNext([100], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
373
374 TestStart('cut off PART of char (end) next-limit-log', 7, 1, 100, 7);
375 TestPreFirst(b( 1, 1, 0), False);
376 TestNext([ 3], b( 1, 1), b( 3, 2), 1, 5, 1, 3, False, #9, b( 3, 1, 2), False);
377 TestNext([99,2], b( 3, 1), b( 5, 2), 1, 5, 3, 5, False, #9, b( 5, 2, 0), False);
378 TestNext([100], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
379
380 // start at 2
381 TestStart('cut off PART of char (begin)', 7, 2, 100, 7);
382 TestPreFirst(b( 2, 1, 1), False);
383 TestNext([ 5], b( 2, 1), b( 5, 2), 1, 5, 2, 5, False, #9);
384 TestNext([100], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
385
386 TestStart('cut off PART of char (both) continue', 7, 2, 100, 7);
387 TestPreFirst(b( 2, 1, 1), False);
388 TestNext([ 3], b( 2, 1), b( 3, 2), 1, 5, 2, 3, False, #9);
389 TestNext([100], b( 3, 1), b( 5, 2), 1, 5, 3, 5, False, #9);
390 TestNext([100], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
391
392 TestStart('cut off PART of char (both) global-limit', 7, 2, 3, 7);
393 TestPreFirst(b( 2, 1, 1), False);
394 TestNext([100], b( 2, 1), b( 3, 2), 1, 5, 2, 3, False, #9);
395 TestEnd;
396
397 TestStart('cut off PART of char (both) next-limit', 7, 2, 100, 7);
398 TestPreFirst(b( 2, 1, 1), False);
399 TestNext([3], b( 2, 1), b( 3, 2), 1, 5, 2, 3, False, #9);
400 //TestEnd(3);
401
402 // start at 3
403 TestStart('cut off PART of char (begin)', 7, 3, 100, 7);
404 TestPreFirst(b( 3, 1, 2), False);
405 TestNext([ 5], b( 3, 1), b( 5, 2), 1, 5, 3, 5, False, #9);
406 TestNext([100], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
407
408 // start at 4
409 TestStart('cut off PART of char (begin)', 7, 4, 100, 7);
410 TestPreFirst(b( 4, 1, 3), False);
411 TestNext([ 5], b( 4, 1), b( 5, 2), 1, 5, 4, 5, False, #9);
412 TestNext([100], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
413
414 // start at 5
415 TestStart('cut off PART of char (begin)', 7, 5, 100, 7);
416 TestPreFirst(b( 5, 2, 0), False);
417 TestNext([100], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
418 {%endregion}
419
420 {%region cut tab in many}
421 TestStart('cut tab in many', 9, 2, 100, 9);
422
423 TestNext([ 3], b( 2, 1), b( 3, 2), 1, 5, 2, 3, False, #9);
424 TestNext([ 6], b( 3, 1), b( 6, 3), 1, 9, 3, 6, False, #9#9);
425 TestNext([ 11], b( 6, 2), b(11, 4), 5,13, 6,11, False, #9#9);
426 TestNext([ 13], b(11, 3), b(13, 4), 9,13, 11, 13, False, #9);
427 TestNext([ 15], b(13, 4), b(15, 5), 13,17, 13, 15, False, #9);
428 {%endregion}
429
430 {%region break line // phys log}
431 TestStart('Scan full line', 14, 1, 100, 14);
432 TestPreFirst(b( 1, 1, 0), False);
433 TestNext([-1, -1], b( 1, 1), b(13, 7), 1,13, 1,13, False, #9'i'#9'12'#9);
434
435 TestStart('Scan full line', 14, 1, 100, 14);
436 TestPreFirst(b( 1, 1, 0), False);
437 TestNext([-1, 2], b( 1, 1), b( 5, 2), 1, 5, 1, 5, False, #9, b( 5, 2, 0), False);
438 TestNext([-1, 3], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
439
440 TestStart('Scan full line', 14, 1, 100, 14);
441 TestPreFirst(b( 1, 1, 0), False);
442 TestNext([99, 2], b( 1, 1), b( 5, 2), 1, 5, 1, 5, False, #9, b( 5, 2, 0), False);
443 TestNext([-1, 3], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
444
445 TestStart('Scan full line', 14, 1, 100, 14);
446 TestPreFirst(b( 1, 1, 0), False);
447 TestNext([ 5, 2], b( 1, 1), b( 5, 2), 1, 5, 1, 5, False, #9, b( 5, 2, 0), False);
448 TestNext([-1, 3], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
449
450 TestStart('Scan full line', 14, 1, 100, 14);
451 TestPreFirst(b( 1, 1, 0), False);
452 TestNext([ 4, 2], b( 1, 1), b( 4, 2), 1, 5, 1, 4, False, #9, b( 4, 1, 3), False);
453 TestNext([-1, 2], b( 4, 1), b( 5, 2), 1, 5, 4, 5, False, #9, b( 5, 2, 0), False);
454 TestNext([-1, 3], b( 5, 2), b( 6, 3), 5, 6, 5, 6, False, 'i');
455
456
457 {%endregion}
458
459 PopBaseName;
460 {%endregion}
461
462 {%region RTL only }
463 PushBaseName('RTL-Only');
464 {%region full line}
465 TestStart('Scan full line', 11, 1, 100, 11);
466 TestPreFirst(b( 3, 1, 0), True);
467 TestNext([100], b( 3, 1, 0), b( 1, 5, 0), 1, 3, 1, 3, True, 'شس', b( 3, 5, 0), False);
468 TestEnd(b( 3, 5, 0));
469
470 TestStart('Scan full line', 11, 1, 100, 11);
471 TestPreFirst(b( 3, 1, 0), True);
472 TestNext([], b( 3, 1, 0), b( 1, 5, 0), 1, 3, 1, 3, True, 'شس', b( 3, 5, 0), False);
473 TestEnd(b( 3, 5, 0));
474
475 TestStart('Scan full line (2 words)', 12, 1, 100, 12);
476 TestPreFirst(b( 5, 1, 0), True);
477 TestNext([100], b( 5, 1, 0), b( 1, 8, 0), 1, 5, 1, 5, True, 'شس ي', b( 5, 8, 0), False);
478 TestEnd(b( 5, 8, 0));
479 {%endregion}
480
481 {%region Cut tab}
482 (*
483 Tab implemetation may change. currently it is calculated on the logical pos of the tab
484 *)
485 // tab will be 3 width
486 TestStart('Scan full line', 15, 3, 7, 15);
487 TestPreFirst(b( 7, 1, 0), True);
488 TestNext([], b( 7, 1, 0), b( 3, 4, 0), 3, 7, 3, 7, True, 'ي'#9, b( 7, 8, 0), False);
489 TestEnd(b( 7, 8, 0));
490
491 TestStart('Scan full line', 15, 4, 7, 15);
492 TestPreFirst(b( 7, 1, 0), True);
493 TestNext([], b( 7, 1, 0), b( 4, 4,-1), 3, 7, 4, 7, True, 'ي'#9, b( 7, 8, 0), False);
494 TestEnd(b( 7, 8, 0));
495
496 TestStart('Scan full line', 15, 5, 7, 15);
497 TestPreFirst(b( 7, 1, 0), True);
498 TestNext([], b( 7, 1, 0), b( 5, 4,-2), 3, 7, 5, 7, True, 'ي'#9, b( 7, 8, 0), False);
499 TestEnd(b( 7, 8, 0));
500
501
502 TestStart('Scan full line', 15, 1, 7, 15);
503 TestPreFirst(b( 7, 1, 0), True);
504 TestNext([], b( 7, 1, 0), b( 1, 8, 0), 1, 7, 1, 7, True, 'ي'#9'شس', b( 7, 8, 0), False);
505 TestEnd(b( 7, 8, 0));
506
507 TestStart('Scan full line', 15, 1, 6, 15);
508 TestPreFirst(b( 6, 3, 0), True);
509 // TODO NextPos and TestEnd: Phys pos is allowed to be 6 OR 7
510 TestNext([], b( 6, 3, 0), b( 1, 8, 0), 1, 6, 1, 6, True, #9'شس', b( 7, 8, 0), False);
511 TestEnd(b( 7, 8, 0));
512
513 TestStart('Scan full line', 15, 1, 5, 15);
514 TestPreFirst(b( 5, 3, 1), True);
515 TestNext([], b( 5, 3, 1), b( 1, 8, 0), 1, 6, 1, 5, True, #9'شس');
516
517 TestStart('Scan full line', 15, 1, 4, 15);
518 TestPreFirst(b( 4, 3, 2), True);
519 TestNext([], b( 4, 3, 2), b( 1, 8, 0), 1, 6, 1, 4, True, #9'شس');
520
521 // RTL tab in 2 pieces
522 TestStart('RTL tab in 2 pieces', 15, 1, 7, 15);
523 TestPreFirst(b( 7, 1, 0), True);
524 TestNext([5], b( 7, 1, 0), b( 5, 4,-2), 3, 7, 5, 7, True, 'ي'#9, b( 5, 3, 1), True);
525 TestNext([], b( 5, 3, 1), b( 1, 8, 0), 1, 6, 1, 5, True, #9'شس', b( 7, 8, 0), False);
526 TestEnd(b( 7, 8, 0));
527
528 {%endregion}
529
530 {%region part line}
531 // 1 char parts
532 TestStart('part line - begin', 12, 1, 2, 12);
533 TestPreFirst(b( 2, 6, 0), True);
534 TestNext([100], b( 2, 6), b( 1, 8), 1, 2, 1, 2, True, 'ي', b( 5, 8, 0), False);
535 TestEnd(b( 5, 8, 0));
536
537 TestStart('part line - mid', 12, 2, 3, 12);
538 TestPreFirst(b( 3, 5, 0), True);
539 TestNext([100], b( 3, 5), b( 2, 6), 2, 3, 2, 3, True, ' ', b( 5, 8, 0), False);
540 TestEnd(b( 5, 8, 0));
541
542 TestStart('part line - mid', 12, 3, 4, 12);
543 TestPreFirst(b( 4, 3, 0), True);
544 TestNext([100], b( 4, 3), b( 3, 5), 3, 4, 3, 4, True, 'س', b( 5, 8, 0), False);
545 TestEnd(b( 5, 8, 0));
546
547 TestStart('part line - end', 12, 4, 5, 12);
548 TestPreFirst(b( 5, 1, 0), True);
549 TestNext([100], b( 5, 1), b( 4, 3), 4, 5, 4, 5, True, 'ش', b( 5, 8, 0), False);
550 TestEnd(b( 5, 8, 0));
551
552 // 2 char parts
553 TestStart('part line - begin(2)', 12, 1, 3, 12);
554 TestPreFirst(b( 3, 5, 0), True);
555 TestNext([100], b( 3, 5), b( 1, 8), 1, 3, 1, 3, True, ' ي');
556 TestEnd;
557
558 TestStart('part line - mid(2)', 12, 2, 4, 12);
559 TestPreFirst(b( 4, 3, 0), True);
560 TestNext([100], b( 4, 3), b( 2, 6), 2, 4, 2, 4, True, 'س ');
561 TestEnd;
562
563 TestStart('part line - end(2)', 12, 3, 5, 12);
564 TestPreFirst(b( 5, 1, 0), True);
565 TestNext([100], b( 5, 1), b( 3, 5), 3, 5, 3, 5, True, 'شس');
566 TestEnd;
567
568 // 1 char parts, several chunks
569 TestStart('part line - begin', 12, 1, 100, 12);
570 TestPreFirst(b( 5, 1, 0), True);
571 TestNext([4], b( 5, 1), b( 4, 3), 4, 5, 4, 5, True, 'ش', b( 4, 3, 0), True);
572 TestNext([3], b( 4, 3), b( 3, 5), 3, 4, 3, 4, True, 'س', b( 3, 5, 0), True);
573 TestNext([2], b( 3, 5), b( 2, 6), 2, 3, 2, 3, True, ' ', b( 2, 6, 0), True);
574 TestNext([1], b( 2, 6), b( 1, 8), 1, 2, 1, 2, True, 'ي', b( 5, 8, 0), False);
575 TestEnd(b( 5, 8, 0));
576
577 // 1 char parts, several chunks
578 TestStart('part line - begin', 12, 1, 100, 12);
579 TestPreFirst(b( 5, 1, 0), True);
580 TestNext([4], b( 5, 1), b( 4, 3), 4, 5, 4, 5, True, 'ش');
581 TestNext([3], b( 4, 3), b( 3, 5), 3, 4, 3, 4, True, 'س');
582 TestNext([0], b( 3, 5), b( 1, 8), 1, 3, 1, 3, True, ' ي');
583 TestEnd;
584
585 //TestStart('part line - begin', 12, 1, 100, 12);
586 //TestNext(2, 1, 6, 2, 5, 2, 5, True, 'شس ');
587 //TestNext(5, 1, 3, 4, 5, 4, 5, True, 'ي');
588 //TestEnd;
589 //
590 //TestStart('part line - begin', 12, 1, 100, 12);
591 //TestNext( 2, 1, 6, 2, 5, 2, 5, True, 'شس ');
592 //TestNext([100], b( 5, 1), b( 4, 3), 4, 5, 4, 5, True, 'شس ي');
593 //TestEnd;
594
595 {%endregion}
596
597 PopBaseName;
598 {%endregion}
599
600 {%region MIXED Rtl/Ltr }
601 PushBaseName('MIXED Rtl/Ltr');
602 {%region full line}
603 TestStart('Scan full line', 13, 1, 100, 13);
604 TestPreFirst(b( 1, 1, 0), False);
605 TestNext([], b( 1, 1), b( 3, 3), 1, 3, 1, 3, False, 'AB', b( 7, 3, 0), True);
606 TestNext([], b( 7, 3), b( 3,10), 3, 7, 3, 7, True, 'شس ي', b( 7,10, 0), False);
607 TestNext([], b( 7,10), b( 9,12), 7, 9, 7, 9, False, 'CD', b( 9,12, 0), False);
608 TestEnd(b( 9,12, 0));
609
610 {%endregion}
611
612 {%region parts}
613 TestStart('Scan part line, cut at start', 13, 2, 100, 13);
614 TestPreFirst(b( 2, 2, 0), False);
615 TestNext([], b( 2, 2), b( 3, 3), 2, 3, 2, 3, False, 'B', b( 7, 3, 0), True);
616 TestNext([], b( 7, 3), b( 3,10), 3, 7, 3, 7, True, 'شس ي', b( 7,10, 0), False);
617 TestNext([], b( 7,10), b( 9,12), 7, 9, 7, 9, False, 'CD');
618 TestEnd;
619
620 TestStart('Scan part line, cut at start', 13, 3, 100, 13);
621 TestPreFirst(b( 7, 3, 0), True);
622 TestNext([], b( 7, 3), b( 3,10), 3, 7, 3, 7, True, 'شس ي', b( 7,10, 0), False);
623 TestNext([], b( 7,10), b( 9,12), 7, 9, 7, 9, False, 'CD');
624 TestEnd;
625
626 TestStart('Scan part line, cut at start', 13, 4, 100, 13);
627 TestPreFirst(b( 7, 3, 0), True);
628 TestNext([], b( 7, 3), b( 4, 8), 4, 7, 4, 7, True, 'شس ', b( 7,10, 0), False);
629 TestNext([], b( 7,10), b( 9,12), 7, 9, 7, 9, False, 'CD');
630 TestEnd;
631
632 TestStart('Scan part line, cut at start', 13, 6, 100, 13);
633 TestPreFirst(b( 7, 3, 0), True);
634 TestNext([], b( 7, 3), b( 6, 5), 6, 7, 6, 7, True, 'ش', b( 7,10, 0), False);
635 TestNext([], b( 7,10), b( 9,12), 7, 9, 7, 9, False, 'CD');
636 TestEnd;
637
638 TestStart('Scan part line, cut at start', 13, 7, 100, 13);
639 TestPreFirst(b( 7,10, 0), False);
640 TestNext([], b( 7,10), b( 9,12), 7, 9, 7, 9, False, 'CD');
641 TestEnd;
642
643 TestStart('Scan part line, cut at start', 13, 8, 100, 13);
644 TestPreFirst(b( 8,11, 0), False);
645 TestNext([], b( 8,11), b( 9,12), 8, 9, 8, 9, False, 'D');
646 TestEnd;
647
648 TestStart('Scan part line, cut at start', 13, 9, 100, 13);
649 TestEnd;
650
651
652 TestStart('Scan part line, cut at end', 13, 1, 8, 13);
653 TestNext([], b( 1, 1), b( 3, 3), 1, 3, 1, 3, False, 'AB', b( 7, 3, 0), True);
654 TestNext([], b( 7, 3), b( 3,10), 3, 7, 3, 7, True, 'شس ي', b( 7,10, 0), False);
655 TestNext([], b( 7,10), b( 8,11), 7, 8, 7, 8, False, 'C');
656 TestEnd;
657
658 TestStart('Scan part line, cut at end', 13, 1, 7, 13);
659 TestNext([], b( 1, 1), b( 3, 3), 1, 3, 1, 3, False, 'AB', b( 7, 3, 0), True);
660 TestNext([], b( 7, 3), b( 3,10), 3, 7, 3, 7, True, 'شس ي');
661 TestEnd;
662
663 TestStart('Scan part line, cut at end', 13, 1, 6, 13);
664 TestNext([], b( 1, 1), b( 3, 3), 1, 3, 1, 3, False, 'AB', b( 6, 5, 0), True);
665 TestNext([], b( 6, 5), b( 3,10), 3, 6, 3, 6, True, 'س ي');
666 TestEnd;
667
668 TestStart('Scan part line, cut at end', 13, 1, 4, 13);
669 TestNext([], b( 1, 1), b( 3, 3), 1, 3, 1, 3, False, 'AB', b( 4, 8, 0), True);
670 TestNext([], b( 4, 8), b( 3,10), 3, 4, 3, 4, True, 'ي');
671 TestEnd;
672
673 TestStart('Scan part line, cut at end', 13, 1, 3, 13);
674 TestNext([], b( 1, 1), b( 3, 3), 1, 3, 1, 3, False, 'AB');
675 TestEnd;
676
677 TestStart('Scan part line, cut at end', 13, 1, 2, 13);
678 TestNext([], b( 1, 1), b( 2, 2), 1, 2, 1, 2, False, 'A');
679 TestEnd;
680
681 {%endregion}
682
683
684 {%region}
685 TestStart('Scan full line 18 / hl-token', 20, 9, 30, 20);
686 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed, b(12, 16, 0), False);
687 TestEnd(b(12, 16, 0));
688
689 TestStart('Scan full line 18 / hl-token', 20, 10, 30, 20);
690 TestNext([], b(12, 8, 0), b(10,12, 0), 10,12, 10,12, True, 'شس', clRed, b(12, 16, 0), False);
691 TestEnd(b(12, 16, 0));
692
693 {%endregion}
694
695
696 PopBaseName;
697 {%endregion}
698
699
700 UseViewTokenOnly := False;
701
702 {%region LTR only }
703 PushBaseName('LTR-Only - WITH MARKUP');
704
705 {%region full line}
706 SynEdit.BlockBegin := Point( 1,1); // clear selection
707 TestStart('Scan full line / hl-token', 1, 1, 99, 1);
708 TestNext([], b( 1, 1, 0), b(10,10, 0), 1,10, 1,10, False, 'unit foo;', clBlack);
709 TestNext([], b(10,10, 0), b(99,99, 0), 10,99, 10,99, False, ' ', clBlack);
710 TestEnd;
711
712 SynEdit.BlockBegin := Point(2,1);
713 SynEdit.BlockEnd := Point(4,1);
714 TestStart('Scan full line / hl-token', 1, 1, 99, 1);
715 TestNext([], b( 1, 1, 0), b( 2, 2, 0), 1, 2, 1, 2, False, 'u', clBlack);
716 TestNext([], b( 2, 2, 0), b( 4, 4, 0), 2, 4, 2, 4, False, 'ni', clPurple);
717 TestNext([], b( 4, 4, 0), b(10,10, 0), 4,10, 4,10, False, 't foo;', clBlack);
718 TestNext([], b(10,10, 0), b(99,99, 0), 10,99, 10,99, False, ' ', clBlack);
719 TestEnd;
720
721 SynEdit.BlockBegin := Point(2,1);
722 SynEdit.BlockEnd := Point(4,1);
723 TestStart('Scan full line / hl-token', 1, 6, 99, 1);
724 TestNext([], b( 6, 6, 0), b(10,10, 0), 6,10, 6,10, False, 'foo;', clBlack);
725 TestNext([], b(10,10, 0), b(99,99, 0), 10,99, 10,99, False, ' ', clBlack);
726 TestEnd;
727
728 SynEdit.BlockBegin := Point(20,1);
729 SynEdit.BlockEnd := Point(30,1);
730 TestStart('Scan full line / hl-token', 1, 1, 99, 1);
731 TestNext([], b( 1, 1, 0), b(10,10, 0), 1,10, 1,10, False, 'unit foo;', clBlack);
732 TestNext([], b(10,10, 0), b(20,20, 0), 10,20, 10,20, False, ' ', clBlack);
733 TestNext([], b(20,20, 0), b(30,30, 0), 20,30, 20,30, False, ' ', clPurple);
734 TestNext([], b(30,30, 0), b(99,99, 0), 30,99, 30,99, False, ' ', clBlack);
735 TestEnd;
736
737 SynEdit.BlockBegin := Point( 8,1);
738 SynEdit.BlockEnd := Point(30,1);
739 TestStart('Scan full line / hl-token', 1, 1, 99, 1);
740 TestNext([], b( 1, 1, 0), b( 8, 8, 0), 1, 8, 1, 8, False, 'unit fo', clBlack);
741 TestNext([], b( 8, 8, 0), b(10,10, 0), 8,10, 8,10, False, 'o;', clPurple);
742 TestNext([], b(10,10, 0), b(30,30, 0), 10,30, 10,30, False, ' ', clPurple);
743 TestNext([], b(30,30, 0), b(99,99, 0), 30,99, 30,99, False, ' ', clBlack);
744 TestEnd;
745
746
747 // Paint eol only
748 SynEdit.BlockBegin := Point( 1,1); // clear selection
749 TestStart('Scan full line / hl-token', 1, 10, 99, 1);
750 TestNext([], b(10,10, 0), b(99,99, 0), 10,99, 10,99, False, ' ', clBlack);
751 TestEnd;
752
753 SynEdit.BlockBegin := Point(20,1);
754 SynEdit.BlockEnd := Point(30,1);
755 TestStart('Scan full line / hl-token', 1, 25, 99, 1);
756 TestNext([], b(25,25, 0), b(30,30, 0), 25,30, 25,30, False, ' ', clPurple);
757 TestNext([], b(30,30, 0), b(99,99, 0), 30,99, 30,99, False, ' ', clBlack);
758 TestEnd;
759 {%endregion}
760
761 {%region}
762 SynEdit.Options :=SynEdit.Options + [eoBracketHighlight];
763 SynEdit.BracketHighlightStyle := sbhsBoth;
764 SynEdit.BracketMatchColor.Foreground := clMaroon;
765 SynEdit.BracketMatchColor.FrameColor := clBlack;
766 SynEdit.BracketMatchColor.FrameEdges := sfeAround;
767 SynEdit.BracketMatchColor.FrameStyle := slsSolid;
768
769 SynEdit.LogicalCaretXY := point(2, 16);
770 TestStart('Scan full line / hl-token', 16, 1, 10, 16);
771 TestNext([], b( 1, 1, 0), b( 5, 2, 0), 1, 5, 1, 5, False, #9, clBlack);
772 AssertEquals(Name + ' #9 No-Frame l', clNone, Token.Attr.FrameSideColors[bsLeft]);
773 AssertEquals(Name + ' #9 No-Frame r', clNone, Token.Attr.FrameSideColors[bsRight]);
774 TestNext([], b( 5, 2, 0), b( 6, 3, 0), 5, 6, 5, 6, False, '(', clMaroon);
775 AssertEquals(Name + ' "(" Frame t', clBlack, Token.Attr.FrameSideColors[bsTop]);
776 AssertEquals(Name + ' "(" Frame l', clBlack, Token.Attr.FrameSideColors[bsLeft]);
777 AssertEquals(Name + ' "(" Frame r', clBlack, Token.Attr.FrameSideColors[bsRight]);
778 TestNext([], b( 6, 3, 0), b( 9, 4, 0), 6, 9, 6, 9, False, #9, clBlack);
779 {%endregion}
780
781
782
783 {%endregion}
784
785 {%region RTL only }
786 PushBaseName('RTL-Only - WITH MARKUP');
787 {%region full line}
788 SynEdit.BlockBegin := Point( 1,1); // clear selection
789 TestStart('Scan full line', 11, 1, 90, 11);
790 TestPreFirst(b( 3, 1, 0), True);
791 TestNext([], b( 3, 1, 0), b( 1, 5, 0), 1, 3, 1, 3, True, 'شس', clBlack);
792 TestNext([], b( 3, 5, 0), b(90,92, 0), 3,90, 3,90, False, ' ', clBlack);
793 TestEnd;
794
795 SynEdit.BlockBegin := Point(3,12); // 2nd logical char
796 SynEdit.BlockEnd := Point(5,12);
797 TestStart('Scan full line', 12, 1, 90, 12);
798 TestPreFirst(b( 5, 1, 0), True);
799 TestNext([], b( 5, 1, 0), b( 4, 3, 0), 4, 5, 4, 5, True, 'ش', clBlack);
800 TestNext([], b( 4, 3, 0), b( 3, 5, 0), 3, 4, 3, 4, True, 'س', clPurple);
801 TestNext([], b( 3, 5, 0), b( 1, 8, 0), 1, 3, 1, 3, True, ' ي', clBlack);
802 TestNext([], b( 5, 8, 0), b(90,93, 0), 5,90, 5,90, False, ' ', clBlack);
803 TestEnd;
804 {%endregion}
805 PopBaseName;
806 {%endregion}
807
808
809 // HL token ends exactly at LTR to RTL change
810
811 SynEdit.BlockBegin := Point(1,1);
812 TestStart('Scan full line 17 / hl-token', 17, 1, 30, 17);
813 TestNext([], b( 1, 1, 0), b( 3, 3, 0), 1, 3, 1, 3, False, '//', clBlue);
814 TestNext([], b(16, 3, 0), b( 3,25, 0), 3,16, 3,16, True, 'شس يشس ي(شس ي', clBlack);
815 TestNext([], b(16,25, 0), b(30,39, 0), 16,30, 16,30, False, ' ', clBlack);
816 TestEnd;
817
818 SynEdit.BlockBegin := Point( 3,17);
819 SynEdit.BlockEnd := Point(25,17);
820 TestStart('Scan full line 17 / hl-token', 17, 1, 30, 17);
821 TestNext([], b( 1, 1, 0), b( 3, 3, 0), 1, 3, 1, 3, False, '//', clBlue);
822 TestNext([], b(16, 3, 0), b( 3,25, 0), 3,16, 3,16, True, 'شس يشس ي(شس ي', clPurple);
823 TestNext([], b(16,25, 0), b(30,39, 0), 16,30, 16,30, False, ' ', clBlack);
824 TestEnd;
825
826 SynEdit.BlockBegin := Point( 3,17);
827 SynEdit.BlockEnd := Point(22,17); // 2 chars off
828 TestStart('Scan full line 17 / hl-token', 17, 1, 30, 17);
829 TestNext([], b( 1, 1, 0), b( 3, 3, 0), 1, 3, 1, 3, False, '//', clBlue);
830 TestNext([], b(16, 3, 0), b( 5,22, 0), 5,16, 5,16, True, 'شس يشس ي(شس', clPurple);
831 TestNext([], b( 5,22, 0), b( 3,25, 0), 3, 5, 3, 5, True, ' ي', clBlack);
832 TestNext([], b(16,25, 0), b(30,39, 0), 16,30, 16,30, False, ' ', clBlack);
833 TestEnd;
834
835 SynEdit.BlockBegin := Point( 7,17); // 2 chars off
836 SynEdit.BlockEnd := Point(25,17);
837 TestStart('Scan full line 17 / hl-token', 17, 1, 30, 17);
838 TestNext([], b( 1, 1, 0), b( 3, 3, 0), 1, 3, 1, 3, False, '//', clBlue);
839 TestNext([], b(16, 3, 0), b(14, 7, 0), 14,16, 14,16, True, 'شس', clBlack);
840 TestNext([], b(14, 7, 0), b( 3,25, 0), 3,14, 3,14, True, ' يشس ي(شس ي', clPurple);
841 TestNext([], b(16,25, 0), b(30,39, 0), 16,30, 16,30, False, ' ', clBlack);
842 TestEnd;
843
844 SynEdit.BlockBegin := Point( 7,17);
845 SynEdit.BlockEnd := Point(22,17);
846 TestStart('Scan full line 17 / hl-token', 17, 1, 30, 17);
847 TestNext([], b( 1, 1, 0), b( 3, 3, 0), 1, 3, 1, 3, False, '//', clBlue);
848 TestNext([], b(16, 3, 0), b(14, 7, 0), 14,16, 14,16, True, 'شس', clBlack);
849 TestNext([], b(14, 7, 0), b( 5,22, 0), 5,14, 5,14, True, ' يشس ي(شس', clPurple);
850 TestNext([], b( 5,22, 0), b( 3,25, 0), 3, 5, 3, 5, True, ' ي', clBlack);
851 TestNext([], b(16,25, 0), b(30,39, 0), 16,30, 16,30, False, ' ', clBlack);
852 TestEnd;
853
854 // Mixed RTL (and weak)
855 // increase LeftChar
856 SynEdit.BlockBegin := Point(1,1);
857 TestStart('Scan full line 18 / hl-token', 18, 1, 30, 18);
858 TestNext([], b( 1, 1, 0), b( 7, 7, 0), 1, 7, 1, 7, False, 'a ', clGreen);
859 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
860 TestNext([], b(10, 8, 0), b( 8,12, 0), 8,10, 8,10, True, 'شس', clBlue);
861 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
862 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
863 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
864 TestEnd;
865
866 TestStart('Scan full line 18 / hl-token', 18, 2, 30, 18);
867 TestNext([], b( 2, 2, 0), b( 7, 7, 0), 2, 7, 2, 7, False, ' ', clGreen);
868 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
869 TestNext([], b(10, 8, 0), b( 8,12, 0), 8,10, 8,10, True, 'شس', clBlue);
870 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
871 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
872 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
873 TestEnd;
874
875 TestStart('Scan full line 18 / hl-token', 18, 3, 30, 18);
876 TestNext([], b( 3, 3, 0), b( 7, 7, 0), 3, 7, 3, 7, False, ' ', clGreen);
877 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
878 TestNext([], b(10, 8, 0), b( 8,12, 0), 8,10, 8,10, True, 'شس', clBlue);
879 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
880 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
881 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
882 TestEnd;
883
884 TestStart('Scan full line 18 / hl-token', 18, 4, 30, 18);
885 TestNext([], b( 4, 4, 0), b( 7, 7, 0), 4, 7, 4, 7, False, ' ', clGreen);
886 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
887 TestNext([], b(10, 8, 0), b( 8,12, 0), 8,10, 8,10, True, 'شس', clBlue);
888 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
889 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
890 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
891 TestEnd;
892
893 TestStart('Scan full line 18 / hl-token', 18, 5, 30, 18);
894 TestNext([], b( 5, 5, 0), b( 7, 7, 0), 5, 7, 5, 7, False, ' ', clGreen);
895 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
896 TestNext([], b(10, 8, 0), b( 8,12, 0), 8,10, 8,10, True, 'شس', clBlue);
897 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
898 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
899 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
900 TestEnd;
901
902 TestStart('Scan full line 18 / hl-token', 18, 6, 30, 18);
903 TestNext([], b( 6, 6, 0), b( 7, 7, 0), 6, 7, 6, 7, False, ' ', clGreen);
904 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
905 TestNext([], b(10, 8, 0), b( 8,12, 0), 8,10, 8,10, True, 'شس', clBlue);
906 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
907 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
908 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
909 TestEnd;
910
911 TestStart('Scan full line 18 / hl-token', 18, 7, 30, 18);
912 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
913 TestNext([], b(10, 8, 0), b( 8,12, 0), 8,10, 8,10, True, 'شس', clBlue);
914 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
915 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
916 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
917 TestEnd;
918
919 TestStart('Scan full line 18 / hl-token', 18, 8, 30, 18);
920 TestNext([], b(10, 8, 0), b( 8,12, 0), 8,10, 8,10, True, 'شس', clBlue);
921 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
922 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
923 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
924 TestEnd;
925
926 TestStart('Scan full line 18 / hl-token', 18, 9, 30, 18);
927 TestNext([], b(10, 8, 0), b( 9,10, 0), 9,10, 9,10, True, 'ش', clBlue);
928 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
929 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
930 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
931 TestEnd;
932
933 TestStart('Scan full line 18 / hl-token', 18, 10, 30, 18);
934 TestNext([], b(10,12, 0), b(11,13, 0), 10,11, 10,11, False, '''', clYellow);
935 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
936 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
937 TestEnd;
938
939 TestStart('Scan full line 18 / hl-token', 18, 11, 30, 18);
940 TestNext([], b(11,13, 0), b(12,14, 0), 11,12, 11,12, False, 'b', clRed);
941 TestNext([], b(12,14, 0), b(30,32, 0), 12,30, 12,30, False, ' ', clBlack);
942 TestEnd;
943
944 // Mixed RTL (and weak), end in RTL
945 // increase LeftChar
946 SynEdit.BlockBegin := Point(1,1);
947 TestStart('Scan full line 18 / hl-token', 19, 1, 30, 19);
948 TestNext([], b( 1, 1, 0), b( 7, 7, 0), 1, 7, 1, 7, False, 'a ', clGreen);
949 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
950 TestNext([], b(12, 8, 0), b( 8,16, 0), 8,12, 8,12, True, 'شسقف', clBlue);
951 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
952 TestEnd;
953
954 TestStart('Scan full line 18 / hl-token', 19, 2, 30, 19);
955 TestNext([], b( 2, 2, 0), b( 7, 7, 0), 2, 7, 2, 7, False, ' ', clGreen);
956 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
957 TestNext([], b(12, 8, 0), b( 8,16, 0), 8,12, 8,12, True, 'شسقف', clBlue);
958 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
959 TestEnd;
960
961 TestStart('Scan full line 18 / hl-token', 19, 3, 30, 19);
962 TestNext([], b( 3, 3, 0), b( 7, 7, 0), 3, 7, 3, 7, False, ' ', clGreen);
963 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
964 TestNext([], b(12, 8, 0), b( 8,16, 0), 8,12, 8,12, True, 'شسقف', clBlue);
965 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
966 TestEnd;
967
968 TestStart('Scan full line 18 / hl-token', 19, 4, 30, 19);
969 TestNext([], b( 4, 4, 0), b( 7, 7, 0), 4, 7, 4, 7, False, ' ', clGreen);
970 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
971 TestNext([], b(12, 8, 0), b( 8,16, 0), 8,12, 8,12, True, 'شسقف', clBlue);
972 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
973 TestEnd;
974
975 TestStart('Scan full line 18 / hl-token', 19, 5, 30, 19);
976 TestNext([], b( 5, 5, 0), b( 7, 7, 0), 5, 7, 5, 7, False, ' ', clGreen);
977 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
978 TestNext([], b(12, 8, 0), b( 8,16, 0), 8,12, 8,12, True, 'شسقف', clBlue);
979 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
980 TestEnd;
981
982 TestStart('Scan full line 18 / hl-token', 19, 6, 30, 19);
983 TestNext([], b( 6, 6, 0), b( 7, 7, 0), 6, 7, 6, 7, False, ' ', clGreen);
984 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
985 TestNext([], b(12, 8, 0), b( 8,16, 0), 8,12, 8,12, True, 'شسقف', clBlue);
986 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
987 TestEnd;
988
989 TestStart('Scan full line 18 / hl-token', 19, 7, 30, 19);
990 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
991 TestNext([], b(12, 8, 0), b( 8,16, 0), 8,12, 8,12, True, 'شسقف', clBlue);
992 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
993 TestEnd;
994
995 TestStart('Scan full line 18 / hl-token', 19, 8, 30, 19);
996 TestNext([], b(12, 8, 0), b( 8,16, 0), 8,12, 8,12, True, 'شسقف', clBlue);
997 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
998 TestEnd;
999
1000 TestStart('Scan full line 18 / hl-token', 19, 9, 30, 19);
1001 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clBlue);
1002 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1003 TestEnd;
1004
1005 TestStart('Scan full line 18 / hl-token', 19, 10, 30, 19);
1006 TestNext([], b(12, 8, 0), b(10,12, 0), 10,12, 10,12, True, 'شس', clBlue);
1007 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1008 TestEnd;
1009
1010 TestStart('Scan full line 18 / hl-token', 19, 11, 30, 19);
1011 TestNext([], b(12, 8, 0), b(11,10, 0), 11,12, 11,12, True, 'ش', clBlue);
1012 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1013 TestEnd;
1014
1015 TestStart('Scan full line 18 / hl-token', 19, 12, 30, 19);
1016 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1017 TestEnd;
1018
1019 TestStart('Scan full line 18 / hl-token', 19, 13, 30, 19);
1020 TestNext([], b(13,17, 0), b(30,34, 0), 13,30, 13,30, False, ' ', clBlack);
1021 TestEnd;
1022
1023 // Change highlight, so last char is diff color
1024
1025 SynEdit.BlockBegin := Point(1,1);
1026 TestStart('Scan full line 18 / hl-token', 20, 1, 30, 20);
1027 TestNext([], b( 1, 1, 0), b( 7, 7, 0), 1, 7, 1, 7, False, 'a ', clGreen);
1028 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
1029 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1030 TestNext([], b( 9,14, 0), b( 8,16, 0), 8, 9, 8, 9, True, 'ف', clBlue);
1031 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1032 TestEnd;
1033
1034 TestStart('Scan full line 18 / hl-token', 20, 2, 30, 20);
1035 TestNext([], b( 2, 2, 0), b( 7, 7, 0), 2, 7, 2, 7, False, ' ', clGreen);
1036 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
1037 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1038 TestNext([], b( 9,14, 0), b( 8,16, 0), 8, 9, 8, 9, True, 'ف', clBlue);
1039 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1040 TestEnd;
1041
1042 TestStart('Scan full line 18 / hl-token', 20, 3, 30, 20);
1043 TestNext([], b( 3, 3, 0), b( 7, 7, 0), 3, 7, 3, 7, False, ' ', clGreen);
1044 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
1045 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1046 TestNext([], b( 9,14, 0), b( 8,16, 0), 8, 9, 8, 9, True, 'ف', clBlue);
1047 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1048 TestEnd;
1049
1050 TestStart('Scan full line 18 / hl-token', 20, 4, 30, 20);
1051 TestNext([], b( 4, 4, 0), b( 7, 7, 0), 4, 7, 4, 7, False, ' ', clGreen);
1052 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
1053 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1054 TestNext([], b( 9,14, 0), b( 8,16, 0), 8, 9, 8, 9, True, 'ف', clBlue);
1055 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1056 TestEnd;
1057
1058 TestStart('Scan full line 18 / hl-token', 20, 5, 30, 20);
1059 TestNext([], b( 5, 5, 0), b( 7, 7, 0), 5, 7, 5, 7, False, ' ', clGreen);
1060 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
1061 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1062 TestNext([], b( 9,14, 0), b( 8,16, 0), 8, 9, 8, 9, True, 'ف', clBlue);
1063 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1064 TestEnd;
1065
1066 TestStart('Scan full line 18 / hl-token', 20, 6, 30, 20);
1067 TestNext([], b( 6, 6, 0), b( 7, 7, 0), 6, 7, 6, 7, False, ' ', clGreen);
1068 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
1069 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1070 TestNext([], b( 9,14, 0), b( 8,16, 0), 8, 9, 8, 9, True, 'ف', clBlue);
1071 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1072 TestEnd;
1073
1074 TestStart('Scan full line 18 / hl-token', 20, 7, 30, 20);
1075 TestNext([], b( 7, 7, 0), b( 8, 8, 0), 7, 8, 7, 8, False, '''', clYellow);
1076 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1077 TestNext([], b( 9,14, 0), b( 8,16, 0), 8, 9, 8, 9, True, 'ف', clBlue);
1078 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1079 TestEnd;
1080
1081 TestStart('Scan full line 18 / hl-token', 20, 8, 30, 20);
1082 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1083 TestNext([], b( 9,14, 0), b( 8,16, 0), 8, 9, 8, 9, True, 'ف', clBlue);
1084 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1085 TestEnd;
1086
1087 TestStart('Scan full line 18 / hl-token', 20, 9, 30, 20);
1088 TestNext([], b(12, 8, 0), b( 9,14, 0), 9,12, 9,12, True, 'شسق', clRed);
1089 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1090 TestEnd;
1091
1092 TestStart('Scan full line 18 / hl-token', 20, 10, 30, 20);
1093 TestNext([], b(12, 8, 0), b(10,12, 0), 10,12, 10,12, True, 'شس', clRed);
1094 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1095 TestEnd;
1096
1097 TestStart('Scan full line 18 / hl-token', 20, 11, 30, 20);
1098 TestNext([], b(12, 8, 0), b(11,10, 0), 11,12, 11,12, True, 'ش', clRed);
1099 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1100 TestEnd;
1101
1102 TestStart('Scan full line 18 / hl-token', 20, 12, 30, 20);
1103 TestNext([], b(12,16, 0), b(30,34, 0), 12,30, 12,30, False, ' ', clBlack);
1104 TestEnd;
1105
1106 TestStart('Scan full line 18 / hl-token', 20, 13, 30, 20);
1107 TestNext([], b(13,17, 0), b(30,34, 0), 13,30, 13,30, False, ' ', clBlack);
1108 TestEnd;
1109
1110
1111
1112
1113
1114
1115
1116 SynEdit.ViewedTextBuffer.DisplayView.FinishHighlighterTokens;
1117
1118 end;
1119 begin
1120 PushBaseName('Incl PreFirst');
1121 SkipPreFirst := False;
1122 DoTests;
1123 PopPushBaseName('Excl PreFirst');
1124 SkipPreFirst := True;
1125 DoTests;
1126 PopBaseName;
1127 end;
1128
1129 initialization
1130 RegisterTest(TTestSynTextArea);
1131
1132 end.
1133
1134