diff options
author | George L. Albany <Megacake1234@gmail.com> | 2024-10-27 13:25:03 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-27 13:25:03 +0000 |
commit | 6e3e9dfb9857b751f59fd4b40c55e9262ff5a864 (patch) | |
tree | d064b49a4766ab69a0ac6e195868ad4b3443bab3 /tests | |
parent | bec9ffacba1385b0ba808f6dbb66abb7dc53639d (diff) | |
parent | 953af98c795066a5a450a3401cc8a4fbc6c12620 (diff) | |
download | redot-engine-6e3e9dfb9857b751f59fd4b40c55e9262ff5a864.tar.gz |
Merge pull request #814 from Spartan322/merge/61accf0
Merge commit godotengine/godot@61accf0
Diffstat (limited to 'tests')
-rw-r--r-- | tests/core/string/test_string.h | 18 | ||||
-rw-r--r-- | tests/core/templates/test_a_hash_map.h | 297 | ||||
-rw-r--r-- | tests/scene/test_tree.h | 126 | ||||
-rw-r--r-- | tests/test_main.cpp | 1 |
4 files changed, 441 insertions, 1 deletions
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 7733105c27..63b85b4b28 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -462,11 +462,27 @@ TEST_CASE("[String] Number to string") { CHECK(String::num(-0.0) == "-0"); // Includes sign even for zero. CHECK(String::num(3.141593) == "3.141593"); CHECK(String::num(3.141593, 3) == "3.142"); + CHECK(String::num(42.100023, 4) == "42.1"); // No trailing zeros. CHECK(String::num_scientific(30000000) == "3e+07"); + + // String::num_int64 tests. CHECK(String::num_int64(3141593) == "3141593"); + CHECK(String::num_int64(-3141593) == "-3141593"); CHECK(String::num_int64(0xA141593, 16) == "a141593"); CHECK(String::num_int64(0xA141593, 16, true) == "A141593"); - CHECK(String::num(42.100023, 4) == "42.1"); // No trailing zeros. + ERR_PRINT_OFF; + CHECK(String::num_int64(3141593, 1) == ""); // Invalid base < 2. + CHECK(String::num_int64(3141593, 37) == ""); // Invalid base > 36. + ERR_PRINT_ON; + + // String::num_uint64 tests. + CHECK(String::num_uint64(4294967295) == "4294967295"); + CHECK(String::num_uint64(0xF141593, 16) == "f141593"); + CHECK(String::num_uint64(0xF141593, 16, true) == "F141593"); + ERR_PRINT_OFF; + CHECK(String::num_uint64(4294967295, 1) == ""); // Invalid base < 2. + CHECK(String::num_uint64(4294967295, 37) == ""); // Invalid base > 36. + ERR_PRINT_ON; // String::num_real tests. CHECK(String::num_real(1.0) == "1.0"); diff --git a/tests/core/templates/test_a_hash_map.h b/tests/core/templates/test_a_hash_map.h new file mode 100644 index 0000000000..19e5e06057 --- /dev/null +++ b/tests/core/templates/test_a_hash_map.h @@ -0,0 +1,297 @@ +/**************************************************************************/ +/* test_a_hash_map.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2024-present Redot Engine contributors */ +/* (see REDOT_AUTHORS.md) */ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef TEST_A_HASH_MAP_H +#define TEST_A_HASH_MAP_H + +#include "core/templates/a_hash_map.h" + +#include "tests/test_macros.h" + +namespace TestAHashMap { + +TEST_CASE("[AHashMap] Insert element") { + AHashMap<int, int> map; + AHashMap<int, int>::Iterator e = map.insert(42, 84); + + CHECK(e); + CHECK(e->key == 42); + CHECK(e->value == 84); + CHECK(map[42] == 84); + CHECK(map.has(42)); + CHECK(map.find(42)); +} + +TEST_CASE("[AHashMap] Overwrite element") { + AHashMap<int, int> map; + map.insert(42, 84); + map.insert(42, 1234); + + CHECK(map[42] == 1234); +} + +TEST_CASE("[AHashMap] Erase via element") { + AHashMap<int, int> map; + AHashMap<int, int>::Iterator e = map.insert(42, 84); + map.remove(e); + CHECK(!map.has(42)); + CHECK(!map.find(42)); +} + +TEST_CASE("[AHashMap] Erase via key") { + AHashMap<int, int> map; + map.insert(42, 84); + map.erase(42); + CHECK(!map.has(42)); + CHECK(!map.find(42)); +} + +TEST_CASE("[AHashMap] Size") { + AHashMap<int, int> map; + map.insert(42, 84); + map.insert(123, 84); + map.insert(123, 84); + map.insert(0, 84); + map.insert(123485, 84); + + CHECK(map.size() == 4); +} + +TEST_CASE("[AHashMap] Iteration") { + AHashMap<int, int> map; + + map.insert(42, 84); + map.insert(123, 12385); + map.insert(0, 12934); + map.insert(123485, 1238888); + map.insert(123, 111111); + + Vector<Pair<int, int>> expected; + expected.push_back(Pair<int, int>(42, 84)); + expected.push_back(Pair<int, int>(123, 111111)); + expected.push_back(Pair<int, int>(0, 12934)); + expected.push_back(Pair<int, int>(123485, 1238888)); + + int idx = 0; + for (const KeyValue<int, int> &E : map) { + CHECK(expected[idx] == Pair<int, int>(E.key, E.value)); + idx++; + } + + idx--; + for (AHashMap<int, int>::Iterator it = map.last(); it; --it) { + CHECK(expected[idx] == Pair<int, int>(it->key, it->value)); + idx--; + } +} + +TEST_CASE("[AHashMap] Const iteration") { + AHashMap<int, int> map; + map.insert(42, 84); + map.insert(123, 12385); + map.insert(0, 12934); + map.insert(123485, 1238888); + map.insert(123, 111111); + + const AHashMap<int, int> const_map = map; + + Vector<Pair<int, int>> expected; + expected.push_back(Pair<int, int>(42, 84)); + expected.push_back(Pair<int, int>(123, 111111)); + expected.push_back(Pair<int, int>(0, 12934)); + expected.push_back(Pair<int, int>(123485, 1238888)); + expected.push_back(Pair<int, int>(123, 111111)); + + int idx = 0; + for (const KeyValue<int, int> &E : const_map) { + CHECK(expected[idx] == Pair<int, int>(E.key, E.value)); + idx++; + } + + idx--; + for (AHashMap<int, int>::ConstIterator it = const_map.last(); it; --it) { + CHECK(expected[idx] == Pair<int, int>(it->key, it->value)); + idx--; + } +} + +TEST_CASE("[AHashMap] Replace key") { + AHashMap<int, int> map; + map.insert(42, 84); + map.insert(0, 12934); + CHECK(map.replace_key(0, 1)); + CHECK(map.has(1)); + CHECK(map[1] == 12934); +} + +TEST_CASE("[AHashMap] Clear") { + AHashMap<int, int> map; + map.insert(42, 84); + map.insert(123, 12385); + map.insert(0, 12934); + + map.clear(); + CHECK(!map.has(42)); + CHECK(map.size() == 0); + CHECK(map.is_empty()); +} + +TEST_CASE("[AHashMap] Get") { + AHashMap<int, int> map; + map.insert(42, 84); + map.insert(123, 12385); + map.insert(0, 12934); + + CHECK(map.get(123) == 12385); + map.get(123) = 10; + CHECK(map.get(123) == 10); + + CHECK(*map.getptr(0) == 12934); + *map.getptr(0) = 1; + CHECK(*map.getptr(0) == 1); + + CHECK(map.get(42) == 84); + CHECK(map.getptr(-10) == nullptr); +} + +TEST_CASE("[AHashMap] Insert, iterate and remove many elements") { + const int elem_max = 1234; + AHashMap<int, int> map; + for (int i = 0; i < elem_max; i++) { + map.insert(i, i); + } + + //insert order should have been kept + int idx = 0; + for (auto &K : map) { + CHECK(idx == K.key); + CHECK(idx == K.value); + CHECK(map.has(idx)); + idx++; + } + + Vector<int> elems_still_valid; + + for (int i = 0; i < elem_max; i++) { + if ((i % 5) == 0) { + map.erase(i); + } else { + elems_still_valid.push_back(i); + } + } + + CHECK(elems_still_valid.size() == map.size()); + + for (int i = 0; i < elems_still_valid.size(); i++) { + CHECK(map.has(elems_still_valid[i])); + } +} + +TEST_CASE("[AHashMap] Insert, iterate and remove many strings") { + const int elem_max = 432; + AHashMap<String, String> map; + for (int i = 0; i < elem_max; i++) { + map.insert(itos(i), itos(i)); + } + + //insert order should have been kept + int idx = 0; + for (auto &K : map) { + CHECK(itos(idx) == K.key); + CHECK(itos(idx) == K.value); + CHECK(map.has(itos(idx))); + idx++; + } + + Vector<String> elems_still_valid; + + for (int i = 0; i < elem_max; i++) { + if ((i % 5) == 0) { + map.erase(itos(i)); + } else { + elems_still_valid.push_back(itos(i)); + } + } + + CHECK(elems_still_valid.size() == map.size()); + + for (int i = 0; i < elems_still_valid.size(); i++) { + CHECK(map.has(elems_still_valid[i])); + } + + elems_still_valid.clear(); +} + +TEST_CASE("[AHashMap] Copy constructor") { + AHashMap<int, int> map0; + const uint32_t count = 5; + for (uint32_t i = 0; i < count; i++) { + map0.insert(i, i); + } + AHashMap<int, int> map1(map0); + CHECK(map0.size() == map1.size()); + CHECK(map0.get_capacity() == map1.get_capacity()); + CHECK(*map0.getptr(0) == *map1.getptr(0)); +} + +TEST_CASE("[AHashMap] Operator =") { + AHashMap<int, int> map0; + AHashMap<int, int> map1; + const uint32_t count = 5; + map1.insert(1234, 1234); + for (uint32_t i = 0; i < count; i++) { + map0.insert(i, i); + } + map1 = map0; + CHECK(map0.size() == map1.size()); + CHECK(map0.get_capacity() == map1.get_capacity()); + CHECK(*map0.getptr(0) == *map1.getptr(0)); +} + +TEST_CASE("[AHashMap] Array methods") { + AHashMap<int, int> map; + for (int i = 0; i < 100; i++) { + map.insert(100 - i, i); + } + for (int i = 0; i < 100; i++) { + CHECK(map.get_by_index(i).value == i); + } + int index = map.get_index(1); + CHECK(map.get_by_index(index).value == 99); + CHECK(map.erase_by_index(index)); + CHECK(!map.erase_by_index(index)); + CHECK(map.get_index(1) == -1); +} + +} // namespace TestAHashMap + +#endif // TEST_A_HASH_MAP_H diff --git a/tests/scene/test_tree.h b/tests/scene/test_tree.h index 5fda4dea73..dc63cb6eb7 100644 --- a/tests/scene/test_tree.h +++ b/tests/scene/test_tree.h @@ -141,18 +141,30 @@ TEST_CASE("[SceneTree][Tree]") { TreeItem *child1 = tree->create_item(); TreeItem *child2 = tree->create_item(); TreeItem *child3 = tree->create_item(); + CHECK_EQ(root->get_next(), nullptr); + CHECK_EQ(root->get_next_visible(), child1); + CHECK_EQ(root->get_next_in_tree(), child1); CHECK_EQ(child1->get_next(), child2); + CHECK_EQ(child1->get_next_visible(), child2); CHECK_EQ(child1->get_next_in_tree(), child2); CHECK_EQ(child2->get_next(), child3); + CHECK_EQ(child2->get_next_visible(), child3); CHECK_EQ(child2->get_next_in_tree(), child3); CHECK_EQ(child3->get_next(), nullptr); + CHECK_EQ(child3->get_next_visible(), nullptr); CHECK_EQ(child3->get_next_in_tree(), nullptr); + CHECK_EQ(root->get_prev(), nullptr); + CHECK_EQ(root->get_prev_visible(), nullptr); + CHECK_EQ(root->get_prev_in_tree(), nullptr); CHECK_EQ(child1->get_prev(), nullptr); + CHECK_EQ(child1->get_prev_visible(), root); CHECK_EQ(child1->get_prev_in_tree(), root); CHECK_EQ(child2->get_prev(), child1); + CHECK_EQ(child2->get_prev_visible(), child1); CHECK_EQ(child2->get_prev_in_tree(), child1); CHECK_EQ(child3->get_prev(), child2); + CHECK_EQ(child3->get_prev_visible(), child2); CHECK_EQ(child3->get_prev_in_tree(), child2); TreeItem *nested1 = tree->create_item(child2); @@ -160,13 +172,127 @@ TEST_CASE("[SceneTree][Tree]") { TreeItem *nested3 = tree->create_item(child2); CHECK_EQ(child1->get_next(), child2); + CHECK_EQ(child1->get_next_visible(), child2); CHECK_EQ(child1->get_next_in_tree(), child2); CHECK_EQ(child2->get_next(), child3); + CHECK_EQ(child2->get_next_visible(), nested1); CHECK_EQ(child2->get_next_in_tree(), nested1); CHECK_EQ(child3->get_prev(), child2); + CHECK_EQ(child3->get_prev_visible(), nested3); CHECK_EQ(child3->get_prev_in_tree(), nested3); CHECK_EQ(nested1->get_prev_in_tree(), child2); CHECK_EQ(nested1->get_next_in_tree(), nested2); + CHECK_EQ(nested3->get_next_in_tree(), child3); + + memdelete(tree); + } + + SUBCASE("[Tree] Previous and Next items with hide root.") { + Tree *tree = memnew(Tree); + tree->set_hide_root(true); + TreeItem *root = tree->create_item(); + + TreeItem *child1 = tree->create_item(); + TreeItem *child2 = tree->create_item(); + TreeItem *child3 = tree->create_item(); + CHECK_EQ(root->get_next(), nullptr); + CHECK_EQ(root->get_next_visible(), child1); + CHECK_EQ(root->get_next_in_tree(), child1); + CHECK_EQ(child1->get_next(), child2); + CHECK_EQ(child1->get_next_visible(), child2); + CHECK_EQ(child1->get_next_in_tree(), child2); + CHECK_EQ(child2->get_next(), child3); + CHECK_EQ(child2->get_next_visible(), child3); + CHECK_EQ(child2->get_next_in_tree(), child3); + CHECK_EQ(child3->get_next(), nullptr); + CHECK_EQ(child3->get_next_visible(), nullptr); + CHECK_EQ(child3->get_next_in_tree(), nullptr); + + CHECK_EQ(root->get_prev(), nullptr); + CHECK_EQ(root->get_prev_visible(), nullptr); + CHECK_EQ(root->get_prev_in_tree(), nullptr); + CHECK_EQ(child1->get_prev(), nullptr); + CHECK_EQ(child1->get_prev_visible(), nullptr); + CHECK_EQ(child1->get_prev_in_tree(), nullptr); + CHECK_EQ(child2->get_prev(), child1); + CHECK_EQ(child2->get_prev_visible(), child1); + CHECK_EQ(child2->get_prev_in_tree(), child1); + CHECK_EQ(child3->get_prev(), child2); + CHECK_EQ(child3->get_prev_visible(), child2); + CHECK_EQ(child3->get_prev_in_tree(), child2); + + memdelete(tree); + } + + SUBCASE("[Tree] Previous and Next items wrapping.") { + Tree *tree = memnew(Tree); + TreeItem *root = tree->create_item(); + + TreeItem *child1 = tree->create_item(); + TreeItem *child2 = tree->create_item(); + TreeItem *child3 = tree->create_item(); + CHECK_EQ(root->get_next_visible(true), child1); + CHECK_EQ(root->get_next_in_tree(true), child1); + CHECK_EQ(child1->get_next_visible(true), child2); + CHECK_EQ(child1->get_next_in_tree(true), child2); + CHECK_EQ(child2->get_next_visible(true), child3); + CHECK_EQ(child2->get_next_in_tree(true), child3); + CHECK_EQ(child3->get_next_visible(true), root); + CHECK_EQ(child3->get_next_in_tree(true), root); + + CHECK_EQ(root->get_prev_visible(true), child3); + CHECK_EQ(root->get_prev_in_tree(true), child3); + CHECK_EQ(child1->get_prev_visible(true), root); + CHECK_EQ(child1->get_prev_in_tree(true), root); + CHECK_EQ(child2->get_prev_visible(true), child1); + CHECK_EQ(child2->get_prev_in_tree(true), child1); + CHECK_EQ(child3->get_prev_visible(true), child2); + CHECK_EQ(child3->get_prev_in_tree(true), child2); + + TreeItem *nested1 = tree->create_item(child2); + TreeItem *nested2 = tree->create_item(child2); + TreeItem *nested3 = tree->create_item(child2); + + CHECK_EQ(child1->get_next_visible(true), child2); + CHECK_EQ(child1->get_next_in_tree(true), child2); + CHECK_EQ(child2->get_next_visible(true), nested1); + CHECK_EQ(child2->get_next_in_tree(true), nested1); + CHECK_EQ(nested3->get_next_visible(true), child3); + CHECK_EQ(nested3->get_next_in_tree(true), child3); + CHECK_EQ(child3->get_prev_visible(true), nested3); + CHECK_EQ(child3->get_prev_in_tree(true), nested3); + CHECK_EQ(nested1->get_prev_in_tree(true), child2); + CHECK_EQ(nested1->get_next_in_tree(true), nested2); + CHECK_EQ(nested3->get_next_in_tree(true), child3); + + memdelete(tree); + } + + SUBCASE("[Tree] Previous and Next items wrapping with hide root.") { + Tree *tree = memnew(Tree); + tree->set_hide_root(true); + TreeItem *root = tree->create_item(); + + TreeItem *child1 = tree->create_item(); + TreeItem *child2 = tree->create_item(); + TreeItem *child3 = tree->create_item(); + CHECK_EQ(root->get_next_visible(true), child1); + CHECK_EQ(root->get_next_in_tree(true), child1); + CHECK_EQ(child1->get_next_visible(true), child2); + CHECK_EQ(child1->get_next_in_tree(true), child2); + CHECK_EQ(child2->get_next_visible(true), child3); + CHECK_EQ(child2->get_next_in_tree(true), child3); + CHECK_EQ(child3->get_next_visible(true), root); + CHECK_EQ(child3->get_next_in_tree(true), root); + + CHECK_EQ(root->get_prev_visible(true), child3); + CHECK_EQ(root->get_prev_in_tree(true), child3); + CHECK_EQ(child1->get_prev_visible(true), child3); + CHECK_EQ(child1->get_prev_in_tree(true), child3); + CHECK_EQ(child2->get_prev_visible(true), child1); + CHECK_EQ(child2->get_prev_in_tree(true), child1); + CHECK_EQ(child3->get_prev_visible(true), child2); + CHECK_EQ(child3->get_prev_in_tree(true), child2); memdelete(tree); } diff --git a/tests/test_main.cpp b/tests/test_main.cpp index be9ed7bd77..e63ac96067 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -89,6 +89,7 @@ #include "tests/core/string/test_string.h" #include "tests/core/string/test_translation.h" #include "tests/core/string/test_translation_server.h" +#include "tests/core/templates/test_a_hash_map.h" #include "tests/core/templates/test_command_queue.h" #include "tests/core/templates/test_hash_map.h" #include "tests/core/templates/test_hash_set.h" |