1.1 --- a/tests/test_map.cpp Sat Dec 30 15:21:16 2023 +0100 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,521 +0,0 @@ 1.4 -/* 1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 1.6 - * 1.7 - * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 1.8 - * 1.9 - * Redistribution and use in source and binary forms, with or without 1.10 - * modification, are permitted provided that the following conditions are met: 1.11 - * 1.12 - * 1. Redistributions of source code must retain the above copyright 1.13 - * notice, this list of conditions and the following disclaimer. 1.14 - * 1.15 - * 2. Redistributions in binary form must reproduce the above copyright 1.16 - * notice, this list of conditions and the following disclaimer in the 1.17 - * documentation and/or other materials provided with the distribution. 1.18 - * 1.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 1.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.29 - * POSSIBILITY OF SUCH DAMAGE. 1.30 - */ 1.31 - 1.32 -#include "cx/hash_map.h" 1.33 -#include "cx/utils.h" 1.34 -#include "cx/string.h" 1.35 -#include "util_allocator.h" 1.36 -#include "test_map_generics.h" 1.37 - 1.38 -#include <gtest/gtest.h> 1.39 -#include <unordered_map> 1.40 -#include <unordered_set> 1.41 - 1.42 -struct map_operation { 1.43 - enum { 1.44 - put, rm 1.45 - } op; 1.46 - char const *key; 1.47 - char const *value; 1.48 -}; 1.49 - 1.50 -auto generate_map_operations() -> std::vector<map_operation> { 1.51 - return { 1.52 - {map_operation::put, "key 1", "test"}, 1.53 - {map_operation::put, "key 2", "blub"}, 1.54 - {map_operation::put, "key 3", "hallo"}, 1.55 - {map_operation::put, "key 2", "foobar"}, 1.56 - {map_operation::put, "key 4", "value 4"}, 1.57 - {map_operation::put, "key 5", "value 5"}, 1.58 - {map_operation::put, "key 6", "value 6"}, 1.59 - {map_operation::rm, "key 4", nullptr}, 1.60 - {map_operation::put, "key 7", "value 7"}, 1.61 - {map_operation::put, "key 8", "value 8"}, 1.62 - {map_operation::rm, "does not exist", nullptr}, 1.63 - {map_operation::put, "key 9", "value 9"}, 1.64 - {map_operation::put, "key 6", "other value"}, 1.65 - {map_operation::put, "key 7", "something else"}, 1.66 - {map_operation::rm, "key 8", nullptr}, 1.67 - {map_operation::rm, "key 2", nullptr}, 1.68 - {map_operation::put, "key 8", "new value"}, 1.69 - }; 1.70 -} 1.71 - 1.72 -static void verify_map_contents( 1.73 - CxMap *map, 1.74 - std::unordered_map<std::string, std::string> const &refmap 1.75 -) { 1.76 - // verify key iterator 1.77 - { 1.78 - auto keyiter = cxMapIteratorKeys(map); 1.79 - std::unordered_set<std::string> keys; 1.80 - cx_foreach(CxHashKey*, elem, keyiter) { 1.81 - keys.insert(std::string(reinterpret_cast<char const *>(elem->data), elem->len)); 1.82 - } 1.83 - EXPECT_EQ(keyiter.index, map->size); 1.84 - ASSERT_EQ(keys.size(), map->size); 1.85 - for (auto &&k: keys) { 1.86 - EXPECT_NE(refmap.find(k), refmap.end()); 1.87 - } 1.88 - } 1.89 - 1.90 - // verify value iterator 1.91 - { 1.92 - auto valiter = cxMapIteratorValues(map); 1.93 - std::unordered_set<std::string> values; // we use that the values in our test data are unique strings 1.94 - cx_foreach(char const*, elem, valiter) { 1.95 - values.insert(std::string(elem)); 1.96 - } 1.97 - EXPECT_EQ(valiter.index, map->size); 1.98 - ASSERT_EQ(values.size(), map->size); 1.99 - for (auto &&v: values) { 1.100 - EXPECT_NE(std::find_if(refmap.begin(), refmap.end(), 1.101 - [v](auto const &e) { return e.second == v; }), refmap.end()); 1.102 - } 1.103 - } 1.104 - 1.105 - // verify pair iterator 1.106 - { 1.107 - auto pairiter = cxMapIterator(map); 1.108 - std::unordered_map<std::string, std::string> pairs; 1.109 - cx_foreach(CxMapEntry*, entry, pairiter) { 1.110 - pairs[std::string(reinterpret_cast<char const *>(entry->key->data), entry->key->len)] = std::string( 1.111 - (char *) entry->value); 1.112 - } 1.113 - EXPECT_EQ(pairiter.index, map->size); 1.114 - ASSERT_EQ(pairs.size(), refmap.size()); 1.115 - for (auto &&p: pairs) { 1.116 - ASSERT_EQ(p.second, refmap.at(p.first)); 1.117 - } 1.118 - } 1.119 -} 1.120 - 1.121 -TEST(CxHashMap, Create) { 1.122 - CxTestingAllocator allocator; 1.123 - auto map = cxHashMapCreate(&allocator, 1, 0); 1.124 - auto hmap = reinterpret_cast<struct cx_hash_map_s *>(map); 1.125 - EXPECT_GT(hmap->bucket_count, 0); 1.126 - cx_for_n(i, hmap->bucket_count) { 1.127 - EXPECT_EQ(hmap->buckets[i], nullptr); 1.128 - } 1.129 - EXPECT_EQ(map->item_size, 1); 1.130 - EXPECT_EQ(map->size, 0); 1.131 - EXPECT_EQ(map->allocator, &allocator); 1.132 - EXPECT_FALSE(map->store_pointer); 1.133 - EXPECT_EQ(map->cmpfunc, nullptr); 1.134 - EXPECT_EQ(map->simple_destructor, nullptr); 1.135 - EXPECT_EQ(map->advanced_destructor, nullptr); 1.136 - EXPECT_EQ(map->destructor_data, nullptr); 1.137 - cxMapStorePointers(map); 1.138 - EXPECT_TRUE(map->store_pointer); 1.139 - EXPECT_EQ(map->item_size, sizeof(void *)); 1.140 - cxMapStoreObjects(map); 1.141 - EXPECT_FALSE(map->store_pointer); 1.142 - 1.143 - cxMapDestroy(map); 1.144 - EXPECT_TRUE(allocator.verify()); 1.145 -} 1.146 - 1.147 -TEST(CxHashMap, CreateForStoringPointers) { 1.148 - CxTestingAllocator allocator; 1.149 - auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 0); 1.150 - auto hmap = reinterpret_cast<struct cx_hash_map_s *>(map); 1.151 - EXPECT_GT(hmap->bucket_count, 0); 1.152 - cx_for_n(i, hmap->bucket_count) { 1.153 - EXPECT_EQ(hmap->buckets[i], nullptr); 1.154 - } 1.155 - EXPECT_EQ(map->size, 0); 1.156 - EXPECT_EQ(map->allocator, &allocator); 1.157 - EXPECT_TRUE(map->store_pointer); 1.158 - EXPECT_EQ(map->item_size, sizeof(void *)); 1.159 - 1.160 - cxMapDestroy(map); 1.161 - EXPECT_TRUE(allocator.verify()); 1.162 -} 1.163 - 1.164 -TEST(CxHashMap, BasicOperations) { 1.165 - // create the map 1.166 - CxTestingAllocator allocator; 1.167 - auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 8); 1.168 - 1.169 - // create a reference map 1.170 - std::unordered_map<std::string, std::string> refmap; 1.171 - 1.172 - // generate operations 1.173 - auto ops = generate_map_operations(); 1.174 - 1.175 - // verify iterators for empty map 1.176 - verify_map_contents(map, refmap); 1.177 - 1.178 - // execute operations and verify results 1.179 - for (auto &&op: ops) { 1.180 - CxHashKey key = cx_hash_key_str(op.key); 1.181 - key.hash = 0; // force the hash map to compute the hash 1.182 - if (op.op == map_operation::put) { 1.183 - // execute a put operation and verify that the exact value can be read back 1.184 - refmap[std::string(op.key)] = std::string(op.value); 1.185 - int result = cxMapPut(map, key, (void *) op.value); 1.186 - EXPECT_EQ(result, 0); 1.187 - auto added = cxMapGet(map, key); 1.188 - EXPECT_EQ(memcmp(op.value, added, strlen(op.value)), 0); 1.189 - } else { 1.190 - // execute a remove and verify that the removed element was returned (or nullptr) 1.191 - auto found = refmap.find(op.key); 1.192 - auto removed = cxMapRemoveAndGet(map, key); 1.193 - if (found == refmap.end()) { 1.194 - EXPECT_EQ(removed, nullptr); 1.195 - } else { 1.196 - EXPECT_EQ(std::string((char *) removed), found->second); 1.197 - refmap.erase(found); 1.198 - } 1.199 - } 1.200 - // compare the current map state with the reference map 1.201 - verify_map_contents(map, refmap); 1.202 - } 1.203 - 1.204 - // destroy the map and verify the memory (de)allocations 1.205 - cxMapDestroy(map); 1.206 - EXPECT_TRUE(allocator.verify()); 1.207 -} 1.208 - 1.209 -TEST(CxHashMap, RemoveViaIterator) { 1.210 - CxTestingAllocator allocator; 1.211 - auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 4); 1.212 - 1.213 - cxMapPut(map, "key 1", (void *) "val 1"); 1.214 - cxMapPut(map, "key 2", (void *) "val 2"); 1.215 - cxMapPut(map, "key 3", (void *) "val 3"); 1.216 - cxMapPut(map, "key 4", (void *) "val 4"); 1.217 - cxMapPut(map, "key 5", (void *) "val 5"); 1.218 - cxMapPut(map, "key 6", (void *) "val 6"); 1.219 - 1.220 - auto iter = cxMapMutIterator(map); 1.221 - cx_foreach(CxMapEntry*, entry, iter) { 1.222 - if (reinterpret_cast<char const *>(entry->key->data)[4] % 2 == 1) cxIteratorFlagRemoval(iter); 1.223 - } 1.224 - EXPECT_EQ(map->size, 3); 1.225 - EXPECT_EQ(iter.index, map->size); 1.226 - 1.227 - EXPECT_EQ(cxMapGet(map, "key 1"), nullptr); 1.228 - EXPECT_NE(cxMapGet(map, "key 2"), nullptr); 1.229 - EXPECT_EQ(cxMapGet(map, "key 3"), nullptr); 1.230 - EXPECT_NE(cxMapGet(map, "key 4"), nullptr); 1.231 - EXPECT_EQ(cxMapGet(map, "key 5"), nullptr); 1.232 - EXPECT_NE(cxMapGet(map, "key 6"), nullptr); 1.233 - 1.234 - cxMapDestroy(map); 1.235 - EXPECT_TRUE(allocator.verify()); 1.236 -} 1.237 - 1.238 -TEST(CxHashMap, RehashNotRequired) { 1.239 - CxTestingAllocator allocator; 1.240 - auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 8); 1.241 - 1.242 - cxMapPut(map, "key 1", (void *) "val 1"); 1.243 - cxMapPut(map, "key 2", (void *) "val 2"); 1.244 - cxMapPut(map, "key 3", (void *) "val 3"); 1.245 - cxMapPut(map, "key 4", (void *) "val 4"); 1.246 - cxMapPut(map, "key 5", (void *) "val 5"); 1.247 - cxMapPut(map, "key 6", (void *) "val 6"); 1.248 - 1.249 - // 6/8 does not exceed 0.75, therefore the function should not rehash 1.250 - int result = cxMapRehash(map); 1.251 - EXPECT_EQ(result, 0); 1.252 - EXPECT_EQ(reinterpret_cast<struct cx_hash_map_s *>(map)->bucket_count, 8); 1.253 - 1.254 - cxMapDestroy(map); 1.255 - EXPECT_TRUE(allocator.verify()); 1.256 -} 1.257 - 1.258 -TEST(CxHashMap, Rehash) { 1.259 - CxTestingAllocator allocator; 1.260 - auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 7); 1.261 - 1.262 - cxMapPut(map, "key 1", (void *) "val 1"); 1.263 - cxMapPut(map, "key 2", (void *) "val 2"); 1.264 - cxMapPut(map, "key 3", (void *) "val 3"); 1.265 - cxMapPut(map, "foo 4", (void *) "val 4"); 1.266 - cxMapPut(map, "key 5", (void *) "val 5"); 1.267 - cxMapPut(map, "key 6", (void *) "val 6"); 1.268 - cxMapPut(map, "bar 7", (void *) "val 7"); 1.269 - cxMapPut(map, "key 8", (void *) "val 8"); 1.270 - cxMapPut(map, "key 9", (void *) "val 9"); 1.271 - cxMapPut(map, "key 10", (void *) "val 10"); 1.272 - 1.273 - int result = cxMapRehash(map); 1.274 - EXPECT_EQ(result, 0); 1.275 - EXPECT_EQ(reinterpret_cast<struct cx_hash_map_s *>(map)->bucket_count, 25); 1.276 - EXPECT_EQ(map->size, 10); 1.277 - 1.278 - EXPECT_STREQ((char *) cxMapGet(map, "key 1"), "val 1"); 1.279 - EXPECT_STREQ((char *) cxMapGet(map, "key 2"), "val 2"); 1.280 - EXPECT_STREQ((char *) cxMapGet(map, "key 3"), "val 3"); 1.281 - EXPECT_STREQ((char *) cxMapGet(map, "foo 4"), "val 4"); 1.282 - EXPECT_STREQ((char *) cxMapGet(map, "key 5"), "val 5"); 1.283 - EXPECT_STREQ((char *) cxMapGet(map, "key 6"), "val 6"); 1.284 - EXPECT_STREQ((char *) cxMapGet(map, "bar 7"), "val 7"); 1.285 - EXPECT_STREQ((char *) cxMapGet(map, "key 8"), "val 8"); 1.286 - EXPECT_STREQ((char *) cxMapGet(map, "key 9"), "val 9"); 1.287 - EXPECT_STREQ((char *) cxMapGet(map, "key 10"), "val 10"); 1.288 - 1.289 - cxMapDestroy(map); 1.290 - EXPECT_TRUE(allocator.verify()); 1.291 -} 1.292 - 1.293 -TEST(CxHashMap, Clear) { 1.294 - CxTestingAllocator allocator; 1.295 - auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 0); 1.296 - 1.297 - cxMapPut(map, "key 1", (void *) "val 1"); 1.298 - cxMapPut(map, "key 2", (void *) "val 2"); 1.299 - cxMapPut(map, "key 3", (void *) "val 3"); 1.300 - 1.301 - EXPECT_EQ(map->size, 3); 1.302 - 1.303 - cxMapClear(map); 1.304 - 1.305 - EXPECT_EQ(map->size, 0); 1.306 - EXPECT_EQ(cxMapGet(map, "key 1"), nullptr); 1.307 - EXPECT_EQ(cxMapGet(map, "key 2"), nullptr); 1.308 - EXPECT_EQ(cxMapGet(map, "key 3"), nullptr); 1.309 - 1.310 - cxMapDestroy(map); 1.311 - EXPECT_TRUE(allocator.verify()); 1.312 -} 1.313 - 1.314 -TEST(CxHashMap, StoreUcxStrings) { 1.315 - // create the map 1.316 - CxTestingAllocator allocator; 1.317 - auto map = cxHashMapCreate(&allocator, sizeof(cxstring), 8); 1.318 - 1.319 - // define some strings 1.320 - auto s1 = CX_STR("this"); 1.321 - auto s2 = CX_STR("is"); 1.322 - auto s3 = CX_STR("a"); 1.323 - auto s4 = CX_STR("test"); 1.324 - auto s5 = CX_STR("setup"); 1.325 - 1.326 - // put them into the map 1.327 - cxMapPut(map, "s1", &s1); 1.328 - cxMapPut(map, "s2", &s2); 1.329 - cxMapPut(map, "s3", &s3); 1.330 - cxMapPut(map, "s4", &s4); 1.331 - 1.332 - // overwrite a value 1.333 - cxMapPut(map, "s1", &s5); 1.334 - 1.335 - // look up a string 1.336 - auto s3p = reinterpret_cast<cxstring *>(cxMapGet(map, "s3")); 1.337 - EXPECT_EQ(s3p->length, s3.length); 1.338 - EXPECT_EQ(s3p->ptr, s3.ptr); 1.339 - EXPECT_NE(s3p, &s3); 1.340 - 1.341 - // remove a string 1.342 - cxMapRemove(map, "s2"); 1.343 - 1.344 - // iterate 1.345 - auto ref = std::vector{s5.ptr, s3.ptr, s4.ptr}; 1.346 - auto iter = cxMapIteratorValues(map); 1.347 - cx_foreach(cxstring*, s, iter) { 1.348 - auto found = std::find(ref.begin(), ref.end(), s->ptr); 1.349 - ASSERT_NE(found, ref.end()); 1.350 - ref.erase(found); 1.351 - } 1.352 - EXPECT_EQ(ref.size(), 0); 1.353 - 1.354 - cxMapDestroy(map); 1.355 - EXPECT_TRUE(allocator.verify()); 1.356 -} 1.357 - 1.358 -static void test_simple_destructor(void *data) { 1.359 - strcpy((char *) data, "OK"); 1.360 -} 1.361 - 1.362 -static void test_advanced_destructor( 1.363 - [[maybe_unused]] void *unused, 1.364 - void *data 1.365 -) { 1.366 - strcpy((char *) data, "OK"); 1.367 -} 1.368 - 1.369 -static void verify_any_destructor(CxMap *map) { 1.370 - auto k1 = cx_hash_key_str("key 1"); 1.371 - auto k2 = cx_hash_key_str("key 2"); 1.372 - auto k3 = cx_hash_key_str("key 3"); 1.373 - auto k4 = cx_hash_key_str("key 4"); 1.374 - auto k5 = cx_hash_key_str("key 5"); 1.375 - 1.376 - char v1[] = "val 1"; 1.377 - char v2[] = "val 2"; 1.378 - char v3[] = "val 3"; 1.379 - char v4[] = "val 4"; 1.380 - char v5[] = "val 5"; 1.381 - 1.382 - cxMapPut(map, k1, (void *) v1); 1.383 - cxMapPut(map, k2, (void *) v2); 1.384 - cxMapPut(map, k3, (void *) v3); 1.385 - cxMapPut(map, k4, (void *) v4); 1.386 - 1.387 - cxMapRemove(map, k2); 1.388 - auto r = cxMapRemoveAndGet(map, k3); 1.389 - cxMapDetach(map, k1); 1.390 - 1.391 - EXPECT_STREQ(v1, "val 1"); 1.392 - EXPECT_STREQ(v2, "OK"); 1.393 - EXPECT_STREQ(v3, "val 3"); 1.394 - EXPECT_STREQ(v4, "val 4"); 1.395 - EXPECT_STREQ(v5, "val 5"); 1.396 - EXPECT_EQ(r, v3); 1.397 - 1.398 - cxMapClear(map); 1.399 - 1.400 - EXPECT_STREQ(v1, "val 1"); 1.401 - EXPECT_STREQ(v2, "OK"); 1.402 - EXPECT_STREQ(v3, "val 3"); 1.403 - EXPECT_STREQ(v4, "OK"); 1.404 - EXPECT_STREQ(v5, "val 5"); 1.405 - 1.406 - cxMapPut(map, k1, (void *) v1); 1.407 - cxMapPut(map, k3, (void *) v3); 1.408 - cxMapPut(map, k5, (void *) v5); 1.409 - 1.410 - { 1.411 - auto iter = cxMapMutIteratorKeys(map); 1.412 - cx_foreach(CxHashKey*, key, iter) { 1.413 - if (reinterpret_cast<char const *>(key->data)[4] == '1') cxIteratorFlagRemoval(iter); 1.414 - } 1.415 - } 1.416 - { 1.417 - auto iter = cxMapMutIteratorValues(map); 1.418 - cx_foreach(char*, v, iter) { 1.419 - if (v[4] == '5') cxIteratorFlagRemoval(iter); 1.420 - } 1.421 - } 1.422 - 1.423 - EXPECT_STREQ(v1, "OK"); 1.424 - EXPECT_STREQ(v2, "OK"); 1.425 - EXPECT_STREQ(v3, "val 3"); 1.426 - EXPECT_STREQ(v4, "OK"); 1.427 - EXPECT_STREQ(v5, "OK"); 1.428 - 1.429 - v1[0] = v2[0] = v4[0] = v5[0] = 'c'; 1.430 - 1.431 - cxMapDestroy(map); 1.432 - 1.433 - EXPECT_STREQ(v1, "cK"); 1.434 - EXPECT_STREQ(v2, "cK"); 1.435 - EXPECT_STREQ(v3, "OK"); 1.436 - EXPECT_STREQ(v4, "cK"); 1.437 - EXPECT_STREQ(v5, "cK"); 1.438 -} 1.439 - 1.440 -TEST(CxHashMap, SimpleDestructor) { 1.441 - CxTestingAllocator allocator; 1.442 - auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 0); 1.443 - map->simple_destructor = test_simple_destructor; 1.444 - verify_any_destructor(map); 1.445 - EXPECT_TRUE(allocator.verify()); 1.446 -} 1.447 - 1.448 -TEST(CxHashMap, AdvancedDestructor) { 1.449 - CxTestingAllocator allocator; 1.450 - auto map = cxHashMapCreate(&allocator, CX_STORE_POINTERS, 0); 1.451 - map->advanced_destructor = test_advanced_destructor; 1.452 - verify_any_destructor(map); 1.453 - EXPECT_TRUE(allocator.verify()); 1.454 -} 1.455 - 1.456 -TEST(CxHashMap, Generics) { 1.457 - CxTestingAllocator allocator; 1.458 - auto map = test_map_generics_step_1(&allocator); 1.459 - 1.460 - EXPECT_EQ(map->size, 3); 1.461 - EXPECT_STREQ((char *) cxMapGet(map, "test"), "test"); 1.462 - EXPECT_STREQ((char *) cxMapGet(map, "foo"), "bar"); 1.463 - EXPECT_STREQ((char *) cxMapGet(map, "hallo"), "welt"); 1.464 - 1.465 - test_map_generics_step_2(map); 1.466 - 1.467 - EXPECT_EQ(map->size, 2); 1.468 - EXPECT_STREQ((char *) cxMapGet(map, "key"), "value"); 1.469 - EXPECT_STREQ((char *) cxMapGet(map, "foo"), "bar"); 1.470 - 1.471 - test_map_generics_step_3(map); 1.472 - 1.473 - EXPECT_EQ(map->size, 0); 1.474 - 1.475 - cxMapDestroy(map); 1.476 - EXPECT_TRUE(allocator.verify()); 1.477 -} 1.478 - 1.479 -TEST(EmptyMap, Size) { 1.480 - auto map = cxEmptyMap; 1.481 - 1.482 - EXPECT_EQ(map->size, 0); 1.483 -} 1.484 - 1.485 -TEST(EmptyMap, Iterator) { 1.486 - auto map = cxEmptyMap; 1.487 - 1.488 - auto it1 = cxMapIterator(map); 1.489 - auto it2 = cxMapIteratorValues(map); 1.490 - auto it3 = cxMapIteratorKeys(map); 1.491 - auto it4 = cxMapMutIterator(map); 1.492 - auto it5 = cxMapMutIteratorValues(map); 1.493 - auto it6 = cxMapMutIteratorKeys(map); 1.494 - 1.495 - EXPECT_FALSE(cxIteratorValid(it1)); 1.496 - EXPECT_FALSE(cxIteratorValid(it2)); 1.497 - EXPECT_FALSE(cxIteratorValid(it3)); 1.498 - EXPECT_FALSE(cxIteratorValid(it4)); 1.499 - EXPECT_FALSE(cxIteratorValid(it5)); 1.500 - EXPECT_FALSE(cxIteratorValid(it6)); 1.501 - 1.502 - int c = 0; 1.503 - cx_foreach(void*, data, it1) c++; 1.504 - cx_foreach(void*, data, it2) c++; 1.505 - cx_foreach(void*, data, it3) c++; 1.506 - cx_foreach(void*, data, it4) c++; 1.507 - cx_foreach(void*, data, it5) c++; 1.508 - cx_foreach(void*, data, it6) c++; 1.509 - EXPECT_EQ(c, 0); 1.510 -} 1.511 - 1.512 -TEST(EmptyMap, NoOps) { 1.513 - auto map = cxEmptyMap; 1.514 - 1.515 - ASSERT_NO_FATAL_FAILURE(cxMapClear(map)); 1.516 - ASSERT_NO_FATAL_FAILURE(cxMapDestroy(map)); 1.517 -} 1.518 - 1.519 -TEST(EmptyMap, Get) { 1.520 - auto map = cxEmptyMap; 1.521 - 1.522 - CxHashKey key = cx_hash_key_str("test"); 1.523 - EXPECT_EQ(cxMapGet(map, key), nullptr); 1.524 -}