diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/core/io/test_http_client.h | 2 | ||||
-rw-r--r-- | tests/core/io/test_json_native.h | 160 | ||||
-rw-r--r-- | tests/core/object/test_object.h | 25 | ||||
-rw-r--r-- | tests/core/string/test_string.h | 31 | ||||
-rw-r--r-- | tests/scene/test_audio_stream_wav.h | 2 | ||||
-rw-r--r-- | tests/scene/test_path_2d.h | 2 | ||||
-rw-r--r-- | tests/scene/test_path_3d.h | 2 | ||||
-rw-r--r-- | tests/scene/test_primitives.h | 6 | ||||
-rw-r--r-- | tests/servers/test_navigation_server_3d.h | 160 | ||||
-rw-r--r-- | tests/test_main.cpp | 1 |
10 files changed, 382 insertions, 9 deletions
diff --git a/tests/core/io/test_http_client.h b/tests/core/io/test_http_client.h index 961c653a0a..114ce3b4ed 100644 --- a/tests/core/io/test_http_client.h +++ b/tests/core/io/test_http_client.h @@ -41,7 +41,7 @@ namespace TestHTTPClient { TEST_CASE("[HTTPClient] Instantiation") { Ref<HTTPClient> client = HTTPClient::create(); - CHECK_MESSAGE(client != nullptr, "A HTTP Client created should not be a null pointer"); + CHECK_MESSAGE(client.is_valid(), "A HTTP Client created should not be a null pointer"); } TEST_CASE("[HTTPClient] query_string_from_dict") { diff --git a/tests/core/io/test_json_native.h b/tests/core/io/test_json_native.h new file mode 100644 index 0000000000..819078ac57 --- /dev/null +++ b/tests/core/io/test_json_native.h @@ -0,0 +1,160 @@ +/**************************************************************************/ +/* test_json_native.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* 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_JSON_NATIVE_H +#define TEST_JSON_NATIVE_H + +#include "core/io/json.h" + +namespace TestJSONNative { + +bool compare_variants(Variant variant_1, Variant variant_2, int depth = 0) { + if (depth > 100) { + return false; + } + if (variant_1.get_type() == Variant::RID && variant_2.get_type() == Variant::RID) { + return true; + } + if (variant_1.get_type() == Variant::CALLABLE || variant_2.get_type() == Variant::CALLABLE) { + return true; + } + + List<PropertyInfo> variant_1_properties; + variant_1.get_property_list(&variant_1_properties); + List<PropertyInfo> variant_2_properties; + variant_2.get_property_list(&variant_2_properties); + + if (variant_1_properties.size() != variant_2_properties.size()) { + return false; + } + + for (List<PropertyInfo>::Element *E = variant_1_properties.front(); E; E = E->next()) { + String name = E->get().name; + Variant variant_1_value = variant_1.get(name); + Variant variant_2_value = variant_2.get(name); + + if (!compare_variants(variant_1_value, variant_2_value, depth + 1)) { + return false; + } + } + + return true; +} + +TEST_CASE("[JSON][Native][SceneTree] Conversion between native and JSON formats") { + for (int variant_i = 0; variant_i < Variant::VARIANT_MAX; variant_i++) { + Variant::Type type = static_cast<Variant::Type>(variant_i); + Variant native_data; + Callable::CallError error; + + if (type == Variant::Type::INT || type == Variant::Type::FLOAT) { + Variant value = int64_t(INT64_MAX); + const Variant *args[] = { &value }; + Variant::construct(type, native_data, args, 1, error); + } else if (type == Variant::Type::OBJECT) { + Ref<JSON> json = memnew(JSON); + native_data = json; + } else if (type == Variant::Type::DICTIONARY) { + Dictionary dictionary; + dictionary["key"] = "value"; + native_data = dictionary; + } else if (type == Variant::Type::ARRAY) { + Array array; + array.push_back("element1"); + array.push_back("element2"); + native_data = array; + } else if (type == Variant::Type::PACKED_BYTE_ARRAY) { + PackedByteArray packed_array; + packed_array.push_back(1); + packed_array.push_back(2); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_INT32_ARRAY) { + PackedInt32Array packed_array; + packed_array.push_back(INT32_MIN); + packed_array.push_back(INT32_MAX); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_INT64_ARRAY) { + PackedInt64Array packed_array; + packed_array.push_back(INT64_MIN); + packed_array.push_back(INT64_MAX); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_FLOAT32_ARRAY) { + PackedFloat32Array packed_array; + packed_array.push_back(FLT_MIN); + packed_array.push_back(FLT_MAX); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_FLOAT64_ARRAY) { + PackedFloat64Array packed_array; + packed_array.push_back(DBL_MIN); + packed_array.push_back(DBL_MAX); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_STRING_ARRAY) { + PackedStringArray packed_array; + packed_array.push_back("string1"); + packed_array.push_back("string2"); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_VECTOR2_ARRAY) { + PackedVector2Array packed_array; + Vector2 vector(1.0, 2.0); + packed_array.push_back(vector); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_VECTOR3_ARRAY) { + PackedVector3Array packed_array; + Vector3 vector(1.0, 2.0, 3.0); + packed_array.push_back(vector); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_COLOR_ARRAY) { + PackedColorArray packed_array; + Color color(1.0, 1.0, 1.0); + packed_array.push_back(color); + native_data = packed_array; + } else if (type == Variant::Type::PACKED_VECTOR4_ARRAY) { + PackedVector4Array packed_array; + Vector4 vector(1.0, 2.0, 3.0, 4.0); + packed_array.push_back(vector); + native_data = packed_array; + } else { + Variant::construct(type, native_data, nullptr, 0, error); + } + Variant json_converted_from_native = JSON::from_native(native_data, true, true); + Variant variant_native_converted = JSON::to_native(json_converted_from_native, true, true); + CHECK_MESSAGE(compare_variants(native_data, variant_native_converted), + vformat("Conversion from native to JSON type %s and back successful. \nNative: %s \nNative Converted: %s \nError: %s\nConversion from native to JSON type %s successful: %s", + Variant::get_type_name(type), + native_data, + variant_native_converted, + itos(error.error), + Variant::get_type_name(type), + json_converted_from_native)); + } +} +} // namespace TestJSONNative + +#endif // TEST_JSON_NATIVE_H diff --git a/tests/core/object/test_object.h b/tests/core/object/test_object.h index 57bc65328a..f1bb62cb70 100644 --- a/tests/core/object/test_object.h +++ b/tests/core/object/test_object.h @@ -174,6 +174,31 @@ TEST_CASE("[Object] Metadata") { CHECK_MESSAGE( meta_list2.size() == 0, "The metadata list should contain 0 items after removing all metadata items."); + + Object other; + object.set_meta("conflicting_meta", "string"); + object.set_meta("not_conflicting_meta", 123); + other.set_meta("conflicting_meta", Color(0, 1, 0)); + other.set_meta("other_meta", "other"); + object.merge_meta_from(&other); + + CHECK_MESSAGE( + Color(object.get_meta("conflicting_meta")).is_equal_approx(Color(0, 1, 0)), + "String meta should be overwritten with Color after merging."); + + CHECK_MESSAGE( + int(object.get_meta("not_conflicting_meta")) == 123, + "Not conflicting meta on destination should be kept intact."); + + CHECK_MESSAGE( + object.get_meta("other_meta", String()) == "other", + "Not conflicting meta name on source should merged."); + + List<StringName> meta_list3; + object.get_meta_list(&meta_list3); + CHECK_MESSAGE( + meta_list3.size() == 3, + "The metadata list should contain 3 items after merging meta from two objects."); } TEST_CASE("[Object] Construction") { diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index b47e5b1eb9..a9f615af84 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -433,6 +433,19 @@ TEST_CASE("[String] Insertion") { String s = "Who is Frederic?"; s = s.insert(s.find("?"), " Chopin"); CHECK(s == "Who is Frederic Chopin?"); + + s = "foobar"; + CHECK(s.insert(0, "X") == "Xfoobar"); + CHECK(s.insert(-100, "X") == "foobar"); + CHECK(s.insert(6, "X") == "foobarX"); + CHECK(s.insert(100, "X") == "foobarX"); + CHECK(s.insert(2, "") == "foobar"); + + s = ""; + CHECK(s.insert(0, "abc") == "abc"); + CHECK(s.insert(100, "abc") == "abc"); + CHECK(s.insert(-100, "abc") == ""); + CHECK(s.insert(0, "") == ""); } TEST_CASE("[String] Erasing") { @@ -1811,13 +1824,25 @@ TEST_CASE("[String] SHA1/SHA256/MD5") { } TEST_CASE("[String] Join") { - String s = ", "; + String comma = ", "; + String empty = ""; Vector<String> parts; + + CHECK(comma.join(parts) == ""); + CHECK(empty.join(parts) == ""); + parts.push_back("One"); + CHECK(comma.join(parts) == "One"); + CHECK(empty.join(parts) == "One"); + parts.push_back("B"); parts.push_back("C"); - String t = s.join(parts); - CHECK(t == "One, B, C"); + CHECK(comma.join(parts) == "One, B, C"); + CHECK(empty.join(parts) == "OneBC"); + + parts.push_back(""); + CHECK(comma.join(parts) == "One, B, C, "); + CHECK(empty.join(parts) == "OneBC"); } TEST_CASE("[String] Is_*") { diff --git a/tests/scene/test_audio_stream_wav.h b/tests/scene/test_audio_stream_wav.h index e8f3c9e8f5..5166cd3c13 100644 --- a/tests/scene/test_audio_stream_wav.h +++ b/tests/scene/test_audio_stream_wav.h @@ -159,6 +159,8 @@ void run_test(String file_name, AudioStreamWAV::Format data_format, bool stereo, for (const ResourceImporter::ImportOption &E : options_list) { options_map[E.option.name] = E.default_value; } + // Compressed streams can't be saved, disable compression. + options_map["compress/mode"] = 0; REQUIRE(wav_importer->import(save_path, save_path, options_map, nullptr) == OK); diff --git a/tests/scene/test_path_2d.h b/tests/scene/test_path_2d.h index 7b6cec96db..4703bfa3bb 100644 --- a/tests/scene/test_path_2d.h +++ b/tests/scene/test_path_2d.h @@ -40,7 +40,7 @@ namespace TestPath2D { TEST_CASE("[SceneTree][Path2D] Initialization") { SUBCASE("Path should be empty right after initialization") { Path2D *test_path = memnew(Path2D); - CHECK(test_path->get_curve() == nullptr); + CHECK(test_path->get_curve().is_null()); memdelete(test_path); } } diff --git a/tests/scene/test_path_3d.h b/tests/scene/test_path_3d.h index f779f514a4..70c7099d48 100644 --- a/tests/scene/test_path_3d.h +++ b/tests/scene/test_path_3d.h @@ -40,7 +40,7 @@ namespace TestPath3D { TEST_CASE("[Path3D] Initialization") { SUBCASE("Path should be empty right after initialization") { Path3D *test_path = memnew(Path3D); - CHECK(test_path->get_curve() == nullptr); + CHECK(test_path->get_curve().is_null()); memdelete(test_path); } } diff --git a/tests/scene/test_primitives.h b/tests/scene/test_primitives.h index f105e1ac04..59f23983e5 100644 --- a/tests/scene/test_primitives.h +++ b/tests/scene/test_primitives.h @@ -609,7 +609,7 @@ TEST_CASE("[SceneTree][Primitive][TubeTrail] TubeTrail Primitive") { CHECK(tube->get_sections() >= 0); CHECK(tube->get_section_length() > 0); CHECK(tube->get_section_rings() >= 0); - CHECK(tube->get_curve() == nullptr); + CHECK(tube->get_curve().is_null()); CHECK(tube->get_builtin_bind_pose_count() >= 0); } @@ -669,7 +669,7 @@ TEST_CASE("[SceneTree][Primitive][RibbonTrail] RibbonTrail Primitive") { CHECK(ribbon->get_section_length() > 0); CHECK(ribbon->get_section_segments() >= 0); CHECK(ribbon->get_builtin_bind_pose_count() >= 0); - CHECK(ribbon->get_curve() == nullptr); + CHECK(ribbon->get_curve().is_null()); CHECK((ribbon->get_shape() == RibbonTrailMesh::SHAPE_CROSS || ribbon->get_shape() == RibbonTrailMesh::SHAPE_FLAT)); } @@ -731,7 +731,7 @@ TEST_CASE("[SceneTree][Primitive][Text] Text Primitive") { text->get_vertical_alignment() == VERTICAL_ALIGNMENT_TOP || text->get_vertical_alignment() == VERTICAL_ALIGNMENT_CENTER || text->get_vertical_alignment() == VERTICAL_ALIGNMENT_FILL)); - CHECK(text->get_font() == nullptr); + CHECK(text->get_font().is_null()); CHECK(text->get_font_size() > 0); CHECK(text->get_line_spacing() >= 0); CHECK((text->get_autowrap_mode() == TextServer::AUTOWRAP_OFF || diff --git a/tests/servers/test_navigation_server_3d.h b/tests/servers/test_navigation_server_3d.h index cf6b89c330..4411b1aae5 100644 --- a/tests/servers/test_navigation_server_3d.h +++ b/tests/servers/test_navigation_server_3d.h @@ -31,6 +31,7 @@ #ifndef TEST_NAVIGATION_SERVER_3D_H #define TEST_NAVIGATION_SERVER_3D_H +#include "modules/navigation/nav_utils.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/resources/3d/primitive_meshes.h" #include "servers/navigation_server_3d.h" @@ -61,6 +62,32 @@ static inline Array build_array(Variant item, Targs... Fargs) { return a; } +struct GreaterThan { + bool operator()(int p_a, int p_b) const { return p_a > p_b; } +}; + +struct CompareArrayValues { + const int *array; + + CompareArrayValues(const int *p_array) : + array(p_array) {} + + bool operator()(uint32_t p_index_a, uint32_t p_index_b) const { + return array[p_index_a] < array[p_index_b]; + } +}; + +struct RegisterHeapIndexes { + uint32_t *indexes; + + RegisterHeapIndexes(uint32_t *p_indexes) : + indexes(p_indexes) {} + + void operator()(uint32_t p_vector_index, uint32_t p_heap_index) { + indexes[p_vector_index] = p_heap_index; + } +}; + TEST_SUITE("[Navigation]") { TEST_CASE("[NavigationServer3D] Server should be empty when initialized") { NavigationServer3D *navigation_server = NavigationServer3D::get_singleton(); @@ -788,6 +815,139 @@ TEST_SUITE("[Navigation]") { CHECK_EQ(navigation_mesh->get_vertices().size(), 0); } */ + + TEST_CASE("[Heap] size") { + gd::Heap<int> heap; + + CHECK(heap.size() == 0); + + heap.push(0); + CHECK(heap.size() == 1); + + heap.push(1); + CHECK(heap.size() == 2); + + heap.pop(); + CHECK(heap.size() == 1); + + heap.pop(); + CHECK(heap.size() == 0); + } + + TEST_CASE("[Heap] is_empty") { + gd::Heap<int> heap; + + CHECK(heap.is_empty() == true); + + heap.push(0); + CHECK(heap.is_empty() == false); + + heap.pop(); + CHECK(heap.is_empty() == true); + } + + TEST_CASE("[Heap] push/pop") { + SUBCASE("Default comparator") { + gd::Heap<int> heap; + + heap.push(2); + heap.push(7); + heap.push(5); + heap.push(3); + heap.push(4); + + CHECK(heap.pop() == 7); + CHECK(heap.pop() == 5); + CHECK(heap.pop() == 4); + CHECK(heap.pop() == 3); + CHECK(heap.pop() == 2); + } + + SUBCASE("Custom comparator") { + GreaterThan greaterThan; + gd::Heap<int, GreaterThan> heap(greaterThan); + + heap.push(2); + heap.push(7); + heap.push(5); + heap.push(3); + heap.push(4); + + CHECK(heap.pop() == 2); + CHECK(heap.pop() == 3); + CHECK(heap.pop() == 4); + CHECK(heap.pop() == 5); + CHECK(heap.pop() == 7); + } + + SUBCASE("Intermediate pops") { + gd::Heap<int> heap; + + heap.push(0); + heap.push(3); + heap.pop(); + heap.push(1); + heap.push(2); + + CHECK(heap.pop() == 2); + CHECK(heap.pop() == 1); + CHECK(heap.pop() == 0); + } + } + + TEST_CASE("[Heap] shift") { + int values[] = { 5, 3, 6, 7, 1 }; + uint32_t heap_indexes[] = { 0, 0, 0, 0, 0 }; + CompareArrayValues comparator(values); + RegisterHeapIndexes indexer(heap_indexes); + gd::Heap<uint32_t, CompareArrayValues, RegisterHeapIndexes> heap(comparator, indexer); + + heap.push(0); + heap.push(1); + heap.push(2); + heap.push(3); + heap.push(4); + + // Shift down: 6 -> 2 + values[2] = 2; + heap.shift(heap_indexes[2]); + + // Shift up: 5 -> 8 + values[0] = 8; + heap.shift(heap_indexes[0]); + + CHECK(heap.pop() == 0); + CHECK(heap.pop() == 3); + CHECK(heap.pop() == 1); + CHECK(heap.pop() == 2); + CHECK(heap.pop() == 4); + + CHECK(heap_indexes[0] == UINT32_MAX); + CHECK(heap_indexes[1] == UINT32_MAX); + CHECK(heap_indexes[2] == UINT32_MAX); + CHECK(heap_indexes[3] == UINT32_MAX); + CHECK(heap_indexes[4] == UINT32_MAX); + } + + TEST_CASE("[Heap] clear") { + uint32_t heap_indexes[] = { 0, 0, 0, 0 }; + RegisterHeapIndexes indexer(heap_indexes); + gd::Heap<uint32_t, Comparator<uint32_t>, RegisterHeapIndexes> heap(indexer); + + heap.push(0); + heap.push(2); + heap.push(1); + heap.push(3); + + heap.clear(); + + CHECK(heap.size() == 0); + + CHECK(heap_indexes[0] == UINT32_MAX); + CHECK(heap_indexes[1] == UINT32_MAX); + CHECK(heap_indexes[2] == UINT32_MAX); + CHECK(heap_indexes[3] == UINT32_MAX); + } } } //namespace TestNavigationServer3D diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 46714a2627..7e1c431a3c 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -48,6 +48,7 @@ #include "tests/core/io/test_image.h" #include "tests/core/io/test_ip.h" #include "tests/core/io/test_json.h" +#include "tests/core/io/test_json_native.h" #include "tests/core/io/test_marshalls.h" #include "tests/core/io/test_pck_packer.h" #include "tests/core/io/test_resource.h" |