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