Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/core/variant/test_dictionary.cpp
23450 views
1
/**************************************************************************/
2
/* test_dictionary.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_dictionary)
34
35
#include "core/object/ref_counted.h"
36
#include "core/variant/typed_dictionary.h"
37
38
namespace TestDictionary {
39
40
TEST_CASE("[Dictionary] Assignment using bracket notation ([])") {
41
Dictionary map;
42
map["Hello"] = 0;
43
CHECK(int(map["Hello"]) == 0);
44
map["Hello"] = 3;
45
CHECK(int(map["Hello"]) == 3);
46
map["World!"] = 4;
47
CHECK(int(map["World!"]) == 4);
48
49
map[StringName("HelloName")] = 6;
50
CHECK(int(map[StringName("HelloName")]) == 6);
51
CHECK(int(map.find_key(6).get_type()) == Variant::STRING_NAME);
52
map[StringName("HelloName")] = 7;
53
CHECK(int(map[StringName("HelloName")]) == 7);
54
55
// Test String and StringName are equivalent.
56
map[StringName("Hello")] = 8;
57
CHECK(int(map["Hello"]) == 8);
58
map["Hello"] = 9;
59
CHECK(int(map[StringName("Hello")]) == 9);
60
61
// Test non-string keys, since keys can be of any Variant type.
62
map[12345] = -5;
63
CHECK(int(map[12345]) == -5);
64
map[false] = 128;
65
CHECK(int(map[false]) == 128);
66
map[Vector2(10, 20)] = 30;
67
CHECK(int(map[Vector2(10, 20)]) == 30);
68
map[0] = 400;
69
CHECK(int(map[0]) == 400);
70
// Check that assigning 0 doesn't overwrite the value for `false`.
71
CHECK(int(map[false]) == 128);
72
73
// Ensure read-only maps aren't modified by non-existing keys.
74
const int length = map.size();
75
map.make_read_only();
76
CHECK(int(map["This key does not exist"].get_type()) == Variant::NIL);
77
CHECK(map.size() == length);
78
}
79
80
TEST_CASE("[Dictionary] List init") {
81
Dictionary dict{
82
{ 0, "int" },
83
{ "packed_string_array", PackedStringArray({ "array", "of", "values" }) },
84
{ "key", Dictionary({ { "nested", 200 } }) },
85
{ Vector2(), "v2" },
86
};
87
CHECK(dict.size() == 4);
88
CHECK(dict[0] == "int");
89
CHECK(PackedStringArray(dict["packed_string_array"])[2] == "values");
90
CHECK(Dictionary(dict["key"])["nested"] == Variant(200));
91
CHECK(dict[Vector2()] == "v2");
92
93
TypedDictionary<double, double> tdict{
94
{ 0.0, 1.0 },
95
{ 5.0, 2.0 },
96
};
97
CHECK_EQ(tdict[0.0], Variant(1.0));
98
CHECK_EQ(tdict[5.0], Variant(2.0));
99
}
100
101
TEST_CASE("[Dictionary] get_key_list()") {
102
Dictionary map;
103
LocalVector<Variant> keys;
104
keys = map.get_key_list();
105
CHECK(keys.is_empty());
106
map[1] = 3;
107
keys = map.get_key_list();
108
CHECK(keys.size() == 1);
109
CHECK(int(keys[0]) == 1);
110
map[2] = 4;
111
keys = map.get_key_list();
112
CHECK(keys.size() == 2);
113
}
114
115
TEST_CASE("[Dictionary] get_key_at_index()") {
116
Dictionary map;
117
map[4] = 3;
118
Variant val = map.get_key_at_index(0);
119
CHECK(int(val) == 4);
120
map[3] = 1;
121
val = map.get_key_at_index(0);
122
CHECK(int(val) == 4);
123
val = map.get_key_at_index(1);
124
CHECK(int(val) == 3);
125
}
126
127
TEST_CASE("[Dictionary] getptr()") {
128
Dictionary map;
129
map[1] = 3;
130
Variant *key = map.getptr(1);
131
CHECK(int(*key) == 3);
132
key = map.getptr(2);
133
CHECK(key == nullptr);
134
}
135
136
TEST_CASE("[Dictionary] get_valid()") {
137
Dictionary map;
138
map[1] = 3;
139
Variant val = map.get_valid(1);
140
CHECK(int(val) == 3);
141
}
142
143
TEST_CASE("[Dictionary] set(), get(), and get_or_add()") {
144
Dictionary map;
145
146
map.set(1, 3);
147
Variant val = map.get(1, -1);
148
CHECK(int(val) == 3);
149
150
map.set(1, 5);
151
val = map.get(1, -1);
152
CHECK(int(val) == 5);
153
154
CHECK(int(map.get_or_add(1, 7)) == 5);
155
CHECK(int(map.get_or_add(2, 7)) == 7);
156
}
157
158
TEST_CASE("[Dictionary] make_read_only() and is_read_only()") {
159
Dictionary map;
160
CHECK_FALSE(map.is_read_only());
161
CHECK(map.set(1, 1));
162
163
map.make_read_only();
164
CHECK(map.is_read_only());
165
166
ERR_PRINT_OFF;
167
CHECK_FALSE(map.set(1, 2));
168
ERR_PRINT_ON;
169
}
170
171
TEST_CASE("[Dictionary] size(), is_empty() and clear()") {
172
Dictionary map;
173
CHECK(map.size() == 0);
174
CHECK(map.is_empty());
175
map[1] = 3;
176
CHECK(map.size() == 1);
177
CHECK(!map.is_empty());
178
map.clear();
179
CHECK(map.size() == 0);
180
CHECK(map.is_empty());
181
}
182
183
TEST_CASE("[Dictionary] has() and has_all()") {
184
Dictionary map;
185
CHECK(map.has(1) == false);
186
map[1] = 3;
187
CHECK(map.has(1));
188
Array keys;
189
keys.push_back(1);
190
CHECK(map.has_all(keys));
191
keys.push_back(2);
192
CHECK(map.has_all(keys) == false);
193
}
194
195
TEST_CASE("[Dictionary] keys() and values()") {
196
Dictionary map;
197
Array keys = map.keys();
198
Array values = map.values();
199
CHECK(keys.is_empty());
200
CHECK(values.is_empty());
201
map[1] = 3;
202
keys = map.keys();
203
values = map.values();
204
CHECK(int(keys[0]) == 1);
205
CHECK(int(values[0]) == 3);
206
}
207
208
TEST_CASE("[Dictionary] merge() and merged()") {
209
Dictionary d1 = {
210
{ "key1", 1 },
211
{ "key2", 2 },
212
};
213
Dictionary d2 = {
214
{ "key2", 200 },
215
{ "key3", 300 },
216
};
217
Dictionary expected_no_overwrite = {
218
{ "key1", 1 },
219
{ "key2", 2 },
220
{ "key3", 300 },
221
};
222
Dictionary expected_overwrite = {
223
{ "key1", 1 },
224
{ "key2", 200 },
225
{ "key3", 300 },
226
};
227
228
Dictionary d_test = d1.duplicate();
229
d_test.merge(d2, false);
230
CHECK_EQ(d_test, expected_no_overwrite);
231
232
d_test = d1.duplicate();
233
d_test.merge(d2, true);
234
CHECK_EQ(d_test, expected_overwrite);
235
236
CHECK_EQ(d1.merged(d2, false), expected_no_overwrite);
237
CHECK_EQ(d1.merged(d2, true), expected_overwrite);
238
}
239
240
TEST_CASE("[Dictionary] Duplicate dictionary") {
241
// d = {1: {1: 1}, {2: 2}: [2], [3]: 3}
242
Dictionary k2 = { { 2, 2 } };
243
Array k3 = { 3 };
244
Dictionary d = {
245
{ 1, Dictionary({ { 1, 1 } }) },
246
{ k2, Array({ 2 }) },
247
{ k3, 3 }
248
};
249
250
// Deep copy
251
Dictionary deep_d = d.duplicate(true);
252
CHECK_MESSAGE(deep_d.id() != d.id(), "Should create a new dictionary");
253
CHECK_MESSAGE(Dictionary(deep_d[1]).id() != Dictionary(d[1]).id(), "Should clone nested dictionary");
254
CHECK_MESSAGE(Array(deep_d[k2]).id() != Array(d[k2]).id(), "Should clone nested array");
255
CHECK_EQ(deep_d, d);
256
257
// Check that duplicate_deep matches duplicate(true)
258
Dictionary deep_d2 = d.duplicate_deep();
259
CHECK_EQ(deep_d, deep_d2);
260
261
deep_d[0] = 0;
262
CHECK_NE(deep_d, d);
263
deep_d.erase(0);
264
Dictionary(deep_d[1]).operator[](0) = 0;
265
CHECK_NE(deep_d, d);
266
Dictionary(deep_d[1]).erase(0);
267
CHECK_EQ(deep_d, d);
268
// Keys should also be copied
269
k2[0] = 0;
270
CHECK_NE(deep_d, d);
271
k2.erase(0);
272
CHECK_EQ(deep_d, d);
273
k3.push_back(0);
274
CHECK_NE(deep_d, d);
275
k3.pop_back();
276
CHECK_EQ(deep_d, d);
277
278
// Shallow copy
279
Dictionary shallow_d = d.duplicate(false);
280
CHECK_MESSAGE(shallow_d.id() != d.id(), "Should create a new array");
281
CHECK_MESSAGE(Dictionary(shallow_d[1]).id() == Dictionary(d[1]).id(), "Should keep nested dictionary");
282
CHECK_MESSAGE(Array(shallow_d[k2]).id() == Array(d[k2]).id(), "Should keep nested array");
283
CHECK_EQ(shallow_d, d);
284
shallow_d[0] = 0;
285
CHECK_NE(shallow_d, d);
286
shallow_d.erase(0);
287
#if 0 // TODO: recursion in dict key currently is buggy
288
// Keys should also be shallowed
289
k2[0] = 0;
290
CHECK_EQ(shallow_d, d);
291
k2.erase(0);
292
k3.push_back(0);
293
CHECK_EQ(shallow_d, d);
294
#endif
295
}
296
297
TEST_CASE("[Dictionary] Duplicate recursive dictionary") {
298
// Self recursive
299
Dictionary d;
300
d[1] = d;
301
302
Dictionary d_shallow = d.duplicate(false);
303
CHECK_EQ(d, d_shallow);
304
305
// Deep copy of recursive dictionary endup with recursion limit and return
306
// an invalid result (multiple nested dictionaries), the point is we should
307
// not end up with a segfault and an error log should be printed
308
ERR_PRINT_OFF;
309
d.duplicate(true);
310
ERR_PRINT_ON;
311
312
// Nested recursive
313
Dictionary d1;
314
Dictionary d2;
315
d1[2] = d2;
316
d2[1] = d1;
317
318
Dictionary d1_shallow = d1.duplicate(false);
319
CHECK_EQ(d1, d1_shallow);
320
321
// Same deep copy issue as above
322
ERR_PRINT_OFF;
323
d1.duplicate(true);
324
ERR_PRINT_ON;
325
326
// Break the recursivity otherwise Dictionary teardown will leak memory
327
d.clear();
328
d1.clear();
329
d2.clear();
330
}
331
332
#if 0 // TODO: duplicate recursion in dict key is currently buggy
333
TEST_CASE("[Dictionary] Duplicate recursive dictionary on keys") {
334
// Self recursive
335
Dictionary d;
336
d[d] = d;
337
338
Dictionary d_shallow = d.duplicate(false);
339
CHECK_EQ(d, d_shallow);
340
341
// Deep copy of recursive dictionary endup with recursion limit and return
342
// an invalid result (multiple nested dictionaries), the point is we should
343
// not end up with a segfault and an error log should be printed
344
ERR_PRINT_OFF;
345
d.duplicate(true);
346
ERR_PRINT_ON;
347
348
// Nested recursive
349
Dictionary d1;
350
Dictionary d2;
351
d1[d2] = d2;
352
d2[d1] = d1;
353
354
Dictionary d1_shallow = d1.duplicate(false);
355
CHECK_EQ(d1, d1_shallow);
356
357
// Same deep copy issue as above
358
ERR_PRINT_OFF;
359
d1.duplicate(true);
360
ERR_PRINT_ON;
361
362
// Break the recursivity otherwise Dictionary teardown will leak memory
363
d.clear();
364
d1.clear();
365
d2.clear();
366
}
367
#endif
368
369
TEST_CASE("[Dictionary] Hash dictionary") {
370
// d = {1: {1: 1}, {2: 2}: [2], [3]: 3}
371
Dictionary k2 = { { 2, 2 } };
372
Array k3 = { 3 };
373
Dictionary d = {
374
{ 1, Dictionary({ { 1, 1 } }) },
375
{ k2, Array({ 2 }) },
376
{ k3, 3 }
377
};
378
uint32_t original_hash = d.hash();
379
380
// Modify dict change the hash
381
d[0] = 0;
382
CHECK_NE(d.hash(), original_hash);
383
d.erase(0);
384
CHECK_EQ(d.hash(), original_hash);
385
386
// Modify nested item change the hash
387
Dictionary(d[1]).operator[](0) = 0;
388
CHECK_NE(d.hash(), original_hash);
389
Dictionary(d[1]).erase(0);
390
Array(d[k2]).push_back(0);
391
CHECK_NE(d.hash(), original_hash);
392
Array(d[k2]).pop_back();
393
394
// Modify a key change the hash
395
k2[0] = 0;
396
CHECK_NE(d.hash(), original_hash);
397
k2.erase(0);
398
CHECK_EQ(d.hash(), original_hash);
399
k3.push_back(0);
400
CHECK_NE(d.hash(), original_hash);
401
k3.pop_back();
402
CHECK_EQ(d.hash(), original_hash);
403
404
// Duplication doesn't change the hash
405
Dictionary d2 = d.duplicate(true);
406
CHECK_EQ(d2.hash(), original_hash);
407
}
408
409
TEST_CASE("[Dictionary] Hash recursive dictionary") {
410
Dictionary d;
411
d[1] = d;
412
413
// Hash should reach recursion limit, we just make sure this doesn't blow up
414
ERR_PRINT_OFF;
415
d.hash();
416
ERR_PRINT_ON;
417
418
// Break the recursivity otherwise Dictionary teardown will leak memory
419
d.clear();
420
}
421
422
#if 0 // TODO: recursion in dict key is currently buggy
423
TEST_CASE("[Dictionary] Hash recursive dictionary on keys") {
424
Dictionary d;
425
d[d] = 1;
426
427
// Hash should reach recursion limit, we just make sure this doesn't blow up
428
ERR_PRINT_OFF;
429
d.hash();
430
ERR_PRINT_ON;
431
432
// Break the recursivity otherwise Dictionary teardown will leak memory
433
d.clear();
434
}
435
#endif
436
437
TEST_CASE("[Dictionary] Empty comparison") {
438
Dictionary d1;
439
Dictionary d2;
440
441
// test both operator== and operator!=
442
CHECK_EQ(d1, d2);
443
CHECK_FALSE(d1 != d2);
444
}
445
446
TEST_CASE("[Dictionary] Flat comparison") {
447
Dictionary d1 = { { 1, 1 } };
448
Dictionary d2 = { { 1, 1 } };
449
Dictionary other_d = { { 2, 1 } };
450
451
// test both operator== and operator!=
452
CHECK_EQ(d1, d1); // compare self
453
CHECK_FALSE(d1 != d1);
454
CHECK_EQ(d1, d2); // different equivalent arrays
455
CHECK_FALSE(d1 != d2);
456
CHECK_NE(d1, other_d); // different arrays with different content
457
CHECK_FALSE(d1 == other_d);
458
}
459
460
TEST_CASE("[Dictionary] Nested dictionary comparison") {
461
// d1 = {1: {2: {3: 4}}}
462
Dictionary d1 = { { 1, Dictionary({ { 2, Dictionary({ { 3, 4 } }) } }) } };
463
464
Dictionary d2 = d1.duplicate(true);
465
466
// other_d = {1: {2: {3: 0}}}
467
Dictionary other_d = { { 1, Dictionary({ { 2, Dictionary({ { 3, 0 } }) } }) } };
468
469
// test both operator== and operator!=
470
CHECK_EQ(d1, d1); // compare self
471
CHECK_FALSE(d1 != d1);
472
CHECK_EQ(d1, d2); // different equivalent arrays
473
CHECK_FALSE(d1 != d2);
474
CHECK_NE(d1, other_d); // different arrays with different content
475
CHECK_FALSE(d1 == other_d);
476
}
477
478
TEST_CASE("[Dictionary] Nested array comparison") {
479
// d1 = {1: [2, 3]}
480
Dictionary d1 = { { 1, { 2, 3 } } };
481
482
Dictionary d2 = d1.duplicate(true);
483
484
// other_d = {1: [2, 0]}
485
Dictionary other_d = { { 1, { 2, 0 } } };
486
487
// test both operator== and operator!=
488
CHECK_EQ(d1, d1); // compare self
489
CHECK_FALSE(d1 != d1);
490
CHECK_EQ(d1, d2); // different equivalent arrays
491
CHECK_FALSE(d1 != d2);
492
CHECK_NE(d1, other_d); // different arrays with different content
493
CHECK_FALSE(d1 == other_d);
494
}
495
496
TEST_CASE("[Dictionary] Recursive comparison") {
497
Dictionary d1;
498
d1[1] = d1;
499
500
Dictionary d2;
501
d2[1] = d2;
502
503
// Comparison should reach recursion limit
504
ERR_PRINT_OFF;
505
CHECK_EQ(d1, d2);
506
CHECK_FALSE(d1 != d2);
507
ERR_PRINT_ON;
508
509
d1[2] = 2;
510
d2[2] = 2;
511
512
// Comparison should reach recursion limit
513
ERR_PRINT_OFF;
514
CHECK_EQ(d1, d2);
515
CHECK_FALSE(d1 != d2);
516
ERR_PRINT_ON;
517
518
d1[3] = 3;
519
d2[3] = 0;
520
521
// Comparison should reach recursion limit
522
ERR_PRINT_OFF;
523
CHECK_NE(d1, d2);
524
CHECK_FALSE(d1 == d2);
525
ERR_PRINT_ON;
526
527
// Break the recursivity otherwise Dictionary teardown will leak memory
528
d1.clear();
529
d2.clear();
530
}
531
532
#if 0 // TODO: recursion in dict key is currently buggy
533
TEST_CASE("[Dictionary] Recursive comparison on keys") {
534
Dictionary d1;
535
// Hash computation should reach recursion limit
536
ERR_PRINT_OFF;
537
d1[d1] = 1;
538
ERR_PRINT_ON;
539
540
Dictionary d2;
541
// Hash computation should reach recursion limit
542
ERR_PRINT_OFF;
543
d2[d2] = 1;
544
ERR_PRINT_ON;
545
546
// Comparison should reach recursion limit
547
ERR_PRINT_OFF;
548
CHECK_EQ(d1, d2);
549
CHECK_FALSE(d1 != d2);
550
ERR_PRINT_ON;
551
552
d1[2] = 2;
553
d2[2] = 2;
554
555
// Comparison should reach recursion limit
556
ERR_PRINT_OFF;
557
CHECK_EQ(d1, d2);
558
CHECK_FALSE(d1 != d2);
559
ERR_PRINT_ON;
560
561
d1[3] = 3;
562
d2[3] = 0;
563
564
// Comparison should reach recursion limit
565
ERR_PRINT_OFF;
566
CHECK_NE(d1, d2);
567
CHECK_FALSE(d1 == d2);
568
ERR_PRINT_ON;
569
570
// Break the recursivity otherwise Dictionary teardown will leak memory
571
d1.clear();
572
d2.clear();
573
}
574
#endif
575
576
TEST_CASE("[Dictionary] Recursive self comparison") {
577
Dictionary d1;
578
Dictionary d2;
579
d1[1] = d2;
580
d2[1] = d1;
581
582
CHECK_EQ(d1, d1);
583
CHECK_FALSE(d1 != d1);
584
585
// Break the recursivity otherwise Dictionary teardown will leak memory
586
d1.clear();
587
d2.clear();
588
}
589
590
TEST_CASE("[Dictionary] Order and find") {
591
Dictionary d;
592
d[4] = "four";
593
d[8] = "eight";
594
d[12] = "twelve";
595
d["4"] = "four";
596
597
Array keys = { 4, 8, 12, "4" };
598
599
CHECK_EQ(d.keys(), keys);
600
CHECK_EQ(d.find_key("four"), Variant(4));
601
CHECK_EQ(d.find_key("does not exist"), Variant());
602
}
603
604
TEST_CASE("[Dictionary] sort()") {
605
Dictionary d;
606
d[3] = 3;
607
d[2] = 2;
608
d[4] = 4;
609
d[1] = 1;
610
611
Array expected_unsorted = { 3, 2, 4, 1 };
612
CHECK_EQ(d.keys(), expected_unsorted);
613
614
d.sort();
615
Array expected_sorted = { 1, 2, 3, 4 };
616
CHECK_EQ(d.keys(), expected_sorted);
617
618
Dictionary d_str;
619
d_str["b"] = 2;
620
d_str["c"] = 3;
621
d_str["a"] = 1;
622
623
d_str.sort();
624
Array expected_str_sorted = { "a", "b", "c" };
625
CHECK_EQ(d_str.keys(), expected_str_sorted);
626
}
627
628
TEST_CASE("[Dictionary] assign()") {
629
Dictionary untyped;
630
untyped["key1"] = "value";
631
CHECK(untyped.size() == 1);
632
633
Dictionary typed;
634
typed.set_typed(Variant::STRING, StringName(), Variant(), Variant::STRING, StringName(), Variant());
635
typed.assign(untyped);
636
CHECK(typed.size() == 1);
637
typed["key2"] = "value";
638
639
untyped.assign(typed);
640
CHECK(untyped.size() == 2);
641
untyped["key3"] = 5;
642
CHECK(untyped.size() == 3);
643
644
ERR_PRINT_OFF;
645
typed.assign(untyped);
646
ERR_PRINT_ON;
647
CHECK(typed.size() == 2);
648
}
649
650
TEST_CASE("[Dictionary] Typed copying") {
651
TypedDictionary<int, int> d1;
652
d1[0] = 1;
653
654
TypedDictionary<double, double> d2;
655
d2[0] = 1.0;
656
657
Dictionary d3 = d1;
658
TypedDictionary<int, int> d4 = d3;
659
660
Dictionary d5 = d2;
661
TypedDictionary<int, int> d6 = d5;
662
663
d3[0] = 2;
664
d4[0] = 3;
665
666
// Same typed TypedDictionary should be shared.
667
CHECK_EQ(d1[0], Variant(3));
668
CHECK_EQ(d3[0], Variant(3));
669
CHECK_EQ(d4[0], Variant(3));
670
671
d5[0] = 2.0;
672
d6[0] = 3.0;
673
674
// Different typed TypedDictionary should not be shared.
675
CHECK_EQ(d2[0], Variant(2.0));
676
CHECK_EQ(d5[0], Variant(2.0));
677
CHECK_EQ(d6[0], Variant(3.0));
678
679
d1.clear();
680
d2.clear();
681
d3.clear();
682
d4.clear();
683
d5.clear();
684
d6.clear();
685
}
686
687
TEST_CASE("[Dictionary] Type checks/comparisons") {
688
Dictionary d1;
689
CHECK_FALSE(d1.is_typed());
690
CHECK_FALSE(d1.is_typed_key());
691
CHECK_FALSE(d1.is_typed_value());
692
693
d1.set_typed(Variant::STRING, StringName(), Variant(), Variant::OBJECT, "Node", Variant());
694
CHECK(d1.is_typed());
695
CHECK(d1.is_typed_key());
696
CHECK(d1.is_typed_value());
697
CHECK_EQ(d1.get_typed_key_builtin(), Variant::STRING);
698
CHECK_EQ(d1.get_typed_value_builtin(), Variant::OBJECT);
699
CHECK_EQ(d1.get_typed_value_class_name(), "Node");
700
701
Dictionary d2;
702
CHECK_FALSE(d1.is_same_typed(d2));
703
CHECK_FALSE(d1.is_same_typed_key(d2));
704
CHECK_FALSE(d1.is_same_typed_value(d2));
705
706
d2.set_typed(Variant::STRING, StringName(), Variant(), Variant::STRING, StringName(), Variant());
707
CHECK_FALSE(d1.is_same_typed(d2));
708
CHECK(d1.is_same_typed_key(d2));
709
CHECK_FALSE(d1.is_same_typed_value(d2));
710
}
711
712
TEST_CASE("[Dictionary] Iteration") {
713
Dictionary a1 = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
714
Dictionary a2 = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
715
716
int idx = 0;
717
718
for (const KeyValue<Variant, Variant> &kv : (const Dictionary &)a1) {
719
CHECK_EQ(int(a2[kv.key]), int(kv.value));
720
idx++;
721
}
722
723
CHECK_EQ(idx, a1.size());
724
725
a1.clear();
726
a2.clear();
727
}
728
729
TEST_CASE("[Dictionary] Object value init") {
730
Object *a = memnew(Object);
731
Object *b = memnew(Object);
732
TypedDictionary<double, Object *> tdict = {
733
{ 0.0, a },
734
{ 5.0, b },
735
};
736
CHECK_EQ(tdict[0.0], Variant(a));
737
CHECK_EQ(tdict[5.0], Variant(b));
738
memdelete(a);
739
memdelete(b);
740
}
741
742
TEST_CASE("[Dictionary] RefCounted value init") {
743
Ref<RefCounted> a = memnew(RefCounted);
744
Ref<RefCounted> b = memnew(RefCounted);
745
TypedDictionary<double, Ref<RefCounted>> tdict = {
746
{ 0.0, a },
747
{ 5.0, b },
748
};
749
CHECK_EQ(tdict[0.0], Variant(a));
750
CHECK_EQ(tdict[5.0], Variant(b));
751
}
752
753
} // namespace TestDictionary
754
755