diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/core/math/test_vector4.h | 315 | ||||
-rw-r--r-- | tests/core/math/test_vector4i.h | 148 | ||||
-rw-r--r-- | tests/core/object/test_class_db.h | 82 | ||||
-rw-r--r-- | tests/core/object/test_object.h | 6 | ||||
-rw-r--r-- | tests/core/variant/test_variant.h | 62 | ||||
-rw-r--r-- | tests/servers/test_text_server.h | 198 | ||||
-rw-r--r-- | tests/test_main.cpp | 2 |
7 files changed, 692 insertions, 121 deletions
diff --git a/tests/core/math/test_vector4.h b/tests/core/math/test_vector4.h new file mode 100644 index 0000000000..ccf991401b --- /dev/null +++ b/tests/core/math/test_vector4.h @@ -0,0 +1,315 @@ +/*************************************************************************/ +/* test_vector4.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_VECTOR4_H +#define TEST_VECTOR4_H + +#include "core/math/vector4.h" +#include "tests/test_macros.h" + +#define Math_SQRT3 1.7320508075688772935274463415059 + +namespace TestVector4 { + +TEST_CASE("[Vector4] Axis methods") { + Vector4 vector = Vector4(1.2, 3.4, 5.6, -0.9); + CHECK_MESSAGE( + vector.max_axis_index() == Vector4::Axis::AXIS_Z, + "Vector4 max_axis_index should work as expected."); + CHECK_MESSAGE( + vector.min_axis_index() == Vector4::Axis::AXIS_W, + "Vector4 min_axis_index should work as expected."); + CHECK_MESSAGE( + vector.get_axis(vector.max_axis_index()) == (real_t)5.6, + "Vector4 get_axis should work as expected."); + CHECK_MESSAGE( + vector[vector.min_axis_index()] == (real_t)-0.9, + "Vector4 array operator should work as expected."); + + vector.set_axis(Vector4::Axis::AXIS_Y, 4.7); + CHECK_MESSAGE( + vector.get_axis(Vector4::Axis::AXIS_Y) == (real_t)4.7, + "Vector4 set_axis should work as expected."); + vector[Vector4::Axis::AXIS_Y] = 3.7; + CHECK_MESSAGE( + vector[Vector4::Axis::AXIS_Y] == (real_t)3.7, + "Vector4 array operator setter should work as expected."); +} + +TEST_CASE("[Vector4] Interpolation methods") { + const Vector4 vector1 = Vector4(1, 2, 3, 4); + const Vector4 vector2 = Vector4(4, 5, 6, 7); + CHECK_MESSAGE( + vector1.lerp(vector2, 0.5) == Vector4(2.5, 3.5, 4.5, 5.5), + "Vector4 lerp should work as expected."); + CHECK_MESSAGE( + vector1.lerp(vector2, 1.0 / 3.0).is_equal_approx(Vector4(2, 3, 4, 5)), + "Vector4 lerp should work as expected."); + CHECK_MESSAGE( + vector1.cubic_interpolate(vector2, Vector4(), Vector4(7, 7, 7, 7), 0.5) == Vector4(2.375, 3.5, 4.625, 5.75), + "Vector4 cubic_interpolate should work as expected."); + CHECK_MESSAGE( + vector1.cubic_interpolate(vector2, Vector4(), Vector4(7, 7, 7, 7), 1.0 / 3.0).is_equal_approx(Vector4(1.851851940155029297, 2.962963104248046875, 4.074074268341064453, 5.185185185185)), + "Vector4 cubic_interpolate should work as expected."); +} + +TEST_CASE("[Vector4] Length methods") { + const Vector4 vector1 = Vector4(10, 10, 10, 10); + const Vector4 vector2 = Vector4(20, 30, 40, 50); + CHECK_MESSAGE( + vector1.length_squared() == 400, + "Vector4 length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.length(), 20), + "Vector4 length should work as expected."); + CHECK_MESSAGE( + vector2.length_squared() == 5400, + "Vector4 length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector2.length(), (real_t)73.484692283495), + "Vector4 length should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.distance_to(vector2), (real_t)54.772255750517), + "Vector4 distance_to should work as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.distance_squared_to(vector2), 3000), + "Vector4 distance_squared_to should work as expected."); +} + +TEST_CASE("[Vector4] Limiting methods") { + const Vector4 vector = Vector4(10, 10, 10, 10); + CHECK_MESSAGE( + Vector4(-5, 5, 15, -15).clamp(Vector4(), vector) == Vector4(0, 5, 10, 0), + "Vector4 clamp should work as expected."); + CHECK_MESSAGE( + vector.clamp(Vector4(0, 10, 15, 18), Vector4(5, 10, 20, 25)) == Vector4(5, 10, 15, 18), + "Vector4 clamp should work as expected."); +} + +TEST_CASE("[Vector4] Normalization methods") { + CHECK_MESSAGE( + Vector4(1, 0, 0, 0).is_normalized() == true, + "Vector4 is_normalized should return true for a normalized vector."); + CHECK_MESSAGE( + Vector4(1, 1, 1, 1).is_normalized() == false, + "Vector4 is_normalized should return false for a non-normalized vector."); + CHECK_MESSAGE( + Vector4(1, 0, 0, 0).normalized() == Vector4(1, 0, 0, 0), + "Vector4 normalized should return the same vector for a normalized vector."); + CHECK_MESSAGE( + Vector4(1, 1, 0, 0).normalized().is_equal_approx(Vector4(Math_SQRT12, Math_SQRT12, 0, 0)), + "Vector4 normalized should work as expected."); + CHECK_MESSAGE( + Vector4(1, 1, 1, 1).normalized().is_equal_approx(Vector4(0.5, 0.5, 0.5, 0.5)), + "Vector4 normalized should work as expected."); +} + +TEST_CASE("[Vector4] Operators") { + const Vector4 decimal1 = Vector4(2.3, 4.9, 7.8, 3.2); + const Vector4 decimal2 = Vector4(1.2, 3.4, 5.6, 1.7); + const Vector4 power1 = Vector4(0.75, 1.5, 0.625, 0.125); + const Vector4 power2 = Vector4(0.5, 0.125, 0.25, 0.75); + const Vector4 int1 = Vector4(4, 5, 9, 2); + const Vector4 int2 = Vector4(1, 2, 3, 1); + + CHECK_MESSAGE( + -decimal1 == Vector4(-2.3, -4.9, -7.8, -3.2), + "Vector4 change of sign should work as expected."); + CHECK_MESSAGE( + (decimal1 + decimal2).is_equal_approx(Vector4(3.5, 8.3, 13.4, 4.9)), + "Vector4 addition should behave as expected."); + CHECK_MESSAGE( + (power1 + power2) == Vector4(1.25, 1.625, 0.875, 0.875), + "Vector4 addition with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 + int2) == Vector4(5, 7, 12, 3), + "Vector4 addition with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 - decimal2).is_equal_approx(Vector4(1.1, 1.5, 2.2, 1.5)), + "Vector4 subtraction should behave as expected."); + CHECK_MESSAGE( + (power1 - power2) == Vector4(0.25, 1.375, 0.375, -0.625), + "Vector4 subtraction with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 - int2) == Vector4(3, 3, 6, 1), + "Vector4 subtraction with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 * decimal2).is_equal_approx(Vector4(2.76, 16.66, 43.68, 5.44)), + "Vector4 multiplication should behave as expected."); + CHECK_MESSAGE( + (power1 * power2) == Vector4(0.375, 0.1875, 0.15625, 0.09375), + "Vector4 multiplication with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 * int2) == Vector4(4, 10, 27, 2), + "Vector4 multiplication with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 / decimal2).is_equal_approx(Vector4(1.91666666666666666, 1.44117647058823529, 1.39285714285714286, 1.88235294118)), + "Vector4 division should behave as expected."); + CHECK_MESSAGE( + (power1 / power2) == Vector4(1.5, 12.0, 2.5, 1.0 / 6.0), + "Vector4 division with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 / int2) == Vector4(4, 2.5, 3, 2), + "Vector4 division with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 * 2).is_equal_approx(Vector4(4.6, 9.8, 15.6, 6.4)), + "Vector4 multiplication should behave as expected."); + CHECK_MESSAGE( + (power1 * 2) == Vector4(1.5, 3, 1.25, 0.25), + "Vector4 multiplication with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 * 2) == Vector4(8, 10, 18, 4), + "Vector4 multiplication with integers should give exact results."); + + CHECK_MESSAGE( + (decimal1 / 2).is_equal_approx(Vector4(1.15, 2.45, 3.9, 1.6)), + "Vector4 division should behave as expected."); + CHECK_MESSAGE( + (power1 / 2) == Vector4(0.375, 0.75, 0.3125, 0.0625), + "Vector4 division with powers of two should give exact results."); + CHECK_MESSAGE( + (int1 / 2) == Vector4(2, 2.5, 4.5, 1), + "Vector4 division with integers should give exact results."); + + CHECK_MESSAGE( + ((String)decimal1) == "(2.3, 4.9, 7.8, 3.2)", + "Vector4 cast to String should work as expected."); + CHECK_MESSAGE( + ((String)decimal2) == "(1.2, 3.4, 5.6, 1.7)", + "Vector4 cast to String should work as expected."); + CHECK_MESSAGE( + ((String)Vector4(9.7, 9.8, 9.9, -1.8)) == "(9.7, 9.8, 9.9, -1.8)", + "Vector4 cast to String should work as expected."); +#ifdef REAL_T_IS_DOUBLE + CHECK_MESSAGE( + ((String)Vector4(Math_E, Math_SQRT2, Math_SQRT3, Math_SQRT3)) == "(2.71828182845905, 1.4142135623731, 1.73205080756888, 1.73205080756888)", + "Vector4 cast to String should print the correct amount of digits for real_t = double."); +#else + CHECK_MESSAGE( + ((String)Vector4(Math_E, Math_SQRT2, Math_SQRT3, Math_SQRT3)) == "(2.718282, 1.414214, 1.732051, 1.732051)", + "Vector4 cast to String should print the correct amount of digits for real_t = float."); +#endif // REAL_T_IS_DOUBLE +} + +TEST_CASE("[Vector4] Other methods") { + const Vector4 vector = Vector4(1.2, 3.4, 5.6, 1.6); + CHECK_MESSAGE( + vector.direction_to(Vector4()).is_equal_approx(-vector.normalized()), + "Vector4 direction_to should work as expected."); + CHECK_MESSAGE( + Vector4(1, 1, 1, 1).direction_to(Vector4(2, 2, 2, 2)).is_equal_approx(Vector4(0.5, 0.5, 0.5, 0.5)), + "Vector4 direction_to should work as expected."); + CHECK_MESSAGE( + vector.inverse().is_equal_approx(Vector4(1 / 1.2, 1 / 3.4, 1 / 5.6, 1 / 1.6)), + "Vector4 inverse should work as expected."); + CHECK_MESSAGE( + vector.posmod(2).is_equal_approx(Vector4(1.2, 1.4, 1.6, 1.6)), + "Vector4 posmod should work as expected."); + CHECK_MESSAGE( + (-vector).posmod(2).is_equal_approx(Vector4(0.8, 0.6, 0.4, 0.4)), + "Vector4 posmod should work as expected."); + CHECK_MESSAGE( + vector.posmodv(Vector4(1, 2, 3, 4)).is_equal_approx(Vector4(0.2, 1.4, 2.6, 1.6)), + "Vector4 posmodv should work as expected."); + CHECK_MESSAGE( + (-vector).posmodv(Vector4(2, 3, 4, 5)).is_equal_approx(Vector4(0.8, 2.6, 2.4, 3.4)), + "Vector4 posmodv should work as expected."); + CHECK_MESSAGE( + vector.snapped(Vector4(1, 1, 1, 1)) == Vector4(1, 3, 6, 2), + "Vector4 snapped to integers should be the same as rounding."); + CHECK_MESSAGE( + vector.snapped(Vector4(0.25, 0.25, 0.25, 0.25)) == Vector4(1.25, 3.5, 5.5, 1.5), + "Vector4 snapped to 0.25 should give exact results."); +} + +TEST_CASE("[Vector4] Rounding methods") { + const Vector4 vector1 = Vector4(1.2, 3.4, 5.6, 1.6); + const Vector4 vector2 = Vector4(1.2, -3.4, -5.6, -1.6); + CHECK_MESSAGE( + vector1.abs() == vector1, + "Vector4 abs should work as expected."); + CHECK_MESSAGE( + vector2.abs() == vector1, + "Vector4 abs should work as expected."); + CHECK_MESSAGE( + vector1.ceil() == Vector4(2, 4, 6, 2), + "Vector4 ceil should work as expected."); + CHECK_MESSAGE( + vector2.ceil() == Vector4(2, -3, -5, -1), + "Vector4 ceil should work as expected."); + + CHECK_MESSAGE( + vector1.floor() == Vector4(1, 3, 5, 1), + "Vector4 floor should work as expected."); + CHECK_MESSAGE( + vector2.floor() == Vector4(1, -4, -6, -2), + "Vector4 floor should work as expected."); + + CHECK_MESSAGE( + vector1.round() == Vector4(1, 3, 6, 2), + "Vector4 round should work as expected."); + CHECK_MESSAGE( + vector2.round() == Vector4(1, -3, -6, -2), + "Vector4 round should work as expected."); + + CHECK_MESSAGE( + vector1.sign() == Vector4(1, 1, 1, 1), + "Vector4 sign should work as expected."); + CHECK_MESSAGE( + vector2.sign() == Vector4(1, -1, -1, -1), + "Vector4 sign should work as expected."); +} + +TEST_CASE("[Vector4] Linear algebra methods") { + const Vector4 vector_x = Vector4(1, 0, 0, 0); + const Vector4 vector_y = Vector4(0, 1, 0, 0); + const Vector4 vector1 = Vector4(1.7, 2.3, 1, 9.1); + const Vector4 vector2 = Vector4(-8.2, -16, 3, 2.4); + + CHECK_MESSAGE( + vector_x.dot(vector_y) == 0.0, + "Vector4 dot product of perpendicular vectors should be zero."); + CHECK_MESSAGE( + vector_x.dot(vector_x) == 1.0, + "Vector4 dot product of identical unit vectors should be one."); + CHECK_MESSAGE( + (vector_x * 10).dot(vector_x * 10) == 100.0, + "Vector4 dot product of same direction vectors should behave as expected."); + CHECK_MESSAGE( + Math::is_equal_approx((vector1 * 2).dot(vector2 * 4), (real_t)-25.9 * 8), + "Vector4 dot product should work as expected."); +} +} // namespace TestVector4 + +#endif // TEST_VECTOR4_H diff --git a/tests/core/math/test_vector4i.h b/tests/core/math/test_vector4i.h new file mode 100644 index 0000000000..ac63001b24 --- /dev/null +++ b/tests/core/math/test_vector4i.h @@ -0,0 +1,148 @@ +/*************************************************************************/ +/* test_vector4i.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_VECTOR4I_H +#define TEST_VECTOR4I_H + +#include "core/math/vector4i.h" +#include "tests/test_macros.h" + +namespace TestVector4i { + +TEST_CASE("[Vector4i] Axis methods") { + Vector4i vector = Vector4i(1, 2, 3, 4); + CHECK_MESSAGE( + vector.max_axis_index() == Vector4i::Axis::AXIS_W, + "Vector4i max_axis_index should work as expected."); + CHECK_MESSAGE( + vector.min_axis_index() == Vector4i::Axis::AXIS_X, + "Vector4i min_axis_index should work as expected."); + CHECK_MESSAGE( + vector.get_axis(vector.max_axis_index()) == 4, + "Vector4i get_axis should work as expected."); + CHECK_MESSAGE( + vector[vector.min_axis_index()] == 1, + "Vector4i array operator should work as expected."); + + vector.set_axis(Vector4i::Axis::AXIS_Y, 5); + CHECK_MESSAGE( + vector.get_axis(Vector4i::Axis::AXIS_Y) == 5, + "Vector4i set_axis should work as expected."); + vector[Vector4i::Axis::AXIS_Y] = 5; + CHECK_MESSAGE( + vector[Vector4i::Axis::AXIS_Y] == 5, + "Vector4i array operator setter should work as expected."); +} + +TEST_CASE("[Vector4i] Clamp method") { + const Vector4i vector = Vector4i(10, 10, 10, 10); + CHECK_MESSAGE( + Vector4i(-5, 5, 15, INT_MAX).clamp(Vector4i(), vector) == Vector4i(0, 5, 10, 10), + "Vector4i clamp should work as expected."); + CHECK_MESSAGE( + vector.clamp(Vector4i(0, 10, 15, -10), Vector4i(5, 10, 20, -5)) == Vector4i(5, 10, 15, -5), + "Vector4i clamp should work as expected."); +} + +TEST_CASE("[Vector4i] Length methods") { + const Vector4i vector1 = Vector4i(10, 10, 10, 10); + const Vector4i vector2 = Vector4i(20, 30, 40, 50); + CHECK_MESSAGE( + vector1.length_squared() == 400, + "Vector4i length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector1.length(), 20), + "Vector4i length should work as expected."); + CHECK_MESSAGE( + vector2.length_squared() == 5400, + "Vector4i length_squared should work as expected and return exact result."); + CHECK_MESSAGE( + Math::is_equal_approx(vector2.length(), 73.4846922835), + "Vector4i length should work as expected."); +} + +TEST_CASE("[Vector4i] Operators") { + const Vector4i vector1 = Vector4i(4, 5, 9, 2); + const Vector4i vector2 = Vector4i(1, 2, 3, 4); + + CHECK_MESSAGE( + -vector1 == Vector4i(-4, -5, -9, -2), + "Vector4i change of sign should work as expected."); + CHECK_MESSAGE( + (vector1 + vector2) == Vector4i(5, 7, 12, 6), + "Vector4i addition with integers should give exact results."); + CHECK_MESSAGE( + (vector1 - vector2) == Vector4i(3, 3, 6, -2), + "Vector4i subtraction with integers should give exact results."); + CHECK_MESSAGE( + (vector1 * vector2) == Vector4i(4, 10, 27, 8), + "Vector4i multiplication with integers should give exact results."); + CHECK_MESSAGE( + (vector1 / vector2) == Vector4i(4, 2, 3, 0), + "Vector4i division with integers should give exact results."); + + CHECK_MESSAGE( + (vector1 * 2) == Vector4i(8, 10, 18, 4), + "Vector4i multiplication with integers should give exact results."); + CHECK_MESSAGE( + (vector1 / 2) == Vector4i(2, 2, 4, 1), + "Vector4i division with integers should give exact results."); + + CHECK_MESSAGE( + ((Vector4)vector1) == Vector4(4, 5, 9, 2), + "Vector4i cast to Vector4 should work as expected."); + CHECK_MESSAGE( + ((Vector4)vector2) == Vector4(1, 2, 3, 4), + "Vector4i cast to Vector4 should work as expected."); + CHECK_MESSAGE( + Vector4i(Vector4(1.1, 2.9, 3.9, 100.5)) == Vector4i(1, 2, 3, 100), + "Vector4i constructed from Vector4 should work as expected."); +} + +TEST_CASE("[Vector4i] Abs and sign methods") { + const Vector4i vector1 = Vector4i(1, 3, 5, 7); + const Vector4i vector2 = Vector4i(1, -3, -5, 7); + CHECK_MESSAGE( + vector1.abs() == vector1, + "Vector4i abs should work as expected."); + CHECK_MESSAGE( + vector2.abs() == vector1, + "Vector4i abs should work as expected."); + + CHECK_MESSAGE( + vector1.sign() == Vector4i(1, 1, 1, 1), + "Vector4i sign should work as expected."); + CHECK_MESSAGE( + vector2.sign() == Vector4i(1, -1, -1, 1), + "Vector4i sign should work as expected."); +} +} // namespace TestVector4i + +#endif // TEST_VECTOR4I_H diff --git a/tests/core/object/test_class_db.h b/tests/core/object/test_class_db.h index fc329ba0eb..208923edb9 100644 --- a/tests/core/object/test_class_db.h +++ b/tests/core/object/test_class_db.h @@ -71,6 +71,7 @@ struct ArgumentData { String name; bool has_defval = false; Variant defval; + int position; }; struct MethodData { @@ -371,6 +372,39 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co } } +void validate_argument(const Context &p_context, const ExposedClass &p_class, const String &p_owner_name, const String &p_owner_type, const ArgumentData &p_arg) { + TEST_COND((p_arg.name.is_empty() || p_arg.name.begins_with("_unnamed_arg")), + vformat("Unnamed argument in position %d of %s '%s.%s'.", p_arg.position, p_owner_type, p_class.name, p_owner_name)); + + const ExposedClass *arg_class = p_context.find_exposed_class(p_arg.type); + if (arg_class) { + TEST_COND(arg_class->is_singleton, + vformat("Argument type is a singleton: '%s' of %s '%s.%s'.", p_arg.name, p_owner_type, p_class.name, p_owner_name)); + + if (p_class.api_type == ClassDB::API_CORE) { + TEST_COND(arg_class->api_type == ClassDB::API_EDITOR, + vformat("Argument '%s' of %s '%s.%s' has type '%s' from the editor API. Core API cannot have dependencies on the editor API.", + p_arg.name, p_owner_type, p_class.name, p_owner_name, arg_class->name)); + } + } else { + // Look for types that don't inherit Object. + TEST_FAIL_COND(!p_context.has_type(p_arg.type), + vformat("Argument type '%s' not found: '%s' of %s '%s.%s'.", p_arg.type.name, p_arg.name, p_owner_type, p_class.name, p_owner_name)); + } + + if (p_arg.has_defval) { + String type_error_msg; + bool arg_defval_assignable_to_type = arg_default_value_is_assignable_to_type(p_context, p_arg.defval, p_arg.type, &type_error_msg); + + String err_msg = vformat("Invalid default value for parameter '%s' of %s '%s.%s'.", p_arg.name, p_owner_type, p_class.name, p_owner_name); + if (!type_error_msg.is_empty()) { + err_msg += " " + type_error_msg; + } + + TEST_COND(!arg_defval_assignable_to_type, err_msg.utf8().get_data()); + } +} + void validate_method(const Context &p_context, const ExposedClass &p_class, const MethodData &p_method) { if (p_method.return_type.name != StringName()) { const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type); @@ -392,54 +426,14 @@ void validate_method(const Context &p_context, const ExposedClass &p_class, cons for (const ArgumentData &F : p_method.arguments) { const ArgumentData &arg = F; - - const ExposedClass *arg_class = p_context.find_exposed_class(arg.type); - if (arg_class) { - TEST_COND(arg_class->is_singleton, - "Argument type is a singleton: '", arg.name, "' of method '", p_class.name, ".", p_method.name, "'."); - - if (p_class.api_type == ClassDB::API_CORE) { - TEST_COND(arg_class->api_type == ClassDB::API_EDITOR, - "Argument '", arg.name, "' of method '", p_class.name, ".", p_method.name, "' has type '", - arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API."); - } - } else { - // Look for types that don't inherit Object - TEST_FAIL_COND(!p_context.has_type(arg.type), - "Argument type '", arg.type.name, "' not found: '", arg.name, "' of method", p_class.name, ".", p_method.name, "'."); - } - - if (arg.has_defval) { - String type_error_msg; - bool arg_defval_assignable_to_type = arg_default_value_is_assignable_to_type(p_context, arg.defval, arg.type, &type_error_msg); - String err_msg = vformat("Invalid default value for parameter '%s' of method '%s.%s'.", arg.name, p_class.name, p_method.name); - if (!type_error_msg.is_empty()) { - err_msg += " " + type_error_msg; - } - TEST_COND(!arg_defval_assignable_to_type, err_msg.utf8().get_data()); - } + validate_argument(p_context, p_class, p_method.name, "method", arg); } } void validate_signal(const Context &p_context, const ExposedClass &p_class, const SignalData &p_signal) { for (const ArgumentData &F : p_signal.arguments) { const ArgumentData &arg = F; - - const ExposedClass *arg_class = p_context.find_exposed_class(arg.type); - if (arg_class) { - TEST_COND(arg_class->is_singleton, - "Argument class is a singleton: '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "'."); - - if (p_class.api_type == ClassDB::API_CORE) { - TEST_COND(arg_class->api_type == ClassDB::API_EDITOR, - "Argument '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "' has type '", - arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API."); - } - } else { - // Look for types that don't inherit Object - TEST_FAIL_COND(!p_context.has_type(arg.type), - "Argument type '", arg.type.name, "' not found: '", arg.name, "' of signal", p_class.name, ".", p_signal.name, "'."); - } + validate_argument(p_context, p_class, p_signal.name, "signal", arg); } } @@ -625,6 +619,7 @@ void add_exposed_classes(Context &r_context) { ArgumentData arg; arg.name = orig_arg_name; + arg.position = i; 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; @@ -693,6 +688,7 @@ void add_exposed_classes(Context &r_context) { ArgumentData arg; arg.name = orig_arg_name; + arg.position = i; 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; @@ -841,7 +837,7 @@ TEST_SUITE("[ClassDB]") { add_builtin_types(context); add_global_enums(context); - SUBCASE("[ClassDB] Find exposed class") { + SUBCASE("[ClassDB] Validate exposed classes") { const ExposedClass *object_class = context.find_exposed_class(context.names_cache.object_class); TEST_FAIL_COND(!object_class, "Object class not found."); TEST_FAIL_COND(object_class->base != StringName(), diff --git a/tests/core/object/test_object.h b/tests/core/object/test_object.h index 88a3e4ccad..f5c5de7fdf 100644 --- a/tests/core/object/test_object.h +++ b/tests/core/object/test_object.h @@ -82,6 +82,12 @@ public: Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const override { return Variant::PACKED_FLOAT32_ARRAY; } + bool property_can_revert(const StringName &p_name) const override { + return false; + }; + bool property_get_revert(const StringName &p_name, Variant &r_ret) const override { + return false; + }; void get_method_list(List<MethodInfo> *p_list) const override { } bool has_method(const StringName &p_method) const override { diff --git a/tests/core/variant/test_variant.h b/tests/core/variant/test_variant.h index 916686d7c1..d6799928b4 100644 --- a/tests/core/variant/test_variant.h +++ b/tests/core/variant/test_variant.h @@ -719,6 +719,7 @@ TEST_CASE("[Variant] Assignment To Color from Bool,Int,Float,String,Vec2,Vec2i,V vec3i_v = col_v; CHECK(vec3i_v.get_type() == Variant::COLOR); } + TEST_CASE("[Variant] Writer and parser array") { Array a = build_array(1, String("hello"), build_array(Variant())); String a_str; @@ -911,6 +912,67 @@ TEST_CASE("[Variant] Nested dictionary comparison") { CHECK_FALSE(v_d1 == v_d_other_val); } +struct ArgumentData { + Variant::Type type; + String name; + bool has_defval = false; + Variant defval; + int position; +}; + +struct MethodData { + StringName name; + Variant::Type return_type; + List<ArgumentData> arguments; + bool is_virtual = false; + bool is_vararg = false; +}; + +TEST_CASE("[Variant] Utility functions") { + List<MethodData> functions; + + List<StringName> function_names; + Variant::get_utility_function_list(&function_names); + function_names.sort_custom<StringName::AlphCompare>(); + + for (const StringName &E : function_names) { + MethodData md; + md.name = E; + + // Utility function's return type. + if (Variant::has_utility_function_return_value(E)) { + md.return_type = Variant::get_utility_function_return_type(E); + } + + // Utility function's arguments. + if (Variant::is_utility_function_vararg(E)) { + md.is_vararg = true; + } else { + for (int i = 0; i < Variant::get_utility_function_argument_count(E); i++) { + ArgumentData arg; + arg.type = Variant::get_utility_function_argument_type(E, i); + arg.name = Variant::get_utility_function_argument_name(E, i); + arg.position = i; + + md.arguments.push_back(arg); + } + } + + functions.push_back(md); + } + + SUBCASE("[Variant] Validate utility functions") { + for (const MethodData &E : functions) { + for (const ArgumentData &F : E.arguments) { + const ArgumentData &arg = F; + + TEST_COND((arg.name.is_empty() || arg.name.begins_with("_unnamed_arg")), + vformat("Unnamed argument in position %d of function '%s'.", arg.position, E.name)); + } + } + } +} + } // namespace TestVariant #endif // TEST_VARIANT_H diff --git a/tests/servers/test_text_server.h b/tests/servers/test_text_server.h index 57a2cae37f..9ebd0f34b4 100644 --- a/tests/servers/test_text_server.h +++ b/tests/servers/test_text_server.h @@ -44,7 +44,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Loading fonts") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC)) { continue; @@ -52,7 +52,7 @@ TEST_SUITE("[TextServer]") { RID font = ts->create_font(); ts->font_set_data_ptr(font, _font_NotoSans_Regular, _font_NotoSans_Regular_size); - TEST_FAIL_COND(font == RID(), "Loading font failed."); + CHECK_FALSE_MESSAGE(font == RID(), "Loading font failed."); ts->free_rid(font); } } @@ -60,7 +60,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: Font fallback") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -79,26 +79,26 @@ TEST_SUITE("[TextServer]") { // 6^ 17^ RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size == 0, "Shaping failed"); + CHECK_FALSE_MESSAGE(gl_size == 0, "Shaping failed"); for (int j = 0; j < gl_size; j++) { if (glyphs[j].start < 6) { - TEST_FAIL_COND(glyphs[j].font_rid != font[1], "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != font[1], "Incorrect font selected."); } if ((glyphs[j].start > 6) && (glyphs[j].start < 16)) { - TEST_FAIL_COND(glyphs[j].font_rid != font[0], "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != font[0], "Incorrect font selected."); } if (glyphs[j].start > 16) { - TEST_FAIL_COND(glyphs[j].font_rid != RID(), "Incorrect font selected."); - TEST_FAIL_COND(glyphs[j].index != test[glyphs[j].start], "Incorrect glyph index."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != RID(), "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].index != test[glyphs[j].start], "Incorrect glyph index."); } - TEST_FAIL_COND((glyphs[j].start < 0 || glyphs[j].end > test.length()), "Incorrect glyph range."); - TEST_FAIL_COND(glyphs[j].font_size != 16, "Incorrect glyph font size."); + CHECK_FALSE_MESSAGE((glyphs[j].start < 0 || glyphs[j].end > test.length()), "Incorrect glyph range."); + CHECK_FALSE_MESSAGE(glyphs[j].font_size != 16, "Incorrect glyph font size."); } ts->free_rid(ctx); @@ -113,7 +113,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: BiDi") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) { continue; @@ -132,23 +132,23 @@ TEST_SUITE("[TextServer]") { // 7^ 26^ RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size == 0, "Shaping failed"); + CHECK_FALSE_MESSAGE(gl_size == 0, "Shaping failed"); for (int j = 0; j < gl_size; j++) { if (glyphs[j].count > 0) { if (glyphs[j].start < 7) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } if ((glyphs[j].start > 8) && (glyphs[j].start < 23)) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) != TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) != TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } if (glyphs[j].start > 26) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } } } @@ -165,7 +165,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: Line break and align points") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -186,16 +186,16 @@ TEST_SUITE("[TextServer]") { { String test = U"Test test long text long text\n"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 30, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 30, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -203,11 +203,11 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 14 || j == 19 || j == 24) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else if (j == 29) { - TEST_FAIL_COND((soft || !space || !hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || !space || !hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -216,21 +216,63 @@ TEST_SUITE("[TextServer]") { { String test = U"الحمـد"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 6, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { + ts->shaped_text_update_justification_ops(ctx); + + glyphs = ts->shaped_text_get_glyphs(ctx); + gl_size = ts->shaped_text_get_glyph_count(ctx); + + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 1) { + CHECK_FALSE_MESSAGE((soft || space || hard || virt || !elo), "Invalid glyph flags."); + } else { + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + } + ts->free_rid(ctx); + } + + { + String test = U"الحمد"; + RID ctx = ts->create_shaped_text(); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); + bool ok = ts->shaped_text_add_string(ctx, test, font, 16); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); + ts->shaped_text_update_breaks(ctx); + + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + CHECK_FALSE_MESSAGE(gl_size != 5, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { @@ -239,7 +281,7 @@ TEST_SUITE("[TextServer]") { glyphs = ts->shaped_text_get_glyphs(ctx); gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 6, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -247,9 +289,9 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 1) { - TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || !virt || !elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } } @@ -259,15 +301,15 @@ TEST_SUITE("[TextServer]") { { String test = U"الحمـد الرياضي العربي"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 21, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 21, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -275,9 +317,9 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 6 || j == 14) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } @@ -287,7 +329,7 @@ TEST_SUITE("[TextServer]") { glyphs = ts->shaped_text_get_glyphs(ctx); gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 23, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 23, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -295,13 +337,13 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 7 || j == 16) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else if (j == 3 || j == 9) { - TEST_FAIL_COND((soft || space || hard || !virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || !virt || !elo), "Invalid glyph flags."); } else if (j == 18) { - TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || !elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } } @@ -312,16 +354,16 @@ TEST_SUITE("[TextServer]") { { String test = U"เป็น ภาษา ราชการ และ ภาษา"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 25, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 25, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -329,9 +371,9 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 16 || j == 20) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -340,16 +382,16 @@ TEST_SUITE("[TextServer]") { if (ts->has_feature(TextServer::FEATURE_BREAK_ITERATORS)) { String test = U"เป็นภาษาราชการและภาษา"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 25, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 25, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -357,9 +399,9 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 16 || j == 20) { - TEST_FAIL_COND((!soft || !space || hard || !virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || !virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -375,7 +417,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: Line breaking") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -394,21 +436,21 @@ TEST_SUITE("[TextServer]") { font.push_back(font2); RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test_1, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); PackedInt32Array brks = ts->shaped_text_get_line_breaks(ctx, 1); - TEST_FAIL_COND(brks.size() != 6, "Invalid line breaks number."); + CHECK_FALSE_MESSAGE(brks.size() != 6, "Invalid line breaks number."); if (brks.size() == 6) { - TEST_FAIL_COND(brks[0] != 0, "Invalid line break position."); - TEST_FAIL_COND(brks[1] != 5, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[0] != 0, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[1] != 5, "Invalid line break position."); - TEST_FAIL_COND(brks[2] != 5, "Invalid line break position."); - TEST_FAIL_COND(brks[3] != 10, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[2] != 5, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[3] != 10, "Invalid line break position."); - TEST_FAIL_COND(brks[4] != 10, "Invalid line break position."); - TEST_FAIL_COND(brks[5] != 14, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[4] != 10, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[5] != 14, "Invalid line break position."); } ts->free_rid(ctx); @@ -423,7 +465,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: Justification") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -448,40 +490,40 @@ TEST_SUITE("[TextServer]") { float width_old, width; if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_1, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width != width_old), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width != width_old), "Invalid fill width."); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_2, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); } ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_3, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); @@ -495,7 +537,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Unicode identifiers") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); static const char32_t *data[19] = { U"-30", U"100", U"10.1", U"10,1", U"1e2", U"1e-2", U"1e2e3", U"0xAB", U"AB", U"Test1", U"1Test", U"Test*1", U"test_testeT", U"test_tes teT", U"عَلَيْكُمْ", U"عَلَيْكُمْTest", U"ӒӖӚӜ", U"_test", U"ÂÃÄÅĀĂĄÇĆĈĊ" }; static bool isid[19] = { false, false, false, false, false, false, false, false, true, true, false, false, true, false, true, true, true, true, true }; @@ -516,7 +558,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Strip Diacritics") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (ts->has_feature(TextServer::FEATURE_SHAPING)) { CHECK(ts->strip_diacritics(U"ٱلسَّلَامُ عَلَيْكُمْ") == U"ٱلسلام عليكم"); @@ -544,7 +586,7 @@ TEST_SUITE("[TextServer]") { continue; } - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); { String text1 = U"linguistically similar and effectively form"; // 14^ 22^ 26^ 38^ diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 628b9cbc3c..3d186711cb 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -58,6 +58,8 @@ #include "tests/core/math/test_vector2i.h" #include "tests/core/math/test_vector3.h" #include "tests/core/math/test_vector3i.h" +#include "tests/core/math/test_vector4.h" +#include "tests/core/math/test_vector4i.h" #include "tests/core/object/test_class_db.h" #include "tests/core/object/test_method_bind.h" #include "tests/core/object/test_object.h" |