Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/core/templates/test_hash_set.h
10278 views
1
/**************************************************************************/
2
/* test_hash_set.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/templates/hash_set.h"
34
35
#include "tests/test_macros.h"
36
37
namespace TestHashSet {
38
39
TEST_CASE("[HashSet] List initialization") {
40
HashSet<int> set{ 0, 1, 2, 3, 4 };
41
42
CHECK(set.size() == 5);
43
CHECK(set.has(0));
44
CHECK(set.has(1));
45
CHECK(set.has(2));
46
CHECK(set.has(3));
47
CHECK(set.has(4));
48
}
49
50
TEST_CASE("[HashSet] List initialization with existing elements") {
51
HashSet<int> set{ 0, 0, 0, 0, 0 };
52
53
CHECK(set.size() == 1);
54
CHECK(set.has(0));
55
}
56
57
TEST_CASE("[HashSet] Insert element") {
58
HashSet<int> set;
59
HashSet<int>::Iterator e = set.insert(42);
60
61
CHECK(e);
62
CHECK(*e == 42);
63
CHECK(set.has(42));
64
CHECK(set.find(42));
65
set.reset();
66
}
67
68
TEST_CASE("[HashSet] Insert existing element") {
69
HashSet<int> set;
70
set.insert(42);
71
set.insert(42);
72
73
CHECK(set.has(42));
74
CHECK(set.size() == 1);
75
}
76
77
TEST_CASE("[HashSet] Insert, iterate and remove many elements") {
78
const int elem_max = 12343;
79
HashSet<int> set;
80
for (int i = 0; i < elem_max; i++) {
81
set.insert(i);
82
}
83
84
//insert order should have been kept
85
int idx = 0;
86
for (const int &K : set) {
87
CHECK(idx == K);
88
CHECK(set.has(idx));
89
idx++;
90
}
91
92
Vector<int> elems_still_valid;
93
94
for (int i = 0; i < elem_max; i++) {
95
if ((i % 5) == 0) {
96
set.erase(i);
97
} else {
98
elems_still_valid.push_back(i);
99
}
100
}
101
102
CHECK(elems_still_valid.size() == set.size());
103
104
for (int i = 0; i < elems_still_valid.size(); i++) {
105
CHECK(set.has(elems_still_valid[i]));
106
}
107
}
108
109
TEST_CASE("[HashSet] Insert, iterate and remove many strings") {
110
// This tests a key that uses allocation, to see if any leaks occur
111
112
uint64_t pre_mem = Memory::get_mem_usage();
113
const int elem_max = 4018;
114
HashSet<String> set;
115
for (int i = 0; i < elem_max; i++) {
116
set.insert(itos(i));
117
}
118
119
//insert order should have been kept
120
int idx = 0;
121
for (const String &K : set) {
122
CHECK(itos(idx) == K);
123
CHECK(set.has(itos(idx)));
124
idx++;
125
}
126
127
Vector<String> elems_still_valid;
128
129
for (int i = 0; i < elem_max; i++) {
130
if ((i % 5) == 0) {
131
set.erase(itos(i));
132
} else {
133
elems_still_valid.push_back(itos(i));
134
}
135
}
136
137
CHECK(elems_still_valid.size() == set.size());
138
139
for (int i = 0; i < elems_still_valid.size(); i++) {
140
CHECK(set.has(elems_still_valid[i]));
141
}
142
143
elems_still_valid.clear();
144
set.reset();
145
146
CHECK(Memory::get_mem_usage() == pre_mem);
147
}
148
149
TEST_CASE("[HashSet] Erase via element") {
150
HashSet<int> set;
151
HashSet<int>::Iterator e = set.insert(42);
152
set.remove(e);
153
CHECK(!set.has(42));
154
CHECK(!set.find(42));
155
}
156
157
TEST_CASE("[HashSet] Erase via key") {
158
HashSet<int> set;
159
set.insert(42);
160
set.insert(49);
161
set.erase(42);
162
CHECK(!set.has(42));
163
CHECK(!set.find(42));
164
}
165
166
TEST_CASE("[HashSet] Insert and erase half elements") {
167
HashSet<int> set;
168
set.insert(1);
169
set.insert(2);
170
set.insert(3);
171
set.insert(4);
172
set.erase(1);
173
set.erase(3);
174
175
CHECK(set.size() == 2);
176
CHECK(set.has(2));
177
CHECK(set.has(4));
178
}
179
180
TEST_CASE("[HashSet] Size") {
181
HashSet<int> set;
182
set.insert(42);
183
set.insert(123);
184
set.insert(123);
185
set.insert(0);
186
set.insert(123485);
187
188
CHECK(set.size() == 4);
189
}
190
191
TEST_CASE("[HashSet] Iteration") {
192
HashSet<int> set;
193
set.insert(42);
194
set.insert(123);
195
set.insert(0);
196
set.insert(123485);
197
198
Vector<int> expected;
199
expected.push_back(42);
200
expected.push_back(123);
201
expected.push_back(0);
202
expected.push_back(123485);
203
204
int idx = 0;
205
for (const int &E : set) {
206
CHECK(expected[idx] == E);
207
++idx;
208
}
209
}
210
211
TEST_CASE("[HashSet] Copy") {
212
HashSet<int> set;
213
set.insert(42);
214
set.insert(123);
215
set.insert(0);
216
set.insert(123485);
217
218
Vector<int> expected;
219
expected.push_back(42);
220
expected.push_back(123);
221
expected.push_back(0);
222
expected.push_back(123485);
223
224
HashSet<int> copy_assign = set;
225
226
int idx = 0;
227
for (const int &E : copy_assign) {
228
CHECK(expected[idx] == E);
229
++idx;
230
}
231
232
HashSet<int> copy_construct(set);
233
234
idx = 0;
235
for (const int &E : copy_construct) {
236
CHECK(expected[idx] == E);
237
++idx;
238
}
239
}
240
241
TEST_CASE("[HashSet] Equality") {
242
// Empty sets.
243
CHECK(HashSet<int>{} == HashSet<int>{});
244
CHECK(HashSet<int>{} != HashSet<int>{ 1, 2, 3 });
245
CHECK(HashSet<int>{ 1, 2, 3 } != HashSet<int>{});
246
247
// Different length.
248
CHECK(HashSet<int>{ 1, 2, 3 } != HashSet<int>{ 1, 2, 3, 4 });
249
CHECK(HashSet<int>{ 1, 2, 3, 4 } != HashSet<int>{ 4, 3, 2 });
250
251
// Same length.
252
CHECK(HashSet<int>{ 1, 2, 3 } == HashSet<int>{ 1, 2, 3 });
253
CHECK(HashSet<int>{ 1, 2, 3 } == HashSet<int>{ 3, 2, 1 });
254
CHECK(HashSet<int>{ 1, 2, 3 } != HashSet<int>{ 1, 2, 8 });
255
}
256
257
} // namespace TestHashSet
258
259