summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/core/math/test_vector4.h315
-rw-r--r--tests/core/math/test_vector4i.h148
-rw-r--r--tests/core/object/test_class_db.h82
-rw-r--r--tests/core/object/test_object.h6
-rw-r--r--tests/core/variant/test_variant.h62
-rw-r--r--tests/servers/test_text_server.h198
-rw-r--r--tests/test_main.cpp2
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"