diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/core/io/test_image.h | 39 | ||||
-rw-r--r-- | tests/core/io/test_resource.h | 6 | ||||
-rw-r--r-- | tests/core/math/test_basis.h | 2 | ||||
-rw-r--r-- | tests/core/math/test_plane.h | 172 | ||||
-rw-r--r-- | tests/core/object/test_class_db.h | 12 | ||||
-rw-r--r-- | tests/core/string/test_string.h | 75 | ||||
-rw-r--r-- | tests/core/templates/test_hash_set.h | 2 | ||||
-rw-r--r-- | tests/core/threads/test_worker_thread_pool.h | 158 | ||||
-rw-r--r-- | tests/scene/test_code_edit.h | 2 | ||||
-rw-r--r-- | tests/scene/test_path_3d.h | 2 | ||||
-rw-r--r-- | tests/scene/test_text_edit.h | 20 | ||||
-rw-r--r-- | tests/scene/test_theme.h | 2 | ||||
-rw-r--r-- | tests/servers/test_text_server.h | 7 | ||||
-rw-r--r-- | tests/test_main.cpp | 2 |
14 files changed, 427 insertions, 74 deletions
diff --git a/tests/core/io/test_image.h b/tests/core/io/test_image.h index 1c778c3228..36e6b83bfd 100644 --- a/tests/core/io/test_image.h +++ b/tests/core/io/test_image.h @@ -161,8 +161,8 @@ TEST_CASE("[Image] Basic getters") { CHECK(image->get_height() == 4); CHECK(image->get_size() == Vector2(8, 4)); CHECK(image->get_format() == Image::FORMAT_LA8); - CHECK(image->get_used_rect() == Rect2(0, 0, 0, 0)); - Ref<Image> image_get_rect = image->get_rect(Rect2(0, 0, 2, 1)); + CHECK(image->get_used_rect() == Rect2i(0, 0, 0, 0)); + Ref<Image> image_get_rect = image->get_rect(Rect2i(0, 0, 2, 1)); CHECK(image_get_rect->get_size() == Vector2(2, 1)); } @@ -213,8 +213,8 @@ TEST_CASE("[Image] Modifying pixels of an image") { image->get_pixelv(Vector2(0, 0)).is_equal_approx(Color(1, 1, 1, 1)), "Image's get_pixel() should return the same color value as the one being set with set_pixel() in the same position."); CHECK_MESSAGE( - image->get_used_rect() == Rect2(0, 0, 1, 1), - "Image's get_used_rect should return the expected value, larger than Rect2(0, 0, 0, 0) if it's visible."); + image->get_used_rect() == Rect2i(0, 0, 1, 1), + "Image's get_used_rect should return the expected value, larger than Rect2i(0, 0, 0, 0) if it's visible."); image->set_pixelv(Vector2(0, 0), Color(0.5, 0.5, 0.5, 0.5)); Ref<Image> image2 = memnew(Image(3, 3, false, Image::FORMAT_RGBA8)); @@ -233,19 +233,19 @@ TEST_CASE("[Image] Modifying pixels of an image") { { const int img_width = 3; const int img_height = 3; - Vector<Rect2> rects; - rects.push_back(Rect2()); - rects.push_back(Rect2(-5, -5, 3, 3)); - rects.push_back(Rect2(img_width, 0, 12, 12)); - rects.push_back(Rect2(0, img_height, 12, 12)); - rects.push_back(Rect2(img_width + 1, img_height + 2, 12, 12)); - rects.push_back(Rect2(1, 1, 1, 1)); - rects.push_back(Rect2(0, 1, 2, 3)); - rects.push_back(Rect2(-5, 0, img_width + 10, 2)); - rects.push_back(Rect2(0, -5, 2, img_height + 10)); - rects.push_back(Rect2(-1, -1, img_width + 1, img_height + 1)); - - for (const Rect2 &rect : rects) { + Vector<Rect2i> rects; + rects.push_back(Rect2i()); + rects.push_back(Rect2i(-5, -5, 3, 3)); + rects.push_back(Rect2i(img_width, 0, 12, 12)); + rects.push_back(Rect2i(0, img_height, 12, 12)); + rects.push_back(Rect2i(img_width + 1, img_height + 2, 12, 12)); + rects.push_back(Rect2i(1, 1, 1, 1)); + rects.push_back(Rect2i(0, 1, 2, 3)); + rects.push_back(Rect2i(-5, 0, img_width + 10, 2)); + rects.push_back(Rect2i(0, -5, 2, img_height + 10)); + rects.push_back(Rect2i(-1, -1, img_width + 1, img_height + 1)); + + for (const Rect2i &rect : rects) { Ref<Image> img = memnew(Image(img_width, img_height, false, Image::FORMAT_RGBA8)); CHECK_NOTHROW_MESSAGE( img->fill_rect(rect, Color(1, 1, 1, 1)), @@ -267,7 +267,7 @@ TEST_CASE("[Image] Modifying pixels of an image") { } // Blend two images together - image->blend_rect(image2, Rect2(Vector2(0, 0), image2->get_size()), Vector2(0, 0)); + image->blend_rect(image2, Rect2i(Vector2i(0, 0), image2->get_size()), Vector2i(0, 0)); CHECK_MESSAGE( image->get_pixel(0, 0).a > 0.7, "blend_rect() should blend the alpha values of the two images."); @@ -279,7 +279,7 @@ TEST_CASE("[Image] Modifying pixels of an image") { image3->set_pixel(0, 0, Color(0, 1, 0, 1)); //blit_rect() two images together - image->blit_rect(image3, Rect2(Vector2(0, 0), image3->get_size()), Vector2(0, 0)); + image->blit_rect(image3, Rect2i(Vector2i(0, 0), image3->get_size()), Vector2i(0, 0)); CHECK_MESSAGE( image->get_pixel(0, 0).is_equal_approx(Color(0, 1, 0, 1)), "blit_rect() should replace old colors and not blend them."); @@ -300,4 +300,5 @@ TEST_CASE("[Image] Modifying pixels of an image") { "flip_y() should not leave old pixels behind."); } } // namespace TestImage + #endif // TEST_IMAGE_H diff --git a/tests/core/io/test_resource.h b/tests/core/io/test_resource.h index 84d651b63f..f94349fdd2 100644 --- a/tests/core/io/test_resource.h +++ b/tests/core/io/test_resource.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TEST_RESOURCE -#define TEST_RESOURCE +#ifndef TEST_RESOURCE_H +#define TEST_RESOURCE_H #include "core/io/resource.h" #include "core/io/resource_loader.h" @@ -111,4 +111,4 @@ TEST_CASE("[Resource] Saving and loading") { } } // namespace TestResource -#endif // TEST_RESOURCE +#endif // TEST_RESOURCE_H diff --git a/tests/core/math/test_basis.h b/tests/core/math/test_basis.h index ec58d95eed..ae8ca4acde 100644 --- a/tests/core/math/test_basis.h +++ b/tests/core/math/test_basis.h @@ -283,4 +283,4 @@ TEST_CASE("[Stress][Basis] Euler conversions") { } } // namespace TestBasis -#endif +#endif // TEST_BASIS_H diff --git a/tests/core/math/test_plane.h b/tests/core/math/test_plane.h new file mode 100644 index 0000000000..d81a5af1ce --- /dev/null +++ b/tests/core/math/test_plane.h @@ -0,0 +1,172 @@ +/*************************************************************************/ +/* test_plane.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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_PLANE_H +#define TEST_PLANE_H + +#include "core/math/plane.h" + +#include "thirdparty/doctest/doctest.h" + +namespace TestPlane { + +// Plane + +TEST_CASE("[Plane] Constructor methods") { + const Plane plane = Plane(32, 22, 16, 3); + const Plane plane_vector = Plane(Vector3(32, 22, 16), 3); + const Plane plane_copy_plane = Plane(plane); + + CHECK_MESSAGE( + plane == plane_vector, + "Planes created with same values but different methods should be equal."); + + CHECK_MESSAGE( + plane == plane_copy_plane, + "Planes created with same values but different methods should be equal."); +} + +TEST_CASE("[Plane] Basic getters") { + const Plane plane = Plane(32, 22, 16, 3); + const Plane plane_normalized = Plane(32.0 / 42, 22.0 / 42, 16.0 / 42, 3.0 / 42); + + CHECK_MESSAGE( + plane.get_normal().is_equal_approx(Vector3(32, 22, 16)), + "get_normal() should return the expected value."); + + CHECK_MESSAGE( + plane.normalized().is_equal_approx(plane_normalized), + "normalized() should return a copy of the normalized value."); +} + +TEST_CASE("[Plane] Basic setters") { + Plane plane = Plane(32, 22, 16, 3); + plane.set_normal(Vector3(4, 2, 3)); + + CHECK_MESSAGE( + plane.is_equal_approx(Plane(4, 2, 3, 3)), + "set_normal() should result in the expected plane."); + + plane = Plane(32, 22, 16, 3); + plane.normalize(); + + CHECK_MESSAGE( + plane.is_equal_approx(Plane(32.0 / 42, 22.0 / 42, 16.0 / 42, 3.0 / 42)), + "normalize() should result in the expected plane."); +} + +TEST_CASE("[Plane] Plane-point operations") { + const Plane plane = Plane(32, 22, 16, 3); + const Plane y_facing_plane = Plane(0, 1, 0, 4); + + CHECK_MESSAGE( + plane.center().is_equal_approx(Vector3(32 * 3, 22 * 3, 16 * 3)), + "center() should return a vector pointing to the center of the plane."); + + CHECK_MESSAGE( + y_facing_plane.is_point_over(Vector3(0, 5, 0)), + "is_point_over() should return the expected result."); + + CHECK_MESSAGE( + y_facing_plane.get_any_perpendicular_normal().is_equal_approx(Vector3(1, 0, 0)), + "get_any_perpindicular_normal() should return the expected result."); + + // TODO distance_to() +} + +TEST_CASE("[Plane] Has point") { + const Plane x_facing_plane = Plane(1, 0, 0, 0); + const Plane y_facing_plane = Plane(0, 1, 0, 0); + const Plane z_facing_plane = Plane(0, 0, 1, 0); + + const Vector3 x_axis_point = Vector3(10, 0, 0); + const Vector3 y_axis_point = Vector3(0, 10, 0); + const Vector3 z_axis_point = Vector3(0, 0, 10); + + const Plane x_facing_plane_with_d_offset = Plane(1, 0, 0, 1); + const Vector3 y_axis_point_with_d_offset = Vector3(1, 10, 0); + + CHECK_MESSAGE( + x_facing_plane.has_point(y_axis_point), + "has_point() with contained Vector3 should return the expected result."); + CHECK_MESSAGE( + x_facing_plane.has_point(z_axis_point), + "has_point() with contained Vector3 should return the expected result."); + + CHECK_MESSAGE( + y_facing_plane.has_point(x_axis_point), + "has_point() with contained Vector3 should return the expected result."); + CHECK_MESSAGE( + y_facing_plane.has_point(z_axis_point), + "has_point() with contained Vector3 should return the expected result."); + + CHECK_MESSAGE( + z_facing_plane.has_point(y_axis_point), + "has_point() with contained Vector3 should return the expected result."); + CHECK_MESSAGE( + z_facing_plane.has_point(x_axis_point), + "has_point() with contained Vector3 should return the expected result."); + + CHECK_MESSAGE( + x_facing_plane_with_d_offset.has_point(y_axis_point_with_d_offset), + "has_point() with passed Vector3 should return the expected result."); +} + +TEST_CASE("[Plane] Intersection") { + const Plane x_facing_plane = Plane(1, 0, 0, 1); + const Plane y_facing_plane = Plane(0, 1, 0, 2); + const Plane z_facing_plane = Plane(0, 0, 1, 3); + + Vector3 vec_out; + + CHECK_MESSAGE( + x_facing_plane.intersect_3(y_facing_plane, z_facing_plane, &vec_out), + "intersect_3() should return the expected result."); + CHECK_MESSAGE( + vec_out.is_equal_approx(Vector3(1, 2, 3)), + "intersect_3() should modify vec_out to the expected result."); + + CHECK_MESSAGE( + x_facing_plane.intersects_ray(Vector3(0, 1, 1), Vector3(2, 0, 0), &vec_out), + "intersects_ray() should return the expected result."); + CHECK_MESSAGE( + vec_out.is_equal_approx(Vector3(1, 1, 1)), + "intersects_ray() should modify vec_out to the expected result."); + + CHECK_MESSAGE( + x_facing_plane.intersects_segment(Vector3(0, 1, 1), Vector3(2, 1, 1), &vec_out), + "intersects_segment() should return the expected result."); + CHECK_MESSAGE( + vec_out.is_equal_approx(Vector3(1, 1, 1)), + "intersects_segment() should modify vec_out to the expected result."); +} +} // namespace TestPlane + +#endif // TEST_PLANE_H diff --git a/tests/core/object/test_class_db.h b/tests/core/object/test_class_db.h index 7ea9e16ff1..c7535426df 100644 --- a/tests/core/object/test_class_db.h +++ b/tests/core/object/test_class_db.h @@ -597,7 +597,7 @@ void add_exposed_classes(Context &r_context) { (exposed_class.name != r_context.names_cache.object_class || String(method.name) != "free"), warn_msg.utf8().get_data()); - } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + } else if (return_info.type == Variant::INT && return_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) { method.return_type.name = return_info.class_name; method.return_type.is_enum = true; } else if (return_info.class_name != StringName()) { @@ -626,7 +626,7 @@ void add_exposed_classes(Context &r_context) { ArgumentData arg; arg.name = orig_arg_name; - if (arg_info.type == Variant::INT && arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + if (arg_info.type == Variant::INT && arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) { arg.type.name = arg_info.class_name; arg.type.is_enum = true; } else if (arg_info.class_name != StringName()) { @@ -694,7 +694,7 @@ void add_exposed_classes(Context &r_context) { ArgumentData arg; arg.name = orig_arg_name; - if (arg_info.type == Variant::INT && arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + if (arg_info.type == Variant::INT && arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) { arg.type.name = arg_info.class_name; arg.type.is_enum = true; } else if (arg_info.class_name != StringName()) { @@ -732,13 +732,13 @@ void add_exposed_classes(Context &r_context) { List<String> constants; ClassDB::get_integer_constant_list(class_name, &constants, true); - const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map; + const HashMap<StringName, ClassDB::ClassInfo::EnumInfo> &enum_map = class_info->enum_map; - for (const KeyValue<StringName, List<StringName>> &K : enum_map) { + for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &K : enum_map) { EnumData enum_; enum_.name = K.key; - for (const StringName &E : K.value) { + for (const StringName &E : K.value.constants) { const StringName &constant_name = E; TEST_FAIL_COND(String(constant_name).find("::") != -1, "Enum constant contains '::', check bindings to remove the scope: '", diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 0b191d2d94..0c5704d6c9 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -89,12 +89,12 @@ TEST_CASE("[String] UTF8") { static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 }; static const uint8_t u8str[] = { 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 }; String s = u32str; - bool err = s.parse_utf8(s.utf8().get_data()); - CHECK(!err); + Error err = s.parse_utf8(s.utf8().get_data()); + CHECK(err == OK); CHECK(s == u32str); err = s.parse_utf8((const char *)u8str); - CHECK(!err); + CHECK(err == OK); CHECK(s == u32str); CharString cs = (const char *)u8str; @@ -106,12 +106,12 @@ TEST_CASE("[String] UTF16") { static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 }; static const char16_t u16str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 }; String s = u32str; - bool err = s.parse_utf16(s.utf16().get_data()); - CHECK(!err); + Error err = s.parse_utf16(s.utf16().get_data()); + CHECK(err == OK); CHECK(s == u32str); err = s.parse_utf16(u16str); - CHECK(!err); + CHECK(err == OK); CHECK(s == u32str); Char16String cs = u16str; @@ -123,8 +123,8 @@ TEST_CASE("[String] UTF8 with BOM") { static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 }; static const uint8_t u8str[] = { 0xEF, 0xBB, 0xBF, 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 }; String s; - bool err = s.parse_utf8((const char *)u8str); - CHECK(!err); + Error err = s.parse_utf8((const char *)u8str); + CHECK(err == OK); CHECK(s == u32str); CharString cs = (const char *)u8str; @@ -137,12 +137,12 @@ TEST_CASE("[String] UTF16 with BOM") { static const char16_t u16str[] = { 0xFEFF, 0x0020, 0x0045, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 }; static const char16_t u16str_swap[] = { 0xFFFE, 0x2000, 0x4500, 0x4A30, 0x0F36, 0x8830, 0x4630, 0x3CD8, 0xA4DF, 0 }; String s; - bool err = s.parse_utf16(u16str); - CHECK(!err); + Error err = s.parse_utf16(u16str); + CHECK(err == OK); CHECK(s == u32str); err = s.parse_utf16(u16str_swap); - CHECK(!err); + CHECK(err == OK); CHECK(s == u32str); Char16String cs = u16str; @@ -152,29 +152,48 @@ TEST_CASE("[String] UTF16 with BOM") { CHECK(String::utf16(cs) == s); } -TEST_CASE("[String] Invalid UTF8") { +TEST_CASE("[String] Invalid UTF8 (non-standard)") { ERR_PRINT_OFF - static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 }; + static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0xF0, 0x82, 0x82, 0xAC, 0xED, 0xA0, 0x81, 0 }; + // + +2 +2 +2 +3 overlong +3 unpaired +2 + static const char32_t u32str[] = { 0x45, 0x304A, 0x3088, 0x3046, 0x1F3A4, 0x20AC, 0xD801, 0 }; String s; - bool err = s.parse_utf8((const char *)u8str); - CHECK(err); - CHECK(s.is_empty()); + Error err = s.parse_utf8((const char *)u8str); + CHECK(err == ERR_PARSE_ERROR); + CHECK(s == u32str); CharString cs = (const char *)u8str; - CHECK(String::utf8(cs).is_empty()); + CHECK(String::utf8(cs) == s); ERR_PRINT_ON } -TEST_CASE("[String] Invalid UTF16") { +TEST_CASE("[String] Invalid UTF8 (unrecoverable)") { + ERR_PRINT_OFF + static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xC0, 0x80, 0xF0, 0x9F, 0x8E, 0xA4, 0xF0, 0x82, 0x82, 0xAC, 0xED, 0xA0, 0x81, 0 }; + // + +2 inv +2 inv inv inv +2 +2 ovl NUL +1 +3 overlong +3 unpaired +2 + static const char32_t u32str[] = { 0x45, 0x304A, 0x20, 0x20, 0x20, 0x20, 0x3088, 0x3046, 0x20, 0x1F3A4, 0x20AC, 0xD801, 0 }; + String s; + Error err = s.parse_utf8((const char *)u8str); + CHECK(err == ERR_INVALID_DATA); + CHECK(s == u32str); + + CharString cs = (const char *)u8str; + CHECK(String::utf8(cs) == s); + ERR_PRINT_ON +} + +TEST_CASE("[String] Invalid UTF16 (non-standard)") { ERR_PRINT_OFF static const char16_t u16str[] = { 0x0045, 0x304A, 0x3088, 0x3046, 0xDFA4, 0 }; + // + + + + unpaired + static const char32_t u32str[] = { 0x0045, 0x304A, 0x3088, 0x3046, 0xDFA4, 0 }; String s; - bool err = s.parse_utf16(u16str); - CHECK(err); - CHECK(s.is_empty()); + Error err = s.parse_utf16(u16str); + CHECK(err == ERR_PARSE_ERROR); + CHECK(s == u32str); Char16String cs = u16str; - CHECK(String::utf16(cs).is_empty()); + CHECK(String::utf16(cs) == s); ERR_PRINT_ON } @@ -262,8 +281,8 @@ TEST_CASE("[String] Test chr") { CHECK(String::chr('H') == "H"); CHECK(String::chr(0x3012)[0] == 0x3012); ERR_PRINT_OFF - CHECK(String::chr(0xd812)[0] == 0xfffd); // Unpaired UTF-16 surrogate - CHECK(String::chr(0x20d812)[0] == 0xfffd); // Outside UTF-32 range + CHECK(String::chr(0xd812)[0] == 0xd812); // Unpaired UTF-16 surrogate + CHECK(String::chr(0x20d812)[0] == 0x20d812); // Outside UTF-32 range ERR_PRINT_ON } @@ -1125,9 +1144,9 @@ TEST_CASE("[String] lstrip and rstrip") { #undef STRIP_TEST } -TEST_CASE("[String] ensuring empty string into parse_utf8 passes empty string") { +TEST_CASE("[String] Ensuring empty string into parse_utf8 passes empty string") { String empty; - CHECK(empty.parse_utf8(nullptr, -1)); + CHECK(empty.parse_utf8(nullptr, -1) == ERR_INVALID_DATA); } TEST_CASE("[String] Cyrillic to_lower()") { @@ -1440,8 +1459,8 @@ TEST_CASE("[String] validate_node_name") { String name_with_spaces = "Name with spaces"; CHECK(name_with_spaces.validate_node_name() == "Name with spaces"); - String name_with_kana = "Name with kana ゴドツ"; - CHECK(name_with_kana.validate_node_name() == "Name with kana ゴドツ"); + String name_with_kana = U"Name with kana ゴドツ"; + CHECK(name_with_kana.validate_node_name() == U"Name with kana ゴドツ"); String name_with_invalid_chars = "Name with invalid characters :.@removed!"; CHECK(name_with_invalid_chars.validate_node_name() == "Name with invalid characters removed!"); diff --git a/tests/core/templates/test_hash_set.h b/tests/core/templates/test_hash_set.h index 93fc0b26a3..3b9a800641 100644 --- a/tests/core/templates/test_hash_set.h +++ b/tests/core/templates/test_hash_set.h @@ -225,4 +225,4 @@ TEST_CASE("[HashSet] Copy") { } // namespace TestHashSet -#endif // TEST_HASH_MAP_H +#endif // TEST_HASH_SET_H diff --git a/tests/core/threads/test_worker_thread_pool.h b/tests/core/threads/test_worker_thread_pool.h new file mode 100644 index 0000000000..641b293c8a --- /dev/null +++ b/tests/core/threads/test_worker_thread_pool.h @@ -0,0 +1,158 @@ +/*************************************************************************/ +/* test_worker_thread_pool.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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_WORKER_THREAD_POOL_H +#define TEST_WORKER_THREAD_POOL_H + +#include "core/object/worker_thread_pool.h" + +#include "tests/test_macros.h" + +namespace TestWorkerThreadPool { + +int u32scmp(const char32_t *l, const char32_t *r) { + for (; *l == *r && *l && *r; l++, r++) { + // Continue. + } + return *l - *r; +} + +static void static_test(void *p_arg) { + SafeNumeric<uint32_t> *counter = (SafeNumeric<uint32_t> *)p_arg; + counter->increment(); +} + +static SafeNumeric<uint32_t> callable_counter; + +static void static_callable_test() { + callable_counter.increment(); +} + +TEST_CASE("[WorkerThreadPool] Process 256 threads using native task") { + const int count = 256; + SafeNumeric<uint32_t> counter; + WorkerThreadPool::TaskID tasks[count]; + for (int i = 0; i < count; i++) { + tasks[i] = WorkerThreadPool::get_singleton()->add_native_task(static_test, &counter, true); + } + for (int i = 0; i < count; i++) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]); + } + + CHECK(counter.get() == count); +} + +TEST_CASE("[WorkerThreadPool] Process 256 threads using native low priority") { + const int count = 256; + SafeNumeric<uint32_t> counter = SafeNumeric<uint32_t>(0); + WorkerThreadPool::TaskID tasks[count]; + for (int i = 0; i < count; i++) { + tasks[i] = WorkerThreadPool::get_singleton()->add_native_task(static_test, &counter, false); + } + for (int i = 0; i < count; i++) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]); + } + + CHECK(counter.get() == count); +} + +TEST_CASE("[WorkerThreadPool] Process 256 threads using callable") { + const int count = 256; + WorkerThreadPool::TaskID tasks[count]; + callable_counter.set(0); + for (int i = 0; i < count; i++) { + tasks[i] = WorkerThreadPool::get_singleton()->add_task(callable_mp_static(static_callable_test), true); + } + for (int i = 0; i < count; i++) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]); + } + + CHECK(callable_counter.get() == count); +} + +TEST_CASE("[WorkerThreadPool] Process 256 threads using callable low priority") { + const int count = 256; + WorkerThreadPool::TaskID tasks[count]; + callable_counter.set(0); + for (int i = 0; i < count; i++) { + tasks[i] = WorkerThreadPool::get_singleton()->add_task(callable_mp_static(static_callable_test), false); + } + for (int i = 0; i < count; i++) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]); + } + + CHECK(callable_counter.get() == count); +} + +static void static_group_test(void *p_arg, uint32_t p_index) { + SafeNumeric<uint32_t> *counter = (SafeNumeric<uint32_t> *)p_arg; + counter->exchange_if_greater(p_index); +} + +TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group") { + const int count = 256; + SafeNumeric<uint32_t> counter; + WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_native_group_task(static_group_test, &counter, count, -1, true); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group); + CHECK(counter.get() == count - 1); +} + +TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group low priority") { + const int count = 256; + SafeNumeric<uint32_t> counter; + WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_native_group_task(static_group_test, &counter, count, -1, false); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group); + CHECK(counter.get() == count - 1); +} + +static SafeNumeric<uint32_t> callable_group_counter; + +static void static_callable_group_test(uint32_t p_index) { + callable_group_counter.exchange_if_greater(p_index); +} + +TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group") { + const int count = 256; + WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_group_task(callable_mp_static(static_callable_group_test), count, -1, true); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group); + CHECK(callable_group_counter.get() == count - 1); +} + +TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group low priority") { + const int count = 256; + callable_group_counter.set(0); + WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_group_task(callable_mp_static(static_callable_group_test), count, -1, false); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group); + CHECK(callable_group_counter.get() == count - 1); +} + +} // namespace TestWorkerThreadPool + +#endif // TEST_WORKER_THREAD_POOL_H diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index d28380d056..7605f24cf8 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -3251,7 +3251,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") { SIGNAL_WATCH(code_edit, "symbol_validate"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(code_edit, Key::META); #else SEND_GUI_KEY_EVENT(code_edit, Key::CTRL); diff --git a/tests/scene/test_path_3d.h b/tests/scene/test_path_3d.h index 78f4e97f03..8ac3d7b5b4 100644 --- a/tests/scene/test_path_3d.h +++ b/tests/scene/test_path_3d.h @@ -81,4 +81,4 @@ TEST_CASE("[Path3D] Curve setter and getter") { } // namespace TestPath3D -#endif // TEST_PATH_3D +#endif // TEST_PATH_3D_H diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h index 4098dd7ace..0fce359c5a 100644 --- a/tests/scene/test_text_edit.h +++ b/tests/scene/test_text_edit.h @@ -724,7 +724,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { CHECK(text_edit->has_selection()); CHECK(text_edit->get_selected_text() == "t"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::SHIFT | KeyModifierMask::ALT) #else SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::SHIFT | KeyModifierMask::CMD) @@ -736,7 +736,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { CHECK(text_edit->has_selection()); CHECK(text_edit->get_selected_text() == "tes"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::SHIFT | KeyModifierMask::ALT) #else SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::SHIFT | KeyModifierMask::CMD) @@ -1902,7 +1902,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::ALT | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::CMD | KeyModifierMask::SHIFT); @@ -2013,7 +2013,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::ALT | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::CMD | KeyModifierMask::SHIFT); @@ -2244,7 +2244,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::UP | KeyModifierMask::CMD | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::HOME | KeyModifierMask::CMD | KeyModifierMask::SHIFT); @@ -2285,7 +2285,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::DOWN | KeyModifierMask::CMD | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::END | KeyModifierMask::CMD | KeyModifierMask::SHIFT); @@ -2326,7 +2326,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::CMD | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::HOME | KeyModifierMask::SHIFT); @@ -2383,7 +2383,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::CMD | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::END | KeyModifierMask::SHIFT); @@ -3139,7 +3139,7 @@ TEST_CASE("[SceneTree][TextEdit] viewport") { v_scroll = text_edit->get_v_scroll(); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButton::WHEEL_DOWN, Key::NONE); text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); - CHECK(text_edit->get_v_scroll() > v_scroll); + CHECK(text_edit->get_v_scroll() >= v_scroll); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, MouseButton::WHEEL_UP, Key::NONE); text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); CHECK(text_edit->get_v_scroll() == v_scroll); @@ -3148,7 +3148,7 @@ TEST_CASE("[SceneTree][TextEdit] viewport") { text_edit->set_v_scroll_speed(10000); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButton::WHEEL_DOWN, Key::NONE); text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); - CHECK(text_edit->get_v_scroll() > v_scroll); + CHECK(text_edit->get_v_scroll() >= v_scroll); SEND_GUI_MOUSE_BUTTON_EVENT(text_edit, Point2i(10, 10), MouseButton::WHEEL_UP, MouseButton::WHEEL_UP, Key::NONE); text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); CHECK(text_edit->get_v_scroll() == v_scroll); diff --git a/tests/scene/test_theme.h b/tests/scene/test_theme.h index fedffc8449..f7cfa0fd5b 100644 --- a/tests/scene/test_theme.h +++ b/tests/scene/test_theme.h @@ -46,7 +46,7 @@ public: } const valid_data[Theme::DATA_TYPE_MAX] = { { Theme::DATA_TYPE_COLOR, Color() }, { Theme::DATA_TYPE_CONSTANT, 42 }, - { Theme::DATA_TYPE_FONT, Ref<Font>(memnew(Font)) }, + { Theme::DATA_TYPE_FONT, Ref<FontFile>(memnew(FontFile)) }, { Theme::DATA_TYPE_FONT_SIZE, 42 }, { Theme::DATA_TYPE_ICON, Ref<Texture>(memnew(ImageTexture)) }, { Theme::DATA_TYPE_STYLEBOX, Ref<StyleBox>(memnew(StyleBoxFlat)) }, diff --git a/tests/servers/test_text_server.h b/tests/servers/test_text_server.h index 066c280fd5..61207216fc 100644 --- a/tests/servers/test_text_server.h +++ b/tests/servers/test_text_server.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef TOOLS_ENABLED - #ifndef TEST_TEXT_SERVER_H #define TEST_TEXT_SERVER_H +#ifdef TOOLS_ENABLED + #include "editor/builtin_fonts.gen.h" #include "servers/text_server.h" #include "tests/test_macros.h" @@ -561,5 +561,6 @@ TEST_SUITE("[[TextServer]") { } }; // namespace TestTextServer -#endif // TEST_TEXT_SERVER_H #endif // TOOLS_ENABLED + +#endif // TEST_TEXT_SERVER_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index ac0cdf0cc1..e71f2edba3 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -45,6 +45,7 @@ #include "tests/core/math/test_expression.h" #include "tests/core/math/test_geometry_2d.h" #include "tests/core/math/test_geometry_3d.h" +#include "tests/core/math/test_plane.h" #include "tests/core/math/test_random_number_generator.h" #include "tests/core/math/test_rect2.h" #include "tests/core/math/test_rect2i.h" @@ -69,6 +70,7 @@ #include "tests/core/test_crypto.h" #include "tests/core/test_hashing_context.h" #include "tests/core/test_time.h" +#include "tests/core/threads/test_worker_thread_pool.h" #include "tests/core/variant/test_array.h" #include "tests/core/variant/test_dictionary.h" #include "tests/core/variant/test_variant.h" |