Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/scene/test_code_edit.h
10277 views
1
/**************************************************************************/
2
/* test_code_edit.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "scene/gui/code_edit.h"
34
35
#include "tests/test_macros.h"
36
37
namespace TestCodeEdit {
38
TEST_CASE("[SceneTree][CodeEdit] line gutters") {
39
CodeEdit *code_edit = memnew(CodeEdit);
40
SceneTree::get_singleton()->get_root()->add_child(code_edit);
41
code_edit->grab_focus();
42
43
SUBCASE("[CodeEdit] breakpoints") {
44
SIGNAL_WATCH(code_edit, "breakpoint_toggled");
45
46
SUBCASE("[CodeEdit] draw breakpoints gutter") {
47
code_edit->set_draw_breakpoints_gutter(false);
48
CHECK_FALSE(code_edit->is_drawing_breakpoints_gutter());
49
50
code_edit->set_draw_breakpoints_gutter(true);
51
CHECK(code_edit->is_drawing_breakpoints_gutter());
52
}
53
54
SUBCASE("[CodeEdit] set line as breakpoint") {
55
/* Out of bounds. */
56
ERR_PRINT_OFF;
57
58
code_edit->set_line_as_breakpoint(-1, true);
59
CHECK_FALSE(code_edit->is_line_breakpointed(-1));
60
SIGNAL_CHECK_FALSE("breakpoint_toggled");
61
62
code_edit->set_line_as_breakpoint(1, true);
63
CHECK_FALSE(code_edit->is_line_breakpointed(1));
64
SIGNAL_CHECK_FALSE("breakpoint_toggled");
65
66
ERR_PRINT_ON;
67
68
Array args = { { 0 } };
69
70
code_edit->set_line_as_breakpoint(0, true);
71
CHECK(code_edit->is_line_breakpointed(0));
72
CHECK(code_edit->get_breakpointed_lines()[0] == 0);
73
SIGNAL_CHECK("breakpoint_toggled", args);
74
75
code_edit->set_line_as_breakpoint(0, false);
76
CHECK_FALSE(code_edit->is_line_breakpointed(0));
77
SIGNAL_CHECK("breakpoint_toggled", args);
78
}
79
80
SUBCASE("[CodeEdit] clear breakpointed lines") {
81
code_edit->clear_breakpointed_lines();
82
SIGNAL_CHECK_FALSE("breakpoint_toggled");
83
84
Array args = { { 0 } };
85
86
code_edit->set_line_as_breakpoint(0, true);
87
CHECK(code_edit->is_line_breakpointed(0));
88
SIGNAL_CHECK("breakpoint_toggled", args);
89
90
code_edit->clear_breakpointed_lines();
91
CHECK_FALSE(code_edit->is_line_breakpointed(0));
92
SIGNAL_CHECK("breakpoint_toggled", args);
93
}
94
95
SUBCASE("[CodeEdit] breakpoints and set text") {
96
Array args = { { 0 } };
97
98
code_edit->set_text("test\nline");
99
code_edit->set_line_as_breakpoint(0, true);
100
CHECK(code_edit->is_line_breakpointed(0));
101
SIGNAL_CHECK("breakpoint_toggled", args);
102
103
/* breakpoint on lines that still exist are kept. */
104
code_edit->set_text("");
105
MessageQueue::get_singleton()->flush();
106
CHECK(code_edit->is_line_breakpointed(0));
107
SIGNAL_CHECK_FALSE("breakpoint_toggled");
108
109
/* breakpoint on lines that are removed should also be removed. */
110
code_edit->clear_breakpointed_lines();
111
SIGNAL_DISCARD("breakpoint_toggled")
112
113
args = { { 1 } };
114
code_edit->set_text("test\nline");
115
code_edit->set_line_as_breakpoint(1, true);
116
CHECK(code_edit->is_line_breakpointed(1));
117
SIGNAL_CHECK("breakpoint_toggled", args);
118
119
code_edit->set_text("");
120
MessageQueue::get_singleton()->flush();
121
CHECK_FALSE(code_edit->is_line_breakpointed(0));
122
ERR_PRINT_OFF;
123
CHECK_FALSE(code_edit->is_line_breakpointed(1));
124
ERR_PRINT_ON;
125
SIGNAL_CHECK("breakpoint_toggled", args);
126
}
127
128
SUBCASE("[CodeEdit] breakpoints and clear") {
129
Array args = { { 0 } };
130
131
code_edit->set_text("test\nline");
132
code_edit->set_line_as_breakpoint(0, true);
133
CHECK(code_edit->is_line_breakpointed(0));
134
SIGNAL_CHECK("breakpoint_toggled", args);
135
136
/* breakpoint on lines that still exist are removed. */
137
code_edit->clear();
138
MessageQueue::get_singleton()->flush();
139
CHECK_FALSE(code_edit->is_line_breakpointed(0));
140
SIGNAL_CHECK("breakpoint_toggled", args);
141
142
/* breakpoint on lines that are removed should also be removed. */
143
code_edit->clear_breakpointed_lines();
144
SIGNAL_DISCARD("breakpoint_toggled")
145
146
args = { { 1 } };
147
code_edit->set_text("test\nline");
148
code_edit->set_line_as_breakpoint(1, true);
149
CHECK(code_edit->is_line_breakpointed(1));
150
SIGNAL_CHECK("breakpoint_toggled", args);
151
152
code_edit->clear();
153
MessageQueue::get_singleton()->flush();
154
CHECK_FALSE(code_edit->is_line_breakpointed(0));
155
ERR_PRINT_OFF;
156
CHECK_FALSE(code_edit->is_line_breakpointed(1));
157
ERR_PRINT_ON;
158
SIGNAL_CHECK("breakpoint_toggled", args);
159
}
160
161
SUBCASE("[CodeEdit] breakpoints and new lines no text") {
162
Array args = { { 0 } };
163
164
/* No text moves breakpoint. */
165
code_edit->set_line_as_breakpoint(0, true);
166
CHECK(code_edit->is_line_breakpointed(0));
167
SIGNAL_CHECK("breakpoint_toggled", args);
168
169
// Normal.
170
args = { { 0 }, { 1 } };
171
172
SEND_GUI_ACTION("ui_text_newline");
173
CHECK(code_edit->get_line_count() == 2);
174
CHECK_FALSE(code_edit->is_line_breakpointed(0));
175
CHECK(code_edit->is_line_breakpointed(1));
176
SIGNAL_CHECK("breakpoint_toggled", args);
177
178
// Non-Breaking.
179
args = { { 1 }, { 2 } };
180
SEND_GUI_ACTION("ui_text_newline_blank");
181
CHECK(code_edit->get_line_count() == 3);
182
CHECK_FALSE(code_edit->is_line_breakpointed(1));
183
CHECK(code_edit->is_line_breakpointed(2));
184
SIGNAL_CHECK("breakpoint_toggled", args);
185
186
// Above.
187
args = { { 2 }, { 3 } };
188
SEND_GUI_ACTION("ui_text_newline_above");
189
CHECK(code_edit->get_line_count() == 4);
190
CHECK_FALSE(code_edit->is_line_breakpointed(2));
191
CHECK(code_edit->is_line_breakpointed(3));
192
SIGNAL_CHECK("breakpoint_toggled", args);
193
}
194
195
SUBCASE("[CodeEdit] breakpoints and new lines with text") {
196
Array args = { { 0 } };
197
198
/* Having text does not move breakpoint. */
199
code_edit->insert_text_at_caret("text");
200
code_edit->set_line_as_breakpoint(0, true);
201
CHECK(code_edit->is_line_breakpointed(0));
202
SIGNAL_CHECK("breakpoint_toggled", args);
203
204
/* Normal. */
205
SEND_GUI_ACTION("ui_text_newline");
206
CHECK(code_edit->get_line_count() == 2);
207
CHECK(code_edit->is_line_breakpointed(0));
208
CHECK_FALSE(code_edit->is_line_breakpointed(1));
209
SIGNAL_CHECK_FALSE("breakpoint_toggled");
210
211
/* Non-Breaking. */
212
code_edit->set_caret_line(0);
213
SEND_GUI_ACTION("ui_text_newline_blank");
214
CHECK(code_edit->get_line_count() == 3);
215
CHECK(code_edit->is_line_breakpointed(0));
216
CHECK_FALSE(code_edit->is_line_breakpointed(1));
217
SIGNAL_CHECK_FALSE("breakpoint_toggled");
218
219
// Above does move.
220
args = { { 0 }, { 1 } };
221
222
code_edit->set_caret_line(0);
223
SEND_GUI_ACTION("ui_text_newline_above");
224
CHECK(code_edit->get_line_count() == 4);
225
CHECK_FALSE(code_edit->is_line_breakpointed(0));
226
CHECK(code_edit->is_line_breakpointed(1));
227
SIGNAL_CHECK("breakpoint_toggled", args);
228
}
229
230
SUBCASE("[CodeEdit] breakpoints and backspace") {
231
Array args = { { 1 } };
232
233
code_edit->set_text("\n\n");
234
code_edit->set_line_as_breakpoint(1, true);
235
CHECK(code_edit->is_line_breakpointed(1));
236
SIGNAL_CHECK("breakpoint_toggled", args);
237
238
code_edit->set_caret_line(2);
239
240
/* backspace onto line does not remove breakpoint */
241
SEND_GUI_ACTION("ui_text_backspace");
242
CHECK(code_edit->is_line_breakpointed(1));
243
SIGNAL_CHECK_FALSE("breakpoint_toggled");
244
245
/* backspace on breakpointed line removes it */
246
SEND_GUI_ACTION("ui_text_backspace");
247
CHECK_FALSE(code_edit->is_line_breakpointed(0));
248
ERR_PRINT_OFF;
249
CHECK_FALSE(code_edit->is_line_breakpointed(1));
250
ERR_PRINT_ON;
251
SIGNAL_CHECK("breakpoint_toggled", args);
252
253
// Backspace above breakpointed line moves it.
254
args = { { 2 } };
255
256
code_edit->set_text("\n\n");
257
code_edit->set_line_as_breakpoint(2, true);
258
CHECK(code_edit->is_line_breakpointed(2));
259
SIGNAL_CHECK("breakpoint_toggled", args);
260
261
code_edit->set_caret_line(1);
262
263
args = { { 2 }, { 1 } };
264
SEND_GUI_ACTION("ui_text_backspace");
265
ERR_PRINT_OFF;
266
CHECK_FALSE(code_edit->is_line_breakpointed(2));
267
ERR_PRINT_ON;
268
CHECK(code_edit->is_line_breakpointed(1));
269
SIGNAL_CHECK("breakpoint_toggled", args);
270
}
271
272
SUBCASE("[CodeEdit] breakpoints and delete") {
273
Array args = { { 1 } };
274
275
code_edit->set_text("\n\n");
276
code_edit->set_line_as_breakpoint(1, true);
277
CHECK(code_edit->is_line_breakpointed(1));
278
SIGNAL_CHECK("breakpoint_toggled", args);
279
code_edit->set_caret_line(1);
280
281
/* Delete onto breakpointed lines does not remove it. */
282
SEND_GUI_ACTION("ui_text_delete");
283
CHECK(code_edit->get_line_count() == 2);
284
CHECK(code_edit->is_line_breakpointed(1));
285
SIGNAL_CHECK_FALSE("breakpoint_toggled");
286
287
/* Delete moving breakpointed line up removes it. */
288
code_edit->set_caret_line(0);
289
SEND_GUI_ACTION("ui_text_delete");
290
CHECK(code_edit->get_line_count() == 1);
291
ERR_PRINT_OFF;
292
CHECK_FALSE(code_edit->is_line_breakpointed(1));
293
ERR_PRINT_ON;
294
SIGNAL_CHECK("breakpoint_toggled", args);
295
296
// Delete above breakpointed line moves it.
297
args = { { 2 } };
298
299
code_edit->set_text("\n\n");
300
code_edit->set_line_as_breakpoint(2, true);
301
CHECK(code_edit->is_line_breakpointed(2));
302
SIGNAL_CHECK("breakpoint_toggled", args);
303
304
code_edit->set_caret_line(0);
305
306
args = { { 2 }, { 1 } };
307
SEND_GUI_ACTION("ui_text_delete");
308
ERR_PRINT_OFF;
309
CHECK_FALSE(code_edit->is_line_breakpointed(2));
310
ERR_PRINT_ON;
311
CHECK(code_edit->is_line_breakpointed(1));
312
SIGNAL_CHECK("breakpoint_toggled", args);
313
}
314
315
SUBCASE("[CodeEdit] breakpoints and delete selection") {
316
Array args = { { 1 } };
317
318
code_edit->set_text("\n\n");
319
code_edit->set_line_as_breakpoint(1, true);
320
CHECK(code_edit->is_line_breakpointed(1));
321
SIGNAL_CHECK("breakpoint_toggled", args);
322
323
code_edit->select(0, 0, 2, 0);
324
code_edit->delete_selection();
325
MessageQueue::get_singleton()->flush();
326
CHECK_FALSE(code_edit->is_line_breakpointed(0));
327
SIGNAL_CHECK("breakpoint_toggled", args);
328
329
// Should handle breakpoint move when deleting selection by adding less text then removed.
330
args = { { 9 } };
331
332
code_edit->set_text("\n\n\n\n\n\n\n\n\n");
333
code_edit->set_line_as_breakpoint(9, true);
334
CHECK(code_edit->is_line_breakpointed(9));
335
SIGNAL_CHECK("breakpoint_toggled", args);
336
337
code_edit->select(0, 0, 6, 0);
338
339
args = { { 9 }, { 4 } };
340
SEND_GUI_ACTION("ui_text_newline");
341
ERR_PRINT_OFF;
342
CHECK_FALSE(code_edit->is_line_breakpointed(9));
343
ERR_PRINT_ON;
344
CHECK(code_edit->is_line_breakpointed(4));
345
SIGNAL_CHECK("breakpoint_toggled", args);
346
347
// Should handle breakpoint move when deleting selection by adding more text then removed.
348
args = { { 9 }, { 14 } };
349
350
code_edit->insert_text_at_caret("\n\n\n\n\n");
351
MessageQueue::get_singleton()->flush();
352
SIGNAL_DISCARD("breakpoint_toggled")
353
CHECK(code_edit->is_line_breakpointed(9));
354
355
code_edit->select(0, 0, 6, 0);
356
code_edit->insert_text_at_caret("\n\n\n\n\n\n\n\n\n\n\n");
357
MessageQueue::get_singleton()->flush();
358
CHECK(code_edit->is_line_breakpointed(14));
359
SIGNAL_CHECK("breakpoint_toggled", args);
360
}
361
362
SUBCASE("[CodeEdit] breakpoints and undo") {
363
Array args = { { 1 } };
364
365
code_edit->set_text("\n\n");
366
code_edit->set_line_as_breakpoint(1, true);
367
CHECK(code_edit->is_line_breakpointed(1));
368
SIGNAL_CHECK("breakpoint_toggled", args);
369
370
code_edit->select(0, 0, 2, 0);
371
code_edit->delete_selection();
372
MessageQueue::get_singleton()->flush();
373
CHECK_FALSE(code_edit->is_line_breakpointed(0));
374
SIGNAL_CHECK("breakpoint_toggled", args);
375
376
/* Undo does not restore breakpoint. */
377
code_edit->undo();
378
CHECK_FALSE(code_edit->is_line_breakpointed(1));
379
SIGNAL_CHECK_FALSE("breakpoint_toggled");
380
}
381
382
SIGNAL_UNWATCH(code_edit, "breakpoint_toggled");
383
}
384
385
SUBCASE("[CodeEdit] bookmarks") {
386
SUBCASE("[CodeEdit] draw bookmarks gutter") {
387
code_edit->set_draw_bookmarks_gutter(false);
388
CHECK_FALSE(code_edit->is_drawing_bookmarks_gutter());
389
390
code_edit->set_draw_bookmarks_gutter(true);
391
CHECK(code_edit->is_drawing_bookmarks_gutter());
392
}
393
394
SUBCASE("[CodeEdit] set line as bookmarks") {
395
/* Out of bounds. */
396
ERR_PRINT_OFF;
397
398
code_edit->set_line_as_bookmarked(-1, true);
399
CHECK_FALSE(code_edit->is_line_bookmarked(-1));
400
401
code_edit->set_line_as_bookmarked(1, true);
402
CHECK_FALSE(code_edit->is_line_bookmarked(1));
403
404
ERR_PRINT_ON;
405
406
code_edit->set_line_as_bookmarked(0, true);
407
CHECK(code_edit->get_bookmarked_lines()[0] == 0);
408
CHECK(code_edit->is_line_bookmarked(0));
409
410
code_edit->set_line_as_bookmarked(0, false);
411
CHECK_FALSE(code_edit->is_line_bookmarked(0));
412
}
413
414
SUBCASE("[CodeEdit] clear bookmarked lines") {
415
code_edit->clear_bookmarked_lines();
416
417
code_edit->set_line_as_bookmarked(0, true);
418
CHECK(code_edit->is_line_bookmarked(0));
419
420
code_edit->clear_bookmarked_lines();
421
CHECK_FALSE(code_edit->is_line_bookmarked(0));
422
}
423
424
SUBCASE("[CodeEdit] bookmarks and set text") {
425
code_edit->set_text("test\nline");
426
code_edit->set_line_as_bookmarked(0, true);
427
CHECK(code_edit->is_line_bookmarked(0));
428
429
/* bookmarks on lines that still exist are kept. */
430
code_edit->set_text("");
431
MessageQueue::get_singleton()->flush();
432
CHECK(code_edit->is_line_bookmarked(0));
433
434
/* bookmarks on lines that are removed should also be removed. */
435
code_edit->clear_bookmarked_lines();
436
437
code_edit->set_text("test\nline");
438
code_edit->set_line_as_bookmarked(1, true);
439
CHECK(code_edit->is_line_bookmarked(1));
440
441
code_edit->set_text("");
442
MessageQueue::get_singleton()->flush();
443
CHECK_FALSE(code_edit->is_line_bookmarked(0));
444
ERR_PRINT_OFF;
445
CHECK_FALSE(code_edit->is_line_bookmarked(1));
446
ERR_PRINT_ON;
447
}
448
449
SUBCASE("[CodeEdit] bookmarks and clear") {
450
code_edit->set_text("test\nline");
451
code_edit->set_line_as_bookmarked(0, true);
452
CHECK(code_edit->is_line_bookmarked(0));
453
454
/* bookmarks on lines that still exist are removed. */
455
code_edit->clear();
456
MessageQueue::get_singleton()->flush();
457
CHECK_FALSE(code_edit->is_line_bookmarked(0));
458
459
/* bookmarks on lines that are removed should also be removed. */
460
code_edit->clear_bookmarked_lines();
461
462
code_edit->set_text("test\nline");
463
code_edit->set_line_as_bookmarked(1, true);
464
CHECK(code_edit->is_line_bookmarked(1));
465
466
code_edit->clear();
467
MessageQueue::get_singleton()->flush();
468
CHECK_FALSE(code_edit->is_line_bookmarked(0));
469
ERR_PRINT_OFF;
470
CHECK_FALSE(code_edit->is_line_bookmarked(1));
471
ERR_PRINT_ON;
472
}
473
474
SUBCASE("[CodeEdit] bookmarks and new lines no text") {
475
/* No text moves bookmarks. */
476
code_edit->set_line_as_bookmarked(0, true);
477
CHECK(code_edit->is_line_bookmarked(0));
478
479
/* Normal. */
480
SEND_GUI_ACTION("ui_text_newline");
481
CHECK(code_edit->get_line_count() == 2);
482
CHECK_FALSE(code_edit->is_line_bookmarked(0));
483
CHECK(code_edit->is_line_bookmarked(1));
484
485
/* Non-Breaking. */
486
SEND_GUI_ACTION("ui_text_newline_blank");
487
CHECK(code_edit->get_line_count() == 3);
488
CHECK_FALSE(code_edit->is_line_bookmarked(1));
489
CHECK(code_edit->is_line_bookmarked(2));
490
491
/* Above. */
492
SEND_GUI_ACTION("ui_text_newline_above");
493
CHECK(code_edit->get_line_count() == 4);
494
CHECK_FALSE(code_edit->is_line_bookmarked(2));
495
CHECK(code_edit->is_line_bookmarked(3));
496
}
497
498
SUBCASE("[CodeEdit] bookmarks and new lines with text") {
499
/* Having text does not move bookmark. */
500
code_edit->insert_text_at_caret("text");
501
code_edit->set_line_as_bookmarked(0, true);
502
CHECK(code_edit->is_line_bookmarked(0));
503
504
/* Normal. */
505
SEND_GUI_ACTION("ui_text_newline");
506
CHECK(code_edit->get_line_count() == 2);
507
CHECK(code_edit->is_line_bookmarked(0));
508
CHECK_FALSE(code_edit->is_line_bookmarked(1));
509
510
/* Non-Breaking. */
511
code_edit->set_caret_line(0);
512
SEND_GUI_ACTION("ui_text_newline_blank");
513
CHECK(code_edit->get_line_count() == 3);
514
CHECK(code_edit->is_line_bookmarked(0));
515
CHECK_FALSE(code_edit->is_line_bookmarked(1));
516
517
/* Above does move. */
518
code_edit->set_caret_line(0);
519
SEND_GUI_ACTION("ui_text_newline_above");
520
CHECK(code_edit->get_line_count() == 4);
521
CHECK_FALSE(code_edit->is_line_bookmarked(0));
522
CHECK(code_edit->is_line_bookmarked(1));
523
}
524
525
SUBCASE("[CodeEdit] bookmarks and backspace") {
526
code_edit->set_text("\n\n");
527
code_edit->set_line_as_bookmarked(1, true);
528
CHECK(code_edit->is_line_bookmarked(1));
529
530
code_edit->set_caret_line(2);
531
532
/* backspace onto line does not remove bookmark */
533
SEND_GUI_ACTION("ui_text_backspace");
534
CHECK(code_edit->is_line_bookmarked(1));
535
536
/* backspace on bookmarked line removes it */
537
SEND_GUI_ACTION("ui_text_backspace");
538
CHECK_FALSE(code_edit->is_line_bookmarked(0));
539
ERR_PRINT_OFF;
540
CHECK_FALSE(code_edit->is_line_bookmarked(1));
541
ERR_PRINT_ON;
542
}
543
544
SUBCASE("[CodeEdit] bookmarks and delete") {
545
code_edit->set_text("\n\n");
546
code_edit->set_line_as_bookmarked(1, true);
547
CHECK(code_edit->is_line_bookmarked(1));
548
code_edit->set_caret_line(1);
549
550
/* Delete onto bookmarked lines does not remove it. */
551
SEND_GUI_ACTION("ui_text_delete");
552
CHECK(code_edit->get_line_count() == 2);
553
CHECK(code_edit->is_line_bookmarked(1));
554
555
/* Delete moving bookmarked line up removes it. */
556
code_edit->set_caret_line(0);
557
SEND_GUI_ACTION("ui_text_delete");
558
CHECK(code_edit->get_line_count() == 1);
559
ERR_PRINT_OFF;
560
CHECK_FALSE(code_edit->is_line_bookmarked(1));
561
ERR_PRINT_ON;
562
}
563
564
SUBCASE("[CodeEdit] bookmarks and delete selection") {
565
code_edit->set_text("\n\n");
566
code_edit->set_line_as_bookmarked(1, true);
567
CHECK(code_edit->is_line_bookmarked(1));
568
569
code_edit->select(0, 0, 2, 0);
570
code_edit->delete_selection();
571
MessageQueue::get_singleton()->flush();
572
CHECK_FALSE(code_edit->is_line_bookmarked(0));
573
}
574
575
SUBCASE("[CodeEdit] bookmarks and undo") {
576
code_edit->set_text("\n\n");
577
code_edit->set_line_as_bookmarked(1, true);
578
CHECK(code_edit->is_line_bookmarked(1));
579
580
code_edit->select(0, 0, 2, 0);
581
code_edit->delete_selection();
582
MessageQueue::get_singleton()->flush();
583
CHECK_FALSE(code_edit->is_line_bookmarked(0));
584
585
/* Undo does not restore bookmark. */
586
code_edit->undo();
587
CHECK_FALSE(code_edit->is_line_bookmarked(1));
588
}
589
}
590
591
SUBCASE("[CodeEdit] executing lines") {
592
SUBCASE("[CodeEdit] draw executing lines gutter") {
593
code_edit->set_draw_executing_lines_gutter(false);
594
CHECK_FALSE(code_edit->is_drawing_executing_lines_gutter());
595
596
code_edit->set_draw_executing_lines_gutter(true);
597
CHECK(code_edit->is_drawing_executing_lines_gutter());
598
}
599
600
SUBCASE("[CodeEdit] set line as executing lines") {
601
/* Out of bounds. */
602
ERR_PRINT_OFF;
603
604
code_edit->set_line_as_executing(-1, true);
605
CHECK_FALSE(code_edit->is_line_executing(-1));
606
607
code_edit->set_line_as_executing(1, true);
608
CHECK_FALSE(code_edit->is_line_executing(1));
609
610
ERR_PRINT_ON;
611
612
code_edit->set_line_as_executing(0, true);
613
CHECK(code_edit->get_executing_lines()[0] == 0);
614
CHECK(code_edit->is_line_executing(0));
615
616
code_edit->set_line_as_executing(0, false);
617
CHECK_FALSE(code_edit->is_line_executing(0));
618
}
619
620
SUBCASE("[CodeEdit] clear executing lines lines") {
621
code_edit->clear_executing_lines();
622
623
code_edit->set_line_as_executing(0, true);
624
CHECK(code_edit->is_line_executing(0));
625
626
code_edit->clear_executing_lines();
627
CHECK_FALSE(code_edit->is_line_executing(0));
628
}
629
630
SUBCASE("[CodeEdit] executing lines and set text") {
631
code_edit->set_text("test\nline");
632
code_edit->set_line_as_executing(0, true);
633
CHECK(code_edit->is_line_executing(0));
634
635
/* executing on lines that still exist are kept. */
636
code_edit->set_text("");
637
MessageQueue::get_singleton()->flush();
638
CHECK(code_edit->is_line_executing(0));
639
640
/* executing on lines that are removed should also be removed. */
641
code_edit->clear_executing_lines();
642
643
code_edit->set_text("test\nline");
644
code_edit->set_line_as_executing(1, true);
645
CHECK(code_edit->is_line_executing(1));
646
647
code_edit->set_text("");
648
MessageQueue::get_singleton()->flush();
649
CHECK_FALSE(code_edit->is_line_executing(0));
650
ERR_PRINT_OFF;
651
CHECK_FALSE(code_edit->is_line_executing(1));
652
ERR_PRINT_ON;
653
}
654
655
SUBCASE("[CodeEdit] executing lines and clear") {
656
code_edit->set_text("test\nline");
657
code_edit->set_line_as_executing(0, true);
658
CHECK(code_edit->is_line_executing(0));
659
660
/* executing on lines that still exist are removed. */
661
code_edit->clear();
662
MessageQueue::get_singleton()->flush();
663
CHECK_FALSE(code_edit->is_line_executing(0));
664
665
/* executing on lines that are removed should also be removed. */
666
code_edit->clear_executing_lines();
667
668
code_edit->set_text("test\nline");
669
code_edit->set_line_as_executing(1, true);
670
CHECK(code_edit->is_line_executing(1));
671
672
code_edit->clear();
673
MessageQueue::get_singleton()->flush();
674
CHECK_FALSE(code_edit->is_line_executing(0));
675
ERR_PRINT_OFF;
676
CHECK_FALSE(code_edit->is_line_executing(1));
677
ERR_PRINT_ON;
678
}
679
680
SUBCASE("[CodeEdit] executing lines and new lines no text") {
681
/* No text moves executing lines. */
682
code_edit->set_line_as_executing(0, true);
683
CHECK(code_edit->is_line_executing(0));
684
685
/* Normal. */
686
SEND_GUI_ACTION("ui_text_newline");
687
CHECK(code_edit->get_line_count() == 2);
688
CHECK_FALSE(code_edit->is_line_executing(0));
689
CHECK(code_edit->is_line_executing(1));
690
691
/* Non-Breaking. */
692
SEND_GUI_ACTION("ui_text_newline_blank");
693
CHECK(code_edit->get_line_count() == 3);
694
CHECK_FALSE(code_edit->is_line_executing(1));
695
CHECK(code_edit->is_line_executing(2));
696
697
/* Above. */
698
SEND_GUI_ACTION("ui_text_newline_above");
699
CHECK(code_edit->get_line_count() == 4);
700
CHECK_FALSE(code_edit->is_line_executing(2));
701
CHECK(code_edit->is_line_executing(3));
702
}
703
704
SUBCASE("[CodeEdit] executing lines and new lines with text") {
705
/* Having text does not move executing lines. */
706
code_edit->insert_text_at_caret("text");
707
code_edit->set_line_as_executing(0, true);
708
CHECK(code_edit->is_line_executing(0));
709
710
/* Normal. */
711
SEND_GUI_ACTION("ui_text_newline");
712
CHECK(code_edit->get_line_count() == 2);
713
CHECK(code_edit->is_line_executing(0));
714
CHECK_FALSE(code_edit->is_line_executing(1));
715
716
/* Non-Breaking. */
717
code_edit->set_caret_line(0);
718
SEND_GUI_ACTION("ui_text_newline_blank");
719
CHECK(code_edit->get_line_count() == 3);
720
CHECK(code_edit->is_line_executing(0));
721
CHECK_FALSE(code_edit->is_line_executing(1));
722
723
/* Above does move. */
724
code_edit->set_caret_line(0);
725
SEND_GUI_ACTION("ui_text_newline_above");
726
CHECK(code_edit->get_line_count() == 4);
727
CHECK_FALSE(code_edit->is_line_executing(0));
728
CHECK(code_edit->is_line_executing(1));
729
}
730
731
SUBCASE("[CodeEdit] executing lines and backspace") {
732
code_edit->set_text("\n\n");
733
code_edit->set_line_as_executing(1, true);
734
CHECK(code_edit->is_line_executing(1));
735
736
code_edit->set_caret_line(2);
737
738
/* backspace onto line does not remove executing lines. */
739
SEND_GUI_ACTION("ui_text_backspace");
740
CHECK(code_edit->is_line_executing(1));
741
742
/* backspace on executing line removes it */
743
SEND_GUI_ACTION("ui_text_backspace");
744
CHECK_FALSE(code_edit->is_line_executing(0));
745
ERR_PRINT_OFF;
746
CHECK_FALSE(code_edit->is_line_executing(1));
747
ERR_PRINT_ON;
748
}
749
750
SUBCASE("[CodeEdit] executing lines and delete") {
751
code_edit->set_text("\n\n");
752
code_edit->set_line_as_executing(1, true);
753
CHECK(code_edit->is_line_executing(1));
754
code_edit->set_caret_line(1);
755
756
/* Delete onto executing lines does not remove it. */
757
SEND_GUI_ACTION("ui_text_delete");
758
CHECK(code_edit->get_line_count() == 2);
759
CHECK(code_edit->is_line_executing(1));
760
761
/* Delete moving executing line up removes it. */
762
code_edit->set_caret_line(0);
763
SEND_GUI_ACTION("ui_text_delete");
764
CHECK(code_edit->get_line_count() == 1);
765
ERR_PRINT_OFF;
766
CHECK_FALSE(code_edit->is_line_executing(1));
767
ERR_PRINT_ON;
768
}
769
770
SUBCASE("[CodeEdit] executing lines and delete selection") {
771
code_edit->set_text("\n\n");
772
code_edit->set_line_as_executing(1, true);
773
CHECK(code_edit->is_line_executing(1));
774
775
code_edit->select(0, 0, 2, 0);
776
code_edit->delete_selection();
777
MessageQueue::get_singleton()->flush();
778
CHECK_FALSE(code_edit->is_line_executing(0));
779
}
780
781
SUBCASE("[CodeEdit] executing lines and undo") {
782
code_edit->set_text("\n\n");
783
code_edit->set_line_as_executing(1, true);
784
CHECK(code_edit->is_line_executing(1));
785
786
code_edit->select(0, 0, 2, 0);
787
code_edit->delete_selection();
788
MessageQueue::get_singleton()->flush();
789
CHECK_FALSE(code_edit->is_line_executing(0));
790
791
/* Undo does not restore executing lines. */
792
code_edit->undo();
793
CHECK_FALSE(code_edit->is_line_executing(1));
794
}
795
}
796
797
SUBCASE("[CodeEdit] line numbers") {
798
SUBCASE("[CodeEdit] draw line numbers gutter and padding") {
799
code_edit->set_draw_line_numbers(false);
800
CHECK_FALSE(code_edit->is_draw_line_numbers_enabled());
801
802
code_edit->set_draw_line_numbers(true);
803
CHECK(code_edit->is_draw_line_numbers_enabled());
804
805
code_edit->set_line_numbers_zero_padded(false);
806
CHECK_FALSE(code_edit->is_line_numbers_zero_padded());
807
808
code_edit->set_line_numbers_zero_padded(true);
809
CHECK(code_edit->is_line_numbers_zero_padded());
810
811
code_edit->set_line_numbers_zero_padded(false);
812
CHECK_FALSE(code_edit->is_line_numbers_zero_padded());
813
814
code_edit->set_draw_line_numbers(false);
815
CHECK_FALSE(code_edit->is_draw_line_numbers_enabled());
816
817
code_edit->set_line_numbers_zero_padded(true);
818
CHECK(code_edit->is_line_numbers_zero_padded());
819
}
820
}
821
822
SUBCASE("[CodeEdit] line folding") {
823
SUBCASE("[CodeEdit] draw line folding gutter") {
824
code_edit->set_draw_fold_gutter(false);
825
CHECK_FALSE(code_edit->is_drawing_fold_gutter());
826
827
code_edit->set_draw_fold_gutter(true);
828
CHECK(code_edit->is_drawing_fold_gutter());
829
}
830
}
831
832
memdelete(code_edit);
833
}
834
835
TEST_CASE("[SceneTree][CodeEdit] delimiters") {
836
CodeEdit *code_edit = memnew(CodeEdit);
837
SceneTree::get_singleton()->get_root()->add_child(code_edit);
838
code_edit->grab_focus();
839
840
const Point2 OUTSIDE_DELIMITER = Point2(-1, -1);
841
842
code_edit->clear_string_delimiters();
843
code_edit->clear_comment_delimiters();
844
845
SUBCASE("[CodeEdit] add and remove delimiters") {
846
SUBCASE("[CodeEdit] add and remove string delimiters") {
847
/* Add a delimiter.*/
848
code_edit->add_string_delimiter("\"", "\"", false);
849
CHECK(code_edit->has_string_delimiter("\""));
850
CHECK(code_edit->get_string_delimiters().size() == 1);
851
852
ERR_PRINT_OFF;
853
854
/* Adding a duplicate start key is not allowed. */
855
code_edit->add_string_delimiter("\"", "\'", false);
856
CHECK(code_edit->get_string_delimiters().size() == 1);
857
858
/* Adding a duplicate end key is allowed. */
859
code_edit->add_string_delimiter("'", "\"", false);
860
CHECK(code_edit->has_string_delimiter("'"));
861
CHECK(code_edit->get_string_delimiters().size() == 2);
862
863
/* Both start and end keys have to be symbols. */
864
code_edit->add_string_delimiter("f", "\"", false);
865
CHECK_FALSE(code_edit->has_string_delimiter("f"));
866
CHECK(code_edit->get_string_delimiters().size() == 2);
867
868
code_edit->add_string_delimiter("f", "\"", false);
869
CHECK_FALSE(code_edit->has_string_delimiter("f"));
870
CHECK(code_edit->get_string_delimiters().size() == 2);
871
872
code_edit->add_string_delimiter("@", "f", false);
873
CHECK_FALSE(code_edit->has_string_delimiter("@"));
874
CHECK(code_edit->get_string_delimiters().size() == 2);
875
876
code_edit->add_string_delimiter("f", "f", false);
877
CHECK_FALSE(code_edit->has_string_delimiter("f"));
878
CHECK(code_edit->get_string_delimiters().size() == 2);
879
880
/* Blank start keys are not allowed */
881
code_edit->add_string_delimiter("", "#", false);
882
CHECK_FALSE(code_edit->has_string_delimiter("#"));
883
CHECK(code_edit->get_string_delimiters().size() == 2);
884
885
ERR_PRINT_ON;
886
887
/* Blank end keys are allowed. */
888
code_edit->add_string_delimiter("#", "", false);
889
CHECK(code_edit->has_string_delimiter("#"));
890
CHECK(code_edit->get_string_delimiters().size() == 3);
891
892
/* Remove a delimiter. */
893
code_edit->remove_string_delimiter("#");
894
CHECK_FALSE(code_edit->has_string_delimiter("#"));
895
CHECK(code_edit->get_string_delimiters().size() == 2);
896
897
/* Set should override existing, and test multiline */
898
TypedArray<String> delimiters = { "^^ ^^" };
899
900
code_edit->set_string_delimiters(delimiters);
901
CHECK_FALSE(code_edit->has_string_delimiter("\""));
902
CHECK(code_edit->has_string_delimiter("^^"));
903
CHECK(code_edit->get_string_delimiters().size() == 1);
904
905
/* clear should remove all. */
906
code_edit->clear_string_delimiters();
907
CHECK_FALSE(code_edit->has_string_delimiter("^^"));
908
CHECK(code_edit->get_string_delimiters().size() == 0);
909
}
910
911
SUBCASE("[CodeEdit] add and remove comment delimiters") {
912
/* Add a delimiter.*/
913
code_edit->add_comment_delimiter("\"", "\"", false);
914
CHECK(code_edit->has_comment_delimiter("\""));
915
CHECK(code_edit->get_comment_delimiters().size() == 1);
916
917
ERR_PRINT_OFF;
918
919
/* Adding a duplicate start key is not allowed. */
920
code_edit->add_comment_delimiter("\"", "\'", false);
921
CHECK(code_edit->get_comment_delimiters().size() == 1);
922
923
/* Adding a duplicate end key is allowed. */
924
code_edit->add_comment_delimiter("'", "\"", false);
925
CHECK(code_edit->has_comment_delimiter("'"));
926
CHECK(code_edit->get_comment_delimiters().size() == 2);
927
928
/* Both start and end keys have to be symbols. */
929
code_edit->add_comment_delimiter("f", "\"", false);
930
CHECK_FALSE(code_edit->has_comment_delimiter("f"));
931
CHECK(code_edit->get_comment_delimiters().size() == 2);
932
933
code_edit->add_comment_delimiter("f", "\"", false);
934
CHECK_FALSE(code_edit->has_comment_delimiter("f"));
935
CHECK(code_edit->get_comment_delimiters().size() == 2);
936
937
code_edit->add_comment_delimiter("@", "f", false);
938
CHECK_FALSE(code_edit->has_comment_delimiter("@"));
939
CHECK(code_edit->get_comment_delimiters().size() == 2);
940
941
code_edit->add_comment_delimiter("f", "f", false);
942
CHECK_FALSE(code_edit->has_comment_delimiter("f"));
943
CHECK(code_edit->get_comment_delimiters().size() == 2);
944
945
/* Blank start keys are not allowed. */
946
code_edit->add_comment_delimiter("", "#", false);
947
CHECK_FALSE(code_edit->has_comment_delimiter("#"));
948
CHECK(code_edit->get_comment_delimiters().size() == 2);
949
950
ERR_PRINT_ON;
951
952
/* Blank end keys are allowed. */
953
code_edit->add_comment_delimiter("#", "", false);
954
CHECK(code_edit->has_comment_delimiter("#"));
955
CHECK(code_edit->get_comment_delimiters().size() == 3);
956
957
/* Remove a delimiter. */
958
code_edit->remove_comment_delimiter("#");
959
CHECK_FALSE(code_edit->has_comment_delimiter("#"));
960
CHECK(code_edit->get_comment_delimiters().size() == 2);
961
962
/* Set should override existing, and test multiline. */
963
TypedArray<String> delimiters = { "^^ ^^" };
964
965
code_edit->set_comment_delimiters(delimiters);
966
CHECK_FALSE(code_edit->has_comment_delimiter("\""));
967
CHECK(code_edit->has_comment_delimiter("^^"));
968
CHECK(code_edit->get_comment_delimiters().size() == 1);
969
970
/* clear should remove all. */
971
code_edit->clear_comment_delimiters();
972
CHECK_FALSE(code_edit->has_comment_delimiter("^^"));
973
CHECK(code_edit->get_comment_delimiters().size() == 0);
974
}
975
976
SUBCASE("[CodeEdit] add and remove mixed delimiters") {
977
code_edit->add_comment_delimiter("#", "", false);
978
CHECK(code_edit->has_comment_delimiter("#"));
979
CHECK(code_edit->get_comment_delimiters().size() == 1);
980
981
ERR_PRINT_OFF;
982
983
/* Disallow adding a string with the same start key as comment. */
984
code_edit->add_string_delimiter("#", "", false);
985
CHECK_FALSE(code_edit->has_string_delimiter("#"));
986
CHECK(code_edit->get_string_delimiters().size() == 0);
987
988
code_edit->add_string_delimiter("\"", "\"", false);
989
CHECK(code_edit->has_string_delimiter("\""));
990
CHECK(code_edit->get_comment_delimiters().size() == 1);
991
992
/* Disallow adding a comment with the same start key as string. */
993
code_edit->add_comment_delimiter("\"", "", false);
994
CHECK_FALSE(code_edit->has_comment_delimiter("\""));
995
CHECK(code_edit->get_comment_delimiters().size() == 1);
996
997
ERR_PRINT_ON;
998
999
/* Cannot remove string with remove comment. */
1000
code_edit->remove_comment_delimiter("\"");
1001
CHECK(code_edit->has_string_delimiter("\""));
1002
CHECK(code_edit->get_string_delimiters().size() == 1);
1003
1004
/* Cannot remove comment with remove string. */
1005
code_edit->remove_string_delimiter("#");
1006
CHECK(code_edit->has_comment_delimiter("#"));
1007
CHECK(code_edit->get_comment_delimiters().size() == 1);
1008
1009
/* Clear comments leave strings. */
1010
code_edit->clear_comment_delimiters();
1011
CHECK(code_edit->has_string_delimiter("\""));
1012
CHECK(code_edit->get_string_delimiters().size() == 1);
1013
1014
/* Clear string leave comments. */
1015
code_edit->add_comment_delimiter("#", "", false);
1016
CHECK(code_edit->has_comment_delimiter("#"));
1017
CHECK(code_edit->get_comment_delimiters().size() == 1);
1018
1019
code_edit->clear_string_delimiters();
1020
CHECK(code_edit->has_comment_delimiter("#"));
1021
CHECK(code_edit->get_comment_delimiters().size() == 1);
1022
}
1023
}
1024
1025
SUBCASE("[CodeEdit] single line delimiters") {
1026
SUBCASE("[CodeEdit] single line string delimiters") {
1027
/* Blank end key should set lineonly to true. */
1028
code_edit->add_string_delimiter("#", "", false);
1029
CHECK(code_edit->has_string_delimiter("#"));
1030
CHECK(code_edit->get_string_delimiters().size() == 1);
1031
1032
/* Insert line above, line with string then line below. */
1033
code_edit->insert_text_at_caret(" \n#\n ");
1034
1035
/* Check line above is not in string. */
1036
CHECK(code_edit->is_in_string(0, 1) == -1);
1037
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1038
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1039
1040
/* Check column before start key is not in string. */
1041
CHECK(code_edit->is_in_string(1, 0) == -1);
1042
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1043
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1044
1045
/* Check column after start key is in string and start / end positions are correct. */
1046
CHECK(code_edit->is_in_string(1, 1) != -1);
1047
CHECK(code_edit->get_delimiter_start_position(1, 1) == Point2(1, 1));
1048
CHECK(code_edit->get_delimiter_end_position(1, 1) == Point2(2, 1));
1049
1050
/* Check line after is not in string. */
1051
CHECK(code_edit->is_in_string(2, 1) == -1);
1052
CHECK(code_edit->get_delimiter_start_position(2, 1) == OUTSIDE_DELIMITER);
1053
CHECK(code_edit->get_delimiter_end_position(2, 1) == OUTSIDE_DELIMITER);
1054
1055
/* Check region metadata. */
1056
int idx = code_edit->is_in_string(1, 1);
1057
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1058
CHECK(code_edit->get_delimiter_end_key(idx) == "");
1059
1060
/* Check nested strings are handled correctly. */
1061
code_edit->set_text(" \n# # \n ");
1062
1063
/* Check line above is not in string. */
1064
CHECK(code_edit->is_in_string(0, 1) == -1);
1065
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1066
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1067
1068
/* Check column before first start key is not in string. */
1069
CHECK(code_edit->is_in_string(1, 0) == -1);
1070
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1071
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1072
1073
/* Check column after the first start key is in string and start / end positions are correct. */
1074
CHECK(code_edit->is_in_string(1, 1) != -1);
1075
CHECK(code_edit->get_delimiter_start_position(1, 1) == Point2(1, 1));
1076
CHECK(code_edit->get_delimiter_end_position(1, 1) == Point2(6, 1));
1077
1078
/* Check column after the second start key returns data for the first. */
1079
CHECK(code_edit->is_in_string(1, 5) != -1);
1080
CHECK(code_edit->get_delimiter_start_position(1, 5) == Point2(1, 1));
1081
CHECK(code_edit->get_delimiter_end_position(1, 5) == Point2(6, 1));
1082
1083
/* Check line after is not in string. */
1084
CHECK(code_edit->is_in_string(2, 1) == -1);
1085
CHECK(code_edit->get_delimiter_start_position(2, 1) == OUTSIDE_DELIMITER);
1086
CHECK(code_edit->get_delimiter_end_position(2, 1) == OUTSIDE_DELIMITER);
1087
1088
/* Check is in string with no column returns true if entire line is comment excluding whitespace. */
1089
code_edit->set_text(" \n # # \n ");
1090
CHECK(code_edit->is_in_string(1) != -1);
1091
1092
code_edit->set_text(" \n text # # \n ");
1093
CHECK(code_edit->is_in_string(1) == -1);
1094
1095
/* Removing delimiter should update. */
1096
code_edit->set_text(" \n # # \n ");
1097
1098
code_edit->remove_string_delimiter("#");
1099
CHECK_FALSE(code_edit->has_string_delimiter("$"));
1100
CHECK(code_edit->get_string_delimiters().size() == 0);
1101
1102
CHECK(code_edit->is_in_string(1) == -1);
1103
1104
/* Adding and clear should update. */
1105
code_edit->add_string_delimiter("#", "", false);
1106
CHECK(code_edit->has_string_delimiter("#"));
1107
CHECK(code_edit->get_string_delimiters().size() == 1);
1108
CHECK(code_edit->is_in_string(1) != -1);
1109
1110
code_edit->clear_string_delimiters();
1111
CHECK_FALSE(code_edit->has_string_delimiter("$"));
1112
CHECK(code_edit->get_string_delimiters().size() == 0);
1113
1114
CHECK(code_edit->is_in_string(1) == -1);
1115
}
1116
1117
SUBCASE("[CodeEdit] single line comment delimiters") {
1118
/* Blank end key should set lineonly to true. */
1119
code_edit->add_comment_delimiter("#", "", false);
1120
CHECK(code_edit->has_comment_delimiter("#"));
1121
CHECK(code_edit->get_comment_delimiters().size() == 1);
1122
1123
/* Insert line above, line with comment then line below. */
1124
code_edit->insert_text_at_caret(" \n#\n ");
1125
1126
/* Check line above is not in comment. */
1127
CHECK(code_edit->is_in_comment(0, 1) == -1);
1128
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1129
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1130
1131
/* Check column before start key is not in comment. */
1132
CHECK(code_edit->is_in_comment(1, 0) == -1);
1133
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1134
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1135
1136
/* Check column after start key is in comment and start / end positions are correct. */
1137
CHECK(code_edit->is_in_comment(1, 1) != -1);
1138
CHECK(code_edit->get_delimiter_start_position(1, 1) == Point2(1, 1));
1139
CHECK(code_edit->get_delimiter_end_position(1, 1) == Point2(2, 1));
1140
1141
/* Check line after is not in comment. */
1142
CHECK(code_edit->is_in_comment(2, 1) == -1);
1143
CHECK(code_edit->get_delimiter_start_position(2, 1) == OUTSIDE_DELIMITER);
1144
CHECK(code_edit->get_delimiter_end_position(2, 1) == OUTSIDE_DELIMITER);
1145
1146
/* Check region metadata. */
1147
int idx = code_edit->is_in_comment(1, 1);
1148
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1149
CHECK(code_edit->get_delimiter_end_key(idx) == "");
1150
1151
/* Check nested comments are handled correctly. */
1152
code_edit->set_text(" \n# # \n ");
1153
1154
/* Check line above is not in comment. */
1155
CHECK(code_edit->is_in_comment(0, 1) == -1);
1156
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1157
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1158
1159
/* Check column before first start key is not in comment. */
1160
CHECK(code_edit->is_in_comment(1, 0) == -1);
1161
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1162
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1163
1164
/* Check column after the first start key is in comment and start / end positions are correct. */
1165
CHECK(code_edit->is_in_comment(1, 1) != -1);
1166
CHECK(code_edit->get_delimiter_start_position(1, 1) == Point2(1, 1));
1167
CHECK(code_edit->get_delimiter_end_position(1, 1) == Point2(6, 1));
1168
1169
/* Check column after the second start key returns data for the first. */
1170
CHECK(code_edit->is_in_comment(1, 5) != -1);
1171
CHECK(code_edit->get_delimiter_start_position(1, 5) == Point2(1, 1));
1172
CHECK(code_edit->get_delimiter_end_position(1, 5) == Point2(6, 1));
1173
1174
/* Check line after is not in comment. */
1175
CHECK(code_edit->is_in_comment(2, 1) == -1);
1176
CHECK(code_edit->get_delimiter_start_position(2, 1) == OUTSIDE_DELIMITER);
1177
CHECK(code_edit->get_delimiter_end_position(2, 1) == OUTSIDE_DELIMITER);
1178
1179
/* Check is in comment with no column returns true if entire line is comment excluding whitespace. */
1180
code_edit->set_text(" \n # # \n ");
1181
CHECK(code_edit->is_in_comment(1) != -1);
1182
1183
code_edit->set_text(" \n text # # \n ");
1184
CHECK(code_edit->is_in_comment(1) == -1);
1185
1186
/* Removing delimiter should update. */
1187
code_edit->set_text(" \n # # \n ");
1188
1189
code_edit->remove_comment_delimiter("#");
1190
CHECK_FALSE(code_edit->has_comment_delimiter("$"));
1191
CHECK(code_edit->get_comment_delimiters().size() == 0);
1192
1193
CHECK(code_edit->is_in_comment(1) == -1);
1194
1195
/* Adding and clear should update. */
1196
code_edit->add_comment_delimiter("#", "", false);
1197
CHECK(code_edit->has_comment_delimiter("#"));
1198
CHECK(code_edit->get_comment_delimiters().size() == 1);
1199
CHECK(code_edit->is_in_comment(1) != -1);
1200
1201
code_edit->clear_comment_delimiters();
1202
CHECK_FALSE(code_edit->has_comment_delimiter("$"));
1203
CHECK(code_edit->get_comment_delimiters().size() == 0);
1204
1205
CHECK(code_edit->is_in_comment(1) == -1);
1206
}
1207
1208
SUBCASE("[CodeEdit] single line mixed delimiters") {
1209
/* Blank end key should set lineonly to true. */
1210
/* Add string delimiter. */
1211
code_edit->add_string_delimiter("&", "", false);
1212
CHECK(code_edit->has_string_delimiter("&"));
1213
CHECK(code_edit->get_string_delimiters().size() == 1);
1214
1215
/* Add comment delimiter. */
1216
code_edit->add_comment_delimiter("#", "", false);
1217
CHECK(code_edit->has_comment_delimiter("#"));
1218
CHECK(code_edit->get_comment_delimiters().size() == 1);
1219
1220
/* Nest a string delimiter inside a comment. */
1221
code_edit->set_text(" \n# & \n ");
1222
1223
/* Check line above is not in comment. */
1224
CHECK(code_edit->is_in_comment(0, 1) == -1);
1225
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1226
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1227
1228
/* Check column before first start key is not in comment. */
1229
CHECK(code_edit->is_in_comment(1, 0) == -1);
1230
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1231
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1232
1233
/* Check column after the first start key is in comment and start / end positions are correct. */
1234
CHECK(code_edit->is_in_comment(1, 1) != -1);
1235
CHECK(code_edit->get_delimiter_start_position(1, 1) == Point2(1, 1));
1236
CHECK(code_edit->get_delimiter_end_position(1, 1) == Point2(6, 1));
1237
1238
/* Check column after the second start key returns data for the first, and does not state string. */
1239
CHECK(code_edit->is_in_comment(1, 5) != -1);
1240
CHECK(code_edit->get_delimiter_start_position(1, 5) == Point2(1, 1));
1241
CHECK(code_edit->get_delimiter_end_position(1, 5) == Point2(6, 1));
1242
CHECK(code_edit->is_in_string(1, 5) == -1);
1243
1244
/* Check line after is not in comment. */
1245
CHECK(code_edit->is_in_comment(2, 1) == -1);
1246
CHECK(code_edit->get_delimiter_start_position(2, 1) == OUTSIDE_DELIMITER);
1247
CHECK(code_edit->get_delimiter_end_position(2, 1) == OUTSIDE_DELIMITER);
1248
1249
/* Remove the comment delimiter. */
1250
code_edit->remove_comment_delimiter("#");
1251
CHECK_FALSE(code_edit->has_comment_delimiter("$"));
1252
CHECK(code_edit->get_comment_delimiters().size() == 0);
1253
1254
/* The "first" comment region is no longer valid. */
1255
CHECK(code_edit->is_in_comment(1, 1) == -1);
1256
CHECK(code_edit->get_delimiter_start_position(1, 1) == OUTSIDE_DELIMITER);
1257
CHECK(code_edit->get_delimiter_end_position(1, 1) == OUTSIDE_DELIMITER);
1258
1259
/* The "second" region as string is now valid. */
1260
CHECK(code_edit->is_in_string(1, 5) != -1);
1261
CHECK(code_edit->get_delimiter_start_position(1, 5) == Point2(4, 1));
1262
CHECK(code_edit->get_delimiter_end_position(1, 5) == Point2(6, 1));
1263
}
1264
}
1265
1266
SUBCASE("[CodeEdit] multiline delimiters") {
1267
SUBCASE("[CodeEdit] multiline string delimiters") {
1268
code_edit->clear_string_delimiters();
1269
code_edit->clear_comment_delimiters();
1270
1271
/* Add string delimiter. */
1272
code_edit->add_string_delimiter("#", "#", false);
1273
CHECK(code_edit->has_string_delimiter("#"));
1274
CHECK(code_edit->get_string_delimiters().size() == 1);
1275
1276
/* First test over a single line. */
1277
code_edit->set_text(" \n # # \n ");
1278
1279
/* Check line above is not in string. */
1280
CHECK(code_edit->is_in_string(0, 1) == -1);
1281
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1282
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1283
1284
/* Check column before start key is not in string. */
1285
CHECK(code_edit->is_in_string(1, 0) == -1);
1286
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1287
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1288
1289
/* Check column before closing delimiter is in string. */
1290
CHECK(code_edit->is_in_string(1, 2) != -1);
1291
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1292
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(5, 1));
1293
1294
/* Check column after end key is not in string. */
1295
CHECK(code_edit->is_in_string(1, 6) == -1);
1296
CHECK(code_edit->get_delimiter_start_position(1, 6) == OUTSIDE_DELIMITER);
1297
CHECK(code_edit->get_delimiter_end_position(1, 6) == OUTSIDE_DELIMITER);
1298
1299
/* Check line after is not in string. */
1300
CHECK(code_edit->is_in_string(2, 1) == -1);
1301
CHECK(code_edit->get_delimiter_start_position(2, 1) == OUTSIDE_DELIMITER);
1302
CHECK(code_edit->get_delimiter_end_position(2, 1) == OUTSIDE_DELIMITER);
1303
1304
/* Check the region metadata. */
1305
int idx = code_edit->is_in_string(1, 2);
1306
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1307
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1308
1309
/* Next test over a multiple blank lines. */
1310
code_edit->set_text(" \n # \n\n # \n ");
1311
1312
/* Check line above is not in string. */
1313
CHECK(code_edit->is_in_string(0, 1) == -1);
1314
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1315
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1316
1317
/* Check column before start key is not in string. */
1318
CHECK(code_edit->is_in_string(1, 0) == -1);
1319
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1320
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1321
1322
/* Check column just after start key is in string. */
1323
CHECK(code_edit->is_in_string(1, 2) != -1);
1324
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1325
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(2, 3));
1326
1327
/* Check blank middle line. */
1328
CHECK(code_edit->is_in_string(2, 0) != -1);
1329
CHECK(code_edit->get_delimiter_start_position(2, 0) == Point2(2, 1));
1330
CHECK(code_edit->get_delimiter_end_position(2, 0) == Point2(2, 3));
1331
1332
/* Check column just before end key is in string. */
1333
CHECK(code_edit->is_in_string(3, 0) != -1);
1334
CHECK(code_edit->get_delimiter_start_position(3, 0) == Point2(2, 1));
1335
CHECK(code_edit->get_delimiter_end_position(3, 0) == Point2(2, 3));
1336
1337
/* Check column after end key is not in string. */
1338
CHECK(code_edit->is_in_string(3, 3) == -1);
1339
CHECK(code_edit->get_delimiter_start_position(3, 3) == OUTSIDE_DELIMITER);
1340
CHECK(code_edit->get_delimiter_end_position(3, 3) == OUTSIDE_DELIMITER);
1341
1342
/* Check line after is not in string. */
1343
CHECK(code_edit->is_in_string(4, 1) == -1);
1344
CHECK(code_edit->get_delimiter_start_position(4, 1) == OUTSIDE_DELIMITER);
1345
CHECK(code_edit->get_delimiter_end_position(4, 1) == OUTSIDE_DELIMITER);
1346
1347
/* Next test over a multiple non-blank lines. */
1348
code_edit->set_text(" \n # \n \n # \n ");
1349
1350
/* Check line above is not in string. */
1351
CHECK(code_edit->is_in_string(0, 1) == -1);
1352
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1353
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1354
1355
/* Check column before start key is not in string. */
1356
CHECK(code_edit->is_in_string(1, 0) == -1);
1357
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1358
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1359
1360
/* Check column just after start key is in string. */
1361
CHECK(code_edit->is_in_string(1, 2) != -1);
1362
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1363
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(2, 3));
1364
1365
/* Check middle line. */
1366
CHECK(code_edit->is_in_string(2, 0) != -1);
1367
CHECK(code_edit->get_delimiter_start_position(2, 0) == Point2(2, 1));
1368
CHECK(code_edit->get_delimiter_end_position(2, 0) == Point2(2, 3));
1369
1370
/* Check column just before end key is in string. */
1371
CHECK(code_edit->is_in_string(3, 0) != -1);
1372
CHECK(code_edit->get_delimiter_start_position(3, 0) == Point2(2, 1));
1373
CHECK(code_edit->get_delimiter_end_position(3, 0) == Point2(2, 3));
1374
1375
/* Check column after end key is not in string. */
1376
CHECK(code_edit->is_in_string(3, 3) == -1);
1377
CHECK(code_edit->get_delimiter_start_position(3, 3) == OUTSIDE_DELIMITER);
1378
CHECK(code_edit->get_delimiter_end_position(3, 3) == OUTSIDE_DELIMITER);
1379
1380
/* Check line after is not in string. */
1381
CHECK(code_edit->is_in_string(4, 1) == -1);
1382
CHECK(code_edit->get_delimiter_start_position(4, 1) == OUTSIDE_DELIMITER);
1383
CHECK(code_edit->get_delimiter_end_position(4, 1) == OUTSIDE_DELIMITER);
1384
1385
/* check the region metadata. */
1386
idx = code_edit->is_in_string(1, 2);
1387
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1388
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1389
1390
/* Next test nested strings. */
1391
code_edit->add_string_delimiter("^", "^", false);
1392
CHECK(code_edit->has_string_delimiter("^"));
1393
CHECK(code_edit->get_string_delimiters().size() == 2);
1394
1395
code_edit->set_text(" \n # ^\n \n^ # \n ");
1396
1397
/* Check line above is not in string. */
1398
CHECK(code_edit->is_in_string(0, 1) == -1);
1399
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1400
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1401
1402
/* Check column before start key is not in string. */
1403
CHECK(code_edit->is_in_string(1, 0) == -1);
1404
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1405
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1406
1407
/* Check column just after start key is in string. */
1408
CHECK(code_edit->is_in_string(1, 2) != -1);
1409
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1410
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(3, 3));
1411
1412
/* Check middle line. */
1413
CHECK(code_edit->is_in_string(2, 0) != -1);
1414
CHECK(code_edit->get_delimiter_start_position(2, 0) == Point2(2, 1));
1415
CHECK(code_edit->get_delimiter_end_position(2, 0) == Point2(3, 3));
1416
1417
/* Check column just before end key is in string. */
1418
CHECK(code_edit->is_in_string(3, 0) != -1);
1419
CHECK(code_edit->get_delimiter_start_position(3, 0) == Point2(2, 1));
1420
CHECK(code_edit->get_delimiter_end_position(3, 0) == Point2(3, 3));
1421
1422
/* Check column after end key is not in string. */
1423
CHECK(code_edit->is_in_string(3, 3) == -1);
1424
CHECK(code_edit->get_delimiter_start_position(3, 3) == OUTSIDE_DELIMITER);
1425
CHECK(code_edit->get_delimiter_end_position(3, 3) == OUTSIDE_DELIMITER);
1426
1427
/* Check line after is not in string. */
1428
CHECK(code_edit->is_in_string(4, 1) == -1);
1429
CHECK(code_edit->get_delimiter_start_position(4, 1) == OUTSIDE_DELIMITER);
1430
CHECK(code_edit->get_delimiter_end_position(4, 1) == OUTSIDE_DELIMITER);
1431
1432
/* check the region metadata. */
1433
idx = code_edit->is_in_string(1, 2);
1434
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1435
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1436
1437
/* Next test no end key. */
1438
code_edit->set_text(" \n # \n ");
1439
1440
/* check the region metadata. */
1441
idx = code_edit->is_in_string(1, 2);
1442
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1443
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(-1, -1));
1444
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1445
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1446
1447
/* Check is in string with no column returns true if entire line is string excluding whitespace. */
1448
code_edit->set_text(" \n # \n\n #\n ");
1449
CHECK(code_edit->is_in_string(1) != -1);
1450
CHECK(code_edit->is_in_string(2) != -1);
1451
CHECK(code_edit->is_in_string(3) != -1);
1452
1453
code_edit->set_text(" \n test # \n\n # test \n ");
1454
CHECK(code_edit->is_in_string(1) == -1);
1455
CHECK(code_edit->is_in_string(2) != -1);
1456
CHECK(code_edit->is_in_string(3) == -1);
1457
1458
/* Next check updating the delimiter cache while typing. */
1459
code_edit->set_text("\n\n");
1460
code_edit->set_caret_line(0);
1461
code_edit->set_caret_column(0);
1462
CHECK(code_edit->is_in_string(0) == -1);
1463
CHECK(code_edit->is_in_string(1) == -1);
1464
code_edit->insert_text_at_caret("#");
1465
CHECK(code_edit->is_in_string(0) != -1);
1466
CHECK(code_edit->is_in_string(1) != -1);
1467
code_edit->insert_text_at_caret("#");
1468
CHECK(code_edit->is_in_string(0) != -1);
1469
CHECK(code_edit->is_in_string(1) == -1);
1470
}
1471
1472
SUBCASE("[CodeEdit] multiline comment delimiters") {
1473
/* Add comment delimiter. */
1474
code_edit->add_comment_delimiter("#", "#", false);
1475
CHECK(code_edit->has_comment_delimiter("#"));
1476
CHECK(code_edit->get_comment_delimiters().size() == 1);
1477
1478
/* First test over a single line. */
1479
code_edit->set_text(" \n # # \n ");
1480
1481
/* Check line above is not in comment. */
1482
CHECK(code_edit->is_in_comment(0, 1) == -1);
1483
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1484
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1485
1486
/* Check column before start key is not in comment. */
1487
CHECK(code_edit->is_in_comment(1, 0) == -1);
1488
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1489
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1490
1491
/* Check column before closing delimiter is in comment. */
1492
CHECK(code_edit->is_in_comment(1, 2) != -1);
1493
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1494
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(5, 1));
1495
1496
/* Check column after end key is not in comment. */
1497
CHECK(code_edit->is_in_comment(1, 6) == -1);
1498
CHECK(code_edit->get_delimiter_start_position(1, 6) == OUTSIDE_DELIMITER);
1499
CHECK(code_edit->get_delimiter_end_position(1, 6) == OUTSIDE_DELIMITER);
1500
1501
/* Check line after is not in comment. */
1502
CHECK(code_edit->is_in_comment(2, 1) == -1);
1503
CHECK(code_edit->get_delimiter_start_position(2, 1) == OUTSIDE_DELIMITER);
1504
CHECK(code_edit->get_delimiter_end_position(2, 1) == OUTSIDE_DELIMITER);
1505
1506
/* Check the region metadata. */
1507
int idx = code_edit->is_in_comment(1, 2);
1508
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1509
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1510
1511
/* Next test over a multiple blank lines. */
1512
code_edit->set_text(" \n # \n\n # \n ");
1513
1514
/* Check line above is not in comment. */
1515
CHECK(code_edit->is_in_comment(0, 1) == -1);
1516
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1517
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1518
1519
/* Check column before start key is not in comment. */
1520
CHECK(code_edit->is_in_comment(1, 0) == -1);
1521
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1522
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1523
1524
/* Check column just after start key is in comment. */
1525
CHECK(code_edit->is_in_comment(1, 2) != -1);
1526
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1527
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(2, 3));
1528
1529
/* Check blank middle line. */
1530
CHECK(code_edit->is_in_comment(2, 0) != -1);
1531
CHECK(code_edit->get_delimiter_start_position(2, 0) == Point2(2, 1));
1532
CHECK(code_edit->get_delimiter_end_position(2, 0) == Point2(2, 3));
1533
1534
/* Check column just before end key is in comment. */
1535
CHECK(code_edit->is_in_comment(3, 0) != -1);
1536
CHECK(code_edit->get_delimiter_start_position(3, 0) == Point2(2, 1));
1537
CHECK(code_edit->get_delimiter_end_position(3, 0) == Point2(2, 3));
1538
1539
/* Check column after end key is not in comment. */
1540
CHECK(code_edit->is_in_comment(3, 3) == -1);
1541
CHECK(code_edit->get_delimiter_start_position(3, 3) == OUTSIDE_DELIMITER);
1542
CHECK(code_edit->get_delimiter_end_position(3, 3) == OUTSIDE_DELIMITER);
1543
1544
/* Check line after is not in comment. */
1545
CHECK(code_edit->is_in_comment(4, 1) == -1);
1546
CHECK(code_edit->get_delimiter_start_position(4, 1) == OUTSIDE_DELIMITER);
1547
CHECK(code_edit->get_delimiter_end_position(4, 1) == OUTSIDE_DELIMITER);
1548
1549
/* Next test over a multiple non-blank lines. */
1550
code_edit->set_text(" \n # \n \n # \n ");
1551
1552
/* Check line above is not in comment. */
1553
CHECK(code_edit->is_in_comment(0, 1) == -1);
1554
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1555
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1556
1557
/* Check column before start key is not in comment. */
1558
CHECK(code_edit->is_in_comment(1, 0) == -1);
1559
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1560
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1561
1562
/* Check column just after start key is in comment. */
1563
CHECK(code_edit->is_in_comment(1, 2) != -1);
1564
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1565
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(2, 3));
1566
1567
/* Check middle line. */
1568
CHECK(code_edit->is_in_comment(2, 0) != -1);
1569
CHECK(code_edit->get_delimiter_start_position(2, 0) == Point2(2, 1));
1570
CHECK(code_edit->get_delimiter_end_position(2, 0) == Point2(2, 3));
1571
1572
/* Check column just before end key is in comment. */
1573
CHECK(code_edit->is_in_comment(3, 0) != -1);
1574
CHECK(code_edit->get_delimiter_start_position(3, 0) == Point2(2, 1));
1575
CHECK(code_edit->get_delimiter_end_position(3, 0) == Point2(2, 3));
1576
1577
/* Check column after end key is not in comment. */
1578
CHECK(code_edit->is_in_comment(3, 3) == -1);
1579
CHECK(code_edit->get_delimiter_start_position(3, 3) == OUTSIDE_DELIMITER);
1580
CHECK(code_edit->get_delimiter_end_position(3, 3) == OUTSIDE_DELIMITER);
1581
1582
/* Check line after is not in comment. */
1583
CHECK(code_edit->is_in_comment(4, 1) == -1);
1584
CHECK(code_edit->get_delimiter_start_position(4, 1) == OUTSIDE_DELIMITER);
1585
CHECK(code_edit->get_delimiter_end_position(4, 1) == OUTSIDE_DELIMITER);
1586
1587
/* check the region metadata. */
1588
idx = code_edit->is_in_comment(1, 2);
1589
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1590
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1591
1592
/* Next test nested comments. */
1593
code_edit->add_comment_delimiter("^", "^", false);
1594
CHECK(code_edit->has_comment_delimiter("^"));
1595
CHECK(code_edit->get_comment_delimiters().size() == 2);
1596
1597
code_edit->set_text(" \n # ^\n \n^ # \n ");
1598
1599
/* Check line above is not in comment. */
1600
CHECK(code_edit->is_in_comment(0, 1) == -1);
1601
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1602
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1603
1604
/* Check column before start key is not in comment. */
1605
CHECK(code_edit->is_in_comment(1, 0) == -1);
1606
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1607
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1608
1609
/* Check column just after start key is in comment. */
1610
CHECK(code_edit->is_in_comment(1, 2) != -1);
1611
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1612
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(3, 3));
1613
1614
/* Check middle line. */
1615
CHECK(code_edit->is_in_comment(2, 0) != -1);
1616
CHECK(code_edit->get_delimiter_start_position(2, 0) == Point2(2, 1));
1617
CHECK(code_edit->get_delimiter_end_position(2, 0) == Point2(3, 3));
1618
1619
/* Check column just before end key is in comment. */
1620
CHECK(code_edit->is_in_comment(3, 0) != -1);
1621
CHECK(code_edit->get_delimiter_start_position(3, 0) == Point2(2, 1));
1622
CHECK(code_edit->get_delimiter_end_position(3, 0) == Point2(3, 3));
1623
1624
/* Check column after end key is not in comment. */
1625
CHECK(code_edit->is_in_comment(3, 3) == -1);
1626
CHECK(code_edit->get_delimiter_start_position(3, 3) == OUTSIDE_DELIMITER);
1627
CHECK(code_edit->get_delimiter_end_position(3, 3) == OUTSIDE_DELIMITER);
1628
1629
/* Check line after is not in comment. */
1630
CHECK(code_edit->is_in_comment(4, 1) == -1);
1631
CHECK(code_edit->get_delimiter_start_position(4, 1) == OUTSIDE_DELIMITER);
1632
CHECK(code_edit->get_delimiter_end_position(4, 1) == OUTSIDE_DELIMITER);
1633
1634
/* check the region metadata. */
1635
idx = code_edit->is_in_comment(1, 2);
1636
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1637
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1638
1639
/* Next test no end key. */
1640
code_edit->set_text(" \n # \n ");
1641
1642
/* check the region metadata. */
1643
idx = code_edit->is_in_comment(1, 2);
1644
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1645
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(-1, -1));
1646
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1647
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1648
1649
/* Check is in comment with no column returns true if entire line is comment excluding whitespace. */
1650
code_edit->set_text(" \n # \n\n #\n ");
1651
CHECK(code_edit->is_in_comment(1) != -1);
1652
CHECK(code_edit->is_in_comment(2) != -1);
1653
CHECK(code_edit->is_in_comment(3) != -1);
1654
1655
code_edit->set_text(" \n test # \n\n # test \n ");
1656
CHECK(code_edit->is_in_comment(1) == -1);
1657
CHECK(code_edit->is_in_comment(2) != -1);
1658
CHECK(code_edit->is_in_comment(3) == -1);
1659
1660
/* Next check updating the delimiter cache while typing. */
1661
code_edit->set_text("\n\n");
1662
code_edit->set_caret_line(0);
1663
code_edit->set_caret_column(0);
1664
CHECK(code_edit->is_in_comment(0) == -1);
1665
CHECK(code_edit->is_in_comment(1) == -1);
1666
code_edit->insert_text_at_caret("#");
1667
CHECK(code_edit->is_in_comment(0) != -1);
1668
CHECK(code_edit->is_in_comment(1) != -1);
1669
code_edit->insert_text_at_caret("#");
1670
CHECK(code_edit->is_in_comment(0) != -1);
1671
CHECK(code_edit->is_in_comment(1) == -1);
1672
}
1673
1674
SUBCASE("[CodeEdit] multiline mixed delimiters") {
1675
/* Add comment delimiter. */
1676
code_edit->add_comment_delimiter("#", "#", false);
1677
CHECK(code_edit->has_comment_delimiter("#"));
1678
CHECK(code_edit->get_comment_delimiters().size() == 1);
1679
1680
/* Add string delimiter. */
1681
code_edit->add_string_delimiter("^", "^", false);
1682
CHECK(code_edit->has_string_delimiter("^"));
1683
CHECK(code_edit->get_string_delimiters().size() == 1);
1684
1685
/* Nest a string inside a comment. */
1686
code_edit->set_text(" \n # ^\n \n^ # \n ");
1687
1688
/* Check line above is not in comment. */
1689
CHECK(code_edit->is_in_comment(0, 1) == -1);
1690
CHECK(code_edit->get_delimiter_start_position(0, 1) == OUTSIDE_DELIMITER);
1691
CHECK(code_edit->get_delimiter_end_position(0, 1) == OUTSIDE_DELIMITER);
1692
1693
/* Check column before start key is not in comment. */
1694
CHECK(code_edit->is_in_comment(1, 0) == -1);
1695
CHECK(code_edit->get_delimiter_start_position(1, 0) == OUTSIDE_DELIMITER);
1696
CHECK(code_edit->get_delimiter_end_position(1, 0) == OUTSIDE_DELIMITER);
1697
1698
/* Check column just after start key is in comment. */
1699
CHECK(code_edit->is_in_comment(1, 2) != -1);
1700
CHECK(code_edit->get_delimiter_start_position(1, 2) == Point2(2, 1));
1701
CHECK(code_edit->get_delimiter_end_position(1, 2) == Point2(3, 3));
1702
1703
/* Check middle line. */
1704
CHECK(code_edit->is_in_comment(2, 0) != -1);
1705
CHECK(code_edit->get_delimiter_start_position(2, 0) == Point2(2, 1));
1706
CHECK(code_edit->get_delimiter_end_position(2, 0) == Point2(3, 3));
1707
1708
/* Check column just before end key is in comment. */
1709
CHECK(code_edit->is_in_comment(3, 0) != -1);
1710
CHECK(code_edit->get_delimiter_start_position(3, 0) == Point2(2, 1));
1711
CHECK(code_edit->get_delimiter_end_position(3, 0) == Point2(3, 3));
1712
1713
/* Check column after end key is not in comment. */
1714
CHECK(code_edit->is_in_comment(3, 3) == -1);
1715
CHECK(code_edit->get_delimiter_start_position(3, 3) == OUTSIDE_DELIMITER);
1716
CHECK(code_edit->get_delimiter_end_position(3, 3) == OUTSIDE_DELIMITER);
1717
1718
/* Check line after is not in comment. */
1719
CHECK(code_edit->is_in_comment(4, 1) == -1);
1720
CHECK(code_edit->get_delimiter_start_position(4, 1) == OUTSIDE_DELIMITER);
1721
CHECK(code_edit->get_delimiter_end_position(4, 1) == OUTSIDE_DELIMITER);
1722
1723
/* check the region metadata. */
1724
int idx = code_edit->is_in_comment(1, 2);
1725
CHECK(code_edit->get_delimiter_start_key(idx) == "#");
1726
CHECK(code_edit->get_delimiter_end_key(idx) == "#");
1727
1728
/* Check is in comment with no column returns true as inner delimiter should not be counted. */
1729
CHECK(code_edit->is_in_comment(1) != -1);
1730
CHECK(code_edit->is_in_comment(2) != -1);
1731
CHECK(code_edit->is_in_comment(3) != -1);
1732
}
1733
}
1734
1735
memdelete(code_edit);
1736
}
1737
1738
TEST_CASE("[SceneTree][CodeEdit] indent") {
1739
CodeEdit *code_edit = memnew(CodeEdit);
1740
SceneTree::get_singleton()->get_root()->add_child(code_edit);
1741
code_edit->grab_focus();
1742
1743
SUBCASE("[CodeEdit] indent settings") {
1744
code_edit->set_indent_size(10);
1745
CHECK(code_edit->get_indent_size() == 10);
1746
CHECK(code_edit->get_tab_size() == 10);
1747
1748
code_edit->set_auto_indent_enabled(false);
1749
CHECK_FALSE(code_edit->is_auto_indent_enabled());
1750
1751
code_edit->set_auto_indent_enabled(true);
1752
CHECK(code_edit->is_auto_indent_enabled());
1753
1754
code_edit->set_indent_using_spaces(false);
1755
CHECK_FALSE(code_edit->is_indent_using_spaces());
1756
1757
code_edit->set_indent_using_spaces(true);
1758
CHECK(code_edit->is_indent_using_spaces());
1759
1760
/* Only the first char is registered. */
1761
TypedArray<String> auto_indent_prefixes = { "::", "s", "1" };
1762
code_edit->set_auto_indent_prefixes(auto_indent_prefixes);
1763
1764
auto_indent_prefixes = code_edit->get_auto_indent_prefixes();
1765
CHECK(auto_indent_prefixes.has(":"));
1766
CHECK(auto_indent_prefixes.has("s"));
1767
CHECK(auto_indent_prefixes.has("1"));
1768
}
1769
1770
SUBCASE("[CodeEdit] indent tabs") {
1771
code_edit->set_indent_size(4);
1772
code_edit->set_auto_indent_enabled(true);
1773
code_edit->set_indent_using_spaces(false);
1774
1775
/* Do nothing if not editable. */
1776
code_edit->set_editable(false);
1777
1778
code_edit->do_indent();
1779
CHECK(code_edit->get_line(0).is_empty());
1780
1781
code_edit->indent_lines();
1782
CHECK(code_edit->get_line(0).is_empty());
1783
1784
code_edit->set_editable(true);
1785
1786
/* Simple indent. */
1787
code_edit->do_indent();
1788
CHECK(code_edit->get_line(0) == "\t");
1789
1790
/* Check input action. */
1791
SEND_GUI_ACTION("ui_text_indent");
1792
CHECK(code_edit->get_line(0) == "\t\t");
1793
1794
/* Insert in place. */
1795
code_edit->set_text("");
1796
code_edit->insert_text_at_caret("test");
1797
code_edit->do_indent();
1798
CHECK(code_edit->get_line(0) == "test\t");
1799
1800
// Insert in place with multiple carets.
1801
code_edit->set_text("test text");
1802
code_edit->set_caret_column(5);
1803
code_edit->add_caret(0, 7);
1804
code_edit->add_caret(0, 2);
1805
code_edit->do_indent();
1806
CHECK(code_edit->get_line(0) == "te\tst \tte\txt");
1807
CHECK(code_edit->get_caret_count() == 3);
1808
CHECK(code_edit->get_caret_column(0) == 7);
1809
CHECK(code_edit->get_caret_column(1) == 10);
1810
CHECK(code_edit->get_caret_column(2) == 3);
1811
code_edit->remove_secondary_carets();
1812
1813
// Indent lines does entire line and works without selection.
1814
code_edit->set_text("");
1815
code_edit->insert_text_at_caret("test");
1816
code_edit->indent_lines();
1817
CHECK(code_edit->get_line(0) == "\ttest");
1818
CHECK(code_edit->get_caret_column() == 5);
1819
1820
/* Selection does entire line. */
1821
code_edit->set_text("test");
1822
code_edit->select_all();
1823
code_edit->do_indent();
1824
CHECK(code_edit->get_line(0) == "\ttest");
1825
CHECK(code_edit->has_selection());
1826
CHECK(code_edit->get_selection_origin_line() == 0);
1827
CHECK(code_edit->get_selection_origin_column() == 0);
1828
CHECK(code_edit->get_caret_line() == 0);
1829
CHECK(code_edit->get_caret_column() == 5);
1830
1831
// Selection does entire line, right to left selection.
1832
code_edit->set_text("test");
1833
code_edit->select(0, 4, 0, 0);
1834
code_edit->do_indent();
1835
CHECK(code_edit->get_line(0) == "\ttest");
1836
CHECK(code_edit->has_selection());
1837
CHECK(code_edit->get_selection_origin_line() == 0);
1838
CHECK(code_edit->get_selection_origin_column() == 5);
1839
CHECK(code_edit->get_caret_line() == 0);
1840
CHECK(code_edit->get_caret_column() == 0);
1841
1842
/* Handles multiple lines. */
1843
code_edit->set_text("test\ntext");
1844
code_edit->select_all();
1845
code_edit->do_indent();
1846
CHECK(code_edit->get_line(0) == "\ttest");
1847
CHECK(code_edit->get_line(1) == "\ttext");
1848
CHECK(code_edit->has_selection());
1849
CHECK(code_edit->get_selection_origin_line() == 0);
1850
CHECK(code_edit->get_selection_origin_column() == 0);
1851
CHECK(code_edit->get_caret_line() == 1);
1852
CHECK(code_edit->get_caret_column() == 5);
1853
1854
/* Do not indent line if last col is zero. */
1855
code_edit->set_text("test\ntext");
1856
code_edit->select(0, 0, 1, 0);
1857
code_edit->do_indent();
1858
CHECK(code_edit->get_line(0) == "\ttest");
1859
CHECK(code_edit->get_line(1) == "text");
1860
CHECK(code_edit->has_selection());
1861
CHECK(code_edit->get_selection_origin_line() == 0);
1862
CHECK(code_edit->get_selection_origin_column() == 0);
1863
CHECK(code_edit->get_caret_line() == 1);
1864
CHECK(code_edit->get_caret_column() == 0);
1865
1866
/* Indent even if last column of first line. */
1867
code_edit->set_text("test\ntext");
1868
code_edit->select(0, 4, 1, 0);
1869
code_edit->do_indent();
1870
CHECK(code_edit->get_line(0) == "\ttest");
1871
CHECK(code_edit->get_line(1) == "text");
1872
CHECK(code_edit->has_selection());
1873
CHECK(code_edit->get_selection_origin_line() == 0);
1874
CHECK(code_edit->get_selection_origin_column() == 5);
1875
CHECK(code_edit->get_caret_line() == 1);
1876
CHECK(code_edit->get_caret_column() == 0);
1877
1878
// Indent even if last column of first line, reversed.
1879
code_edit->set_text("test\ntext");
1880
code_edit->select(1, 0, 0, 4);
1881
code_edit->do_indent();
1882
CHECK(code_edit->get_line(0) == "\ttest");
1883
CHECK(code_edit->get_line(1) == "text");
1884
CHECK(code_edit->has_selection());
1885
CHECK(code_edit->get_selection_origin_line() == 1);
1886
CHECK(code_edit->get_selection_origin_column() == 0);
1887
CHECK(code_edit->get_caret_line() == 0);
1888
CHECK(code_edit->get_caret_column() == 5);
1889
1890
/* Check selection is adjusted. */
1891
code_edit->set_text("test");
1892
code_edit->select(0, 1, 0, 2);
1893
code_edit->do_indent();
1894
CHECK(code_edit->get_line(0) == "\ttest");
1895
CHECK(code_edit->has_selection());
1896
CHECK(code_edit->get_selection_origin_line() == 0);
1897
CHECK(code_edit->get_selection_origin_column() == 2);
1898
CHECK(code_edit->get_caret_line() == 0);
1899
CHECK(code_edit->get_caret_column() == 3);
1900
1901
// Indent once with multiple selections.
1902
code_edit->set_text("test");
1903
code_edit->select(0, 1, 0, 2);
1904
code_edit->add_caret(0, 4);
1905
code_edit->select(0, 4, 0, 3, 1);
1906
code_edit->do_indent();
1907
CHECK(code_edit->get_line(0) == "\ttest");
1908
CHECK(code_edit->get_caret_count() == 2);
1909
CHECK(code_edit->has_selection(0));
1910
CHECK(code_edit->get_selection_origin_line(0) == 0);
1911
CHECK(code_edit->get_selection_origin_column(0) == 2);
1912
CHECK(code_edit->get_caret_line(0) == 0);
1913
CHECK(code_edit->get_caret_column(0) == 3);
1914
CHECK(code_edit->has_selection(1));
1915
CHECK(code_edit->get_selection_origin_line(1) == 0);
1916
CHECK(code_edit->get_selection_origin_column(1) == 5);
1917
CHECK(code_edit->get_caret_line(1) == 0);
1918
CHECK(code_edit->get_caret_column(1) == 4);
1919
}
1920
1921
SUBCASE("[CodeEdit] indent spaces") {
1922
code_edit->set_indent_size(4);
1923
code_edit->set_auto_indent_enabled(true);
1924
code_edit->set_indent_using_spaces(true);
1925
1926
/* Do nothing if not editable. */
1927
code_edit->set_editable(false);
1928
1929
code_edit->do_indent();
1930
CHECK(code_edit->get_line(0).is_empty());
1931
1932
code_edit->indent_lines();
1933
CHECK(code_edit->get_line(0).is_empty());
1934
1935
code_edit->set_editable(true);
1936
1937
/* Simple indent. */
1938
code_edit->do_indent();
1939
CHECK(code_edit->get_line(0) == " ");
1940
1941
/* Check input action. */
1942
SEND_GUI_ACTION("ui_text_indent");
1943
CHECK(code_edit->get_line(0) == " ");
1944
1945
/* Insert in place. */
1946
code_edit->set_text("");
1947
code_edit->insert_text_at_caret("test");
1948
code_edit->do_indent();
1949
CHECK(code_edit->get_line(0) == "test ");
1950
1951
// Insert in place with multiple carets.
1952
code_edit->set_text("test text");
1953
code_edit->set_caret_column(5);
1954
code_edit->add_caret(0, 7);
1955
code_edit->add_caret(0, 2);
1956
code_edit->do_indent();
1957
CHECK(code_edit->get_line(0) == "te st te xt");
1958
CHECK(code_edit->get_caret_count() == 3);
1959
CHECK(code_edit->get_caret_column(0) == 10);
1960
CHECK(code_edit->get_caret_column(1) == 14);
1961
CHECK(code_edit->get_caret_column(2) == 4);
1962
code_edit->remove_secondary_carets();
1963
1964
// Indent lines does entire line and works without selection.
1965
code_edit->set_text("");
1966
code_edit->insert_text_at_caret("test");
1967
code_edit->indent_lines();
1968
CHECK(code_edit->get_line(0) == " test");
1969
CHECK(code_edit->get_caret_column() == 8);
1970
1971
/* Selection does entire line. */
1972
code_edit->set_text("test");
1973
code_edit->select_all();
1974
code_edit->do_indent();
1975
CHECK(code_edit->get_line(0) == " test");
1976
CHECK(code_edit->has_selection());
1977
CHECK(code_edit->get_selection_origin_line() == 0);
1978
CHECK(code_edit->get_selection_origin_column() == 0);
1979
CHECK(code_edit->get_caret_line() == 0);
1980
CHECK(code_edit->get_caret_column() == 8);
1981
1982
// Selection does entire line, right to left selection.
1983
code_edit->set_text("test");
1984
code_edit->select(0, 4, 0, 0);
1985
code_edit->do_indent();
1986
CHECK(code_edit->get_line(0) == " test");
1987
CHECK(code_edit->has_selection());
1988
CHECK(code_edit->get_selection_origin_line() == 0);
1989
CHECK(code_edit->get_selection_origin_column() == 8);
1990
CHECK(code_edit->get_caret_line() == 0);
1991
CHECK(code_edit->get_caret_column() == 0);
1992
1993
/* single indent only add required spaces. */
1994
code_edit->set_text(" test");
1995
code_edit->select_all();
1996
code_edit->do_indent();
1997
CHECK(code_edit->get_line(0) == " test");
1998
CHECK(code_edit->has_selection());
1999
CHECK(code_edit->get_selection_origin_line() == 0);
2000
CHECK(code_edit->get_selection_origin_column() == 0);
2001
CHECK(code_edit->get_caret_line() == 0);
2002
CHECK(code_edit->get_caret_column() == 8);
2003
2004
/* Handles multiple lines. */
2005
code_edit->set_text("test\ntext");
2006
code_edit->select_all();
2007
code_edit->do_indent();
2008
CHECK(code_edit->get_line(0) == " test");
2009
CHECK(code_edit->get_line(1) == " text");
2010
CHECK(code_edit->has_selection());
2011
CHECK(code_edit->get_selection_origin_line() == 0);
2012
CHECK(code_edit->get_selection_origin_column() == 0);
2013
CHECK(code_edit->get_caret_line() == 1);
2014
CHECK(code_edit->get_caret_column() == 8);
2015
2016
/* Do not indent line if last col is zero. */
2017
code_edit->set_text("test\ntext");
2018
code_edit->select(0, 0, 1, 0);
2019
code_edit->do_indent();
2020
CHECK(code_edit->get_line(0) == " test");
2021
CHECK(code_edit->get_line(1) == "text");
2022
CHECK(code_edit->has_selection());
2023
CHECK(code_edit->get_selection_origin_line() == 0);
2024
CHECK(code_edit->get_selection_origin_column() == 0);
2025
CHECK(code_edit->get_caret_line() == 1);
2026
CHECK(code_edit->get_caret_column() == 0);
2027
2028
/* Indent even if last column of first line. */
2029
code_edit->set_text("test\ntext");
2030
code_edit->select(0, 4, 1, 0);
2031
code_edit->do_indent();
2032
CHECK(code_edit->get_line(0) == " test");
2033
CHECK(code_edit->get_line(1) == "text");
2034
CHECK(code_edit->has_selection());
2035
CHECK(code_edit->get_selection_origin_line() == 0);
2036
CHECK(code_edit->get_selection_origin_column() == 8);
2037
CHECK(code_edit->get_caret_line() == 1);
2038
CHECK(code_edit->get_caret_column() == 0);
2039
2040
// Indent even if last column of first line, right to left selection.
2041
code_edit->set_text("test\ntext");
2042
code_edit->select(1, 0, 0, 4);
2043
code_edit->do_indent();
2044
CHECK(code_edit->get_line(0) == " test");
2045
CHECK(code_edit->get_line(1) == "text");
2046
CHECK(code_edit->has_selection());
2047
CHECK(code_edit->get_selection_origin_line() == 1);
2048
CHECK(code_edit->get_selection_origin_column() == 0);
2049
CHECK(code_edit->get_caret_line() == 0);
2050
CHECK(code_edit->get_caret_column() == 8);
2051
2052
/* Check selection is adjusted. */
2053
code_edit->set_text("test");
2054
code_edit->select(0, 1, 0, 2);
2055
code_edit->do_indent();
2056
CHECK(code_edit->get_line(0) == " test");
2057
CHECK(code_edit->has_selection());
2058
CHECK(code_edit->get_selection_origin_line() == 0);
2059
CHECK(code_edit->get_selection_origin_column() == 5);
2060
CHECK(code_edit->get_caret_line() == 0);
2061
CHECK(code_edit->get_caret_column() == 6);
2062
2063
// Indent once with multiple selections.
2064
code_edit->set_text("test");
2065
code_edit->select(0, 1, 0, 2);
2066
code_edit->add_caret(0, 4);
2067
code_edit->select(0, 4, 0, 3, 1);
2068
code_edit->do_indent();
2069
CHECK(code_edit->get_line(0) == " test");
2070
CHECK(code_edit->get_caret_count() == 2);
2071
CHECK(code_edit->has_selection(0));
2072
CHECK(code_edit->get_selection_origin_line(0) == 0);
2073
CHECK(code_edit->get_selection_origin_column(0) == 5);
2074
CHECK(code_edit->get_caret_line(0) == 0);
2075
CHECK(code_edit->get_caret_column(0) == 6);
2076
CHECK(code_edit->has_selection(1));
2077
CHECK(code_edit->get_selection_origin_line(1) == 0);
2078
CHECK(code_edit->get_selection_origin_column(1) == 8);
2079
CHECK(code_edit->get_caret_line(1) == 0);
2080
CHECK(code_edit->get_caret_column(1) == 7);
2081
}
2082
2083
SUBCASE("[CodeEdit] unindent tabs") {
2084
code_edit->set_indent_size(4);
2085
code_edit->set_auto_indent_enabled(true);
2086
code_edit->set_indent_using_spaces(false);
2087
2088
/* Do nothing if not editable. */
2089
code_edit->set_text("\t");
2090
2091
code_edit->set_editable(false);
2092
2093
code_edit->unindent_lines();
2094
CHECK(code_edit->get_line(0) == "\t");
2095
2096
code_edit->unindent_lines();
2097
CHECK(code_edit->get_line(0) == "\t");
2098
2099
code_edit->set_editable(true);
2100
2101
/* Simple unindent. */
2102
code_edit->unindent_lines();
2103
CHECK(code_edit->get_line(0) == "");
2104
2105
/* Backspace does a simple unindent. */
2106
code_edit->set_text("");
2107
code_edit->insert_text_at_caret("\t");
2108
code_edit->backspace();
2109
CHECK(code_edit->get_line(0) == "");
2110
2111
/* Unindent lines does entire line and works without selection. */
2112
code_edit->set_text("");
2113
code_edit->insert_text_at_caret("\ttest");
2114
code_edit->unindent_lines();
2115
CHECK(code_edit->get_line(0) == "test");
2116
CHECK(code_edit->get_caret_column() == 4);
2117
2118
// Unindent lines once with multiple carets.
2119
code_edit->set_text("\t\ttest");
2120
code_edit->set_caret_column(1);
2121
code_edit->add_caret(0, 3);
2122
code_edit->unindent_lines();
2123
CHECK(code_edit->get_line(0) == "\ttest");
2124
CHECK(code_edit->get_caret_count() == 2);
2125
CHECK_FALSE(code_edit->has_selection());
2126
CHECK(code_edit->get_caret_line(0) == 0);
2127
CHECK(code_edit->get_caret_column(0) == 0);
2128
CHECK(code_edit->get_caret_line(1) == 0);
2129
CHECK(code_edit->get_caret_column(1) == 2);
2130
code_edit->remove_secondary_carets();
2131
2132
/* Caret on col zero unindent line. */
2133
code_edit->set_text("\t\ttest");
2134
code_edit->set_caret_column(0);
2135
code_edit->unindent_lines();
2136
CHECK(code_edit->get_line(0) == "\ttest");
2137
CHECK(code_edit->get_caret_column() == 0);
2138
2139
/* Check input action. */
2140
code_edit->set_text("\t\ttest");
2141
SEND_GUI_ACTION("ui_text_dedent");
2142
CHECK(code_edit->get_line(0) == "\ttest");
2143
2144
/* Selection does entire line. */
2145
code_edit->set_text("\t\ttest");
2146
code_edit->select_all();
2147
code_edit->unindent_lines();
2148
CHECK(code_edit->get_line(0) == "\ttest");
2149
CHECK(code_edit->has_selection());
2150
CHECK(code_edit->get_selection_origin_line() == 0);
2151
CHECK(code_edit->get_selection_origin_column() == 0);
2152
CHECK(code_edit->get_caret_line() == 0);
2153
CHECK(code_edit->get_caret_column() == 5);
2154
2155
// Selection does entire line, right to left selection.
2156
code_edit->set_text("\t\ttest");
2157
code_edit->select(0, 6, 0, 0);
2158
code_edit->unindent_lines();
2159
CHECK(code_edit->get_line(0) == "\ttest");
2160
CHECK(code_edit->has_selection());
2161
CHECK(code_edit->get_selection_origin_line() == 0);
2162
CHECK(code_edit->get_selection_origin_column() == 5);
2163
CHECK(code_edit->get_caret_line() == 0);
2164
CHECK(code_edit->get_caret_column() == 0);
2165
2166
// Handles multiple lines.
2167
code_edit->set_text("\t\ttest\n\t\ttext");
2168
code_edit->select_all();
2169
code_edit->unindent_lines();
2170
CHECK(code_edit->get_line(0) == "\ttest");
2171
CHECK(code_edit->get_line(1) == "\ttext");
2172
CHECK(code_edit->has_selection());
2173
CHECK(code_edit->get_selection_origin_line() == 0);
2174
CHECK(code_edit->get_selection_origin_column() == 0);
2175
CHECK(code_edit->get_caret_line() == 1);
2176
CHECK(code_edit->get_caret_column() == 5);
2177
2178
/* Do not unindent line if last col is zero. */
2179
code_edit->set_text("\ttest\n\ttext");
2180
code_edit->select(0, 0, 1, 0);
2181
code_edit->unindent_lines();
2182
CHECK(code_edit->get_line(0) == "test");
2183
CHECK(code_edit->get_line(1) == "\ttext");
2184
CHECK(code_edit->has_selection());
2185
CHECK(code_edit->get_selection_origin_line() == 0);
2186
CHECK(code_edit->get_selection_origin_column() == 0);
2187
CHECK(code_edit->get_caret_line() == 1);
2188
CHECK(code_edit->get_caret_column() == 0);
2189
2190
// Do not unindent line if last col is zero, right to left selection.
2191
code_edit->set_text("\ttest\n\ttext");
2192
code_edit->select(1, 0, 0, 0);
2193
code_edit->unindent_lines();
2194
CHECK(code_edit->get_line(0) == "test");
2195
CHECK(code_edit->get_line(1) == "\ttext");
2196
CHECK(code_edit->has_selection());
2197
CHECK(code_edit->get_selection_origin_line() == 1);
2198
CHECK(code_edit->get_selection_origin_column() == 0);
2199
CHECK(code_edit->get_caret_line() == 0);
2200
CHECK(code_edit->get_caret_column() == 0);
2201
2202
/* Unindent even if last column of first line. */
2203
code_edit->set_text("\ttest\n\ttext");
2204
code_edit->select(0, 5, 1, 1);
2205
code_edit->unindent_lines();
2206
CHECK(code_edit->get_line(0) == "test");
2207
CHECK(code_edit->get_line(1) == "text");
2208
CHECK(code_edit->has_selection());
2209
CHECK(code_edit->get_selection_origin_line() == 0);
2210
CHECK(code_edit->get_selection_origin_column() == 4);
2211
CHECK(code_edit->get_caret_line() == 1);
2212
CHECK(code_edit->get_caret_column() == 0);
2213
2214
/* Check selection is adjusted. */
2215
code_edit->set_text("\ttest");
2216
code_edit->select(0, 1, 0, 2);
2217
code_edit->unindent_lines();
2218
CHECK(code_edit->get_line(0) == "test");
2219
CHECK(code_edit->has_selection());
2220
CHECK(code_edit->get_selection_origin_line() == 0);
2221
CHECK(code_edit->get_selection_origin_column() == 0);
2222
CHECK(code_edit->get_caret_line() == 0);
2223
CHECK(code_edit->get_caret_column() == 1);
2224
2225
// Deselect if only the tab was selected.
2226
code_edit->set_text("\ttest");
2227
code_edit->select(0, 0, 0, 1);
2228
code_edit->unindent_lines();
2229
CHECK(code_edit->get_line(0) == "test");
2230
CHECK_FALSE(code_edit->has_selection());
2231
CHECK(code_edit->get_caret_line() == 0);
2232
CHECK(code_edit->get_caret_column() == 0);
2233
2234
// Unindent once with multiple selections.
2235
code_edit->set_text("\t\ttest");
2236
code_edit->select(0, 1, 0, 2);
2237
code_edit->add_caret(0, 4);
2238
code_edit->select(0, 4, 0, 3, 1);
2239
code_edit->unindent_lines();
2240
CHECK(code_edit->get_line(0) == "\ttest");
2241
CHECK(code_edit->get_caret_count() == 2);
2242
CHECK(code_edit->has_selection(0));
2243
CHECK(code_edit->get_selection_origin_line(0) == 0);
2244
CHECK(code_edit->get_selection_origin_column(0) == 0);
2245
CHECK(code_edit->get_caret_line(0) == 0);
2246
CHECK(code_edit->get_caret_column(0) == 1);
2247
CHECK(code_edit->has_selection(1));
2248
CHECK(code_edit->get_selection_origin_line(1) == 0);
2249
CHECK(code_edit->get_selection_origin_column(1) == 3);
2250
CHECK(code_edit->get_caret_line(1) == 0);
2251
CHECK(code_edit->get_caret_column(1) == 2);
2252
}
2253
2254
SUBCASE("[CodeEdit] unindent spaces") {
2255
code_edit->set_indent_size(4);
2256
code_edit->set_auto_indent_enabled(true);
2257
code_edit->set_indent_using_spaces(true);
2258
2259
/* Do nothing if not editable. */
2260
code_edit->set_text(" ");
2261
2262
code_edit->set_editable(false);
2263
2264
code_edit->unindent_lines();
2265
CHECK(code_edit->get_line(0) == " ");
2266
2267
code_edit->unindent_lines();
2268
CHECK(code_edit->get_line(0) == " ");
2269
2270
code_edit->set_editable(true);
2271
2272
/* Simple unindent. */
2273
code_edit->unindent_lines();
2274
CHECK(code_edit->get_line(0) == "");
2275
2276
/* Backspace does a simple unindent. */
2277
code_edit->set_text("");
2278
code_edit->insert_text_at_caret(" ");
2279
code_edit->backspace();
2280
CHECK(code_edit->get_line(0) == "");
2281
2282
/* Backspace with letter. */
2283
code_edit->set_text("");
2284
code_edit->insert_text_at_caret(" a");
2285
code_edit->backspace();
2286
CHECK(code_edit->get_line(0) == " ");
2287
2288
/* Unindent lines does entire line and works without selection. */
2289
code_edit->set_text("");
2290
code_edit->insert_text_at_caret(" test");
2291
code_edit->unindent_lines();
2292
CHECK(code_edit->get_line(0) == "test");
2293
CHECK(code_edit->get_caret_column() == 4);
2294
2295
// Unindent lines once with multiple carets.
2296
code_edit->set_text(" test");
2297
code_edit->set_caret_column(1);
2298
code_edit->add_caret(0, 9);
2299
code_edit->unindent_lines();
2300
CHECK(code_edit->get_line(0) == " test");
2301
CHECK(code_edit->get_caret_count() == 2);
2302
CHECK_FALSE(code_edit->has_selection());
2303
CHECK(code_edit->get_caret_line(0) == 0);
2304
CHECK(code_edit->get_caret_column(0) == 0);
2305
CHECK(code_edit->get_caret_line(1) == 0);
2306
CHECK(code_edit->get_caret_column(1) == 5);
2307
code_edit->remove_secondary_carets();
2308
2309
/* Caret on col zero unindent line. */
2310
code_edit->set_text(" test");
2311
code_edit->set_caret_column(0);
2312
code_edit->unindent_lines();
2313
CHECK(code_edit->get_line(0) == " test");
2314
CHECK(code_edit->get_caret_column() == 0);
2315
2316
/* Only as far as needed */
2317
code_edit->set_text(" test");
2318
code_edit->unindent_lines();
2319
CHECK(code_edit->get_line(0) == " test");
2320
2321
/* Check input action. */
2322
code_edit->set_text(" test");
2323
SEND_GUI_ACTION("ui_text_dedent");
2324
CHECK(code_edit->get_line(0) == " test");
2325
2326
/* Selection does entire line. */
2327
code_edit->set_text(" test");
2328
code_edit->select_all();
2329
code_edit->unindent_lines();
2330
CHECK(code_edit->get_line(0) == " test");
2331
CHECK(code_edit->has_selection());
2332
CHECK(code_edit->get_selection_origin_line() == 0);
2333
CHECK(code_edit->get_selection_origin_column() == 0);
2334
CHECK(code_edit->get_caret_line() == 0);
2335
CHECK(code_edit->get_caret_column() == 8);
2336
2337
// Selection does entire line, right to left selection.
2338
code_edit->set_text(" test");
2339
code_edit->select(0, 12, 0, 0);
2340
code_edit->unindent_lines();
2341
CHECK(code_edit->get_line(0) == " test");
2342
CHECK(code_edit->has_selection());
2343
CHECK(code_edit->get_selection_origin_line() == 0);
2344
CHECK(code_edit->get_selection_origin_column() == 8);
2345
CHECK(code_edit->get_caret_line() == 0);
2346
CHECK(code_edit->get_caret_column() == 0);
2347
2348
// Handles multiple lines.
2349
code_edit->set_text(" test\n text");
2350
code_edit->select_all();
2351
code_edit->unindent_lines();
2352
CHECK(code_edit->get_line(0) == " test");
2353
CHECK(code_edit->get_line(1) == " text");
2354
CHECK(code_edit->has_selection());
2355
CHECK(code_edit->get_selection_origin_line() == 0);
2356
CHECK(code_edit->get_selection_origin_column() == 0);
2357
CHECK(code_edit->get_caret_line() == 1);
2358
CHECK(code_edit->get_caret_column() == 8);
2359
2360
/* Do not unindent line if last col is zero. */
2361
code_edit->set_text(" test\n text");
2362
code_edit->select(0, 0, 1, 0);
2363
code_edit->unindent_lines();
2364
CHECK(code_edit->get_line(0) == "test");
2365
CHECK(code_edit->get_line(1) == " text");
2366
CHECK(code_edit->has_selection());
2367
CHECK(code_edit->get_selection_origin_line() == 0);
2368
CHECK(code_edit->get_selection_origin_column() == 0);
2369
CHECK(code_edit->get_caret_line() == 1);
2370
CHECK(code_edit->get_caret_column() == 0);
2371
2372
// Do not unindent line if last col is zero, right to left selection.
2373
code_edit->set_text(" test\n text");
2374
code_edit->select(1, 0, 0, 0);
2375
code_edit->unindent_lines();
2376
CHECK(code_edit->get_line(0) == "test");
2377
CHECK(code_edit->get_line(1) == " text");
2378
CHECK(code_edit->has_selection());
2379
CHECK(code_edit->get_selection_origin_line() == 1);
2380
CHECK(code_edit->get_selection_origin_column() == 0);
2381
CHECK(code_edit->get_caret_line() == 0);
2382
CHECK(code_edit->get_caret_column() == 0);
2383
2384
/* Unindent even if last column of first line. */
2385
code_edit->set_text(" test\n text");
2386
code_edit->select(0, 5, 1, 1);
2387
code_edit->unindent_lines();
2388
CHECK(code_edit->get_line(0) == "test");
2389
CHECK(code_edit->get_line(1) == "text");
2390
CHECK(code_edit->has_selection());
2391
CHECK(code_edit->get_selection_origin_line() == 0);
2392
CHECK(code_edit->get_selection_origin_column() == 1);
2393
CHECK(code_edit->get_caret_line() == 1);
2394
CHECK(code_edit->get_caret_column() == 0);
2395
2396
/* Check selection is adjusted. */
2397
code_edit->set_text(" test");
2398
code_edit->select(0, 4, 0, 5);
2399
code_edit->unindent_lines();
2400
CHECK(code_edit->get_line(0) == "test");
2401
CHECK(code_edit->has_selection());
2402
CHECK(code_edit->get_selection_origin_line() == 0);
2403
CHECK(code_edit->get_selection_origin_column() == 0);
2404
CHECK(code_edit->get_caret_line() == 0);
2405
CHECK(code_edit->get_caret_column() == 1);
2406
2407
// Deselect if only the tab was selected.
2408
code_edit->set_text(" test");
2409
code_edit->select(0, 0, 0, 4);
2410
code_edit->unindent_lines();
2411
CHECK(code_edit->get_line(0) == "test");
2412
CHECK_FALSE(code_edit->has_selection());
2413
CHECK(code_edit->get_caret_line() == 0);
2414
CHECK(code_edit->get_caret_column() == 0);
2415
2416
// Unindent once with multiple selections.
2417
code_edit->set_text(" test");
2418
code_edit->select(0, 1, 0, 2);
2419
code_edit->add_caret(0, 4);
2420
code_edit->select(0, 12, 0, 10, 1);
2421
code_edit->unindent_lines();
2422
CHECK(code_edit->get_line(0) == " test");
2423
CHECK(code_edit->get_caret_count() == 2);
2424
CHECK_FALSE(code_edit->has_selection(0));
2425
CHECK(code_edit->get_caret_line(0) == 0);
2426
CHECK(code_edit->get_caret_column(0) == 0);
2427
CHECK(code_edit->has_selection(1));
2428
CHECK(code_edit->get_selection_origin_line(1) == 0);
2429
CHECK(code_edit->get_selection_origin_column(1) == 8);
2430
CHECK(code_edit->get_caret_line(1) == 0);
2431
CHECK(code_edit->get_caret_column(1) == 6);
2432
}
2433
2434
SUBCASE("[CodeEdit] auto indent") {
2435
SUBCASE("[CodeEdit] auto indent tabs") {
2436
code_edit->set_indent_size(4);
2437
code_edit->set_auto_indent_enabled(true);
2438
code_edit->set_indent_using_spaces(false);
2439
2440
/* Simple indent on new line. */
2441
code_edit->set_text("");
2442
code_edit->insert_text_at_caret("test:");
2443
SEND_GUI_ACTION("ui_text_newline");
2444
CHECK(code_edit->get_line(0) == "test:");
2445
CHECK(code_edit->get_line(1) == "\t");
2446
CHECK(code_edit->get_caret_line() == 1);
2447
CHECK(code_edit->get_caret_column() == 1);
2448
2449
/* new blank line should still indent. */
2450
code_edit->set_text("");
2451
code_edit->insert_text_at_caret("test:");
2452
SEND_GUI_ACTION("ui_text_newline_blank");
2453
CHECK(code_edit->get_line(0) == "test:");
2454
CHECK(code_edit->get_line(1) == "\t");
2455
CHECK(code_edit->get_caret_line() == 1);
2456
CHECK(code_edit->get_caret_column() == 1);
2457
2458
/* new line above should not indent. */
2459
code_edit->set_text("");
2460
code_edit->insert_text_at_caret("test:");
2461
SEND_GUI_ACTION("ui_text_newline_above");
2462
CHECK(code_edit->get_line(0) == "");
2463
CHECK(code_edit->get_line(1) == "test:");
2464
CHECK(code_edit->get_caret_line() == 0);
2465
CHECK(code_edit->get_caret_column() == 0);
2466
2467
/* Whitespace between symbol and caret is okay. */
2468
code_edit->set_text("");
2469
code_edit->insert_text_at_caret("test: ");
2470
SEND_GUI_ACTION("ui_text_newline");
2471
CHECK(code_edit->get_line(0) == "test: ");
2472
CHECK(code_edit->get_line(1) == "\t");
2473
CHECK(code_edit->get_caret_line() == 1);
2474
CHECK(code_edit->get_caret_column() == 1);
2475
2476
/* Comment between symbol and caret is okay. */
2477
code_edit->add_comment_delimiter("#", "");
2478
code_edit->set_text("");
2479
code_edit->insert_text_at_caret("test: # comment");
2480
SEND_GUI_ACTION("ui_text_newline");
2481
CHECK(code_edit->get_line(0) == "test: # comment");
2482
CHECK(code_edit->get_line(1) == "\t");
2483
code_edit->remove_comment_delimiter("#");
2484
CHECK(code_edit->get_caret_line() == 1);
2485
CHECK(code_edit->get_caret_column() == 1);
2486
2487
/* Strings between symbol and caret are not okay. */
2488
code_edit->add_string_delimiter("#", "");
2489
code_edit->set_text("");
2490
code_edit->insert_text_at_caret("test: # string");
2491
SEND_GUI_ACTION("ui_text_newline");
2492
CHECK(code_edit->get_line(0) == "test: # string");
2493
CHECK(code_edit->get_line(1) == "");
2494
code_edit->remove_string_delimiter("#");
2495
CHECK(code_edit->get_caret_line() == 1);
2496
CHECK(code_edit->get_caret_column() == 0);
2497
2498
/* Non-whitespace prevents auto-indentation. */
2499
code_edit->add_comment_delimiter("#", "");
2500
code_edit->set_text("");
2501
code_edit->insert_text_at_caret("test := 0 # comment");
2502
SEND_GUI_ACTION("ui_text_newline");
2503
CHECK(code_edit->get_line(0) == "test := 0 # comment");
2504
CHECK(code_edit->get_line(1) == "");
2505
code_edit->remove_comment_delimiter("#");
2506
CHECK(code_edit->get_caret_line() == 1);
2507
CHECK(code_edit->get_caret_column() == 0);
2508
2509
/* Even when there's no comments. */
2510
code_edit->set_text("");
2511
code_edit->insert_text_at_caret("test := 0");
2512
SEND_GUI_ACTION("ui_text_newline");
2513
CHECK(code_edit->get_line(0) == "test := 0");
2514
CHECK(code_edit->get_line(1) == "");
2515
CHECK(code_edit->get_caret_line() == 1);
2516
CHECK(code_edit->get_caret_column() == 0);
2517
2518
// Preserve current indentation.
2519
code_edit->set_text("\ttest");
2520
code_edit->set_caret_column(3);
2521
SEND_GUI_ACTION("ui_text_newline");
2522
CHECK(code_edit->get_line(0) == "\tte");
2523
CHECK(code_edit->get_line(1) == "\tst");
2524
CHECK(code_edit->get_caret_line() == 1);
2525
CHECK(code_edit->get_caret_column() == 1);
2526
2527
// Preserve current indentation blank.
2528
code_edit->set_text("\ttest");
2529
code_edit->set_caret_column(3);
2530
SEND_GUI_ACTION("ui_text_newline_blank");
2531
CHECK(code_edit->get_line(0) == "\ttest");
2532
CHECK(code_edit->get_line(1) == "\t");
2533
CHECK(code_edit->get_caret_line() == 1);
2534
CHECK(code_edit->get_caret_column() == 1);
2535
2536
// Preserve current indentation above.
2537
code_edit->set_text("\ttest");
2538
code_edit->set_caret_column(3);
2539
SEND_GUI_ACTION("ui_text_newline_above");
2540
CHECK(code_edit->get_line(0) == "\t");
2541
CHECK(code_edit->get_line(1) == "\ttest");
2542
CHECK(code_edit->get_caret_line() == 0);
2543
CHECK(code_edit->get_caret_column() == 1);
2544
2545
// Increase existing indentation.
2546
code_edit->set_text("\ttest:");
2547
code_edit->set_caret_column(6);
2548
SEND_GUI_ACTION("ui_text_newline");
2549
CHECK(code_edit->get_line(0) == "\ttest:");
2550
CHECK(code_edit->get_line(1) == "\t\t");
2551
CHECK(code_edit->get_caret_line() == 1);
2552
CHECK(code_edit->get_caret_column() == 2);
2553
2554
// Increase existing indentation blank.
2555
code_edit->set_text("\ttest:");
2556
code_edit->set_caret_column(3);
2557
SEND_GUI_ACTION("ui_text_newline_blank");
2558
CHECK(code_edit->get_line(0) == "\ttest:");
2559
CHECK(code_edit->get_line(1) == "\t\t");
2560
CHECK(code_edit->get_caret_line() == 1);
2561
CHECK(code_edit->get_caret_column() == 2);
2562
2563
/* If between brace pairs an extra line is added. */
2564
code_edit->set_text("");
2565
code_edit->insert_text_at_caret("test{}");
2566
code_edit->set_caret_column(5);
2567
SEND_GUI_ACTION("ui_text_newline");
2568
CHECK(code_edit->get_line(0) == "test{");
2569
CHECK(code_edit->get_line(1) == "\t");
2570
CHECK(code_edit->get_line(2) == "}");
2571
CHECK(code_edit->get_caret_line() == 1);
2572
CHECK(code_edit->get_caret_column() == 1);
2573
2574
/* Except when we are going above. */
2575
code_edit->set_text("");
2576
code_edit->insert_text_at_caret("test{}");
2577
code_edit->set_caret_column(5);
2578
SEND_GUI_ACTION("ui_text_newline_above");
2579
CHECK(code_edit->get_line(0) == "");
2580
CHECK(code_edit->get_line(1) == "test{}");
2581
CHECK(code_edit->get_caret_line() == 0);
2582
CHECK(code_edit->get_caret_column() == 0);
2583
2584
/* or below. */
2585
code_edit->set_text("");
2586
code_edit->insert_text_at_caret("test{}");
2587
code_edit->set_caret_column(5);
2588
SEND_GUI_ACTION("ui_text_newline_blank");
2589
CHECK(code_edit->get_line(0) == "test{}");
2590
CHECK(code_edit->get_line(1) == "");
2591
CHECK(code_edit->get_caret_line() == 1);
2592
CHECK(code_edit->get_caret_column() == 0);
2593
}
2594
2595
SUBCASE("[CodeEdit] auto indent spaces") {
2596
code_edit->set_indent_size(4);
2597
code_edit->set_auto_indent_enabled(true);
2598
code_edit->set_indent_using_spaces(true);
2599
2600
/* Simple indent on new line. */
2601
code_edit->set_text("");
2602
code_edit->insert_text_at_caret("test:");
2603
SEND_GUI_ACTION("ui_text_newline");
2604
CHECK(code_edit->get_line(0) == "test:");
2605
CHECK(code_edit->get_line(1) == " ");
2606
CHECK(code_edit->get_caret_line() == 1);
2607
CHECK(code_edit->get_caret_column() == 4);
2608
2609
/* new blank line should still indent. */
2610
code_edit->set_text("");
2611
code_edit->insert_text_at_caret("test:");
2612
SEND_GUI_ACTION("ui_text_newline_blank");
2613
CHECK(code_edit->get_line(0) == "test:");
2614
CHECK(code_edit->get_line(1) == " ");
2615
CHECK(code_edit->get_caret_line() == 1);
2616
CHECK(code_edit->get_caret_column() == 4);
2617
2618
/* new line above should not indent. */
2619
code_edit->set_text("");
2620
code_edit->insert_text_at_caret("test:");
2621
SEND_GUI_ACTION("ui_text_newline_above");
2622
CHECK(code_edit->get_line(0) == "");
2623
CHECK(code_edit->get_line(1) == "test:");
2624
CHECK(code_edit->get_caret_line() == 0);
2625
CHECK(code_edit->get_caret_column() == 0);
2626
2627
/* Whitespace between symbol and caret is okay. */
2628
code_edit->set_text("");
2629
code_edit->insert_text_at_caret("test: ");
2630
SEND_GUI_ACTION("ui_text_newline");
2631
CHECK(code_edit->get_line(0) == "test: ");
2632
CHECK(code_edit->get_line(1) == " ");
2633
CHECK(code_edit->get_caret_line() == 1);
2634
CHECK(code_edit->get_caret_column() == 4);
2635
2636
/* Comment between symbol and caret is okay. */
2637
code_edit->add_comment_delimiter("#", "");
2638
code_edit->set_text("");
2639
code_edit->insert_text_at_caret("test: # comment");
2640
SEND_GUI_ACTION("ui_text_newline");
2641
CHECK(code_edit->get_line(0) == "test: # comment");
2642
CHECK(code_edit->get_line(1) == " ");
2643
code_edit->remove_comment_delimiter("#");
2644
CHECK(code_edit->get_caret_line() == 1);
2645
CHECK(code_edit->get_caret_column() == 4);
2646
2647
/* Strings between symbol and caret are not okay. */
2648
code_edit->add_string_delimiter("#", "");
2649
code_edit->set_text("");
2650
code_edit->insert_text_at_caret("test: # string");
2651
SEND_GUI_ACTION("ui_text_newline");
2652
CHECK(code_edit->get_line(0) == "test: # string");
2653
CHECK(code_edit->get_line(1) == "");
2654
code_edit->remove_string_delimiter("#");
2655
CHECK(code_edit->get_caret_line() == 1);
2656
CHECK(code_edit->get_caret_column() == 0);
2657
2658
/* Non-whitespace prevents auto-indentation. */
2659
code_edit->add_comment_delimiter("#", "");
2660
code_edit->set_text("");
2661
code_edit->insert_text_at_caret("test := 0 # comment");
2662
SEND_GUI_ACTION("ui_text_newline");
2663
CHECK(code_edit->get_line(0) == "test := 0 # comment");
2664
CHECK(code_edit->get_line(1) == "");
2665
code_edit->remove_comment_delimiter("#");
2666
CHECK(code_edit->get_caret_line() == 1);
2667
CHECK(code_edit->get_caret_column() == 0);
2668
2669
/* Even when there's no comments. */
2670
code_edit->set_text("");
2671
code_edit->insert_text_at_caret("test := 0");
2672
SEND_GUI_ACTION("ui_text_newline");
2673
CHECK(code_edit->get_line(0) == "test := 0");
2674
CHECK(code_edit->get_line(1) == "");
2675
CHECK(code_edit->get_caret_line() == 1);
2676
CHECK(code_edit->get_caret_column() == 0);
2677
2678
// Preserve current indentation.
2679
code_edit->set_text(" test");
2680
code_edit->set_caret_column(6);
2681
SEND_GUI_ACTION("ui_text_newline");
2682
CHECK(code_edit->get_line(0) == " te");
2683
CHECK(code_edit->get_line(1) == " st");
2684
CHECK(code_edit->get_caret_line() == 1);
2685
CHECK(code_edit->get_caret_column() == 4);
2686
2687
// Preserve current indentation blank.
2688
code_edit->set_text(" test");
2689
code_edit->set_caret_column(6);
2690
SEND_GUI_ACTION("ui_text_newline_blank");
2691
CHECK(code_edit->get_line(0) == " test");
2692
CHECK(code_edit->get_line(1) == " ");
2693
CHECK(code_edit->get_caret_line() == 1);
2694
CHECK(code_edit->get_caret_column() == 4);
2695
2696
// Preserve current indentation above.
2697
code_edit->set_text(" test");
2698
code_edit->set_caret_column(6);
2699
SEND_GUI_ACTION("ui_text_newline_above");
2700
CHECK(code_edit->get_line(0) == " ");
2701
CHECK(code_edit->get_line(1) == " test");
2702
CHECK(code_edit->get_caret_line() == 0);
2703
CHECK(code_edit->get_caret_column() == 4);
2704
2705
// Increase existing indentation.
2706
code_edit->set_text(" test:");
2707
code_edit->set_caret_column(9);
2708
SEND_GUI_ACTION("ui_text_newline");
2709
CHECK(code_edit->get_line(0) == " test:");
2710
CHECK(code_edit->get_line(1) == " ");
2711
CHECK(code_edit->get_caret_line() == 1);
2712
CHECK(code_edit->get_caret_column() == 8);
2713
2714
// Increase existing indentation blank.
2715
code_edit->set_text(" test:");
2716
code_edit->set_caret_column(9);
2717
SEND_GUI_ACTION("ui_text_newline");
2718
CHECK(code_edit->get_line(0) == " test:");
2719
CHECK(code_edit->get_line(1) == " ");
2720
CHECK(code_edit->get_caret_line() == 1);
2721
CHECK(code_edit->get_caret_column() == 8);
2722
2723
/* If between brace pairs an extra line is added. */
2724
code_edit->set_text("");
2725
code_edit->insert_text_at_caret("test{}");
2726
code_edit->set_caret_column(5);
2727
SEND_GUI_ACTION("ui_text_newline");
2728
CHECK(code_edit->get_line(0) == "test{");
2729
CHECK(code_edit->get_line(1) == " ");
2730
CHECK(code_edit->get_line(2) == "}");
2731
CHECK(code_edit->get_caret_line() == 1);
2732
CHECK(code_edit->get_caret_column() == 4);
2733
2734
/* Except when we are going above. */
2735
code_edit->set_text("");
2736
code_edit->insert_text_at_caret("test{}");
2737
code_edit->set_caret_column(5);
2738
SEND_GUI_ACTION("ui_text_newline_above");
2739
CHECK(code_edit->get_line(0) == "");
2740
CHECK(code_edit->get_line(1) == "test{}");
2741
CHECK(code_edit->get_caret_line() == 0);
2742
CHECK(code_edit->get_caret_column() == 0);
2743
2744
/* or below. */
2745
code_edit->set_text("");
2746
code_edit->insert_text_at_caret("test{}");
2747
code_edit->set_caret_column(5);
2748
SEND_GUI_ACTION("ui_text_newline_blank");
2749
CHECK(code_edit->get_line(0) == "test{}");
2750
CHECK(code_edit->get_line(1) == "");
2751
CHECK(code_edit->get_caret_line() == 1);
2752
CHECK(code_edit->get_caret_column() == 0);
2753
2754
/* If there is something after a colon
2755
and there is a colon in the comment it
2756
should not indent. */
2757
code_edit->add_comment_delimiter("#", "");
2758
code_edit->set_text("");
2759
code_edit->insert_text_at_caret("test:test#:");
2760
SEND_GUI_ACTION("ui_text_newline");
2761
CHECK(code_edit->get_line(0) == "test:test#:");
2762
CHECK(code_edit->get_line(1) == "");
2763
code_edit->remove_comment_delimiter("#");
2764
CHECK(code_edit->get_caret_line() == 1);
2765
CHECK(code_edit->get_caret_column() == 0);
2766
}
2767
}
2768
2769
SUBCASE("[CodeEdit] convert indent to tabs") {
2770
code_edit->set_indent_size(4);
2771
code_edit->set_indent_using_spaces(false);
2772
2773
// Only line.
2774
code_edit->set_text(" test");
2775
code_edit->select(0, 9, 0, 8);
2776
code_edit->convert_indent();
2777
CHECK(code_edit->get_line(0) == "\t\ttest");
2778
CHECK(code_edit->has_selection());
2779
CHECK(code_edit->get_selection_origin_column() == 3);
2780
CHECK(code_edit->get_caret_column() == 2);
2781
2782
// First line.
2783
code_edit->set_text(" test\n");
2784
code_edit->select(0, 8, 0, 9);
2785
code_edit->convert_indent();
2786
CHECK(code_edit->get_line(0) == "\t\ttest");
2787
CHECK(code_edit->has_selection());
2788
CHECK(code_edit->get_selection_origin_column() == 2);
2789
CHECK(code_edit->get_caret_column() == 3);
2790
2791
// Middle line.
2792
code_edit->set_text("\n test\n");
2793
code_edit->select(1, 8, 1, 9);
2794
code_edit->convert_indent();
2795
CHECK(code_edit->get_line(1) == "\t\ttest");
2796
CHECK(code_edit->has_selection());
2797
CHECK(code_edit->get_selection_origin_column() == 2);
2798
CHECK(code_edit->get_caret_column() == 3);
2799
2800
// End line.
2801
code_edit->set_text("\n test");
2802
code_edit->select(1, 8, 1, 9);
2803
code_edit->convert_indent();
2804
CHECK(code_edit->get_line(1) == "\t\ttest");
2805
CHECK(code_edit->has_selection());
2806
CHECK(code_edit->get_selection_origin_column() == 2);
2807
CHECK(code_edit->get_caret_column() == 3);
2808
2809
// Within provided range.
2810
code_edit->set_text(" test\n test\n");
2811
code_edit->select(1, 8, 1, 9);
2812
code_edit->convert_indent(1, 1);
2813
CHECK(code_edit->get_line(0) == " test");
2814
CHECK(code_edit->get_line(1) == "\t\ttest");
2815
CHECK(code_edit->has_selection());
2816
CHECK(code_edit->get_selection_origin_column() == 2);
2817
CHECK(code_edit->get_caret_column() == 3);
2818
2819
// Multiline blocks.
2820
code_edit->set_text("'''\n test\n test\n'''");
2821
code_edit->select(1, 0, 1, 8);
2822
code_edit->convert_indent();
2823
CHECK(code_edit->get_line(1) == " test");
2824
CHECK(code_edit->get_line(2) == " test");
2825
CHECK(code_edit->has_selection());
2826
CHECK(code_edit->get_selection_origin_column() == 0);
2827
CHECK(code_edit->get_caret_column() == 8);
2828
}
2829
2830
SUBCASE("[CodeEdit] convert indent to spaces") {
2831
code_edit->set_indent_size(4);
2832
code_edit->set_indent_using_spaces(true);
2833
2834
// Only line.
2835
code_edit->set_text("\t\ttest");
2836
code_edit->select(0, 3, 0, 2);
2837
code_edit->convert_indent();
2838
CHECK(code_edit->get_line(0) == " test");
2839
CHECK(code_edit->has_selection());
2840
CHECK(code_edit->get_selection_origin_column() == 9);
2841
CHECK(code_edit->get_caret_column() == 8);
2842
2843
// First line.
2844
code_edit->set_text("\t\ttest\n");
2845
code_edit->select(0, 2, 0, 3);
2846
code_edit->convert_indent();
2847
CHECK(code_edit->get_line(0) == " test");
2848
CHECK(code_edit->has_selection());
2849
CHECK(code_edit->get_selection_origin_column() == 8);
2850
CHECK(code_edit->get_caret_column() == 9);
2851
2852
// Middle line.
2853
code_edit->set_text("\n\t\ttest\n");
2854
code_edit->select(1, 2, 1, 3);
2855
code_edit->convert_indent();
2856
CHECK(code_edit->get_line(1) == " test");
2857
CHECK(code_edit->has_selection());
2858
CHECK(code_edit->get_selection_origin_column() == 8);
2859
CHECK(code_edit->get_caret_column() == 9);
2860
2861
// End line.
2862
code_edit->set_text("\n\t\ttest");
2863
code_edit->select(1, 2, 1, 3);
2864
code_edit->convert_indent();
2865
CHECK(code_edit->get_line(1) == " test");
2866
CHECK(code_edit->has_selection());
2867
CHECK(code_edit->get_selection_origin_column() == 8);
2868
CHECK(code_edit->get_caret_column() == 9);
2869
2870
// Within provided range.
2871
code_edit->set_text("\ttest\n\t\ttest\n");
2872
code_edit->select(1, 2, 1, 3);
2873
code_edit->convert_indent(1, 1);
2874
CHECK(code_edit->get_line(0) == "\ttest");
2875
CHECK(code_edit->get_line(1) == " test");
2876
CHECK(code_edit->has_selection());
2877
CHECK(code_edit->get_selection_origin_column() == 8);
2878
CHECK(code_edit->get_caret_column() == 9);
2879
2880
// Outside of range.
2881
ERR_PRINT_OFF;
2882
code_edit->convert_indent(0, 4);
2883
code_edit->convert_indent(4, 5);
2884
code_edit->convert_indent(4, 1);
2885
ERR_PRINT_ON;
2886
}
2887
2888
memdelete(code_edit);
2889
}
2890
2891
TEST_CASE("[SceneTree][CodeEdit] folding") {
2892
CodeEdit *code_edit = memnew(CodeEdit);
2893
SceneTree::get_singleton()->get_root()->add_child(code_edit);
2894
code_edit->grab_focus();
2895
code_edit->set_line_folding_enabled(true);
2896
2897
SUBCASE("[CodeEdit] folding settings") {
2898
code_edit->set_line_folding_enabled(true);
2899
CHECK(code_edit->is_line_folding_enabled());
2900
2901
code_edit->set_line_folding_enabled(false);
2902
CHECK_FALSE(code_edit->is_line_folding_enabled());
2903
}
2904
2905
SUBCASE("[CodeEdit] folding") {
2906
// No indent.
2907
code_edit->set_text("line1\nline2\nline3");
2908
for (int i = 0; i < 2; i++) {
2909
CHECK_FALSE(code_edit->can_fold_line(i));
2910
code_edit->fold_line(i);
2911
CHECK_FALSE(code_edit->is_line_folded(i));
2912
}
2913
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
2914
2915
// Indented lines.
2916
code_edit->set_text("\tline1\n\tline2\n\tline3");
2917
for (int i = 0; i < 2; i++) {
2918
CHECK_FALSE(code_edit->can_fold_line(i));
2919
code_edit->fold_line(i);
2920
CHECK_FALSE(code_edit->is_line_folded(i));
2921
}
2922
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
2923
2924
// Indent.
2925
code_edit->set_text("line1\n\tline2\nline3");
2926
CHECK(code_edit->can_fold_line(0));
2927
for (int i = 1; i < 2; i++) {
2928
CHECK_FALSE(code_edit->can_fold_line(i));
2929
code_edit->fold_line(i);
2930
CHECK_FALSE(code_edit->is_line_folded(i));
2931
}
2932
code_edit->fold_line(0);
2933
CHECK(code_edit->is_line_folded(0));
2934
CHECK_FALSE(code_edit->is_line_folded(1));
2935
CHECK_FALSE(code_edit->is_line_folded(2));
2936
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
2937
2938
// Indent with blank lines.
2939
code_edit->set_text("line1\n\tline2\n\n\nline3");
2940
CHECK(code_edit->can_fold_line(0));
2941
for (int i = 1; i < 2; i++) {
2942
CHECK_FALSE(code_edit->can_fold_line(i));
2943
code_edit->fold_line(i);
2944
CHECK_FALSE(code_edit->is_line_folded(i));
2945
}
2946
code_edit->fold_line(0);
2947
CHECK(code_edit->is_line_folded(0));
2948
CHECK_FALSE(code_edit->is_line_folded(1));
2949
CHECK_FALSE(code_edit->is_line_folded(2));
2950
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
2951
2952
// Nested indents.
2953
code_edit->set_text("line1\n\tline2\n\t\tline3\nline4");
2954
CHECK(code_edit->can_fold_line(0));
2955
CHECK(code_edit->can_fold_line(1));
2956
for (int i = 2; i < 3; i++) {
2957
CHECK_FALSE(code_edit->can_fold_line(i));
2958
code_edit->fold_line(i);
2959
CHECK_FALSE(code_edit->is_line_folded(i));
2960
}
2961
code_edit->fold_line(1);
2962
CHECK_FALSE(code_edit->is_line_folded(0));
2963
CHECK(code_edit->is_line_folded(1));
2964
CHECK_FALSE(code_edit->is_line_folded(2));
2965
CHECK_FALSE(code_edit->is_line_folded(3));
2966
CHECK(code_edit->get_next_visible_line_offset_from(2, 1) == 2);
2967
2968
code_edit->fold_line(0);
2969
CHECK(code_edit->is_line_folded(0));
2970
CHECK_FALSE(code_edit->is_line_folded(1));
2971
CHECK_FALSE(code_edit->is_line_folded(2));
2972
CHECK_FALSE(code_edit->is_line_folded(3));
2973
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
2974
2975
// Check metadata.
2976
CHECK(code_edit->get_folded_lines().size() == 1);
2977
CHECK((int)code_edit->get_folded_lines()[0] == 0);
2978
2979
// Cannot unfold nested.
2980
code_edit->unfold_line(1);
2981
CHECK_FALSE(code_edit->is_line_folded(0));
2982
CHECK_FALSE(code_edit->is_line_folded(1));
2983
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
2984
2985
// (un)Fold all / toggle.
2986
code_edit->unfold_line(0);
2987
CHECK_FALSE(code_edit->is_line_folded(0));
2988
CHECK_FALSE(code_edit->is_line_folded(1));
2989
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
2990
2991
// Check metadata.
2992
CHECK(code_edit->get_folded_lines().size() == 0);
2993
2994
code_edit->fold_all_lines();
2995
CHECK(code_edit->is_line_folded(0));
2996
CHECK_FALSE(code_edit->is_line_folded(1));
2997
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
2998
2999
code_edit->unfold_all_lines();
3000
CHECK_FALSE(code_edit->is_line_folded(0));
3001
CHECK_FALSE(code_edit->is_line_folded(1));
3002
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3003
3004
code_edit->toggle_foldable_line(0);
3005
CHECK(code_edit->is_line_folded(0));
3006
CHECK_FALSE(code_edit->is_line_folded(1));
3007
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
3008
3009
// Can also unfold from hidden line.
3010
code_edit->unfold_line(1);
3011
CHECK_FALSE(code_edit->is_line_folded(0));
3012
CHECK_FALSE(code_edit->is_line_folded(1));
3013
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3014
3015
// Blank lines.
3016
code_edit->set_text("line1\n\tline2\n\n\n\ttest\n\nline3");
3017
CHECK(code_edit->can_fold_line(0));
3018
for (int i = 1; i < code_edit->get_line_count(); i++) {
3019
CHECK_FALSE(code_edit->can_fold_line(i));
3020
code_edit->fold_line(i);
3021
CHECK_FALSE(code_edit->is_line_folded(i));
3022
}
3023
code_edit->fold_line(0);
3024
CHECK(code_edit->is_line_folded(0));
3025
for (int i = 1; i < code_edit->get_line_count(); i++) {
3026
CHECK_FALSE(code_edit->is_line_folded(i));
3027
}
3028
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 5);
3029
3030
// End of file.
3031
code_edit->set_text("line1\n\tline2");
3032
CHECK(code_edit->can_fold_line(0));
3033
CHECK_FALSE(code_edit->can_fold_line(1));
3034
code_edit->fold_line(1);
3035
CHECK_FALSE(code_edit->is_line_folded(1));
3036
code_edit->fold_line(0);
3037
CHECK(code_edit->is_line_folded(0));
3038
CHECK_FALSE(code_edit->is_line_folded(1));
3039
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3040
3041
// Comment & string blocks.
3042
// Single line block
3043
code_edit->add_comment_delimiter("#", "", true);
3044
code_edit->set_text("#line1\n#\tline2");
3045
CHECK(code_edit->can_fold_line(0));
3046
CHECK_FALSE(code_edit->can_fold_line(1));
3047
code_edit->fold_line(1);
3048
CHECK_FALSE(code_edit->is_line_folded(1));
3049
code_edit->fold_line(0);
3050
CHECK(code_edit->is_line_folded(0));
3051
CHECK_FALSE(code_edit->is_line_folded(1));
3052
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3053
3054
// Has to be full line.
3055
code_edit->set_text("test #line1\n#\tline2");
3056
CHECK_FALSE(code_edit->can_fold_line(0));
3057
CHECK_FALSE(code_edit->can_fold_line(1));
3058
code_edit->fold_line(1);
3059
CHECK_FALSE(code_edit->is_line_folded(1));
3060
code_edit->fold_line(0);
3061
CHECK_FALSE(code_edit->is_line_folded(0));
3062
CHECK_FALSE(code_edit->is_line_folded(1));
3063
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3064
3065
code_edit->set_text("#line1\ntest #\tline2");
3066
CHECK_FALSE(code_edit->can_fold_line(0));
3067
CHECK_FALSE(code_edit->can_fold_line(1));
3068
code_edit->fold_line(1);
3069
CHECK_FALSE(code_edit->is_line_folded(1));
3070
code_edit->fold_line(0);
3071
CHECK_FALSE(code_edit->is_line_folded(0));
3072
CHECK_FALSE(code_edit->is_line_folded(1));
3073
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3074
3075
// String.
3076
code_edit->add_string_delimiter("^", "", true);
3077
code_edit->set_text("^line1\n^\tline2");
3078
CHECK(code_edit->can_fold_line(0));
3079
CHECK_FALSE(code_edit->can_fold_line(1));
3080
code_edit->fold_line(1);
3081
CHECK_FALSE(code_edit->is_line_folded(1));
3082
code_edit->fold_line(0);
3083
CHECK(code_edit->is_line_folded(0));
3084
CHECK_FALSE(code_edit->is_line_folded(1));
3085
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3086
3087
// Has to be full line.
3088
code_edit->set_text("test ^line1\n^\tline2");
3089
CHECK_FALSE(code_edit->can_fold_line(0));
3090
CHECK_FALSE(code_edit->can_fold_line(1));
3091
code_edit->fold_line(1);
3092
CHECK_FALSE(code_edit->is_line_folded(1));
3093
code_edit->fold_line(0);
3094
CHECK_FALSE(code_edit->is_line_folded(0));
3095
CHECK_FALSE(code_edit->is_line_folded(1));
3096
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3097
3098
code_edit->set_text("^line1\ntest ^\tline2");
3099
CHECK_FALSE(code_edit->can_fold_line(0));
3100
CHECK_FALSE(code_edit->can_fold_line(1));
3101
code_edit->fold_line(1);
3102
CHECK_FALSE(code_edit->is_line_folded(1));
3103
code_edit->fold_line(0);
3104
CHECK_FALSE(code_edit->is_line_folded(0));
3105
CHECK_FALSE(code_edit->is_line_folded(1));
3106
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3107
3108
// Multiline blocks.
3109
code_edit->add_comment_delimiter("&", "&", false);
3110
code_edit->set_text("&line1\n\tline2&\nline3");
3111
CHECK(code_edit->can_fold_line(0));
3112
CHECK_FALSE(code_edit->can_fold_line(1));
3113
code_edit->fold_line(1);
3114
CHECK_FALSE(code_edit->is_line_folded(1));
3115
code_edit->fold_line(0);
3116
CHECK(code_edit->is_line_folded(0));
3117
CHECK_FALSE(code_edit->is_line_folded(1));
3118
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
3119
3120
// Multiline comment before last line.
3121
code_edit->set_text("&line1\nline2&\ntest");
3122
CHECK(code_edit->can_fold_line(0));
3123
CHECK_FALSE(code_edit->can_fold_line(2));
3124
code_edit->fold_line(1);
3125
CHECK_FALSE(code_edit->is_line_folded(1));
3126
code_edit->fold_line(0);
3127
CHECK(code_edit->is_line_folded(0));
3128
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
3129
3130
// Has to be full line.
3131
code_edit->set_text("test &line1\n\tline2&");
3132
CHECK_FALSE(code_edit->can_fold_line(0));
3133
CHECK_FALSE(code_edit->can_fold_line(1));
3134
code_edit->fold_line(1);
3135
CHECK_FALSE(code_edit->is_line_folded(1));
3136
code_edit->fold_line(0);
3137
CHECK_FALSE(code_edit->is_line_folded(0));
3138
CHECK_FALSE(code_edit->is_line_folded(1));
3139
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3140
3141
code_edit->set_text("&line1\n\tline2& test");
3142
CHECK_FALSE(code_edit->can_fold_line(0));
3143
CHECK_FALSE(code_edit->can_fold_line(1));
3144
code_edit->fold_line(1);
3145
CHECK_FALSE(code_edit->is_line_folded(1));
3146
code_edit->fold_line(0);
3147
CHECK_FALSE(code_edit->is_line_folded(0));
3148
CHECK_FALSE(code_edit->is_line_folded(1));
3149
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3150
3151
// Strings.
3152
code_edit->add_string_delimiter("$", "$", false);
3153
code_edit->set_text("$line1\n\tline2$");
3154
CHECK(code_edit->can_fold_line(0));
3155
CHECK_FALSE(code_edit->can_fold_line(1));
3156
code_edit->fold_line(1);
3157
CHECK_FALSE(code_edit->is_line_folded(1));
3158
code_edit->fold_line(0);
3159
CHECK(code_edit->is_line_folded(0));
3160
CHECK_FALSE(code_edit->is_line_folded(1));
3161
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3162
3163
// Has to be full line.
3164
code_edit->set_text("test $line1\n\tline2$");
3165
CHECK_FALSE(code_edit->can_fold_line(0));
3166
CHECK_FALSE(code_edit->can_fold_line(1));
3167
code_edit->fold_line(1);
3168
CHECK_FALSE(code_edit->is_line_folded(1));
3169
code_edit->fold_line(0);
3170
CHECK_FALSE(code_edit->is_line_folded(0));
3171
CHECK_FALSE(code_edit->is_line_folded(1));
3172
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3173
3174
code_edit->set_text("$line1\n\tline2$ test");
3175
CHECK_FALSE(code_edit->can_fold_line(0));
3176
CHECK_FALSE(code_edit->can_fold_line(1));
3177
code_edit->fold_line(1);
3178
CHECK_FALSE(code_edit->is_line_folded(1));
3179
code_edit->fold_line(0);
3180
CHECK_FALSE(code_edit->is_line_folded(0));
3181
CHECK_FALSE(code_edit->is_line_folded(1));
3182
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 1);
3183
3184
// Non-indented comments/strings.
3185
// Single line
3186
code_edit->set_text("test\n\tline1\n#line1\n#line2\n\ttest");
3187
CHECK(code_edit->can_fold_line(0));
3188
CHECK_FALSE(code_edit->can_fold_line(1));
3189
code_edit->fold_line(1);
3190
CHECK_FALSE(code_edit->is_line_folded(1));
3191
code_edit->fold_line(0);
3192
CHECK(code_edit->is_line_folded(0));
3193
CHECK_FALSE(code_edit->is_line_folded(1));
3194
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
3195
3196
code_edit->set_text("test\n\tline1\n^line1\n^line2\n\ttest");
3197
CHECK(code_edit->can_fold_line(0));
3198
CHECK_FALSE(code_edit->can_fold_line(1));
3199
code_edit->fold_line(1);
3200
CHECK_FALSE(code_edit->is_line_folded(1));
3201
code_edit->fold_line(0);
3202
CHECK(code_edit->is_line_folded(0));
3203
CHECK_FALSE(code_edit->is_line_folded(1));
3204
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
3205
3206
// Indent level 0->1, comment after lines
3207
code_edit->set_text("line1\n\tline2\n#test");
3208
CHECK(code_edit->can_fold_line(0));
3209
CHECK_FALSE(code_edit->can_fold_line(1));
3210
code_edit->fold_line(1);
3211
CHECK_FALSE(code_edit->is_line_folded(1));
3212
code_edit->fold_line(0);
3213
CHECK(code_edit->is_line_folded(0));
3214
CHECK_FALSE(code_edit->is_line_folded(1));
3215
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
3216
3217
// Indent level 0->1, comment between lines
3218
code_edit->set_text("line1\n#test\n\tline2\nline3");
3219
CHECK(code_edit->can_fold_line(0));
3220
CHECK_FALSE(code_edit->can_fold_line(2));
3221
code_edit->fold_line(2);
3222
CHECK_FALSE(code_edit->is_line_folded(2));
3223
code_edit->fold_line(0);
3224
CHECK(code_edit->is_line_folded(0));
3225
CHECK_FALSE(code_edit->is_line_folded(2));
3226
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
3227
3228
// Indent level 1->2, comment after lines
3229
code_edit->set_text("\tline1\n\t\tline2\n#test");
3230
CHECK(code_edit->can_fold_line(0));
3231
CHECK_FALSE(code_edit->can_fold_line(1));
3232
code_edit->fold_line(1);
3233
CHECK_FALSE(code_edit->is_line_folded(1));
3234
code_edit->fold_line(0);
3235
CHECK(code_edit->is_line_folded(0));
3236
CHECK_FALSE(code_edit->is_line_folded(1));
3237
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 2);
3238
3239
// Indent level 1->2, comment between lines
3240
code_edit->set_text("\tline1\n#test\n\t\tline2\nline3");
3241
CHECK(code_edit->can_fold_line(0));
3242
CHECK_FALSE(code_edit->can_fold_line(2));
3243
code_edit->fold_line(2);
3244
CHECK_FALSE(code_edit->is_line_folded(2));
3245
code_edit->fold_line(0);
3246
CHECK(code_edit->is_line_folded(0));
3247
CHECK_FALSE(code_edit->is_line_folded(2));
3248
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 3);
3249
3250
// Multiline
3251
code_edit->set_text("test\n\tline1\n&line1\nline2&\n\ttest");
3252
CHECK(code_edit->can_fold_line(0));
3253
CHECK_FALSE(code_edit->can_fold_line(1));
3254
code_edit->fold_line(1);
3255
CHECK_FALSE(code_edit->is_line_folded(1));
3256
code_edit->fold_line(0);
3257
CHECK(code_edit->is_line_folded(0));
3258
CHECK_FALSE(code_edit->is_line_folded(1));
3259
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
3260
3261
code_edit->set_text("test\n\tline1\n$line1\nline2$\n\ttest");
3262
CHECK(code_edit->can_fold_line(0));
3263
CHECK_FALSE(code_edit->can_fold_line(1));
3264
code_edit->fold_line(1);
3265
CHECK_FALSE(code_edit->is_line_folded(1));
3266
code_edit->fold_line(0);
3267
CHECK(code_edit->is_line_folded(0));
3268
CHECK_FALSE(code_edit->is_line_folded(1));
3269
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
3270
}
3271
3272
SUBCASE("[CodeEdit] folding comments including and/or adjacent to code regions") {
3273
code_edit->add_comment_delimiter("#", "", true);
3274
3275
// Single line comment directly above a code region tag is not foldable.
3276
code_edit->set_text("#line0\n#region a\nnothing\n#line3\n#endregion");
3277
CHECK_FALSE(code_edit->can_fold_line(0));
3278
CHECK_FALSE(code_edit->can_fold_line(3));
3279
3280
// Comment blocks.
3281
// Foldable even when directly below a code region start tag.
3282
code_edit->set_text("#line0\n#line1\n#region a\n#line3\n#line4\nnothing\n#endregion");
3283
CHECK(code_edit->can_fold_line(3));
3284
3285
// Doesn't fold beyond region start tag.
3286
code_edit->fold_line(0);
3287
CHECK(code_edit->is_line_folded(0));
3288
CHECK_EQ(code_edit->get_visible_line_count_in_range(0, 1), 1);
3289
CHECK_EQ(code_edit->get_visible_line_count_in_range(2, 2), 1);
3290
3291
// Foldable even when directly below a code region end tag.
3292
code_edit->set_text("#region a\nnothing\n#line2\n#line3\n#endregion\n#line5\n#line6");
3293
CHECK(code_edit->can_fold_line(5));
3294
3295
// Doesn't fold beyond region end tag.
3296
code_edit->fold_line(2);
3297
CHECK(code_edit->is_line_folded(2));
3298
CHECK_EQ(code_edit->get_visible_line_count_in_range(2, 3), 1);
3299
CHECK_EQ(code_edit->get_visible_line_count_in_range(4, 4), 1);
3300
3301
code_edit->add_comment_delimiter("/*", "*/", false);
3302
3303
// Multiline comments.
3304
// Folds a region tag inside it.
3305
code_edit->set_text("/*\nnothing\n#region a\n*/\n#endregion");
3306
CHECK(code_edit->can_fold_line(0));
3307
code_edit->fold_line(0);
3308
CHECK(code_edit->is_line_folded(0));
3309
CHECK_EQ(code_edit->get_visible_line_count_in_range(0, 3), 1);
3310
CHECK_EQ(code_edit->get_visible_line_count_in_range(4, 4), 1);
3311
}
3312
3313
SUBCASE("[CodeEdit] folding carets") {
3314
// Folding a line moves all carets that would be hidden.
3315
code_edit->set_text("test\n\tline1\n\t\tline 2\n");
3316
code_edit->set_caret_line(1);
3317
code_edit->set_caret_column(0);
3318
code_edit->add_caret(1, 3);
3319
code_edit->add_caret(2, 8);
3320
code_edit->add_caret(2, 1);
3321
code_edit->select(2, 0, 2, 1, 3);
3322
3323
code_edit->fold_line(0);
3324
CHECK(code_edit->is_line_folded(0));
3325
CHECK_FALSE(code_edit->is_line_folded(1));
3326
CHECK(code_edit->get_caret_count() == 1);
3327
CHECK_FALSE(code_edit->has_selection());
3328
CHECK(code_edit->get_caret_line() == 0);
3329
CHECK(code_edit->get_caret_column() == 4);
3330
3331
// Undoing an action that puts the caret on a folded line unfolds it.
3332
code_edit->set_text("test\n\tline1");
3333
code_edit->select(1, 1, 1, 2);
3334
code_edit->duplicate_selection();
3335
CHECK(code_edit->get_text() == "test\n\tlline1");
3336
CHECK(code_edit->has_selection());
3337
CHECK(code_edit->get_caret_line() == 1);
3338
CHECK(code_edit->get_caret_column() == 3);
3339
CHECK(code_edit->get_selection_origin_line() == 1);
3340
CHECK(code_edit->get_selection_origin_column() == 2);
3341
code_edit->fold_line(0);
3342
CHECK(code_edit->is_line_folded(0));
3343
CHECK_FALSE(code_edit->is_line_folded(1));
3344
CHECK_FALSE(code_edit->has_selection());
3345
CHECK(code_edit->get_caret_line() == 0);
3346
CHECK(code_edit->get_caret_column() == 4);
3347
3348
code_edit->undo();
3349
CHECK(code_edit->get_text() == "test\n\tline1");
3350
CHECK(code_edit->has_selection());
3351
CHECK(code_edit->get_caret_line() == 1);
3352
CHECK(code_edit->get_caret_column() == 2);
3353
CHECK(code_edit->get_selection_origin_line() == 1);
3354
CHECK(code_edit->get_selection_origin_column() == 1);
3355
CHECK_FALSE(code_edit->is_line_folded(0));
3356
CHECK_FALSE(code_edit->is_line_folded(1));
3357
3358
// Redoing doesn't refold.
3359
code_edit->redo();
3360
CHECK(code_edit->has_selection());
3361
CHECK(code_edit->get_caret_line() == 1);
3362
CHECK(code_edit->get_caret_column() == 3);
3363
CHECK(code_edit->get_selection_origin_line() == 1);
3364
CHECK(code_edit->get_selection_origin_column() == 2);
3365
CHECK_FALSE(code_edit->is_line_folded(0));
3366
CHECK_FALSE(code_edit->is_line_folded(1));
3367
}
3368
3369
SUBCASE("[CodeEdit] actions unfold") {
3370
// add_selection_for_next_occurrence unfolds.
3371
code_edit->set_text("test\n\tline1 test\n\t\tline 2\ntest2");
3372
code_edit->select(0, 0, 0, 4);
3373
code_edit->fold_line(0);
3374
CHECK(code_edit->is_line_folded(0));
3375
code_edit->add_selection_for_next_occurrence();
3376
3377
CHECK(code_edit->get_caret_count() == 2);
3378
CHECK(code_edit->has_selection(0));
3379
CHECK(code_edit->get_caret_line() == 0);
3380
CHECK(code_edit->get_selection_origin_line() == 0);
3381
CHECK(code_edit->get_caret_column() == 4);
3382
CHECK(code_edit->get_selection_origin_column() == 0);
3383
CHECK(code_edit->has_selection(1));
3384
CHECK(code_edit->get_caret_line(1) == 1);
3385
CHECK(code_edit->get_selection_origin_line(1) == 1);
3386
CHECK(code_edit->get_caret_column(1) == 11);
3387
CHECK(code_edit->get_selection_origin_column(1) == 7);
3388
CHECK_FALSE(code_edit->is_line_folded(0));
3389
code_edit->remove_secondary_carets();
3390
3391
// skip_selection_for_next_occurrence unfolds.
3392
code_edit->select(0, 0, 0, 4);
3393
code_edit->fold_line(0);
3394
CHECK(code_edit->is_line_folded(0));
3395
code_edit->skip_selection_for_next_occurrence();
3396
3397
CHECK(code_edit->get_caret_count() == 1);
3398
CHECK(code_edit->has_selection(0));
3399
CHECK(code_edit->get_caret_line() == 1);
3400
CHECK(code_edit->get_selection_origin_line() == 1);
3401
CHECK(code_edit->get_caret_column() == 11);
3402
CHECK(code_edit->get_selection_origin_column() == 7);
3403
CHECK_FALSE(code_edit->is_line_folded(0));
3404
code_edit->remove_secondary_carets();
3405
code_edit->deselect();
3406
}
3407
3408
SUBCASE("[CodeEdit] toggle folding carets") {
3409
code_edit->set_text("test\n\tline1\ntest2\n\tline2");
3410
3411
// Fold lines with carets on them.
3412
code_edit->set_caret_line(0);
3413
code_edit->set_caret_column(1);
3414
code_edit->toggle_foldable_lines_at_carets();
3415
CHECK(code_edit->is_line_folded(0));
3416
CHECK_FALSE(code_edit->is_line_folded(2));
3417
3418
// Toggle fold on lines with carets.
3419
code_edit->add_caret(2, 0);
3420
code_edit->toggle_foldable_lines_at_carets();
3421
CHECK_FALSE(code_edit->is_line_folded(0));
3422
CHECK(code_edit->is_line_folded(2));
3423
CHECK(code_edit->get_caret_count() == 2);
3424
CHECK(code_edit->get_caret_line(0) == 0);
3425
CHECK(code_edit->get_caret_column(0) == 1);
3426
CHECK(code_edit->get_caret_line(1) == 2);
3427
CHECK(code_edit->get_caret_column(1) == 0);
3428
3429
// Multiple carets as part of one fold.
3430
code_edit->unfold_all_lines();
3431
code_edit->remove_secondary_carets();
3432
code_edit->set_caret_line(0);
3433
code_edit->set_caret_column(1);
3434
code_edit->add_caret(0, 4);
3435
code_edit->add_caret(1, 2);
3436
code_edit->toggle_foldable_lines_at_carets();
3437
CHECK(code_edit->is_line_folded(0));
3438
CHECK_FALSE(code_edit->is_line_folded(2));
3439
CHECK(code_edit->get_caret_count() == 2);
3440
CHECK(code_edit->get_caret_line(0) == 0);
3441
CHECK(code_edit->get_caret_column(0) == 1);
3442
CHECK(code_edit->get_caret_line(1) == 0);
3443
CHECK(code_edit->get_caret_column(1) == 4);
3444
}
3445
3446
memdelete(code_edit);
3447
}
3448
3449
TEST_CASE("[SceneTree][CodeEdit] region folding") {
3450
CodeEdit *code_edit = memnew(CodeEdit);
3451
SceneTree::get_singleton()->get_root()->add_child(code_edit);
3452
code_edit->grab_focus();
3453
3454
SUBCASE("[CodeEdit] region tags") {
3455
code_edit->set_line_folding_enabled(true);
3456
3457
// Region tag detection.
3458
code_edit->set_text("#region region_name\nline2\n#endregion");
3459
code_edit->clear_comment_delimiters();
3460
code_edit->add_comment_delimiter("#", "");
3461
CHECK(code_edit->is_line_code_region_start(0));
3462
CHECK_FALSE(code_edit->is_line_code_region_start(1));
3463
CHECK_FALSE(code_edit->is_line_code_region_start(2));
3464
CHECK_FALSE(code_edit->is_line_code_region_end(0));
3465
CHECK_FALSE(code_edit->is_line_code_region_end(1));
3466
CHECK(code_edit->is_line_code_region_end(2));
3467
3468
// Region tag customization.
3469
code_edit->set_text("#region region_name\nline2\n#endregion\n#open region_name\nline2\n#close");
3470
code_edit->clear_comment_delimiters();
3471
code_edit->add_comment_delimiter("#", "");
3472
CHECK(code_edit->is_line_code_region_start(0));
3473
CHECK(code_edit->is_line_code_region_end(2));
3474
CHECK_FALSE(code_edit->is_line_code_region_start(3));
3475
CHECK_FALSE(code_edit->is_line_code_region_end(5));
3476
code_edit->set_code_region_tags("open", "close");
3477
CHECK_FALSE(code_edit->is_line_code_region_start(0));
3478
CHECK_FALSE(code_edit->is_line_code_region_end(2));
3479
CHECK(code_edit->is_line_code_region_start(3));
3480
CHECK(code_edit->is_line_code_region_end(5));
3481
code_edit->set_code_region_tags("region", "endregion");
3482
3483
// Setting identical start and end region tags should fail.
3484
CHECK(code_edit->get_code_region_start_tag() == "region");
3485
CHECK(code_edit->get_code_region_end_tag() == "endregion");
3486
ERR_PRINT_OFF;
3487
code_edit->set_code_region_tags("same_tag", "same_tag");
3488
ERR_PRINT_ON;
3489
CHECK(code_edit->get_code_region_start_tag() == "region");
3490
CHECK(code_edit->get_code_region_end_tag() == "endregion");
3491
}
3492
3493
SUBCASE("[CodeEdit] create code region") {
3494
code_edit->set_line_folding_enabled(true);
3495
3496
// Region creation with selection adds start and close region lines. Region name is selected and the region is folded.
3497
code_edit->set_text("line1\nline2\nline3");
3498
code_edit->clear_comment_delimiters();
3499
code_edit->add_comment_delimiter("#", "");
3500
code_edit->select(1, 0, 1, 4);
3501
code_edit->create_code_region();
3502
CHECK(code_edit->is_line_code_region_start(1));
3503
CHECK(code_edit->is_line_code_region_end(3));
3504
CHECK(code_edit->get_text() == "line1\n#region New Code Region\nline2\n#endregion\nline3");
3505
CHECK(code_edit->get_caret_count() == 1);
3506
CHECK(code_edit->has_selection());
3507
CHECK(code_edit->get_selected_text() == "New Code Region");
3508
CHECK(code_edit->get_caret_line() == 1);
3509
CHECK(code_edit->get_caret_column() == 23);
3510
CHECK(code_edit->get_selection_origin_line() == 1);
3511
CHECK(code_edit->get_selection_origin_column() == 8);
3512
CHECK(code_edit->is_line_folded(1));
3513
3514
// Undo region creation. Line get unfolded.
3515
code_edit->undo();
3516
CHECK(code_edit->get_text() == "line1\nline2\nline3");
3517
CHECK(code_edit->get_caret_count() == 1);
3518
CHECK(code_edit->has_selection());
3519
CHECK(code_edit->get_caret_line() == 1);
3520
CHECK(code_edit->get_caret_column() == 4);
3521
CHECK(code_edit->get_selection_origin_line() == 1);
3522
CHECK(code_edit->get_selection_origin_column() == 0);
3523
CHECK_FALSE(code_edit->is_line_folded(1));
3524
3525
// Redo region creation.
3526
code_edit->redo();
3527
CHECK(code_edit->get_text() == "line1\n#region New Code Region\nline2\n#endregion\nline3");
3528
CHECK(code_edit->get_caret_count() == 1);
3529
CHECK(code_edit->has_selection());
3530
CHECK(code_edit->get_selected_text() == "New Code Region");
3531
CHECK(code_edit->get_caret_line() == 1);
3532
CHECK(code_edit->get_caret_column() == 23);
3533
CHECK(code_edit->get_selection_origin_line() == 1);
3534
CHECK(code_edit->get_selection_origin_column() == 8);
3535
CHECK_FALSE(code_edit->is_line_folded(1));
3536
3537
// Region creation without any selection has no effect.
3538
code_edit->set_text("line1\nline2\nline3");
3539
code_edit->clear_comment_delimiters();
3540
code_edit->add_comment_delimiter("#", "");
3541
code_edit->create_code_region();
3542
CHECK(code_edit->get_text() == "line1\nline2\nline3");
3543
3544
// Region creation with multiple selections. Secondary carets are removed and the first region name is selected.
3545
code_edit->set_text("line1\nline2\nline3");
3546
code_edit->clear_comment_delimiters();
3547
code_edit->add_comment_delimiter("#", "");
3548
code_edit->select(0, 0, 0, 4, 0);
3549
code_edit->add_caret(2, 5);
3550
code_edit->select(2, 0, 2, 5, 1);
3551
code_edit->create_code_region();
3552
CHECK(code_edit->get_text() == "#region New Code Region\nline1\n#endregion\nline2\n#region New Code Region\nline3\n#endregion");
3553
CHECK(code_edit->get_caret_count() == 1);
3554
CHECK(code_edit->has_selection());
3555
CHECK(code_edit->get_selected_text() == "New Code Region");
3556
CHECK(code_edit->get_caret_line() == 0);
3557
CHECK(code_edit->get_caret_column() == 23);
3558
CHECK(code_edit->get_selection_origin_line() == 0);
3559
CHECK(code_edit->get_selection_origin_column() == 8);
3560
3561
// Region creation with mixed selection and non-selection carets. Regular carets are ignored.
3562
code_edit->set_text("line1\nline2\nline3");
3563
code_edit->clear_comment_delimiters();
3564
code_edit->add_comment_delimiter("#", "");
3565
code_edit->select(0, 0, 0, 4, 0);
3566
code_edit->add_caret(2, 5);
3567
code_edit->create_code_region();
3568
CHECK(code_edit->get_text() == "#region New Code Region\nline1\n#endregion\nline2\nline3");
3569
CHECK(code_edit->get_caret_count() == 1);
3570
CHECK(code_edit->has_selection());
3571
CHECK(code_edit->get_selected_text() == "New Code Region");
3572
3573
// Two selections on the same line create only one region.
3574
code_edit->set_text("test line1\ntest line2\ntest line3");
3575
code_edit->clear_comment_delimiters();
3576
code_edit->add_comment_delimiter("#", "");
3577
code_edit->select(0, 0, 1, 2, 0);
3578
code_edit->add_caret(1, 4);
3579
code_edit->select(1, 4, 2, 5, 1);
3580
code_edit->create_code_region();
3581
CHECK(code_edit->get_text() == "#region New Code Region\ntest line1\ntest line2\ntest line3\n#endregion");
3582
3583
// Region tag with // comment delimiter.
3584
code_edit->set_text("//region region_name\nline2\n//endregion");
3585
code_edit->clear_comment_delimiters();
3586
code_edit->add_comment_delimiter("//", "");
3587
CHECK(code_edit->is_line_code_region_start(0));
3588
CHECK(code_edit->is_line_code_region_end(2));
3589
3590
// Creating region with no valid one line comment delimiter has no effect.
3591
code_edit->set_text("line1\nline2\nline3");
3592
code_edit->clear_comment_delimiters();
3593
code_edit->create_code_region();
3594
CHECK(code_edit->get_text() == "line1\nline2\nline3");
3595
code_edit->add_comment_delimiter("/*", "*/");
3596
code_edit->create_code_region();
3597
CHECK(code_edit->get_text() == "line1\nline2\nline3");
3598
}
3599
3600
SUBCASE("[CodeEdit] region comment delimiters") {
3601
code_edit->set_line_folding_enabled(true);
3602
3603
// Choose one line comment delimiter.
3604
code_edit->set_text("//region region_name\nline2\n//endregion");
3605
code_edit->clear_comment_delimiters();
3606
code_edit->add_comment_delimiter("/*", "*/");
3607
code_edit->add_comment_delimiter("//", "");
3608
CHECK(code_edit->is_line_code_region_start(0));
3609
CHECK(code_edit->is_line_code_region_end(2));
3610
3611
// Update code region delimiter when removing comment delimiter.
3612
code_edit->set_text("#region region_name\nline2\n#endregion\n//region region_name\nline2\n//endregion");
3613
code_edit->clear_comment_delimiters();
3614
code_edit->add_comment_delimiter("//", "");
3615
code_edit->add_comment_delimiter("#", ""); // A shorter delimiter has higher priority.
3616
CHECK(code_edit->is_line_code_region_start(0));
3617
CHECK(code_edit->is_line_code_region_end(2));
3618
CHECK_FALSE(code_edit->is_line_code_region_start(3));
3619
CHECK_FALSE(code_edit->is_line_code_region_end(5));
3620
code_edit->remove_comment_delimiter("#");
3621
CHECK_FALSE(code_edit->is_line_code_region_start(0));
3622
CHECK_FALSE(code_edit->is_line_code_region_end(2));
3623
CHECK(code_edit->is_line_code_region_start(3));
3624
CHECK(code_edit->is_line_code_region_end(5));
3625
3626
// Update code region delimiter when clearing comment delimiters.
3627
code_edit->set_text("//region region_name\nline2\n//endregion");
3628
code_edit->clear_comment_delimiters();
3629
code_edit->add_comment_delimiter("//", "");
3630
CHECK(code_edit->is_line_code_region_start(0));
3631
CHECK(code_edit->is_line_code_region_end(2));
3632
code_edit->clear_comment_delimiters();
3633
CHECK_FALSE(code_edit->is_line_code_region_start(0));
3634
CHECK_FALSE(code_edit->is_line_code_region_end(2));
3635
}
3636
3637
SUBCASE("[CodeEdit] fold region") {
3638
code_edit->set_line_folding_enabled(true);
3639
3640
// Fold region.
3641
code_edit->clear_comment_delimiters();
3642
code_edit->add_comment_delimiter("#", "");
3643
code_edit->set_text("#region region_name\nline2\nline3\n#endregion\nvisible line");
3644
CHECK(code_edit->can_fold_line(0));
3645
for (int i = 1; i < 5; i++) {
3646
CHECK_FALSE(code_edit->can_fold_line(i));
3647
}
3648
for (int i = 0; i < 5; i++) {
3649
CHECK_FALSE(code_edit->is_line_folded(i));
3650
}
3651
code_edit->fold_line(0);
3652
CHECK(code_edit->is_line_folded(0));
3653
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
3654
3655
// Region with no end can't be folded.
3656
ERR_PRINT_OFF;
3657
code_edit->clear_comment_delimiters();
3658
code_edit->add_comment_delimiter("#", "");
3659
code_edit->set_text("#region region_name\nline2\nline3\n#bad_end_tag\nvisible line");
3660
CHECK_FALSE(code_edit->can_fold_line(0));
3661
ERR_PRINT_ON;
3662
3663
// Bad nested region can't be folded.
3664
ERR_PRINT_OFF;
3665
code_edit->clear_comment_delimiters();
3666
code_edit->add_comment_delimiter("#", "");
3667
code_edit->set_text("#region without end\n#region region2\nline3\n#endregion\n#no_end");
3668
CHECK_FALSE(code_edit->can_fold_line(0));
3669
CHECK(code_edit->can_fold_line(1));
3670
ERR_PRINT_ON;
3671
3672
// Nested region folding.
3673
ERR_PRINT_OFF;
3674
code_edit->clear_comment_delimiters();
3675
code_edit->add_comment_delimiter("#", "");
3676
code_edit->set_text("#region region1\n#region region2\nline3\n#endregion\n#endregion");
3677
CHECK(code_edit->can_fold_line(0));
3678
CHECK(code_edit->can_fold_line(1));
3679
code_edit->fold_line(1);
3680
CHECK(code_edit->get_next_visible_line_offset_from(2, 1) == 3);
3681
code_edit->fold_line(0);
3682
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
3683
ERR_PRINT_ON;
3684
3685
// Unfolding a line inside a region unfold whole region.
3686
code_edit->clear_comment_delimiters();
3687
code_edit->add_comment_delimiter("#", "");
3688
code_edit->set_text("#region region\ninside\nline3\n#endregion\nvisible");
3689
code_edit->fold_line(0);
3690
CHECK(code_edit->is_line_folded(0));
3691
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 4);
3692
code_edit->unfold_line(1);
3693
CHECK_FALSE(code_edit->is_line_folded(0));
3694
3695
// Region start and end tags are ignored if in a string and at the start of the line.
3696
code_edit->clear_comment_delimiters();
3697
code_edit->add_comment_delimiter("#", "");
3698
code_edit->clear_string_delimiters();
3699
code_edit->add_string_delimiter("\"", "\"");
3700
code_edit->set_text("#region region_name1\nline2\n\"\n#region region_name2\n#endregion\n\"\n#endregion\nvisible");
3701
CHECK(code_edit->is_line_code_region_start(0));
3702
CHECK(code_edit->is_line_code_region_end(6));
3703
CHECK(code_edit->can_fold_line(0));
3704
for (int i = 1; i < 7; i++) {
3705
if (i == 2) {
3706
continue;
3707
}
3708
CHECK_FALSE(code_edit->can_fold_line(i));
3709
}
3710
for (int i = 0; i < 7; i++) {
3711
CHECK_FALSE(code_edit->is_line_folded(i));
3712
}
3713
code_edit->fold_line(0);
3714
CHECK(code_edit->is_line_folded(0));
3715
CHECK(code_edit->get_next_visible_line_offset_from(1, 1) == 7);
3716
}
3717
3718
memdelete(code_edit);
3719
}
3720
3721
TEST_CASE("[SceneTree][CodeEdit] completion") {
3722
CodeEdit *code_edit = memnew(CodeEdit);
3723
SceneTree::get_singleton()->get_root()->add_child(code_edit);
3724
code_edit->grab_focus();
3725
3726
SUBCASE("[CodeEdit] auto brace completion") {
3727
code_edit->set_auto_brace_completion_enabled(true);
3728
CHECK(code_edit->is_auto_brace_completion_enabled());
3729
3730
code_edit->set_highlight_matching_braces_enabled(true);
3731
CHECK(code_edit->is_highlight_matching_braces_enabled());
3732
3733
/* Try setters, any length. */
3734
Dictionary auto_brace_completion_pairs;
3735
auto_brace_completion_pairs["["] = "]";
3736
auto_brace_completion_pairs["'"] = "'";
3737
auto_brace_completion_pairs[";"] = "'";
3738
auto_brace_completion_pairs["'''"] = "'''";
3739
code_edit->set_auto_brace_completion_pairs(auto_brace_completion_pairs);
3740
CHECK(code_edit->get_auto_brace_completion_pairs().size() == 4);
3741
CHECK(code_edit->get_auto_brace_completion_pairs()["["] == "]");
3742
CHECK(code_edit->get_auto_brace_completion_pairs()["'"] == "'");
3743
CHECK(code_edit->get_auto_brace_completion_pairs()[";"] == "'");
3744
CHECK(code_edit->get_auto_brace_completion_pairs()["'''"] == "'''");
3745
3746
ERR_PRINT_OFF;
3747
3748
/* No duplicate start keys. */
3749
code_edit->add_auto_brace_completion_pair("[", "]");
3750
CHECK(code_edit->get_auto_brace_completion_pairs().size() == 4);
3751
3752
/* No empty keys. */
3753
code_edit->add_auto_brace_completion_pair("[", "");
3754
CHECK(code_edit->get_auto_brace_completion_pairs().size() == 4);
3755
3756
code_edit->add_auto_brace_completion_pair("", "]");
3757
CHECK(code_edit->get_auto_brace_completion_pairs().size() == 4);
3758
3759
code_edit->add_auto_brace_completion_pair("", "");
3760
CHECK(code_edit->get_auto_brace_completion_pairs().size() == 4);
3761
3762
/* Must be a symbol. */
3763
code_edit->add_auto_brace_completion_pair("a", "]");
3764
CHECK(code_edit->get_auto_brace_completion_pairs().size() == 4);
3765
3766
code_edit->add_auto_brace_completion_pair("[", "a");
3767
CHECK(code_edit->get_auto_brace_completion_pairs().size() == 4);
3768
3769
code_edit->add_auto_brace_completion_pair("a", "a");
3770
CHECK(code_edit->get_auto_brace_completion_pairs().size() == 4);
3771
3772
ERR_PRINT_ON;
3773
3774
/* Check metadata. */
3775
CHECK(code_edit->has_auto_brace_completion_open_key("["));
3776
CHECK(code_edit->has_auto_brace_completion_open_key("'"));
3777
CHECK(code_edit->has_auto_brace_completion_open_key(";"));
3778
CHECK(code_edit->has_auto_brace_completion_open_key("'''"));
3779
CHECK_FALSE(code_edit->has_auto_brace_completion_open_key("("));
3780
3781
CHECK(code_edit->has_auto_brace_completion_close_key("]"));
3782
CHECK(code_edit->has_auto_brace_completion_close_key("'"));
3783
CHECK(code_edit->has_auto_brace_completion_close_key("'''"));
3784
CHECK_FALSE(code_edit->has_auto_brace_completion_close_key(")"));
3785
3786
CHECK(code_edit->get_auto_brace_completion_close_key("[") == "]");
3787
CHECK(code_edit->get_auto_brace_completion_close_key("'") == "'");
3788
CHECK(code_edit->get_auto_brace_completion_close_key(";") == "'");
3789
CHECK(code_edit->get_auto_brace_completion_close_key("'''") == "'''");
3790
CHECK(code_edit->get_auto_brace_completion_close_key("(").is_empty());
3791
3792
/* Check typing inserts closing pair. */
3793
code_edit->clear();
3794
SEND_GUI_KEY_EVENT(Key::BRACKETLEFT);
3795
CHECK(code_edit->get_line(0) == "[]");
3796
3797
/* Should first match and insert smaller key. */
3798
code_edit->clear();
3799
SEND_GUI_KEY_EVENT(Key::APOSTROPHE);
3800
CHECK(code_edit->get_line(0) == "''");
3801
CHECK(code_edit->get_caret_column() == 1);
3802
3803
/* Move out from center, Should match and insert larger key. */
3804
SEND_GUI_ACTION("ui_text_caret_right");
3805
SEND_GUI_KEY_EVENT(Key::APOSTROPHE);
3806
CHECK(code_edit->get_line(0) == "''''''");
3807
CHECK(code_edit->get_caret_column() == 3);
3808
3809
/* Backspace should remove all. */
3810
SEND_GUI_ACTION("ui_text_backspace");
3811
CHECK(code_edit->get_line(0).is_empty());
3812
3813
/* If in between and typing close key should "skip". */
3814
SEND_GUI_KEY_EVENT(Key::BRACKETLEFT);
3815
CHECK(code_edit->get_line(0) == "[]");
3816
CHECK(code_edit->get_caret_column() == 1);
3817
SEND_GUI_KEY_EVENT(Key::BRACKETRIGHT);
3818
CHECK(code_edit->get_line(0) == "[]");
3819
CHECK(code_edit->get_caret_column() == 2);
3820
3821
/* If current is char and inserting a string, do not autocomplete. */
3822
code_edit->clear();
3823
SEND_GUI_KEY_EVENT(Key::A);
3824
SEND_GUI_KEY_EVENT(Key::APOSTROPHE);
3825
CHECK(code_edit->get_line(0) == "A'");
3826
3827
/* If in comment, do not complete. */
3828
code_edit->add_comment_delimiter("#", "");
3829
code_edit->clear();
3830
SEND_GUI_KEY_EVENT(Key::NUMBERSIGN);
3831
SEND_GUI_KEY_EVENT(Key::APOSTROPHE);
3832
CHECK(code_edit->get_line(0) == "#'");
3833
3834
/* If in string, and inserting string do not complete. */
3835
code_edit->clear();
3836
SEND_GUI_KEY_EVENT(Key::APOSTROPHE);
3837
SEND_GUI_KEY_EVENT(Key::QUOTEDBL);
3838
CHECK(code_edit->get_line(0) == "'\"'");
3839
3840
/* Wrap single line selection with brackets */
3841
code_edit->clear();
3842
code_edit->insert_text_at_caret("abc");
3843
code_edit->select_all();
3844
SEND_GUI_KEY_EVENT(Key::BRACKETLEFT);
3845
CHECK(code_edit->get_line(0) == "[abc]");
3846
3847
/* Caret should be after the last character of the single line selection */
3848
CHECK(code_edit->get_caret_column() == 4);
3849
3850
/* Wrap multi line selection with brackets */
3851
code_edit->clear();
3852
code_edit->insert_text_at_caret("abc\nabc");
3853
code_edit->select_all();
3854
SEND_GUI_KEY_EVENT(Key::BRACKETLEFT);
3855
CHECK(code_edit->get_text() == "[abc\nabc]");
3856
3857
/* Caret should be after the last character of the multi line selection */
3858
CHECK(code_edit->get_caret_line() == 1);
3859
CHECK(code_edit->get_caret_column() == 3);
3860
3861
/* If inserted character is not a auto brace completion open key, replace selected text with the inserted character */
3862
code_edit->clear();
3863
code_edit->insert_text_at_caret("abc");
3864
code_edit->select_all();
3865
SEND_GUI_KEY_EVENT(Key::KEY_1);
3866
CHECK(code_edit->get_text() == "1");
3867
3868
/* If potential multichar and single brace completion is matched, it should wrap the single. */
3869
code_edit->clear();
3870
code_edit->insert_text_at_caret("\'\'abc");
3871
code_edit->select(0, 2, 0, 5);
3872
SEND_GUI_KEY_EVENT(Key::APOSTROPHE);
3873
CHECK(code_edit->get_text() == "\'\'\'abc\'");
3874
3875
/* If only the potential multichar brace completion is matched, it does not wrap or complete. */
3876
auto_brace_completion_pairs.erase("\'");
3877
code_edit->set_auto_brace_completion_pairs(auto_brace_completion_pairs);
3878
CHECK_FALSE(code_edit->has_auto_brace_completion_open_key("\'"));
3879
3880
code_edit->clear();
3881
code_edit->insert_text_at_caret("\'\'abc");
3882
code_edit->select(0, 2, 0, 5);
3883
SEND_GUI_KEY_EVENT(Key::APOSTROPHE);
3884
CHECK(code_edit->get_text() == "\'\'\'");
3885
}
3886
3887
SUBCASE("[CodeEdit] autocomplete with brace completion") {
3888
code_edit->set_auto_brace_completion_enabled(true);
3889
CHECK(code_edit->is_auto_brace_completion_enabled());
3890
3891
code_edit->insert_text_at_caret("(te)");
3892
code_edit->set_caret_column(3);
3893
3894
// Full completion.
3895
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_FUNCTION, "test()", "test()");
3896
code_edit->update_code_completion_options();
3897
code_edit->confirm_code_completion();
3898
CHECK(code_edit->get_line(0) == "(test())");
3899
CHECK(code_edit->get_caret_column() == 7);
3900
code_edit->undo();
3901
3902
// With "arg".
3903
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_FUNCTION, "test(", "test(");
3904
code_edit->update_code_completion_options();
3905
code_edit->confirm_code_completion();
3906
CHECK(code_edit->get_line(0) == "(test())");
3907
CHECK(code_edit->get_caret_column() == 6);
3908
code_edit->undo();
3909
3910
// brace completion disabled
3911
code_edit->set_auto_brace_completion_enabled(false);
3912
3913
// Full completion.
3914
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_FUNCTION, "test()", "test()");
3915
code_edit->update_code_completion_options();
3916
code_edit->confirm_code_completion();
3917
CHECK(code_edit->get_line(0) == "(test())");
3918
CHECK(code_edit->get_caret_column() == 7);
3919
code_edit->undo();
3920
3921
// With "arg".
3922
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_FUNCTION, "test(", "test(");
3923
code_edit->update_code_completion_options();
3924
code_edit->confirm_code_completion();
3925
CHECK(code_edit->get_line(0) == "(test()");
3926
CHECK(code_edit->get_caret_column() == 6);
3927
3928
// String
3929
code_edit->set_auto_brace_completion_enabled(true);
3930
code_edit->clear();
3931
code_edit->insert_text_at_caret("\"\"");
3932
code_edit->set_caret_column(1);
3933
3934
// Full completion.
3935
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_NODE_PATH, "\"test\"", "\"test\"");
3936
code_edit->update_code_completion_options();
3937
code_edit->confirm_code_completion();
3938
CHECK(code_edit->get_line(0) == "\"test\"");
3939
CHECK(code_edit->get_caret_column() == 6);
3940
code_edit->undo();
3941
3942
// With "arg".
3943
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_NODE_PATH, "\"test", "\"test");
3944
code_edit->update_code_completion_options();
3945
code_edit->confirm_code_completion();
3946
CHECK(code_edit->get_line(0) == "\"\"test\"");
3947
CHECK(code_edit->get_caret_column() == 7);
3948
code_edit->undo();
3949
3950
// brace completion disabled
3951
code_edit->set_auto_brace_completion_enabled(false);
3952
3953
// Full completion.
3954
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_NODE_PATH, "\"test\"", "\"test\"");
3955
code_edit->update_code_completion_options();
3956
code_edit->confirm_code_completion();
3957
CHECK(code_edit->get_line(0) == "\"test\"");
3958
CHECK(code_edit->get_caret_column() == 6);
3959
code_edit->undo();
3960
3961
// With "arg".
3962
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_NODE_PATH, "\"test", "\"test");
3963
code_edit->update_code_completion_options();
3964
code_edit->confirm_code_completion();
3965
CHECK(code_edit->get_line(0) == "\"\"test\"");
3966
CHECK(code_edit->get_caret_column() == 7);
3967
code_edit->undo();
3968
}
3969
3970
SUBCASE("[CodeEdit] autocomplete") {
3971
code_edit->set_code_completion_enabled(true);
3972
CHECK(code_edit->is_code_completion_enabled());
3973
3974
/* Set prefixes, single char only, disallow empty. */
3975
TypedArray<String> completion_prefixes = { "", ".", ".", ",," };
3976
3977
ERR_PRINT_OFF;
3978
code_edit->set_code_completion_prefixes(completion_prefixes);
3979
ERR_PRINT_ON;
3980
completion_prefixes = code_edit->get_code_completion_prefixes();
3981
CHECK(completion_prefixes.size() == 2);
3982
CHECK(completion_prefixes.has("."));
3983
CHECK(completion_prefixes.has(","));
3984
3985
code_edit->set_text("test\ntest");
3986
CHECK(code_edit->get_text_for_code_completion() == String::chr(0xFFFF) + "test\ntest");
3987
}
3988
3989
SUBCASE("[CodeEdit] autocomplete request") {
3990
SIGNAL_WATCH(code_edit, "code_completion_requested");
3991
code_edit->set_code_completion_enabled(true);
3992
3993
Array signal_args = { {} };
3994
3995
/* Force request. */
3996
code_edit->request_code_completion();
3997
SIGNAL_CHECK_FALSE("code_completion_requested");
3998
code_edit->request_code_completion(true);
3999
SIGNAL_CHECK("code_completion_requested", signal_args);
4000
4001
/* Manual request should force. */
4002
SEND_GUI_ACTION("ui_text_completion_query");
4003
SIGNAL_CHECK("code_completion_requested", signal_args);
4004
4005
/* Insert prefix. */
4006
TypedArray<String> completion_prefixes = { "." };
4007
code_edit->set_code_completion_prefixes(completion_prefixes);
4008
4009
code_edit->insert_text_at_caret(".");
4010
code_edit->request_code_completion();
4011
SIGNAL_CHECK("code_completion_requested", signal_args);
4012
4013
/* Should work with space too. */
4014
code_edit->insert_text_at_caret(" ");
4015
code_edit->request_code_completion();
4016
SIGNAL_CHECK("code_completion_requested", signal_args);
4017
4018
/* Should work when complete ends with prefix. */
4019
code_edit->clear();
4020
code_edit->insert_text_at_caret("t");
4021
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "test.", "test.");
4022
code_edit->update_code_completion_options();
4023
code_edit->confirm_code_completion();
4024
CHECK(code_edit->get_line(0) == "test.");
4025
SIGNAL_CHECK("code_completion_requested", signal_args);
4026
4027
SIGNAL_UNWATCH(code_edit, "code_completion_requested");
4028
}
4029
4030
SUBCASE("[CodeEdit] autocomplete completion") {
4031
if (TS->has_feature(TextServer::FEATURE_FONT_DYNAMIC) && TS->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
4032
CHECK(code_edit->get_code_completion_selected_index() == -1);
4033
code_edit->set_code_completion_enabled(true);
4034
CHECK(code_edit->get_code_completion_selected_index() == -1);
4035
4036
code_edit->update_code_completion_options();
4037
code_edit->set_code_completion_selected_index(1);
4038
CHECK(code_edit->get_code_completion_selected_index() == -1);
4039
CHECK(code_edit->get_code_completion_option(0).size() == 0);
4040
CHECK(code_edit->get_code_completion_options().size() == 0);
4041
4042
/* Adding does not update the list. */
4043
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_0.", "item_0");
4044
4045
code_edit->set_code_completion_selected_index(1);
4046
CHECK(code_edit->get_code_completion_selected_index() == -1);
4047
CHECK(code_edit->get_code_completion_option(0).size() == 0);
4048
CHECK(code_edit->get_code_completion_options().size() == 0);
4049
4050
/* After update, pending add should not be counted, */
4051
/* also does not work on col 0 */
4052
int before_text_caret_column = code_edit->get_caret_column();
4053
code_edit->insert_text_at_caret("i");
4054
4055
code_edit->update_code_completion_options();
4056
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0", Color(1, 0, 0), Ref<Resource>(), Color(1, 0, 0));
4057
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_1.", "item_1");
4058
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_2.", "item_2");
4059
4060
ERR_PRINT_OFF;
4061
code_edit->set_code_completion_selected_index(1);
4062
ERR_PRINT_ON;
4063
CHECK(code_edit->get_code_completion_selected_index() == 0);
4064
CHECK(code_edit->get_code_completion_option(0).size() == 7);
4065
CHECK(code_edit->get_code_completion_options().size() == 1);
4066
4067
/* Check cancel closes completion. */
4068
SEND_GUI_ACTION("ui_cancel");
4069
CHECK(code_edit->get_code_completion_selected_index() == -1);
4070
4071
code_edit->update_code_completion_options();
4072
CHECK(code_edit->get_code_completion_selected_index() == 0);
4073
code_edit->set_code_completion_selected_index(1);
4074
CHECK(code_edit->get_code_completion_selected_index() == 1);
4075
CHECK(code_edit->get_code_completion_option(0).size() == 7);
4076
CHECK(code_edit->get_code_completion_options().size() == 3);
4077
4078
/* Check data. */
4079
Dictionary option = code_edit->get_code_completion_option(0);
4080
CHECK((int)option["kind"] == (int)CodeEdit::CodeCompletionKind::KIND_CLASS);
4081
CHECK(option["display_text"] == "item_0.");
4082
CHECK(option["insert_text"] == "item_0");
4083
CHECK(option["font_color"] == Color(1, 0, 0));
4084
CHECK(option["icon"] == Ref<Resource>());
4085
CHECK(option["default_value"] == Color(1, 0, 0));
4086
4087
/* Set size for mouse input. */
4088
code_edit->set_size(Size2(100, 100));
4089
4090
/* Test home and end keys close the completion and move the caret */
4091
/* => ui_text_caret_line_start */
4092
code_edit->set_caret_column(before_text_caret_column + 1);
4093
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0", Color(1, 0, 0), Ref<Resource>(), Color(1, 0, 0));
4094
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_1.", "item_1");
4095
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_2.", "item_2");
4096
4097
code_edit->update_code_completion_options();
4098
4099
SEND_GUI_ACTION("ui_text_caret_line_start");
4100
code_edit->update_code_completion_options();
4101
CHECK(code_edit->get_code_completion_selected_index() == -1);
4102
CHECK(code_edit->get_caret_column() == 0);
4103
4104
/* => ui_text_caret_line_end */
4105
code_edit->set_caret_column(before_text_caret_column + 1);
4106
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0", Color(1, 0, 0), Ref<Resource>(), Color(1, 0, 0));
4107
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_1.", "item_1");
4108
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_2.", "item_2");
4109
4110
code_edit->update_code_completion_options();
4111
4112
SEND_GUI_ACTION("ui_text_caret_line_end");
4113
code_edit->update_code_completion_options();
4114
CHECK(code_edit->get_code_completion_selected_index() == -1);
4115
CHECK(code_edit->get_caret_column() == before_text_caret_column + 1);
4116
4117
/* Check input. */
4118
code_edit->set_caret_column(before_text_caret_column + 1);
4119
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0", Color(1, 0, 0), Ref<Resource>(), Color(1, 0, 0));
4120
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_1.", "item_1");
4121
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_2.", "item_2");
4122
4123
code_edit->update_code_completion_options();
4124
4125
SEND_GUI_ACTION("ui_page_down");
4126
CHECK(code_edit->get_code_completion_selected_index() == 2);
4127
4128
SEND_GUI_ACTION("ui_page_up");
4129
CHECK(code_edit->get_code_completion_selected_index() == 0);
4130
4131
SEND_GUI_ACTION("ui_up");
4132
CHECK(code_edit->get_code_completion_selected_index() == 2);
4133
4134
SEND_GUI_ACTION("ui_down");
4135
CHECK(code_edit->get_code_completion_selected_index() == 0);
4136
4137
SEND_GUI_KEY_EVENT(Key::T);
4138
CHECK(code_edit->get_code_completion_selected_index() == 0);
4139
4140
SEND_GUI_ACTION("ui_left");
4141
CHECK(code_edit->get_code_completion_selected_index() == 0);
4142
4143
SEND_GUI_ACTION("ui_right");
4144
CHECK(code_edit->get_code_completion_selected_index() == 0);
4145
4146
SEND_GUI_ACTION("ui_text_backspace");
4147
CHECK(code_edit->get_code_completion_selected_index() == 0);
4148
4149
Point2 caret_pos = code_edit->get_caret_draw_pos();
4150
caret_pos.y += code_edit->get_line_height();
4151
SEND_GUI_MOUSE_BUTTON_EVENT(caret_pos, MouseButton::WHEEL_DOWN, MouseButtonMask::NONE, Key::NONE);
4152
CHECK(code_edit->get_code_completion_selected_index() == 1);
4153
4154
SEND_GUI_MOUSE_BUTTON_EVENT(caret_pos, MouseButton::WHEEL_UP, MouseButtonMask::NONE, Key::NONE);
4155
CHECK(code_edit->get_code_completion_selected_index() == 0);
4156
4157
/* Single click selects. */
4158
caret_pos.y += code_edit->get_line_height() * 2;
4159
SEND_GUI_MOUSE_BUTTON_EVENT(caret_pos, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
4160
SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(caret_pos, MouseButton::LEFT, MouseButtonMask::NONE, Key::NONE);
4161
CHECK(code_edit->get_code_completion_selected_index() == 2);
4162
4163
/* Double click inserts. */
4164
SEND_GUI_DOUBLE_CLICK(caret_pos, Key::NONE);
4165
CHECK(code_edit->get_code_completion_selected_index() == -1);
4166
CHECK(code_edit->get_line(0) == "item_2");
4167
4168
code_edit->set_auto_brace_completion_enabled(false);
4169
4170
/* Does nothing in readonly. */
4171
code_edit->undo();
4172
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
4173
code_edit->update_code_completion_options();
4174
code_edit->set_editable(false);
4175
code_edit->confirm_code_completion();
4176
code_edit->set_editable(true);
4177
CHECK(code_edit->get_line(0) == "i");
4178
4179
/* Replace */
4180
code_edit->clear();
4181
code_edit->insert_text_at_caret("item_1 test");
4182
code_edit->set_caret_column(2);
4183
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
4184
code_edit->update_code_completion_options();
4185
SEND_GUI_ACTION("ui_text_completion_replace");
4186
CHECK(code_edit->get_line(0) == "item_0 test");
4187
4188
/* Replace string. */
4189
code_edit->clear();
4190
code_edit->insert_text_at_caret("\"item_1 test\"");
4191
code_edit->set_caret_column(2);
4192
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
4193
code_edit->update_code_completion_options();
4194
SEND_GUI_ACTION("ui_text_completion_replace");
4195
CHECK(code_edit->get_line(0) == "\"item_0\"");
4196
4197
/* Normal replace if no end is given. */
4198
code_edit->clear();
4199
code_edit->insert_text_at_caret("\"item_1 test");
4200
code_edit->set_caret_column(2);
4201
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
4202
code_edit->update_code_completion_options();
4203
SEND_GUI_ACTION("ui_text_completion_replace");
4204
CHECK(code_edit->get_line(0) == "\"item_0\" test");
4205
4206
/* Insert at completion. */
4207
code_edit->clear();
4208
code_edit->insert_text_at_caret("item_1 test");
4209
code_edit->set_caret_column(2);
4210
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
4211
code_edit->update_code_completion_options();
4212
SEND_GUI_ACTION("ui_text_completion_accept");
4213
CHECK(code_edit->get_line(0) == "item_01 test");
4214
4215
/* Insert at completion with string should have same output. */
4216
code_edit->clear();
4217
code_edit->insert_text_at_caret("\"item_1 test\"");
4218
code_edit->set_caret_column(2);
4219
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
4220
code_edit->update_code_completion_options();
4221
SEND_GUI_ACTION("ui_text_completion_accept");
4222
CHECK(code_edit->get_line(0) == "\"item_0\"1 test\"");
4223
4224
/* Merge symbol at end on insert text. */
4225
/* End on completion entry. */
4226
code_edit->clear();
4227
code_edit->insert_text_at_caret("item_1 test");
4228
code_edit->set_caret_column(2);
4229
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
4230
code_edit->update_code_completion_options();
4231
SEND_GUI_ACTION("ui_text_completion_replace");
4232
CHECK(code_edit->get_line(0) == "item_0( test");
4233
CHECK(code_edit->get_caret_column() == 7);
4234
4235
/* End of text*/
4236
code_edit->clear();
4237
code_edit->insert_text_at_caret("item_1( test");
4238
code_edit->set_caret_column(2);
4239
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
4240
code_edit->update_code_completion_options();
4241
SEND_GUI_ACTION("ui_text_completion_replace");
4242
CHECK(code_edit->get_line(0) == "item_0( test");
4243
CHECK(code_edit->get_caret_column() == 6);
4244
4245
/* End of both. */
4246
code_edit->clear();
4247
code_edit->insert_text_at_caret("item_1( test");
4248
code_edit->set_caret_column(2);
4249
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
4250
code_edit->update_code_completion_options();
4251
SEND_GUI_ACTION("ui_text_completion_replace");
4252
CHECK(code_edit->get_line(0) == "item_0( test");
4253
CHECK(code_edit->get_caret_column() == 7);
4254
4255
/* Full set. */
4256
/* End on completion entry. */
4257
code_edit->clear();
4258
code_edit->insert_text_at_caret("item_1 test");
4259
code_edit->set_caret_column(2);
4260
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
4261
code_edit->update_code_completion_options();
4262
SEND_GUI_ACTION("ui_text_completion_replace");
4263
CHECK(code_edit->get_line(0) == "item_0() test");
4264
CHECK(code_edit->get_caret_column() == 8);
4265
4266
/* End of text*/
4267
code_edit->clear();
4268
code_edit->insert_text_at_caret("item_1() test");
4269
code_edit->set_caret_column(2);
4270
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
4271
code_edit->update_code_completion_options();
4272
SEND_GUI_ACTION("ui_text_completion_replace");
4273
CHECK(code_edit->get_line(0) == "item_0() test");
4274
CHECK(code_edit->get_caret_column() == 6);
4275
4276
/* End of both. */
4277
code_edit->clear();
4278
code_edit->insert_text_at_caret("item_1() test");
4279
code_edit->set_caret_column(2);
4280
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
4281
code_edit->update_code_completion_options();
4282
SEND_GUI_ACTION("ui_text_completion_replace");
4283
CHECK(code_edit->get_line(0) == "item_0() test");
4284
CHECK(code_edit->get_caret_column() == 8);
4285
4286
/* Autobrace completion. */
4287
code_edit->set_auto_brace_completion_enabled(true);
4288
4289
/* End on completion entry. */
4290
code_edit->clear();
4291
code_edit->insert_text_at_caret("item_1 test");
4292
code_edit->set_caret_column(2);
4293
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
4294
code_edit->update_code_completion_options();
4295
SEND_GUI_ACTION("ui_text_completion_replace");
4296
CHECK(code_edit->get_line(0) == "item_0() test");
4297
CHECK(code_edit->get_caret_column() == 7);
4298
4299
/* End of text*/
4300
code_edit->clear();
4301
code_edit->insert_text_at_caret("item_1( test");
4302
code_edit->set_caret_column(2);
4303
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
4304
code_edit->update_code_completion_options();
4305
SEND_GUI_ACTION("ui_text_completion_replace");
4306
CHECK(code_edit->get_line(0) == "item_0( test");
4307
CHECK(code_edit->get_caret_column() == 6);
4308
4309
/* End of both. */
4310
code_edit->clear();
4311
code_edit->insert_text_at_caret("item_1( test");
4312
code_edit->set_caret_column(2);
4313
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
4314
code_edit->update_code_completion_options();
4315
SEND_GUI_ACTION("ui_text_completion_replace");
4316
CHECK(code_edit->get_line(0) == "item_0( test");
4317
CHECK(code_edit->get_caret_column() == 7);
4318
4319
/* Full set. */
4320
/* End on completion entry. */
4321
code_edit->clear();
4322
code_edit->insert_text_at_caret("item_1 test");
4323
code_edit->set_caret_column(2);
4324
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
4325
code_edit->update_code_completion_options();
4326
SEND_GUI_ACTION("ui_text_completion_replace");
4327
CHECK(code_edit->get_line(0) == "item_0() test");
4328
CHECK(code_edit->get_caret_column() == 8);
4329
4330
/* End of text*/
4331
code_edit->clear();
4332
code_edit->insert_text_at_caret("item_1() test");
4333
code_edit->set_caret_column(2);
4334
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
4335
code_edit->update_code_completion_options();
4336
SEND_GUI_ACTION("ui_text_completion_replace");
4337
CHECK(code_edit->get_line(0) == "item_0() test");
4338
CHECK(code_edit->get_caret_column() == 6);
4339
4340
/* End of both. */
4341
code_edit->clear();
4342
code_edit->insert_text_at_caret("item_1() test");
4343
code_edit->set_caret_column(2);
4344
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
4345
code_edit->update_code_completion_options();
4346
SEND_GUI_ACTION("ui_text_completion_replace");
4347
CHECK(code_edit->get_line(0) == "item_0() test");
4348
CHECK(code_edit->get_caret_column() == 8);
4349
}
4350
}
4351
4352
SUBCASE("[CodeEdit] autocomplete suggestion order") {
4353
/* Prefer less fragmented suggestion. */
4354
code_edit->clear();
4355
code_edit->insert_text_at_caret("te");
4356
code_edit->set_caret_column(2);
4357
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test", "test");
4358
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "tset", "tset");
4359
code_edit->update_code_completion_options();
4360
code_edit->confirm_code_completion();
4361
CHECK(code_edit->get_line(0) == "test");
4362
4363
/* Prefer suggestion starting with the string to complete (matching start). */
4364
code_edit->clear();
4365
code_edit->insert_text_at_caret("te");
4366
code_edit->set_caret_column(2);
4367
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test", "test");
4368
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "stest", "stest");
4369
code_edit->update_code_completion_options();
4370
code_edit->confirm_code_completion();
4371
CHECK(code_edit->get_line(0) == "test");
4372
4373
/* Prefer less fragment over matching start. */
4374
code_edit->clear();
4375
code_edit->insert_text_at_caret("te");
4376
code_edit->set_caret_column(2);
4377
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "tset", "tset");
4378
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "stest", "stest");
4379
code_edit->update_code_completion_options();
4380
code_edit->confirm_code_completion();
4381
CHECK(code_edit->get_line(0) == "stest");
4382
4383
/* Prefer good capitalization. */
4384
code_edit->clear();
4385
code_edit->insert_text_at_caret("te");
4386
code_edit->set_caret_column(2);
4387
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test", "test");
4388
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "Test", "Test");
4389
code_edit->update_code_completion_options();
4390
code_edit->confirm_code_completion();
4391
CHECK(code_edit->get_line(0) == "test");
4392
4393
/* Prefer matching start over good capitalization. */
4394
code_edit->clear();
4395
code_edit->insert_text_at_caret("te");
4396
code_edit->set_caret_column(2);
4397
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "Test", "Test");
4398
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "stest_bis", "test_bis");
4399
code_edit->update_code_completion_options();
4400
code_edit->confirm_code_completion();
4401
CHECK(code_edit->get_line(0) == "Test");
4402
4403
/* Prefer closer location. */
4404
code_edit->clear();
4405
code_edit->insert_text_at_caret("te");
4406
code_edit->set_caret_column(2);
4407
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test", "test");
4408
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test_bis", "test_bis", Color(1, 1, 1), Ref<Resource>(), Variant::NIL, CodeEdit::LOCATION_LOCAL);
4409
code_edit->update_code_completion_options();
4410
code_edit->confirm_code_completion();
4411
CHECK(code_edit->get_line(0) == "test_bis");
4412
4413
/* Prefer good capitalization over location. */
4414
code_edit->clear();
4415
code_edit->insert_text_at_caret("te");
4416
code_edit->set_caret_column(2);
4417
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "test", "test");
4418
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "Test", "Test", Color(1, 1, 1), Ref<Resource>(), Variant::NIL, CodeEdit::LOCATION_LOCAL);
4419
code_edit->update_code_completion_options();
4420
code_edit->confirm_code_completion();
4421
CHECK(code_edit->get_line(0) == "test");
4422
4423
/* Prefer the start of the string to complete being closest to the start of the suggestion (closest to start). */
4424
code_edit->clear();
4425
code_edit->insert_text_at_caret("te");
4426
code_edit->set_caret_column(2);
4427
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "stest", "stest");
4428
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "sstest", "sstest");
4429
code_edit->update_code_completion_options();
4430
code_edit->confirm_code_completion();
4431
CHECK(code_edit->get_line(0) == "stest");
4432
4433
/* Prefer location over closest to start. */
4434
code_edit->clear();
4435
code_edit->insert_text_at_caret("te");
4436
code_edit->set_caret_column(2);
4437
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "stest", "stest");
4438
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "sstest", "sstest", Color(1, 1, 1), Ref<Resource>(), Variant::NIL, CodeEdit::LOCATION_LOCAL);
4439
code_edit->update_code_completion_options();
4440
code_edit->confirm_code_completion();
4441
CHECK(code_edit->get_line(0) == "sstest");
4442
}
4443
4444
SUBCASE("[CodeEdit] autocomplete currently selected option") {
4445
code_edit->set_code_completion_enabled(true);
4446
REQUIRE(code_edit->is_code_completion_enabled());
4447
4448
// Initially select item 0.
4449
code_edit->insert_text_at_caret("te");
4450
code_edit->set_caret_column(2);
4451
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te1", "te1");
4452
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te3", "te3");
4453
code_edit->update_code_completion_options();
4454
CHECK_MESSAGE(code_edit->get_code_completion_selected_index() == 0, "Initially selected item should be 0.");
4455
4456
// After adding later options shouldn't update selection.
4457
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te1", "te1");
4458
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te3", "te3");
4459
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te4", "te4"); // Added te4.
4460
code_edit->update_code_completion_options();
4461
CHECK_MESSAGE(code_edit->get_code_completion_selected_index() == 0, "Adding later options shouldn't update selection.");
4462
4463
code_edit->set_code_completion_selected_index(2);
4464
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te1", "te1");
4465
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te3", "te3");
4466
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te4", "te4");
4467
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te5", "te5"); // Added te5.
4468
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te6", "te6"); // Added te6.
4469
code_edit->update_code_completion_options();
4470
CHECK_MESSAGE(code_edit->get_code_completion_selected_index() == 2, "Adding later options shouldn't update selection.");
4471
4472
// Removing elements after selected element shouldn't update selection.
4473
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te1", "te1");
4474
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te3", "te3");
4475
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te4", "te4");
4476
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te5", "te5"); // Removed te6.
4477
code_edit->update_code_completion_options();
4478
CHECK_MESSAGE(code_edit->get_code_completion_selected_index() == 2, "Removing elements after selected element shouldn't update selection.");
4479
4480
// Changing elements after selected element shouldn't update selection.
4481
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te1", "te1");
4482
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te3", "te3");
4483
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te4", "te4");
4484
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te6", "te6"); // Changed te5->te6.
4485
code_edit->update_code_completion_options();
4486
CHECK_MESSAGE(code_edit->get_code_completion_selected_index() == 2, "Changing elements after selected element shouldn't update selection.");
4487
4488
// Changing elements before selected element should reset selection.
4489
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te2", "te2"); // Changed te1->te2.
4490
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te3", "te3");
4491
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te4", "te4");
4492
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te6", "te6");
4493
code_edit->update_code_completion_options();
4494
CHECK_MESSAGE(code_edit->get_code_completion_selected_index() == 0, "Changing elements before selected element should reset selection.");
4495
4496
// Removing elements before selected element should reset selection.
4497
code_edit->set_code_completion_selected_index(2);
4498
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te3", "te3"); // Removed te2.
4499
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te4", "te4");
4500
code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "te6", "te6");
4501
code_edit->update_code_completion_options();
4502
CHECK_MESSAGE(code_edit->get_code_completion_selected_index() == 0, "Removing elements before selected element should reset selection.");
4503
}
4504
4505
memdelete(code_edit);
4506
}
4507
4508
TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
4509
CodeEdit *code_edit = memnew(CodeEdit);
4510
SceneTree::get_singleton()->get_root()->add_child(code_edit);
4511
code_edit->grab_focus();
4512
4513
code_edit->set_symbol_lookup_on_click_enabled(true);
4514
CHECK(code_edit->is_symbol_lookup_on_click_enabled());
4515
4516
if (TS->has_feature(TextServer::FEATURE_FONT_DYNAMIC) && TS->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
4517
/* Set size for mouse input. */
4518
code_edit->set_size(Size2(100, 100));
4519
4520
code_edit->set_text("this is some text");
4521
4522
Point2 caret_pos = code_edit->get_caret_draw_pos();
4523
caret_pos.x += 60;
4524
4525
SEND_GUI_MOUSE_MOTION_EVENT(caret_pos, MouseButtonMask::NONE, Key::NONE);
4526
CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text");
4527
4528
SIGNAL_WATCH(code_edit, "symbol_validate");
4529
4530
#ifdef MACOS_ENABLED
4531
SEND_GUI_KEY_EVENT(Key::META);
4532
#else
4533
SEND_GUI_KEY_EVENT(Key::CTRL);
4534
#endif
4535
4536
Array signal_args = { { "some" } };
4537
SIGNAL_CHECK("symbol_validate", signal_args);
4538
4539
SIGNAL_UNWATCH(code_edit, "symbol_validate");
4540
}
4541
4542
memdelete(code_edit);
4543
}
4544
4545
TEST_CASE("[SceneTree][CodeEdit] line length guidelines") {
4546
CodeEdit *code_edit = memnew(CodeEdit);
4547
SceneTree::get_singleton()->get_root()->add_child(code_edit);
4548
code_edit->grab_focus();
4549
4550
TypedArray<int> guide_lines;
4551
4552
code_edit->set_line_length_guidelines(guide_lines);
4553
CHECK(code_edit->get_line_length_guidelines().size() == 0);
4554
4555
guide_lines.push_back(80);
4556
guide_lines.push_back(120);
4557
4558
/* Order should be preserved. */
4559
code_edit->set_line_length_guidelines(guide_lines);
4560
CHECK((int)code_edit->get_line_length_guidelines()[0] == 80);
4561
CHECK((int)code_edit->get_line_length_guidelines()[1] == 120);
4562
4563
memdelete(code_edit);
4564
}
4565
4566
TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
4567
CodeEdit *code_edit = memnew(CodeEdit);
4568
SceneTree::get_singleton()->get_root()->add_child(code_edit);
4569
code_edit->grab_focus();
4570
4571
SUBCASE("[SceneTree][CodeEdit] backspace") {
4572
// Backspace with selection on first line.
4573
code_edit->set_text("test backspace");
4574
code_edit->select(0, 0, 0, 5);
4575
code_edit->backspace();
4576
CHECK(code_edit->get_line(0) == "backspace");
4577
CHECK(code_edit->get_caret_line() == 0);
4578
CHECK(code_edit->get_caret_column() == 0);
4579
4580
// Backspace with selection on first line and caret at the beginning of file.
4581
code_edit->set_text("test backspace");
4582
code_edit->select(0, 5, 0, 0);
4583
code_edit->backspace();
4584
CHECK(code_edit->get_line(0) == "backspace");
4585
CHECK(code_edit->get_caret_line() == 0);
4586
CHECK(code_edit->get_caret_column() == 0);
4587
4588
// Move caret up to the previous line on backspace if caret is at the first column.
4589
code_edit->set_text("line 1\nline 2");
4590
code_edit->set_caret_line(1);
4591
code_edit->set_caret_column(0);
4592
code_edit->backspace();
4593
CHECK(code_edit->get_line(0) == "line 1line 2");
4594
CHECK(code_edit->get_caret_line() == 0);
4595
CHECK(code_edit->get_caret_column() == 6);
4596
4597
// Multiple carets with a caret at the first column.
4598
code_edit->set_text("line 1\nline 2");
4599
code_edit->set_caret_line(1);
4600
code_edit->set_caret_column(2);
4601
code_edit->add_caret(1, 0);
4602
code_edit->add_caret(1, 5);
4603
code_edit->backspace();
4604
CHECK(code_edit->get_text() == "line 1lne2");
4605
CHECK(code_edit->get_caret_count() == 3);
4606
CHECK(code_edit->get_caret_line(0) == 0);
4607
CHECK(code_edit->get_caret_column(0) == 7);
4608
CHECK(code_edit->get_caret_line(1) == 0);
4609
CHECK(code_edit->get_caret_column(1) == 6);
4610
CHECK(code_edit->get_caret_line(2) == 0);
4611
CHECK(code_edit->get_caret_column(2) == 9);
4612
code_edit->remove_secondary_carets();
4613
4614
// Multiple carets close together.
4615
code_edit->set_text("line 1\nline 2");
4616
code_edit->set_caret_line(1);
4617
code_edit->set_caret_column(2);
4618
code_edit->add_caret(1, 1);
4619
code_edit->backspace();
4620
CHECK(code_edit->get_text() == "line 1\nne 2");
4621
CHECK(code_edit->get_caret_count() == 1);
4622
CHECK(code_edit->get_caret_line() == 1);
4623
CHECK(code_edit->get_caret_column() == 0);
4624
4625
// Backspace delete all text if all text is selected.
4626
code_edit->set_text("line 1\nline 2\nline 3");
4627
code_edit->select_all();
4628
code_edit->backspace();
4629
CHECK(code_edit->get_text().is_empty());
4630
CHECK_FALSE(code_edit->has_selection());
4631
CHECK(code_edit->get_caret_line() == 0);
4632
CHECK(code_edit->get_caret_column() == 0);
4633
4634
// Backspace at the beginning without selection has no effect.
4635
code_edit->set_text("line 1\nline 2\nline 3");
4636
code_edit->set_caret_line(0);
4637
code_edit->set_caret_column(0);
4638
code_edit->backspace();
4639
CHECK(code_edit->get_text() == "line 1\nline 2\nline 3");
4640
CHECK(code_edit->get_caret_line() == 0);
4641
CHECK(code_edit->get_caret_column() == 0);
4642
4643
// Unfold previous folded line on backspace if the caret is at the first column.
4644
code_edit->set_line_folding_enabled(true);
4645
code_edit->set_text("line 1\n\tline 2\nline 3");
4646
code_edit->set_caret_line(2);
4647
code_edit->set_caret_column(0);
4648
code_edit->fold_line(0);
4649
code_edit->backspace();
4650
CHECK_FALSE(code_edit->is_line_folded(0));
4651
code_edit->set_line_folding_enabled(false);
4652
4653
// Do not unfold previous line on backspace if the caret is not at the first column.
4654
code_edit->set_line_folding_enabled(true);
4655
code_edit->set_text("line 1\n\tline 2\nline 3");
4656
code_edit->set_caret_line(2);
4657
code_edit->set_caret_column(4);
4658
code_edit->fold_line(0);
4659
code_edit->backspace();
4660
CHECK(code_edit->is_line_folded(0));
4661
code_edit->set_line_folding_enabled(false);
4662
}
4663
4664
SUBCASE("[TextEdit] cut") {
4665
DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());
4666
code_edit->set_line_folding_enabled(true);
4667
4668
// Cut without a selection removes the entire line.
4669
code_edit->set_text("this is\nsome\n");
4670
code_edit->set_caret_line(0);
4671
code_edit->set_caret_column(6);
4672
4673
code_edit->cut();
4674
CHECK(DS->clipboard_get() == "this is\n");
4675
CHECK(code_edit->get_text() == "some\n");
4676
CHECK(code_edit->get_caret_line() == 0);
4677
CHECK(code_edit->get_caret_column() == 3); // In the default font, this is the same position.
4678
4679
// Undo restores the cut text.
4680
code_edit->undo();
4681
CHECK(DS->clipboard_get() == "this is\n");
4682
CHECK(code_edit->get_text() == "this is\nsome\n");
4683
CHECK(code_edit->get_caret_line() == 0);
4684
CHECK(code_edit->get_caret_column() == 6);
4685
4686
// Redo.
4687
code_edit->redo();
4688
CHECK(DS->clipboard_get() == "this is\n");
4689
CHECK(code_edit->get_text() == "some\n");
4690
CHECK(code_edit->get_caret_line() == 0);
4691
CHECK(code_edit->get_caret_column() == 3);
4692
4693
// Cut unfolds the line.
4694
code_edit->set_text("this is\n\tsome\n");
4695
code_edit->fold_line(0);
4696
CHECK(code_edit->is_line_folded(0));
4697
4698
code_edit->cut();
4699
CHECK_FALSE(code_edit->is_line_folded(0));
4700
CHECK(DS->clipboard_get() == "this is\n");
4701
CHECK(code_edit->get_text() == "\tsome\n");
4702
CHECK(code_edit->get_caret_line() == 0);
4703
4704
// Cut with a selection removes just the selection.
4705
code_edit->set_text("this is\nsome\n");
4706
code_edit->select(0, 5, 0, 7);
4707
4708
SEND_GUI_ACTION("ui_cut");
4709
CHECK(code_edit->get_viewport()->is_input_handled());
4710
CHECK(DS->clipboard_get() == "is");
4711
CHECK(code_edit->get_text() == "this \nsome\n");
4712
CHECK_FALSE(code_edit->get_caret_line());
4713
CHECK(code_edit->get_caret_line() == 0);
4714
CHECK(code_edit->get_caret_column() == 5);
4715
4716
// Cut does not change the text if not editable. Text is still added to clipboard.
4717
code_edit->set_text("this is\nsome\n");
4718
code_edit->set_caret_line(0);
4719
code_edit->set_caret_column(5);
4720
4721
code_edit->set_editable(false);
4722
code_edit->cut();
4723
code_edit->set_editable(true);
4724
CHECK(DS->clipboard_get() == "this is\n");
4725
CHECK(code_edit->get_text() == "this is\nsome\n");
4726
CHECK(code_edit->get_caret_line() == 0);
4727
CHECK(code_edit->get_caret_column() == 5);
4728
4729
// Cut line with multiple carets.
4730
code_edit->set_text("this is\nsome\n");
4731
code_edit->set_caret_line(0);
4732
code_edit->set_caret_column(3);
4733
code_edit->add_caret(0, 2);
4734
code_edit->add_caret(0, 4);
4735
code_edit->add_caret(2, 0);
4736
4737
code_edit->cut();
4738
CHECK(DS->clipboard_get() == "this is\n\n");
4739
CHECK(code_edit->get_text() == "some");
4740
CHECK(code_edit->get_caret_count() == 3);
4741
CHECK_FALSE(code_edit->has_selection(0));
4742
CHECK(code_edit->get_caret_line(0) == 0);
4743
CHECK(code_edit->get_caret_column(0) == 2); // In the default font, this is the same position.
4744
// The previous caret at index 1 was merged.
4745
CHECK_FALSE(code_edit->has_selection(1));
4746
CHECK(code_edit->get_caret_line(1) == 0);
4747
CHECK(code_edit->get_caret_column(1) == 3); // In the default font, this is the same position.
4748
CHECK_FALSE(code_edit->has_selection(2));
4749
CHECK(code_edit->get_caret_line(2) == 0);
4750
CHECK(code_edit->get_caret_column(2) == 4);
4751
code_edit->remove_secondary_carets();
4752
4753
// Cut on the only line removes the contents.
4754
code_edit->set_caret_line(0);
4755
code_edit->set_caret_column(2);
4756
4757
code_edit->cut();
4758
CHECK(DS->clipboard_get() == "some\n");
4759
CHECK(code_edit->get_text() == "");
4760
CHECK(code_edit->get_line_count() == 1);
4761
CHECK(code_edit->get_caret_line() == 0);
4762
CHECK(code_edit->get_caret_column() == 0);
4763
4764
// Cut empty line.
4765
code_edit->cut();
4766
CHECK(DS->clipboard_get() == "\n");
4767
CHECK(code_edit->get_text() == "");
4768
CHECK(code_edit->get_caret_line() == 0);
4769
CHECK(code_edit->get_caret_column() == 0);
4770
4771
// Cut multiple lines, in order.
4772
code_edit->set_text("this is\nsome\ntext to\nbe\n\ncut");
4773
code_edit->set_caret_line(2);
4774
code_edit->set_caret_column(7);
4775
code_edit->add_caret(3, 0);
4776
code_edit->add_caret(0, 2);
4777
4778
code_edit->cut();
4779
CHECK(DS->clipboard_get() == "this is\ntext to\nbe\n");
4780
CHECK(code_edit->get_text() == "some\n\ncut");
4781
CHECK(code_edit->get_caret_count() == 2);
4782
CHECK(code_edit->get_caret_line(0) == 1);
4783
CHECK(code_edit->get_caret_column(0) == 0);
4784
CHECK(code_edit->get_caret_line(1) == 0);
4785
CHECK(code_edit->get_caret_column(1) == 2);
4786
code_edit->remove_secondary_carets();
4787
4788
// Cut multiple selections, in order. Ignores regular carets.
4789
code_edit->set_text("this is\nsome\ntext to\nbe\n\ncut");
4790
code_edit->add_caret(3, 0);
4791
code_edit->add_caret(0, 2);
4792
code_edit->add_caret(2, 0);
4793
code_edit->select(1, 0, 1, 2, 0);
4794
code_edit->select(3, 0, 4, 0, 1);
4795
code_edit->select(0, 5, 0, 3, 2);
4796
4797
code_edit->cut();
4798
CHECK(DS->clipboard_get() == "s \nso\nbe\n");
4799
CHECK(code_edit->get_text() == "thiis\nme\ntext to\n\ncut");
4800
CHECK(code_edit->get_caret_count() == 4);
4801
CHECK_FALSE(code_edit->has_selection());
4802
CHECK(code_edit->get_caret_line(0) == 1);
4803
CHECK(code_edit->get_caret_column(0) == 0);
4804
CHECK(code_edit->get_caret_line(1) == 3);
4805
CHECK(code_edit->get_caret_column(1) == 0);
4806
CHECK(code_edit->get_caret_line(2) == 0);
4807
CHECK(code_edit->get_caret_column(2) == 3);
4808
CHECK(code_edit->get_caret_line(3) == 2);
4809
CHECK(code_edit->get_caret_column(3) == 0);
4810
}
4811
4812
SUBCASE("[SceneTree][CodeEdit] cut when empty selection clipboard disabled") {
4813
DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());
4814
code_edit->set_empty_selection_clipboard_enabled(false);
4815
DS->clipboard_set("");
4816
4817
code_edit->set_text("this is\nsome\n");
4818
code_edit->set_caret_line(0);
4819
code_edit->set_caret_column(6);
4820
MessageQueue::get_singleton()->flush();
4821
SIGNAL_DISCARD("text_set");
4822
SIGNAL_DISCARD("text_changed");
4823
SIGNAL_DISCARD("lines_edited_from");
4824
SIGNAL_DISCARD("caret_changed");
4825
4826
code_edit->cut();
4827
MessageQueue::get_singleton()->flush();
4828
CHECK(DS->clipboard_get() == "");
4829
CHECK(code_edit->get_text() == "this is\nsome\n");
4830
CHECK(code_edit->get_caret_line() == 0);
4831
CHECK(code_edit->get_caret_column() == 6);
4832
SIGNAL_CHECK_FALSE("caret_changed");
4833
SIGNAL_CHECK_FALSE("text_changed");
4834
SIGNAL_CHECK_FALSE("lines_edited_from");
4835
}
4836
4837
SUBCASE("[SceneTree][CodeEdit] new line") {
4838
// Add a new line.
4839
code_edit->set_text("test new line");
4840
code_edit->set_caret_line(0);
4841
code_edit->set_caret_column(13);
4842
SEND_GUI_ACTION("ui_text_newline");
4843
CHECK(code_edit->get_line(0) == "test new line");
4844
CHECK(code_edit->get_line(1) == "");
4845
CHECK(code_edit->get_caret_line() == 1);
4846
CHECK(code_edit->get_caret_column() == 0);
4847
4848
// Split line with new line.
4849
code_edit->set_text("test new line");
4850
code_edit->set_caret_line(0);
4851
code_edit->set_caret_column(5);
4852
SEND_GUI_ACTION("ui_text_newline");
4853
CHECK(code_edit->get_line(0) == "test ");
4854
CHECK(code_edit->get_line(1) == "new line");
4855
CHECK(code_edit->get_caret_line() == 1);
4856
CHECK(code_edit->get_caret_column() == 0);
4857
4858
// Delete selection and split with new line.
4859
code_edit->set_text("test new line");
4860
code_edit->select(0, 0, 0, 5);
4861
SEND_GUI_ACTION("ui_text_newline");
4862
CHECK(code_edit->get_line(0) == "");
4863
CHECK(code_edit->get_line(1) == "new line");
4864
CHECK(code_edit->get_caret_line() == 1);
4865
CHECK(code_edit->get_caret_column() == 0);
4866
4867
// Blank new line below with selection should not split.
4868
code_edit->set_text("test new line");
4869
code_edit->select(0, 0, 0, 5);
4870
SEND_GUI_ACTION("ui_text_newline_blank");
4871
CHECK(code_edit->get_line(0) == "test new line");
4872
CHECK(code_edit->get_line(1) == "");
4873
CHECK(code_edit->get_caret_line() == 1);
4874
CHECK(code_edit->get_caret_column() == 0);
4875
4876
// Blank new line above with selection should not split.
4877
code_edit->set_text("test new line");
4878
code_edit->select(0, 0, 0, 5);
4879
SEND_GUI_ACTION("ui_text_newline_above");
4880
CHECK(code_edit->get_line(0) == "");
4881
CHECK(code_edit->get_line(1) == "test new line");
4882
CHECK(code_edit->get_caret_line() == 0);
4883
CHECK(code_edit->get_caret_column() == 0);
4884
4885
// Multiple new lines with multiple carets.
4886
code_edit->set_text("test new line");
4887
code_edit->set_caret_line(0);
4888
code_edit->set_caret_column(5);
4889
code_edit->add_caret(0, 8);
4890
SEND_GUI_ACTION("ui_text_newline");
4891
CHECK(code_edit->get_line(0) == "test ");
4892
CHECK(code_edit->get_line(1) == "new");
4893
CHECK(code_edit->get_line(2) == " line");
4894
CHECK(code_edit->get_caret_count() == 2);
4895
CHECK(code_edit->get_caret_line(0) == 1);
4896
CHECK(code_edit->get_caret_column(0) == 0);
4897
CHECK(code_edit->get_caret_line(1) == 2);
4898
CHECK(code_edit->get_caret_column(1) == 0);
4899
4900
// Multiple blank new lines with multiple carets.
4901
code_edit->set_text("test new line");
4902
code_edit->remove_secondary_carets();
4903
code_edit->set_caret_line(0);
4904
code_edit->set_caret_column(5);
4905
code_edit->add_caret(0, 8);
4906
SEND_GUI_ACTION("ui_text_newline_blank");
4907
CHECK(code_edit->get_line(0) == "test new line");
4908
CHECK(code_edit->get_line(1) == "");
4909
CHECK(code_edit->get_line(2) == "");
4910
CHECK(code_edit->get_caret_count() == 2);
4911
CHECK(code_edit->get_caret_line(0) == 2);
4912
CHECK(code_edit->get_caret_column(0) == 0);
4913
CHECK(code_edit->get_caret_line(1) == 1);
4914
CHECK(code_edit->get_caret_column(1) == 0);
4915
4916
// Multiple new lines above with multiple carets.
4917
code_edit->set_text("test new line");
4918
code_edit->remove_secondary_carets();
4919
code_edit->set_caret_line(0);
4920
code_edit->set_caret_column(5);
4921
code_edit->add_caret(0, 8);
4922
SEND_GUI_ACTION("ui_text_newline_above");
4923
CHECK(code_edit->get_line(0) == "");
4924
CHECK(code_edit->get_line(1) == "");
4925
CHECK(code_edit->get_line(2) == "test new line");
4926
CHECK(code_edit->get_caret_count() == 2);
4927
CHECK(code_edit->get_caret_line(0) == 0);
4928
CHECK(code_edit->get_caret_column(0) == 0);
4929
CHECK(code_edit->get_caret_line(1) == 1);
4930
CHECK(code_edit->get_caret_column(1) == 0);
4931
4932
// See '[CodeEdit] auto indent' tests for tests about new line with indentation.
4933
}
4934
4935
SUBCASE("[SceneTree][CodeEdit] move lines up") {
4936
code_edit->set_text("test\nlines\nto\n\nmove\naround");
4937
4938
// Move line up with caret on it.
4939
code_edit->set_caret_line(2);
4940
code_edit->set_caret_column(1);
4941
code_edit->move_lines_up();
4942
CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
4943
CHECK(code_edit->get_caret_line() == 1);
4944
CHECK(code_edit->get_caret_column() == 1);
4945
4946
// Undo.
4947
code_edit->undo();
4948
CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
4949
CHECK(code_edit->get_caret_line() == 2);
4950
CHECK(code_edit->get_caret_column() == 1);
4951
4952
// Redo.
4953
code_edit->redo();
4954
CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
4955
CHECK(code_edit->get_caret_line() == 1);
4956
CHECK(code_edit->get_caret_column() == 1);
4957
4958
// Does nothing at the first line.
4959
code_edit->set_text("test\nlines\nto\n\nmove\naround");
4960
code_edit->set_caret_line(0);
4961
code_edit->set_caret_column(1);
4962
code_edit->move_lines_up();
4963
CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
4964
CHECK(code_edit->get_caret_line() == 0);
4965
CHECK(code_edit->get_caret_column() == 1);
4966
4967
// Does nothing at the first line when selection ends at column 0.
4968
code_edit->set_text("test\nlines\nto\n\nmove\naround");
4969
code_edit->select(0, 0, 1, 0);
4970
code_edit->move_lines_up();
4971
CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
4972
CHECK(code_edit->has_selection());
4973
CHECK(code_edit->get_selection_origin_line() == 0);
4974
CHECK(code_edit->get_selection_origin_column() == 0);
4975
CHECK(code_edit->get_caret_line() == 1);
4976
CHECK(code_edit->get_caret_column() == 0);
4977
4978
// Works on empty line.
4979
code_edit->set_text("test\nlines\nto\n\nmove\naround");
4980
code_edit->set_caret_line(3);
4981
code_edit->set_caret_column(0);
4982
code_edit->move_lines_up();
4983
CHECK(code_edit->get_text() == "test\nlines\n\nto\nmove\naround");
4984
CHECK(code_edit->get_caret_line() == 2);
4985
CHECK(code_edit->get_caret_column() == 0);
4986
4987
// Move multiple lines up with selection.
4988
code_edit->set_text("test\nlines\nto\n\nmove\naround");
4989
code_edit->select(4, 0, 5, 1);
4990
code_edit->move_lines_up();
4991
CHECK(code_edit->get_text() == "test\nlines\nto\nmove\naround\n");
4992
CHECK(code_edit->has_selection());
4993
CHECK(code_edit->get_selection_origin_line() == 3);
4994
CHECK(code_edit->get_selection_origin_column() == 0);
4995
CHECK(code_edit->get_caret_line() == 4);
4996
CHECK(code_edit->get_caret_column() == 1);
4997
4998
// Does not affect line with selection end at column 0.
4999
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5000
code_edit->select(4, 0, 5, 0);
5001
code_edit->move_lines_up();
5002
CHECK(code_edit->get_text() == "test\nlines\nto\nmove\n\naround");
5003
CHECK(code_edit->has_selection());
5004
CHECK(code_edit->get_selection_origin_line() == 3);
5005
CHECK(code_edit->get_selection_origin_column() == 0);
5006
CHECK(code_edit->get_caret_line() == 4);
5007
CHECK(code_edit->get_caret_column() == 0);
5008
5009
// Move multiple lines up with selection, right to left selection.
5010
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5011
code_edit->select(5, 2, 4, 1);
5012
code_edit->move_lines_up();
5013
CHECK(code_edit->get_text() == "test\nlines\nto\nmove\naround\n");
5014
CHECK(code_edit->has_selection());
5015
CHECK(code_edit->get_selection_origin_line() == 4);
5016
CHECK(code_edit->get_selection_origin_column() == 2);
5017
CHECK(code_edit->get_caret_line() == 3);
5018
CHECK(code_edit->get_caret_column() == 1);
5019
5020
// Move multiple lines with multiple carets. A line with multiple carets is only moved once.
5021
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5022
code_edit->select(5, 2, 5, 4);
5023
code_edit->add_caret(4, 0);
5024
code_edit->add_caret(4, 4);
5025
code_edit->move_lines_up();
5026
CHECK(code_edit->get_text() == "test\nlines\nto\nmove\naround\n");
5027
CHECK(code_edit->get_caret_count() == 3);
5028
CHECK(code_edit->has_selection(0));
5029
CHECK(code_edit->get_selection_origin_line(0) == 4);
5030
CHECK(code_edit->get_selection_origin_column(0) == 2);
5031
CHECK(code_edit->get_caret_line(0) == 4);
5032
CHECK(code_edit->get_caret_column(0) == 4);
5033
CHECK_FALSE(code_edit->has_selection(1));
5034
CHECK(code_edit->get_caret_line(1) == 3);
5035
CHECK(code_edit->get_caret_column(1) == 0);
5036
CHECK_FALSE(code_edit->has_selection(2));
5037
CHECK(code_edit->get_caret_line(2) == 3);
5038
CHECK(code_edit->get_caret_column(2) == 4);
5039
code_edit->remove_secondary_carets();
5040
5041
// Move multiple separate lines with multiple selections.
5042
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5043
code_edit->select(2, 2, 1, 4);
5044
code_edit->add_caret(5, 0);
5045
code_edit->select(5, 0, 5, 1, 1);
5046
code_edit->move_lines_up();
5047
CHECK(code_edit->get_text() == "lines\nto\ntest\n\naround\nmove");
5048
CHECK(code_edit->get_caret_count() == 2);
5049
CHECK(code_edit->has_selection(0));
5050
CHECK(code_edit->get_selection_origin_line(0) == 1);
5051
CHECK(code_edit->get_selection_origin_column(0) == 2);
5052
CHECK(code_edit->get_caret_line(0) == 0);
5053
CHECK(code_edit->get_caret_column(0) == 4);
5054
CHECK(code_edit->has_selection(1));
5055
CHECK(code_edit->get_selection_origin_line(1) == 4);
5056
CHECK(code_edit->get_selection_origin_column(1) == 0);
5057
CHECK(code_edit->get_caret_line(1) == 4);
5058
CHECK(code_edit->get_caret_column(1) == 1);
5059
code_edit->remove_secondary_carets();
5060
5061
// Move lines with adjacent selections that end at column 0.
5062
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5063
code_edit->select(1, 2, 2, 0);
5064
code_edit->add_caret(2, 2);
5065
code_edit->select(2, 2, 3, 0, 1);
5066
code_edit->move_lines_up();
5067
CHECK(code_edit->get_text() == "lines\nto\ntest\n\nmove\naround");
5068
CHECK(code_edit->get_caret_count() == 2);
5069
CHECK(code_edit->has_selection(0));
5070
CHECK(code_edit->get_selection_origin_line(0) == 0);
5071
CHECK(code_edit->get_selection_origin_column(0) == 2);
5072
CHECK(code_edit->get_caret_line(0) == 1);
5073
CHECK(code_edit->get_caret_column(0) == 0);
5074
CHECK(code_edit->has_selection(1));
5075
CHECK(code_edit->get_selection_origin_line(1) == 1);
5076
CHECK(code_edit->get_selection_origin_column(1) == 2);
5077
CHECK(code_edit->get_caret_line(1) == 2);
5078
CHECK(code_edit->get_caret_column(1) == 0);
5079
code_edit->remove_secondary_carets();
5080
code_edit->deselect();
5081
5082
code_edit->set_line_folding_enabled(true);
5083
5084
// Move line up into a folded region unfolds it.
5085
code_edit->set_text("test\n\tline1 test\n\t\tline 2\ntest2");
5086
code_edit->set_caret_line(3);
5087
code_edit->set_caret_column(0);
5088
code_edit->fold_line(0);
5089
CHECK(code_edit->is_line_folded(0));
5090
code_edit->move_lines_up();
5091
CHECK(code_edit->get_caret_count() == 1);
5092
CHECK_FALSE(code_edit->has_selection(0));
5093
CHECK(code_edit->get_caret_line() == 2);
5094
CHECK(code_edit->get_caret_column() == 0);
5095
CHECK(code_edit->get_text() == "test\n\tline1 test\ntest2\n\t\tline 2");
5096
CHECK_FALSE(code_edit->is_line_folded(0));
5097
}
5098
5099
SUBCASE("[SceneTree][CodeEdit] move lines down") {
5100
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5101
5102
// Move line down with caret on it.
5103
code_edit->set_caret_line(1);
5104
code_edit->set_caret_column(1);
5105
code_edit->move_lines_down();
5106
CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
5107
CHECK(code_edit->get_caret_line() == 2);
5108
CHECK(code_edit->get_caret_column() == 1);
5109
5110
// Undo.
5111
code_edit->undo();
5112
CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
5113
CHECK(code_edit->get_caret_line() == 1);
5114
CHECK(code_edit->get_caret_column() == 1);
5115
5116
// Redo.
5117
code_edit->redo();
5118
CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
5119
CHECK(code_edit->get_caret_line() == 2);
5120
CHECK(code_edit->get_caret_column() == 1);
5121
5122
// Does nothing at the last line.
5123
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5124
code_edit->set_caret_line(5);
5125
code_edit->set_caret_column(1);
5126
code_edit->move_lines_down();
5127
CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
5128
CHECK(code_edit->get_caret_line() == 5);
5129
CHECK(code_edit->get_caret_column() == 1);
5130
5131
// Does nothing at the last line when selection ends at column 0.
5132
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5133
code_edit->select(4, 0, 5, 0);
5134
code_edit->move_lines_down();
5135
CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
5136
CHECK(code_edit->has_selection());
5137
CHECK(code_edit->get_selection_origin_line() == 4);
5138
CHECK(code_edit->get_selection_origin_column() == 0);
5139
CHECK(code_edit->get_caret_line() == 5);
5140
CHECK(code_edit->get_caret_column() == 0);
5141
5142
// Works on empty line.
5143
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5144
code_edit->set_caret_line(3);
5145
code_edit->set_caret_column(0);
5146
code_edit->move_lines_down();
5147
CHECK(code_edit->get_text() == "test\nlines\nto\nmove\n\naround");
5148
CHECK(code_edit->get_caret_line() == 4);
5149
CHECK(code_edit->get_caret_column() == 0);
5150
5151
// Move multiple lines down with selection.
5152
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5153
code_edit->select(1, 0, 2, 1);
5154
code_edit->move_lines_down();
5155
CHECK(code_edit->get_text() == "test\n\nlines\nto\nmove\naround");
5156
CHECK(code_edit->has_selection());
5157
CHECK(code_edit->get_selection_origin_line() == 2);
5158
CHECK(code_edit->get_selection_origin_column() == 0);
5159
CHECK(code_edit->get_caret_line() == 3);
5160
CHECK(code_edit->get_caret_column() == 1);
5161
5162
// Does not affect line with selection end at column 0.
5163
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5164
code_edit->select(1, 0, 2, 0);
5165
code_edit->move_lines_down();
5166
CHECK(code_edit->get_text() == "test\nto\nlines\n\nmove\naround");
5167
CHECK(code_edit->has_selection());
5168
CHECK(code_edit->get_selection_origin_line() == 2);
5169
CHECK(code_edit->get_selection_origin_column() == 0);
5170
CHECK(code_edit->get_caret_line() == 3);
5171
CHECK(code_edit->get_caret_column() == 0);
5172
5173
// Move multiple lines down with selection, right to left selection.
5174
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5175
code_edit->select(2, 2, 1, 1);
5176
code_edit->move_lines_down();
5177
CHECK(code_edit->get_text() == "test\n\nlines\nto\nmove\naround");
5178
CHECK(code_edit->has_selection());
5179
CHECK(code_edit->get_selection_origin_line() == 3);
5180
CHECK(code_edit->get_selection_origin_column() == 2);
5181
CHECK(code_edit->get_caret_line() == 2);
5182
CHECK(code_edit->get_caret_column() == 1);
5183
5184
// Move multiple lines with multiple carets. A line with multiple carets is only moved once.
5185
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5186
code_edit->select(1, 2, 1, 4);
5187
code_edit->add_caret(0, 0);
5188
code_edit->add_caret(0, 1);
5189
code_edit->move_lines_down();
5190
CHECK(code_edit->get_text() == "to\ntest\nlines\n\nmove\naround");
5191
CHECK(code_edit->get_caret_count() == 3);
5192
CHECK(code_edit->has_selection(0));
5193
CHECK(code_edit->get_selection_origin_line(0) == 2);
5194
CHECK(code_edit->get_selection_origin_column(0) == 2);
5195
CHECK(code_edit->get_caret_line(0) == 2);
5196
CHECK(code_edit->get_caret_column(0) == 4);
5197
CHECK_FALSE(code_edit->has_selection(1));
5198
CHECK(code_edit->get_caret_line(1) == 1);
5199
CHECK(code_edit->get_caret_column(1) == 0);
5200
CHECK_FALSE(code_edit->has_selection(2));
5201
CHECK(code_edit->get_caret_line(2) == 1);
5202
CHECK(code_edit->get_caret_column(2) == 1);
5203
5204
// Move multiple separate lines with multiple selections.
5205
code_edit->remove_secondary_carets();
5206
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5207
code_edit->select(0, 2, 1, 4);
5208
code_edit->add_caret(4, 0);
5209
code_edit->select(4, 0, 4, 2, 1);
5210
code_edit->move_lines_down();
5211
CHECK(code_edit->get_text() == "to\ntest\nlines\n\naround\nmove");
5212
CHECK(code_edit->get_caret_count() == 2);
5213
CHECK(code_edit->has_selection(0));
5214
CHECK(code_edit->get_selection_origin_line(0) == 1);
5215
CHECK(code_edit->get_selection_origin_column(0) == 2);
5216
CHECK(code_edit->get_caret_line(0) == 2);
5217
CHECK(code_edit->get_caret_column(0) == 4);
5218
CHECK(code_edit->has_selection(1));
5219
CHECK(code_edit->get_selection_origin_line(1) == 5);
5220
CHECK(code_edit->get_selection_origin_column(1) == 0);
5221
CHECK(code_edit->get_caret_line(1) == 5);
5222
CHECK(code_edit->get_caret_column(1) == 2);
5223
5224
// Move lines with adjacent selections that end at column 0.
5225
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5226
code_edit->select(1, 2, 2, 0);
5227
code_edit->add_caret(2, 2);
5228
code_edit->select(2, 2, 3, 0, 1);
5229
code_edit->move_lines_down();
5230
CHECK(code_edit->get_text() == "test\n\nlines\nto\nmove\naround");
5231
CHECK(code_edit->get_caret_count() == 2);
5232
CHECK(code_edit->has_selection(0));
5233
CHECK(code_edit->get_selection_origin_line(0) == 2);
5234
CHECK(code_edit->get_selection_origin_column(0) == 2);
5235
CHECK(code_edit->get_caret_line(0) == 3);
5236
CHECK(code_edit->get_caret_column(0) == 0);
5237
CHECK(code_edit->has_selection(1));
5238
CHECK(code_edit->get_selection_origin_line(1) == 3);
5239
CHECK(code_edit->get_selection_origin_column(1) == 2);
5240
CHECK(code_edit->get_caret_line(1) == 4);
5241
CHECK(code_edit->get_caret_column(1) == 0);
5242
code_edit->remove_secondary_carets();
5243
5244
// Move lines with disconnected adjacent selections that end at column 0.
5245
code_edit->set_text("test\nlines\nto\n\nmove\naround");
5246
code_edit->select(0, 2, 1, 0);
5247
code_edit->add_caret(2, 2);
5248
code_edit->select(2, 0, 3, 0, 1);
5249
code_edit->move_lines_down();
5250
CHECK(code_edit->get_text() == "lines\ntest\n\nto\nmove\naround");
5251
CHECK(code_edit->get_caret_count() == 2);
5252
CHECK(code_edit->has_selection(0));
5253
CHECK(code_edit->get_selection_origin_line(0) == 1);
5254
CHECK(code_edit->get_selection_origin_column(0) == 2);
5255
CHECK(code_edit->get_caret_line(0) == 2);
5256
CHECK(code_edit->get_caret_column(0) == 0);
5257
CHECK(code_edit->has_selection(1));
5258
CHECK(code_edit->get_selection_origin_line(1) == 3);
5259
CHECK(code_edit->get_selection_origin_column(1) == 0);
5260
CHECK(code_edit->get_caret_line(1) == 4);
5261
CHECK(code_edit->get_caret_column(1) == 0);
5262
code_edit->remove_secondary_carets();
5263
code_edit->deselect();
5264
5265
code_edit->set_line_folding_enabled(true);
5266
5267
// Move line down into a folded region unfolds it.
5268
code_edit->set_text("test\ntest2\n\tline1 test\n\t\tline 2\ntest2");
5269
code_edit->set_caret_line(0);
5270
code_edit->set_caret_column(0);
5271
code_edit->fold_line(1);
5272
CHECK(code_edit->is_line_folded(1));
5273
code_edit->move_lines_down();
5274
CHECK(code_edit->get_caret_count() == 1);
5275
CHECK_FALSE(code_edit->has_selection(0));
5276
CHECK(code_edit->get_caret_line() == 1);
5277
CHECK(code_edit->get_caret_column() == 0);
5278
CHECK(code_edit->get_text() == "test2\ntest\n\tline1 test\n\t\tline 2\ntest2");
5279
CHECK_FALSE(code_edit->is_line_folded(0));
5280
CHECK_FALSE(code_edit->is_line_folded(1));
5281
}
5282
5283
SUBCASE("[SceneTree][CodeEdit] delete lines") {
5284
code_edit->set_text("test\nlines\nto\n\ndelete");
5285
5286
// Delete line with caret on it.
5287
code_edit->set_caret_line(1);
5288
code_edit->set_caret_column(1);
5289
code_edit->delete_lines();
5290
CHECK(code_edit->get_text() == "test\nto\n\ndelete");
5291
CHECK(code_edit->get_caret_line() == 1);
5292
CHECK(code_edit->get_caret_column() == 1);
5293
5294
// Undo.
5295
code_edit->undo();
5296
CHECK(code_edit->get_text() == "test\nlines\nto\n\ndelete");
5297
CHECK(code_edit->get_caret_line() == 1);
5298
CHECK(code_edit->get_caret_column() == 1);
5299
5300
// Redo.
5301
code_edit->redo();
5302
CHECK(code_edit->get_text() == "test\nto\n\ndelete");
5303
CHECK(code_edit->get_caret_line() == 1);
5304
CHECK(code_edit->get_caret_column() == 1);
5305
5306
// Delete empty line.
5307
code_edit->set_caret_line(2);
5308
code_edit->set_caret_column(0);
5309
code_edit->delete_lines();
5310
CHECK(code_edit->get_text() == "test\nto\ndelete");
5311
CHECK(code_edit->get_caret_line() == 2);
5312
CHECK(code_edit->get_caret_column() == 0);
5313
5314
// Deletes only one line when there are multiple carets on it. Carets move down and the column gets clamped.
5315
code_edit->set_caret_line(0);
5316
code_edit->set_caret_column(0);
5317
code_edit->add_caret(0, 1);
5318
code_edit->add_caret(0, 4);
5319
code_edit->delete_lines();
5320
CHECK(code_edit->get_text() == "to\ndelete");
5321
CHECK(code_edit->get_caret_count() == 3);
5322
CHECK(code_edit->get_caret_line(0) == 0);
5323
CHECK(code_edit->get_caret_column(0) == 0);
5324
CHECK(code_edit->get_caret_line(1) == 0);
5325
CHECK(code_edit->get_caret_column(1) == 1);
5326
CHECK(code_edit->get_caret_line(2) == 0);
5327
CHECK(code_edit->get_caret_column(2) == 2);
5328
5329
// Delete multiple lines with selection.
5330
code_edit->remove_secondary_carets();
5331
code_edit->set_text("test\nlines\nto\n\ndelete");
5332
code_edit->select(0, 1, 2, 1);
5333
code_edit->delete_lines();
5334
CHECK(code_edit->get_text() == "\ndelete");
5335
CHECK_FALSE(code_edit->has_selection());
5336
CHECK(code_edit->get_caret_line() == 0);
5337
CHECK(code_edit->get_caret_column() == 0);
5338
5339
// Does not affect line with selection end at column 0.
5340
code_edit->set_text("test\nlines\nto\n\ndelete");
5341
code_edit->select(0, 1, 1, 0);
5342
code_edit->delete_lines();
5343
CHECK(code_edit->get_text() == "lines\nto\n\ndelete");
5344
CHECK_FALSE(code_edit->has_selection());
5345
CHECK(code_edit->get_caret_line() == 0);
5346
CHECK(code_edit->get_caret_column() == 0);
5347
5348
// Delete multiple lines with multiple carets.
5349
code_edit->set_text("test\nlines\nto\n\ndelete");
5350
code_edit->set_caret_line(0);
5351
code_edit->set_caret_column(2);
5352
code_edit->add_caret(1, 0);
5353
code_edit->add_caret(4, 5);
5354
code_edit->delete_lines();
5355
CHECK(code_edit->get_text() == "to\n");
5356
CHECK(code_edit->get_caret_count() == 2);
5357
CHECK(code_edit->get_caret_line(0) == 0);
5358
CHECK(code_edit->get_caret_column(0) == 0);
5359
CHECK(code_edit->get_caret_line(1) == 1);
5360
CHECK(code_edit->get_caret_column(1) == 0);
5361
5362
// Delete multiple separate lines with multiple selections.
5363
code_edit->remove_secondary_carets();
5364
code_edit->set_text("test\nlines\nto\n\ndelete");
5365
code_edit->add_caret(4, 5);
5366
code_edit->select(0, 1, 1, 1);
5367
code_edit->select(5, 5, 4, 0, 1);
5368
code_edit->delete_lines();
5369
CHECK(code_edit->get_text() == "to\n");
5370
CHECK_FALSE(code_edit->has_selection());
5371
CHECK(code_edit->get_caret_count() == 2);
5372
CHECK(code_edit->get_caret_line(0) == 0);
5373
CHECK(code_edit->get_caret_column(0) == 1);
5374
CHECK(code_edit->get_caret_line(1) == 1);
5375
CHECK(code_edit->get_caret_column(1) == 0);
5376
5377
// Deletes contents when there is only one line.
5378
code_edit->remove_secondary_carets();
5379
code_edit->set_text("test");
5380
code_edit->set_caret_line(0);
5381
code_edit->set_caret_column(4);
5382
code_edit->delete_lines();
5383
CHECK(code_edit->get_text() == "");
5384
CHECK_FALSE(code_edit->has_selection());
5385
CHECK(code_edit->get_caret_line() == 0);
5386
CHECK(code_edit->get_caret_column() == 0);
5387
}
5388
5389
SUBCASE("[SceneTree][CodeEdit] duplicate selection") {
5390
code_edit->set_text("test\nlines\nto\n\nduplicate");
5391
5392
// Duplicate selected text.
5393
code_edit->select(0, 1, 1, 2);
5394
code_edit->duplicate_selection();
5395
CHECK(code_edit->get_text() == "test\nliest\nlines\nto\n\nduplicate");
5396
CHECK(code_edit->has_selection());
5397
CHECK(code_edit->get_selection_origin_line() == 1);
5398
CHECK(code_edit->get_selection_origin_column() == 2);
5399
CHECK(code_edit->get_caret_line() == 2);
5400
CHECK(code_edit->get_caret_column() == 2);
5401
5402
// Undo.
5403
code_edit->undo();
5404
CHECK(code_edit->get_text() == "test\nlines\nto\n\nduplicate");
5405
CHECK(code_edit->has_selection());
5406
CHECK(code_edit->get_selection_origin_line() == 0);
5407
CHECK(code_edit->get_selection_origin_column() == 1);
5408
CHECK(code_edit->get_caret_line() == 1);
5409
CHECK(code_edit->get_caret_column() == 2);
5410
5411
// Redo.
5412
code_edit->redo();
5413
CHECK(code_edit->get_text() == "test\nliest\nlines\nto\n\nduplicate");
5414
CHECK(code_edit->has_selection());
5415
CHECK(code_edit->get_selection_origin_line() == 1);
5416
CHECK(code_edit->get_selection_origin_column() == 2);
5417
CHECK(code_edit->get_caret_line() == 2);
5418
CHECK(code_edit->get_caret_column() == 2);
5419
5420
// Duplicate selected text, right to left selection.
5421
code_edit->set_text("test\nlines\nto\n\nduplicate");
5422
code_edit->select(1, 1, 0, 2);
5423
code_edit->duplicate_selection();
5424
CHECK(code_edit->get_text() == "test\nlst\nlines\nto\n\nduplicate");
5425
CHECK(code_edit->has_selection());
5426
CHECK(code_edit->get_selection_origin_line() == 2);
5427
CHECK(code_edit->get_selection_origin_column() == 1);
5428
CHECK(code_edit->get_caret_line() == 1);
5429
CHECK(code_edit->get_caret_column() == 1);
5430
5431
// Duplicate line if there is no selection.
5432
code_edit->deselect();
5433
code_edit->set_text("test\nlines\nto\n\nduplicate");
5434
code_edit->set_caret_line(1);
5435
code_edit->set_caret_column(2);
5436
code_edit->duplicate_selection();
5437
CHECK(code_edit->get_text() == "test\nlines\nlines\nto\n\nduplicate");
5438
CHECK_FALSE(code_edit->has_selection());
5439
CHECK(code_edit->get_caret_line() == 2);
5440
CHECK(code_edit->get_caret_column() == 2);
5441
5442
// Duplicate multiple lines.
5443
code_edit->deselect();
5444
code_edit->set_text("test\nlines\nto\n\nduplicate");
5445
code_edit->set_caret_line(1);
5446
code_edit->set_caret_column(2);
5447
code_edit->add_caret(5, 0);
5448
code_edit->add_caret(0, 4);
5449
code_edit->duplicate_selection();
5450
CHECK(code_edit->get_text() == "test\ntest\nlines\nlines\nto\n\nduplicate\nduplicate");
5451
CHECK(code_edit->get_caret_count() == 3);
5452
CHECK_FALSE(code_edit->has_selection());
5453
CHECK(code_edit->get_caret_line(0) == 3);
5454
CHECK(code_edit->get_caret_column(0) == 2);
5455
CHECK(code_edit->get_caret_line(1) == 7);
5456
CHECK(code_edit->get_caret_column(1) == 0);
5457
CHECK(code_edit->get_caret_line(2) == 1);
5458
CHECK(code_edit->get_caret_column(2) == 4);
5459
5460
// Duplicate multiple separate selections.
5461
code_edit->remove_secondary_carets();
5462
code_edit->set_text("test\nlines\nto\n\nduplicate");
5463
code_edit->add_caret(4, 4);
5464
code_edit->add_caret(0, 1);
5465
code_edit->add_caret(0, 4);
5466
code_edit->select(2, 0, 2, 1, 0);
5467
code_edit->select(3, 0, 4, 4, 1);
5468
code_edit->select(0, 1, 0, 0, 2);
5469
code_edit->select(0, 2, 0, 4, 3);
5470
code_edit->duplicate_selection();
5471
CHECK(code_edit->get_text() == "ttestst\nlines\ntto\n\ndupl\nduplicate");
5472
CHECK(code_edit->get_caret_count() == 4);
5473
CHECK(code_edit->has_selection(0));
5474
CHECK(code_edit->get_selection_origin_line(0) == 2);
5475
CHECK(code_edit->get_selection_origin_column(0) == 1);
5476
CHECK(code_edit->get_caret_line(0) == 2);
5477
CHECK(code_edit->get_caret_column(0) == 2);
5478
CHECK(code_edit->has_selection(1));
5479
CHECK(code_edit->get_selection_origin_line(1) == 4);
5480
CHECK(code_edit->get_selection_origin_column(1) == 4);
5481
CHECK(code_edit->get_caret_line(1) == 5);
5482
CHECK(code_edit->get_caret_column(1) == 4);
5483
CHECK(code_edit->has_selection(2));
5484
CHECK(code_edit->get_selection_origin_line(2) == 0);
5485
CHECK(code_edit->get_selection_origin_column(2) == 2);
5486
CHECK(code_edit->get_caret_line(2) == 0);
5487
CHECK(code_edit->get_caret_column(2) == 1);
5488
CHECK(code_edit->has_selection(3));
5489
CHECK(code_edit->get_selection_origin_line(3) == 0);
5490
CHECK(code_edit->get_selection_origin_column(3) == 5);
5491
CHECK(code_edit->get_caret_line(3) == 0);
5492
CHECK(code_edit->get_caret_column(3) == 7);
5493
5494
// Duplicate adjacent selections.
5495
code_edit->remove_secondary_carets();
5496
code_edit->set_text("test\nlines\nto\n\nduplicate");
5497
code_edit->add_caret(1, 2);
5498
code_edit->select(1, 0, 1, 1, 0);
5499
code_edit->select(1, 1, 1, 4, 1);
5500
code_edit->duplicate_selection();
5501
CHECK(code_edit->get_text() == "test\nllineines\nto\n\nduplicate");
5502
CHECK(code_edit->get_caret_count() == 2);
5503
CHECK(code_edit->has_selection(0));
5504
CHECK(code_edit->get_selection_origin_line(0) == 1);
5505
CHECK(code_edit->get_selection_origin_column(0) == 1);
5506
CHECK(code_edit->get_caret_line(0) == 1);
5507
CHECK(code_edit->get_caret_column(0) == 2);
5508
CHECK(code_edit->has_selection(1));
5509
CHECK(code_edit->get_selection_origin_line(1) == 1);
5510
CHECK(code_edit->get_selection_origin_column(1) == 5);
5511
CHECK(code_edit->get_caret_line(1) == 1);
5512
CHECK(code_edit->get_caret_column(1) == 8);
5513
5514
// Duplicate lines then duplicate selections when there are both selections and non-selections.
5515
code_edit->remove_secondary_carets();
5516
code_edit->set_text("test duplicate");
5517
code_edit->select(0, 14, 0, 13, 0);
5518
code_edit->add_caret(0, 8);
5519
code_edit->add_caret(0, 4);
5520
code_edit->select(0, 2, 0, 4, 2);
5521
code_edit->duplicate_selection();
5522
CHECK(code_edit->get_text() == "test duplicate\ntestst duplicatee");
5523
CHECK(code_edit->get_caret_count() == 3);
5524
CHECK(code_edit->has_selection(0));
5525
CHECK(code_edit->get_selection_origin_line(0) == 1);
5526
CHECK(code_edit->get_selection_origin_column(0) == 17);
5527
CHECK(code_edit->get_caret_line(0) == 1);
5528
CHECK(code_edit->get_caret_column(0) == 16);
5529
CHECK_FALSE(code_edit->has_selection(1));
5530
CHECK(code_edit->get_caret_line(1) == 1);
5531
CHECK(code_edit->get_caret_column(1) == 10);
5532
CHECK(code_edit->has_selection(2));
5533
CHECK(code_edit->get_selection_origin_line(2) == 1);
5534
CHECK(code_edit->get_selection_origin_column(2) == 4);
5535
CHECK(code_edit->get_caret_line(2) == 1);
5536
CHECK(code_edit->get_caret_column(2) == 6);
5537
}
5538
5539
SUBCASE("[SceneTree][CodeEdit] duplicate lines") {
5540
String reset_text = R"(extends Node
5541
5542
func _ready():
5543
var a := len(OS.get_cmdline_args())
5544
var b := get_child_count()
5545
var c := a + b
5546
for i in range(c):
5547
print("This is the solution: ", sin(i))
5548
var pos = get_index() - 1
5549
print("Make sure this exits: %b" % pos)
5550
)";
5551
5552
code_edit->set_text(reset_text);
5553
5554
// Duplicate a single line without selection.
5555
code_edit->set_caret_line(0);
5556
code_edit->duplicate_lines();
5557
CHECK(code_edit->get_line(0) == "extends Node");
5558
CHECK(code_edit->get_line(1) == "extends Node");
5559
CHECK(code_edit->get_line(2) == "");
5560
CHECK(code_edit->get_caret_line() == 1);
5561
CHECK(code_edit->get_caret_column() == 0);
5562
5563
// Duplicate multiple lines with selection.
5564
code_edit->set_text(reset_text);
5565
code_edit->select(4, 8, 6, 15);
5566
code_edit->duplicate_lines();
5567
CHECK(code_edit->get_text() == R"(extends Node
5568
5569
func _ready():
5570
var a := len(OS.get_cmdline_args())
5571
var b := get_child_count()
5572
var c := a + b
5573
for i in range(c):
5574
var b := get_child_count()
5575
var c := a + b
5576
for i in range(c):
5577
print("This is the solution: ", sin(i))
5578
var pos = get_index() - 1
5579
print("Make sure this exits: %b" % pos)
5580
)");
5581
CHECK(code_edit->has_selection());
5582
CHECK(code_edit->get_selection_origin_line() == 7);
5583
CHECK(code_edit->get_selection_origin_column() == 8);
5584
CHECK(code_edit->get_caret_line() == 9);
5585
CHECK(code_edit->get_caret_column() == 15);
5586
5587
// Duplicate multiple lines with right to left selection.
5588
code_edit->set_text(reset_text);
5589
code_edit->select(6, 15, 4, 8);
5590
code_edit->duplicate_lines();
5591
CHECK(code_edit->get_text() == R"(extends Node
5592
5593
func _ready():
5594
var a := len(OS.get_cmdline_args())
5595
var b := get_child_count()
5596
var c := a + b
5597
for i in range(c):
5598
var b := get_child_count()
5599
var c := a + b
5600
for i in range(c):
5601
print("This is the solution: ", sin(i))
5602
var pos = get_index() - 1
5603
print("Make sure this exits: %b" % pos)
5604
)");
5605
CHECK(code_edit->has_selection());
5606
CHECK(code_edit->get_selection_origin_line() == 9);
5607
CHECK(code_edit->get_selection_origin_column() == 15);
5608
CHECK(code_edit->get_caret_line() == 7);
5609
CHECK(code_edit->get_caret_column() == 8);
5610
5611
// Duplicate single lines with multiple carets. Multiple carets on a single line only duplicate once.
5612
code_edit->remove_secondary_carets();
5613
code_edit->deselect();
5614
code_edit->set_text(reset_text);
5615
code_edit->set_caret_line(3);
5616
code_edit->set_caret_column(1);
5617
code_edit->add_caret(5, 1);
5618
code_edit->add_caret(5, 5);
5619
code_edit->add_caret(4, 2);
5620
code_edit->duplicate_lines();
5621
CHECK(code_edit->get_text() == R"(extends Node
5622
5623
func _ready():
5624
var a := len(OS.get_cmdline_args())
5625
var a := len(OS.get_cmdline_args())
5626
var b := get_child_count()
5627
var b := get_child_count()
5628
var c := a + b
5629
var c := a + b
5630
for i in range(c):
5631
print("This is the solution: ", sin(i))
5632
var pos = get_index() - 1
5633
print("Make sure this exits: %b" % pos)
5634
)");
5635
CHECK(code_edit->get_caret_count() == 4);
5636
CHECK_FALSE(code_edit->has_selection(0));
5637
CHECK(code_edit->get_caret_line(0) == 4);
5638
CHECK(code_edit->get_caret_column(0) == 1);
5639
CHECK_FALSE(code_edit->has_selection(1));
5640
CHECK(code_edit->get_caret_line(1) == 8);
5641
CHECK(code_edit->get_caret_column(1) == 1);
5642
CHECK_FALSE(code_edit->has_selection(2));
5643
CHECK(code_edit->get_caret_line(2) == 8);
5644
CHECK(code_edit->get_caret_column(2) == 5);
5645
CHECK_FALSE(code_edit->has_selection(3));
5646
CHECK(code_edit->get_caret_line(3) == 6);
5647
CHECK(code_edit->get_caret_column(3) == 2);
5648
5649
// Duplicate multiple lines with multiple selections.
5650
code_edit->remove_secondary_carets();
5651
code_edit->set_text(reset_text);
5652
code_edit->add_caret(4, 2);
5653
code_edit->add_caret(6, 0);
5654
code_edit->add_caret(7, 8);
5655
code_edit->select(0, 0, 2, 5, 0);
5656
code_edit->select(3, 0, 4, 2, 1);
5657
code_edit->select(7, 1, 6, 0, 2);
5658
code_edit->select(7, 3, 7, 8, 3);
5659
code_edit->duplicate_lines();
5660
CHECK(code_edit->get_text() == R"(extends Node
5661
5662
func _ready():
5663
extends Node
5664
5665
func _ready():
5666
var a := len(OS.get_cmdline_args())
5667
var b := get_child_count()
5668
var a := len(OS.get_cmdline_args())
5669
var b := get_child_count()
5670
var c := a + b
5671
for i in range(c):
5672
print("This is the solution: ", sin(i))
5673
for i in range(c):
5674
print("This is the solution: ", sin(i))
5675
var pos = get_index() - 1
5676
print("Make sure this exits: %b" % pos)
5677
)");
5678
CHECK(code_edit->get_caret_count() == 4);
5679
CHECK(code_edit->has_selection(0));
5680
CHECK(code_edit->get_selection_origin_line(0) == 3);
5681
CHECK(code_edit->get_selection_origin_column(0) == 0);
5682
CHECK(code_edit->get_caret_line(0) == 5);
5683
CHECK(code_edit->get_caret_column(0) == 5);
5684
5685
CHECK(code_edit->has_selection(1));
5686
CHECK(code_edit->get_selection_origin_line(1) == 8);
5687
CHECK(code_edit->get_selection_origin_column(1) == 0);
5688
CHECK(code_edit->get_caret_line(1) == 9);
5689
CHECK(code_edit->get_caret_column(1) == 2);
5690
5691
CHECK(code_edit->has_selection(2));
5692
CHECK(code_edit->get_selection_origin_line(2) == 14);
5693
CHECK(code_edit->get_selection_origin_column(2) == 1);
5694
CHECK(code_edit->get_caret_line(2) == 13);
5695
CHECK(code_edit->get_caret_column(2) == 0);
5696
5697
CHECK(code_edit->has_selection(3));
5698
CHECK(code_edit->get_selection_origin_line(3) == 14);
5699
CHECK(code_edit->get_selection_origin_column(3) == 3);
5700
CHECK(code_edit->get_caret_line(3) == 14);
5701
CHECK(code_edit->get_caret_column(3) == 8);
5702
}
5703
5704
memdelete(code_edit);
5705
}
5706
5707
} // namespace TestCodeEdit
5708
5709