summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/core/io/test_json.h2
-rw-r--r--tests/core/math/test_aabb.h8
-rw-r--r--tests/core/math/test_basis.h10
-rw-r--r--tests/core/math/test_color.h6
-rw-r--r--tests/core/math/test_expression.h20
-rw-r--r--tests/core/math/test_geometry_2d.h24
-rw-r--r--tests/core/math/test_math_funcs.h556
-rw-r--r--tests/core/math/test_quaternion.h27
-rw-r--r--tests/core/math/test_rect2.h8
-rw-r--r--tests/core/math/test_vector2.h28
-rw-r--r--tests/core/math/test_vector2i.h6
-rw-r--r--tests/core/math/test_vector3.h28
-rw-r--r--tests/core/math/test_vector3i.h4
-rw-r--r--tests/core/math/test_vector4.h10
-rw-r--r--tests/core/math/test_vector4i.h4
-rw-r--r--tests/core/string/test_string.h8
-rw-r--r--tests/scene/test_animation.h82
-rw-r--r--tests/scene/test_audio_stream_wav.h2
-rw-r--r--tests/scene/test_curve.h54
-rw-r--r--tests/scene/test_primitives.h40
-rw-r--r--tests/scene/test_text_edit.h34
-rw-r--r--tests/test_main.cpp4
22 files changed, 786 insertions, 179 deletions
diff --git a/tests/core/io/test_json.h b/tests/core/io/test_json.h
index 478cf1766e..af450da3b8 100644
--- a/tests/core/io/test_json.h
+++ b/tests/core/io/test_json.h
@@ -83,7 +83,7 @@ TEST_CASE("[JSON] Parsing single data types") {
json.get_error_line() == 0,
"Parsing a floating-point number as JSON should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(json.get_data()), 0.123456),
+ double(json.get_data()) == doctest::Approx(0.123456),
"Parsing a floating-point number as JSON should return the expected value.");
json.parse("\"hello\"");
diff --git a/tests/core/math/test_aabb.h b/tests/core/math/test_aabb.h
index ebaf441abf..23969556be 100644
--- a/tests/core/math/test_aabb.h
+++ b/tests/core/math/test_aabb.h
@@ -91,7 +91,7 @@ TEST_CASE("[AABB] Basic setters") {
TEST_CASE("[AABB] Volume getters") {
AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
CHECK_MESSAGE(
- Math::is_equal_approx(aabb.get_volume(), 120),
+ aabb.get_volume() == doctest::Approx(120),
"get_volume() should return the expected value with positive size.");
CHECK_MESSAGE(
aabb.has_volume(),
@@ -99,17 +99,17 @@ TEST_CASE("[AABB] Volume getters") {
aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(-4, 5, 6));
CHECK_MESSAGE(
- Math::is_equal_approx(aabb.get_volume(), -120),
+ aabb.get_volume() == doctest::Approx(-120),
"get_volume() should return the expected value with negative size (1 component).");
aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(-4, -5, 6));
CHECK_MESSAGE(
- Math::is_equal_approx(aabb.get_volume(), 120),
+ aabb.get_volume() == doctest::Approx(120),
"get_volume() should return the expected value with negative size (2 components).");
aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(-4, -5, -6));
CHECK_MESSAGE(
- Math::is_equal_approx(aabb.get_volume(), -120),
+ aabb.get_volume() == doctest::Approx(-120),
"get_volume() should return the expected value with negative size (3 components).");
aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 0, 6));
diff --git a/tests/core/math/test_basis.h b/tests/core/math/test_basis.h
index a4099ebf7d..dce9d5cec3 100644
--- a/tests/core/math/test_basis.h
+++ b/tests/core/math/test_basis.h
@@ -223,7 +223,7 @@ TEST_CASE("[Basis] Set axis angle") {
// Testing the singularity when the angle is 180°.
Basis singularityPi(-1, 0, 0, 0, 1, 0, 0, 0, -1);
singularityPi.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, pi));
+ CHECK(angle == doctest::Approx(pi));
// Testing reversing the an axis (of an 30° angle).
float cos30deg = Math::cos(Math::deg_to_rad((real_t)30.0));
@@ -231,17 +231,17 @@ TEST_CASE("[Basis] Set axis angle") {
Basis z_negative(cos30deg, 0.5, 0, -0.5, cos30deg, 0, 0, 0, 1);
z_positive.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, Math::deg_to_rad((real_t)30.0)));
+ CHECK(angle == doctest::Approx(Math::deg_to_rad((real_t)30.0)));
CHECK(axis == Vector3(0, 0, 1));
z_negative.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, Math::deg_to_rad((real_t)30.0)));
+ CHECK(angle == doctest::Approx(Math::deg_to_rad((real_t)30.0)));
CHECK(axis == Vector3(0, 0, -1));
// Testing a rotation of 90° on x-y-z.
Basis x90deg(1, 0, 0, 0, 0, -1, 0, 1, 0);
x90deg.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, pi / (real_t)2));
+ CHECK(angle == doctest::Approx(pi / (real_t)2));
CHECK(axis == Vector3(1, 0, 0));
Basis y90deg(0, 0, 1, 0, 1, 0, -1, 0, 0);
@@ -255,7 +255,7 @@ TEST_CASE("[Basis] Set axis angle") {
// Regression test: checks that the method returns a small angle (not 0).
Basis tiny(1, 0, 0, 0, 0.9999995, -0.001, 0, 001, 0.9999995); // The min angle possible with float is 0.001rad.
tiny.get_axis_angle(axis, angle);
- CHECK(Math::is_equal_approx(angle, (real_t)0.001, (real_t)0.0001));
+ CHECK(angle == doctest::Approx(0.001).epsilon(0.0001));
// Regression test: checks that the method returns an angle which is a number (not NaN)
Basis bugNan(1.00000024, 0, 0.000100001693, 0, 1, 0, -0.000100009143, 0, 1.00000024);
diff --git a/tests/core/math/test_color.h b/tests/core/math/test_color.h
index 51c3bc8bdc..c6550778e8 100644
--- a/tests/core/math/test_color.h
+++ b/tests/core/math/test_color.h
@@ -101,13 +101,13 @@ TEST_CASE("[Color] Reading methods") {
const Color dark_blue = Color(0, 0, 0.5, 0.4);
CHECK_MESSAGE(
- Math::is_equal_approx(dark_blue.get_h(), 240.0f / 360.0f),
+ dark_blue.get_h() == doctest::Approx(240.0f / 360.0f),
"The returned HSV hue should match the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(dark_blue.get_s(), 1.0f),
+ dark_blue.get_s() == doctest::Approx(1.0f),
"The returned HSV saturation should match the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(dark_blue.get_v(), 0.5f),
+ dark_blue.get_v() == doctest::Approx(0.5f),
"The returned HSV value should match the expected value.");
}
diff --git a/tests/core/math/test_expression.h b/tests/core/math/test_expression.h
index 6e3be541b0..9734fd9f36 100644
--- a/tests/core/math/test_expression.h
+++ b/tests/core/math/test_expression.h
@@ -83,42 +83,42 @@ TEST_CASE("[Expression] Floating-point arithmetic") {
expression.parse("-123.456") == OK,
"Float identity should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), -123.456),
+ double(expression.execute()) == doctest::Approx(-123.456),
"Float identity should return the expected result.");
CHECK_MESSAGE(
expression.parse("2.0 + 3.0") == OK,
"Float addition should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 5),
+ double(expression.execute()) == doctest::Approx(5),
"Float addition should return the expected result.");
CHECK_MESSAGE(
expression.parse("3.0 / 10") == OK,
"Float / integer division should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 0.3),
+ double(expression.execute()) == doctest::Approx(0.3),
"Float / integer division should return the expected result.");
CHECK_MESSAGE(
expression.parse("3 / 10.0") == OK,
"Basic integer / float division should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 0.3),
+ double(expression.execute()) == doctest::Approx(0.3),
"Basic integer / float division should return the expected result.");
CHECK_MESSAGE(
expression.parse("3.0 / 10.0") == OK,
"Float / float division should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 0.3),
+ double(expression.execute()) == doctest::Approx(0.3),
"Float / float division should return the expected result.");
CHECK_MESSAGE(
expression.parse("2.5 * (6.0 + 14.25) / 2.0 - 5.12345") == OK,
"Float multiplication-addition-subtraction-division should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 20.18905),
+ double(expression.execute()) == doctest::Approx(20.18905),
"Float multiplication-addition-subtraction-division should return the expected result.");
}
@@ -129,7 +129,7 @@ TEST_CASE("[Expression] Scientific notation") {
expression.parse("2.e5") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 200'000),
+ double(expression.execute()) == doctest::Approx(200'000),
"The expression should return the expected result.");
// The middle "e" is ignored here.
@@ -137,14 +137,14 @@ TEST_CASE("[Expression] Scientific notation") {
expression.parse("2e5") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 2e5),
+ double(expression.execute()) == doctest::Approx(2e5),
"The expression should return the expected result.");
CHECK_MESSAGE(
expression.parse("2e.5") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 2),
+ double(expression.execute()) == doctest::Approx(2),
"The expression should return the expected result.");
}
@@ -176,7 +176,7 @@ TEST_CASE("[Expression] Built-in functions") {
expression.parse("snapped(sin(0.5), 0.01)") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
- Math::is_equal_approx(double(expression.execute()), 0.48),
+ double(expression.execute()) == doctest::Approx(0.48),
"`snapped(sin(0.5), 0.01)` should return the expected result.");
CHECK_MESSAGE(
diff --git a/tests/core/math/test_geometry_2d.h b/tests/core/math/test_geometry_2d.h
index 54893a0b87..27c9e7f58b 100644
--- a/tests/core/math/test_geometry_2d.h
+++ b/tests/core/math/test_geometry_2d.h
@@ -171,43 +171,43 @@ TEST_CASE("[Geometry2D] Segment intersection with circle") {
real_t one = 1.0;
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(4, 0), Vector2(0, 0), 1.0), one_quarter),
+ Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(4, 0), Vector2(0, 0), 1.0) == doctest::Approx(one_quarter),
"Segment from inside to outside of circle should intersect it.");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(4, 0), Vector2(0, 0), Vector2(0, 0), 1.0), three_quarters),
+ Geometry2D::segment_intersects_circle(Vector2(4, 0), Vector2(0, 0), Vector2(0, 0), 1.0) == doctest::Approx(three_quarters),
"Segment from outside to inside of circle should intersect it.");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(-2, 0), Vector2(2, 0), Vector2(0, 0), 1.0), one_quarter),
+ Geometry2D::segment_intersects_circle(Vector2(-2, 0), Vector2(2, 0), Vector2(0, 0), 1.0) == doctest::Approx(one_quarter),
"Segment running through circle should intersect it.");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(-2, 0), Vector2(0, 0), 1.0), one_quarter),
+ Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(-2, 0), Vector2(0, 0), 1.0) == doctest::Approx(one_quarter),
"Segment running through circle should intersect it.");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(1, 0), Vector2(0, 0), 1.0), one),
+ Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(1, 0), Vector2(0, 0), 1.0) == doctest::Approx(one),
"Segment starting inside the circle and ending on the circle should intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(0, 0), Vector2(0, 0), 1.0), zero),
+ Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(0, 0), Vector2(0, 0), 1.0) == doctest::Approx(zero),
"Segment starting on the circle and going inwards should intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(2, 0), Vector2(0, 0), 1.0), zero),
+ Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(2, 0), Vector2(0, 0), 1.0) == doctest::Approx(zero),
"Segment starting on the circle and going outwards should intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(1, 0), Vector2(0, 0), 1.0), one),
+ Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(1, 0), Vector2(0, 0), 1.0) == doctest::Approx(one),
"Segment starting outside the circle and ending on the circle intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(-1, 0), Vector2(1, 0), Vector2(0, 0), 2.0), minus_one),
+ Geometry2D::segment_intersects_circle(Vector2(-1, 0), Vector2(1, 0), Vector2(0, 0), 2.0) == doctest::Approx(minus_one),
"Segment completely within the circle should not intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(-1, 0), Vector2(0, 0), 2.0), minus_one),
+ Geometry2D::segment_intersects_circle(Vector2(1, 0), Vector2(-1, 0), Vector2(0, 0), 2.0) == doctest::Approx(minus_one),
"Segment completely within the circle should not intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(3, 0), Vector2(0, 0), 1.0), minus_one),
+ Geometry2D::segment_intersects_circle(Vector2(2, 0), Vector2(3, 0), Vector2(0, 0), 1.0) == doctest::Approx(minus_one),
"Segment completely outside the circle should not intersect it");
CHECK_MESSAGE(
- Math::is_equal_approx(Geometry2D::segment_intersects_circle(Vector2(3, 0), Vector2(2, 0), Vector2(0, 0), 1.0), minus_one),
+ Geometry2D::segment_intersects_circle(Vector2(3, 0), Vector2(2, 0), Vector2(0, 0), 1.0) == doctest::Approx(minus_one),
"Segment completely outside the circle should not intersect it");
}
diff --git a/tests/core/math/test_math_funcs.h b/tests/core/math/test_math_funcs.h
new file mode 100644
index 0000000000..c468e73b74
--- /dev/null
+++ b/tests/core/math/test_math_funcs.h
@@ -0,0 +1,556 @@
+/*************************************************************************/
+/* test_math_funcs.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_MATH_FUNCS_H
+#define TEST_MATH_FUNCS_H
+
+#include "tests/test_macros.h"
+
+namespace TestMath {
+
+TEST_CASE("[Math] C++ macros") {
+ CHECK(MIN(-2, 2) == -2);
+ CHECK(MIN(600, 2) == 2);
+
+ CHECK(MAX(-2, 2) == 2);
+ CHECK(MAX(600, 2) == 600);
+
+ CHECK(CLAMP(600, -2, 2) == 2);
+ CHECK(CLAMP(620, 600, 650) == 620);
+ // `max` is lower than `min`.
+ CHECK(CLAMP(620, 600, 50) == 50);
+
+ CHECK(ABS(-5) == 5);
+ CHECK(ABS(0) == 0);
+ CHECK(ABS(5) == 5);
+
+ CHECK(SIGN(-5) == -1.0);
+ CHECK(SIGN(0) == 0.0);
+ CHECK(SIGN(5) == 1.0);
+}
+
+TEST_CASE("[Math] Power of two functions") {
+ CHECK(next_power_of_2(0) == 0);
+ CHECK(next_power_of_2(1) == 1);
+ CHECK(next_power_of_2(16) == 16);
+ CHECK(next_power_of_2(17) == 32);
+ CHECK(next_power_of_2(65535) == 65536);
+
+ CHECK(previous_power_of_2(0) == 0);
+ CHECK(previous_power_of_2(1) == 1);
+ CHECK(previous_power_of_2(16) == 16);
+ CHECK(previous_power_of_2(17) == 16);
+ CHECK(previous_power_of_2(65535) == 32768);
+
+ CHECK(closest_power_of_2(0) == 0);
+ CHECK(closest_power_of_2(1) == 1);
+ CHECK(closest_power_of_2(16) == 16);
+ CHECK(closest_power_of_2(17) == 16);
+ CHECK(closest_power_of_2(65535) == 65536);
+
+ CHECK(get_shift_from_power_of_2(0) == -1);
+ CHECK(get_shift_from_power_of_2(1) == 0);
+ CHECK(get_shift_from_power_of_2(16) == 4);
+ CHECK(get_shift_from_power_of_2(17) == -1);
+ CHECK(get_shift_from_power_of_2(65535) == -1);
+
+ CHECK(nearest_shift(0) == 0);
+ CHECK(nearest_shift(1) == 1);
+ CHECK(nearest_shift(16) == 5);
+ CHECK(nearest_shift(17) == 5);
+ CHECK(nearest_shift(65535) == 16);
+}
+
+TEST_CASE("[Math] abs") {
+ // int
+ CHECK(Math::abs(-1) == 1);
+ CHECK(Math::abs(0) == 0);
+ CHECK(Math::abs(1) == 1);
+
+ // double
+ CHECK(Math::abs(-0.1) == 0.1);
+ CHECK(Math::abs(0.0) == 0.0);
+ CHECK(Math::abs(0.1) == 0.1);
+
+ // float
+ CHECK(Math::abs(-0.1f) == 0.1f);
+ CHECK(Math::abs(0.0f) == 0.0f);
+ CHECK(Math::abs(0.1f) == 0.1f);
+}
+
+TEST_CASE("[Math] round/floor/ceil") {
+ CHECK(Math::round(1.5) == 2.0);
+ CHECK(Math::round(1.6) == 2.0);
+ CHECK(Math::round(-1.5) == -2.0);
+ CHECK(Math::round(-1.1) == -1.0);
+
+ CHECK(Math::floor(1.5) == 1.0);
+ CHECK(Math::floor(-1.5) == -2.0);
+
+ CHECK(Math::ceil(1.5) == 2.0);
+ CHECK(Math::ceil(-1.9) == -1.0);
+}
+
+TEST_CASE("[Math] sin/cos/tan") {
+ CHECK(Math::sin(-0.1) == doctest::Approx(-0.0998334166));
+ CHECK(Math::sin(0.1) == doctest::Approx(0.0998334166));
+ CHECK(Math::sin(0.5) == doctest::Approx(0.4794255386));
+ CHECK(Math::sin(1.0) == doctest::Approx(0.8414709848));
+ CHECK(Math::sin(1.5) == doctest::Approx(0.9974949866));
+ CHECK(Math::sin(450.0) == doctest::Approx(-0.683283725));
+
+ CHECK(Math::cos(-0.1) == doctest::Approx(0.99500416530));
+ CHECK(Math::cos(0.1) == doctest::Approx(0.9950041653));
+ CHECK(Math::cos(0.5) == doctest::Approx(0.8775825619));
+ CHECK(Math::cos(1.0) == doctest::Approx(0.5403023059));
+ CHECK(Math::cos(1.5) == doctest::Approx(0.0707372017));
+ CHECK(Math::cos(450.0) == doctest::Approx(-0.7301529642));
+
+ CHECK(Math::tan(-0.1) == doctest::Approx(-0.1003346721));
+ CHECK(Math::tan(0.1) == doctest::Approx(0.1003346721));
+ CHECK(Math::tan(0.5) == doctest::Approx(0.5463024898));
+ CHECK(Math::tan(1.0) == doctest::Approx(1.5574077247));
+ CHECK(Math::tan(1.5) == doctest::Approx(14.1014199472));
+ CHECK(Math::tan(450.0) == doctest::Approx(0.9358090134));
+}
+
+TEST_CASE("[Math] sinh/cosh/tanh") {
+ CHECK(Math::sinh(-0.1) == doctest::Approx(-0.10016675));
+ CHECK(Math::sinh(0.1) == doctest::Approx(0.10016675));
+ CHECK(Math::sinh(0.5) == doctest::Approx(0.5210953055));
+ CHECK(Math::sinh(1.0) == doctest::Approx(1.1752011936));
+ CHECK(Math::sinh(1.5) == doctest::Approx(2.1292794551));
+
+ CHECK(Math::cosh(-0.1) == doctest::Approx(1.0050041681));
+ CHECK(Math::cosh(0.1) == doctest::Approx(1.0050041681));
+ CHECK(Math::cosh(0.5) == doctest::Approx(1.1276259652));
+ CHECK(Math::cosh(1.0) == doctest::Approx(1.5430806348));
+ CHECK(Math::cosh(1.5) == doctest::Approx(2.3524096152));
+
+ CHECK(Math::tanh(-0.1) == doctest::Approx(-0.0996679946));
+ CHECK(Math::tanh(0.1) == doctest::Approx(0.0996679946));
+ CHECK(Math::tanh(0.5) == doctest::Approx(0.4621171573));
+ CHECK(Math::tanh(1.0) == doctest::Approx(0.761594156));
+ CHECK(Math::tanh(1.5) == doctest::Approx(0.9051482536));
+ CHECK(Math::tanh(450.0) == doctest::Approx(1.0));
+}
+
+TEST_CASE("[Math] asin/acos/atan") {
+ CHECK(Math::asin(-0.1) == doctest::Approx(-0.1001674212));
+ CHECK(Math::asin(0.1) == doctest::Approx(0.1001674212));
+ CHECK(Math::asin(0.5) == doctest::Approx(0.5235987756));
+ CHECK(Math::asin(1.0) == doctest::Approx(1.5707963268));
+ CHECK(Math::is_nan(Math::asin(1.5)));
+ CHECK(Math::is_nan(Math::asin(450.0)));
+
+ CHECK(Math::acos(-0.1) == doctest::Approx(1.670963748));
+ CHECK(Math::acos(0.1) == doctest::Approx(1.4706289056));
+ CHECK(Math::acos(0.5) == doctest::Approx(1.0471975512));
+ CHECK(Math::acos(1.0) == doctest::Approx(0.0));
+ CHECK(Math::is_nan(Math::acos(1.5)));
+ CHECK(Math::is_nan(Math::acos(450.0)));
+
+ CHECK(Math::atan(-0.1) == doctest::Approx(-0.0996686525));
+ CHECK(Math::atan(0.1) == doctest::Approx(0.0996686525));
+ CHECK(Math::atan(0.5) == doctest::Approx(0.463647609));
+ CHECK(Math::atan(1.0) == doctest::Approx(0.7853981634));
+ CHECK(Math::atan(1.5) == doctest::Approx(0.9827937232));
+ CHECK(Math::atan(450.0) == doctest::Approx(1.5685741082));
+}
+
+TEST_CASE("[Math] sinc/sincn/atan2") {
+ CHECK(Math::sinc(-0.1) == doctest::Approx(0.9983341665));
+ CHECK(Math::sinc(0.1) == doctest::Approx(0.9983341665));
+ CHECK(Math::sinc(0.5) == doctest::Approx(0.9588510772));
+ CHECK(Math::sinc(1.0) == doctest::Approx(0.8414709848));
+ CHECK(Math::sinc(1.5) == doctest::Approx(0.6649966577));
+ CHECK(Math::sinc(450.0) == doctest::Approx(-0.0015184083));
+
+ CHECK(Math::sincn(-0.1) == doctest::Approx(0.9836316431));
+ CHECK(Math::sincn(0.1) == doctest::Approx(0.9836316431));
+ CHECK(Math::sincn(0.5) == doctest::Approx(0.6366197724));
+ CHECK(Math::sincn(1.0) == doctest::Approx(0.0));
+ CHECK(Math::sincn(1.5) == doctest::Approx(-0.2122065908));
+ CHECK(Math::sincn(450.0) == doctest::Approx(0.0));
+
+ CHECK(Math::atan2(-0.1, 0.5) == doctest::Approx(-0.1973955598));
+ CHECK(Math::atan2(0.1, -0.5) == doctest::Approx(2.9441970937));
+ CHECK(Math::atan2(0.5, 1.5) == doctest::Approx(0.3217505544));
+ CHECK(Math::atan2(1.0, 2.5) == doctest::Approx(0.3805063771));
+ CHECK(Math::atan2(1.5, 1.0) == doctest::Approx(0.9827937232));
+ CHECK(Math::atan2(450.0, 1.0) == doctest::Approx(1.5685741082));
+}
+
+TEST_CASE("[Math] pow/log/log2/exp/sqrt") {
+ CHECK(Math::pow(-0.1, 2.0) == doctest::Approx(0.01));
+ CHECK(Math::pow(0.1, 2.5) == doctest::Approx(0.0031622777));
+ CHECK(Math::pow(0.5, 0.5) == doctest::Approx(0.7071067812));
+ CHECK(Math::pow(1.0, 1.0) == doctest::Approx(1.0));
+ CHECK(Math::pow(1.5, -1.0) == doctest::Approx(0.6666666667));
+ CHECK(Math::pow(450.0, -2.0) == doctest::Approx(0.0000049383));
+ CHECK(Math::pow(450.0, 0.0) == doctest::Approx(1.0));
+
+ CHECK(Math::is_nan(Math::log(-0.1)));
+ CHECK(Math::log(0.1) == doctest::Approx(-2.302585093));
+ CHECK(Math::log(0.5) == doctest::Approx(-0.6931471806));
+ CHECK(Math::log(1.0) == doctest::Approx(0.0));
+ CHECK(Math::log(1.5) == doctest::Approx(0.4054651081));
+ CHECK(Math::log(450.0) == doctest::Approx(6.1092475828));
+
+ CHECK(Math::is_nan(Math::log2(-0.1)));
+ CHECK(Math::log2(0.1) == doctest::Approx(-3.3219280949));
+ CHECK(Math::log2(0.5) == doctest::Approx(-1.0));
+ CHECK(Math::log2(1.0) == doctest::Approx(0.0));
+ CHECK(Math::log2(1.5) == doctest::Approx(0.5849625007));
+ CHECK(Math::log2(450.0) == doctest::Approx(8.8137811912));
+
+ CHECK(Math::exp(-0.1) == doctest::Approx(0.904837418));
+ CHECK(Math::exp(0.1) == doctest::Approx(1.1051709181));
+ CHECK(Math::exp(0.5) == doctest::Approx(1.6487212707));
+ CHECK(Math::exp(1.0) == doctest::Approx(2.7182818285));
+ CHECK(Math::exp(1.5) == doctest::Approx(4.4816890703));
+
+ CHECK(Math::is_nan(Math::sqrt(-0.1)));
+ CHECK(Math::sqrt(0.1) == doctest::Approx(0.316228));
+ CHECK(Math::sqrt(0.5) == doctest::Approx(0.707107));
+ CHECK(Math::sqrt(1.0) == doctest::Approx(1.0));
+ CHECK(Math::sqrt(1.5) == doctest::Approx(1.224745));
+}
+
+TEST_CASE("[Math] is_nan/is_inf") {
+ CHECK(!Math::is_nan(0.0));
+ CHECK(Math::is_nan(NAN));
+
+ CHECK(!Math::is_inf(0.0));
+ CHECK(Math::is_inf(INFINITY));
+}
+
+TEST_CASE("[Math] linear_to_db") {
+ CHECK(Math::linear_to_db(1.0) == doctest::Approx(0.0));
+ CHECK(Math::linear_to_db(20.0) == doctest::Approx(26.0206));
+ CHECK(Math::is_inf(Math::linear_to_db(0.0)));
+ CHECK(Math::is_nan(Math::linear_to_db(-20.0)));
+}
+
+TEST_CASE("[Math] db_to_linear") {
+ CHECK(Math::db_to_linear(0.0) == doctest::Approx(1.0));
+ CHECK(Math::db_to_linear(1.0) == doctest::Approx(1.122018));
+ CHECK(Math::db_to_linear(20.0) == doctest::Approx(10.0));
+ CHECK(Math::db_to_linear(-20.0) == doctest::Approx(0.1));
+}
+
+TEST_CASE("[Math] step_decimals") {
+ CHECK(Math::step_decimals(-0.5) == 1);
+ CHECK(Math::step_decimals(0) == 0);
+ CHECK(Math::step_decimals(1) == 0);
+ CHECK(Math::step_decimals(0.1) == 1);
+ CHECK(Math::step_decimals(0.01) == 2);
+ CHECK(Math::step_decimals(0.001) == 3);
+ CHECK(Math::step_decimals(0.0001) == 4);
+ CHECK(Math::step_decimals(0.00001) == 5);
+ CHECK(Math::step_decimals(0.000001) == 6);
+ CHECK(Math::step_decimals(0.0000001) == 7);
+ CHECK(Math::step_decimals(0.00000001) == 8);
+ CHECK(Math::step_decimals(0.000000001) == 9);
+ // Too many decimals to handle.
+ CHECK(Math::step_decimals(0.0000000001) == 0);
+}
+
+TEST_CASE("[Math] range_step_decimals") {
+ CHECK(Math::range_step_decimals(0.000000001) == 9);
+ // Too many decimals to handle.
+ CHECK(Math::range_step_decimals(0.0000000001) == 0);
+ // Should be treated as a step of 0 for use by the editor.
+ CHECK(Math::range_step_decimals(0.0) == 16);
+ CHECK(Math::range_step_decimals(-0.5) == 16);
+}
+
+TEST_CASE("[Math] lerp") {
+ CHECK(Math::lerp(2.0, 5.0, -0.1) == doctest::Approx(1.7));
+ CHECK(Math::lerp(2.0, 5.0, 0.0) == doctest::Approx(2.0));
+ CHECK(Math::lerp(2.0, 5.0, 0.1) == doctest::Approx(2.3));
+ CHECK(Math::lerp(2.0, 5.0, 1.0) == doctest::Approx(5.0));
+ CHECK(Math::lerp(2.0, 5.0, 2.0) == doctest::Approx(8.0));
+
+ CHECK(Math::lerp(-2.0, -5.0, -0.1) == doctest::Approx(-1.7));
+ CHECK(Math::lerp(-2.0, -5.0, 0.0) == doctest::Approx(-2.0));
+ CHECK(Math::lerp(-2.0, -5.0, 0.1) == doctest::Approx(-2.3));
+ CHECK(Math::lerp(-2.0, -5.0, 1.0) == doctest::Approx(-5.0));
+ CHECK(Math::lerp(-2.0, -5.0, 2.0) == doctest::Approx(-8.0));
+}
+
+TEST_CASE("[Math] inverse_lerp") {
+ CHECK(Math::inverse_lerp(2.0, 5.0, 1.7) == doctest::Approx(-0.1));
+ CHECK(Math::inverse_lerp(2.0, 5.0, 2.0) == doctest::Approx(0.0));
+ CHECK(Math::inverse_lerp(2.0, 5.0, 2.3) == doctest::Approx(0.1));
+ CHECK(Math::inverse_lerp(2.0, 5.0, 5.0) == doctest::Approx(1.0));
+ CHECK(Math::inverse_lerp(2.0, 5.0, 8.0) == doctest::Approx(2.0));
+
+ CHECK(Math::inverse_lerp(-2.0, -5.0, -1.7) == doctest::Approx(-0.1));
+ CHECK(Math::inverse_lerp(-2.0, -5.0, -2.0) == doctest::Approx(0.0));
+ CHECK(Math::inverse_lerp(-2.0, -5.0, -2.3) == doctest::Approx(0.1));
+ CHECK(Math::inverse_lerp(-2.0, -5.0, -5.0) == doctest::Approx(1.0));
+ CHECK(Math::inverse_lerp(-2.0, -5.0, -8.0) == doctest::Approx(2.0));
+}
+
+TEST_CASE("[Math] remap") {
+ CHECK(Math::remap(50.0, 100.0, 200.0, 0.0, 1000.0) == doctest::Approx(-500.0));
+ CHECK(Math::remap(100.0, 100.0, 200.0, 0.0, 1000.0) == doctest::Approx(0.0));
+ CHECK(Math::remap(200.0, 100.0, 200.0, 0.0, 1000.0) == doctest::Approx(1000.0));
+ CHECK(Math::remap(250.0, 100.0, 200.0, 0.0, 1000.0) == doctest::Approx(1500.0));
+
+ CHECK(Math::remap(-50.0, -100.0, -200.0, 0.0, 1000.0) == doctest::Approx(-500.0));
+ CHECK(Math::remap(-100.0, -100.0, -200.0, 0.0, 1000.0) == doctest::Approx(0.0));
+ CHECK(Math::remap(-200.0, -100.0, -200.0, 0.0, 1000.0) == doctest::Approx(1000.0));
+ CHECK(Math::remap(-250.0, -100.0, -200.0, 0.0, 1000.0) == doctest::Approx(1500.0));
+
+ CHECK(Math::remap(-50.0, -100.0, -200.0, 0.0, -1000.0) == doctest::Approx(500.0));
+ CHECK(Math::remap(-100.0, -100.0, -200.0, 0.0, -1000.0) == doctest::Approx(0.0));
+ CHECK(Math::remap(-200.0, -100.0, -200.0, 0.0, -1000.0) == doctest::Approx(-1000.0));
+ CHECK(Math::remap(-250.0, -100.0, -200.0, 0.0, -1000.0) == doctest::Approx(-1500.0));
+}
+
+TEST_CASE("[Math] lerp_angle") {
+ // Counter-clockwise rotation.
+ CHECK(Math::lerp_angle(0.24 * Math_TAU, 0.75 * Math_TAU, 0.5) == doctest::Approx(-0.005 * Math_TAU));
+ // Counter-clockwise rotation.
+ CHECK(Math::lerp_angle(0.25 * Math_TAU, 0.75 * Math_TAU, 0.5) == doctest::Approx(0.0));
+ // Clockwise rotation.
+ CHECK(Math::lerp_angle(0.26 * Math_TAU, 0.75 * Math_TAU, 0.5) == doctest::Approx(0.505 * Math_TAU));
+
+ CHECK(Math::lerp_angle(-0.25 * Math_TAU, 1.25 * Math_TAU, 0.5) == doctest::Approx(-0.5 * Math_TAU));
+ CHECK(Math::lerp_angle(0.72 * Math_TAU, 1.44 * Math_TAU, 0.96) == doctest::Approx(0.4512 * Math_TAU));
+ CHECK(Math::lerp_angle(0.72 * Math_TAU, 1.44 * Math_TAU, 1.04) == doctest::Approx(0.4288 * Math_TAU));
+
+ // Initial and final angles are effectively identical, so the value returned
+ // should always be the same regardless of the `weight` parameter.
+ CHECK(Math::lerp_angle(-4 * Math_TAU, 4 * Math_TAU, -1.0) == doctest::Approx(-4.0 * Math_TAU));
+ CHECK(Math::lerp_angle(-4 * Math_TAU, 4 * Math_TAU, 0.0) == doctest::Approx(-4.0 * Math_TAU));
+ CHECK(Math::lerp_angle(-4 * Math_TAU, 4 * Math_TAU, 0.5) == doctest::Approx(-4.0 * Math_TAU));
+ CHECK(Math::lerp_angle(-4 * Math_TAU, 4 * Math_TAU, 1.0) == doctest::Approx(-4.0 * Math_TAU));
+ CHECK(Math::lerp_angle(-4 * Math_TAU, 4 * Math_TAU, 500.0) == doctest::Approx(-4.0 * Math_TAU));
+}
+
+TEST_CASE("[Math] move_toward") {
+ CHECK(Math::move_toward(2.0, 5.0, -1.0) == doctest::Approx(1.0));
+ CHECK(Math::move_toward(2.0, 5.0, 2.5) == doctest::Approx(4.5));
+ CHECK(Math::move_toward(2.0, 5.0, 4.0) == doctest::Approx(5.0));
+ CHECK(Math::move_toward(-2.0, -5.0, -1.0) == doctest::Approx(-1.0));
+ CHECK(Math::move_toward(-2.0, -5.0, 2.5) == doctest::Approx(-4.5));
+ CHECK(Math::move_toward(-2.0, -5.0, 4.0) == doctest::Approx(-5.0));
+}
+
+TEST_CASE("[Math] smoothstep") {
+ CHECK(Math::smoothstep(0.0, 2.0, -5.0) == doctest::Approx(0.0));
+ CHECK(Math::smoothstep(0.0, 2.0, 0.5) == doctest::Approx(0.15625));
+ CHECK(Math::smoothstep(0.0, 2.0, 1.0) == doctest::Approx(0.5));
+ CHECK(Math::smoothstep(0.0, 2.0, 2.0) == doctest::Approx(1.0));
+}
+
+TEST_CASE("[Math] ease") {
+ CHECK(Math::ease(0.1, 1.0) == doctest::Approx(0.1));
+ CHECK(Math::ease(0.1, 2.0) == doctest::Approx(0.01));
+ CHECK(Math::ease(0.1, 0.5) == doctest::Approx(0.19));
+ CHECK(Math::ease(0.1, 0.0) == doctest::Approx(0));
+ CHECK(Math::ease(0.1, -0.5) == doctest::Approx(0.2236067977));
+ CHECK(Math::ease(0.1, -1.0) == doctest::Approx(0.1));
+ CHECK(Math::ease(0.1, -2.0) == doctest::Approx(0.02));
+
+ CHECK(Math::ease(-1.0, 1.0) == doctest::Approx(0));
+ CHECK(Math::ease(-1.0, 2.0) == doctest::Approx(0));
+ CHECK(Math::ease(-1.0, 0.5) == doctest::Approx(0));
+ CHECK(Math::ease(-1.0, 0.0) == doctest::Approx(0));
+ CHECK(Math::ease(-1.0, -0.5) == doctest::Approx(0));
+ CHECK(Math::ease(-1.0, -1.0) == doctest::Approx(0));
+ CHECK(Math::ease(-1.0, -2.0) == doctest::Approx(0));
+}
+
+TEST_CASE("[Math] snapped") {
+ CHECK(Math::snapped(0.5, 0.04) == doctest::Approx(0.52));
+ CHECK(Math::snapped(-0.5, 0.04) == doctest::Approx(-0.48));
+ CHECK(Math::snapped(0.0, 0.04) == doctest::Approx(0));
+ CHECK(Math::snapped(128'000.025, 0.04) == doctest::Approx(128'000.04));
+
+ CHECK(Math::snapped(0.5, 400) == doctest::Approx(0));
+ CHECK(Math::snapped(-0.5, 400) == doctest::Approx(0));
+ CHECK(Math::snapped(0.0, 400) == doctest::Approx(0));
+ CHECK(Math::snapped(128'000.025, 400) == doctest::Approx(128'000.0));
+
+ CHECK(Math::snapped(0.5, 0.0) == doctest::Approx(0.5));
+ CHECK(Math::snapped(-0.5, 0.0) == doctest::Approx(-0.5));
+ CHECK(Math::snapped(0.0, 0.0) == doctest::Approx(0.0));
+ CHECK(Math::snapped(128'000.025, 0.0) == doctest::Approx(128'000.0));
+
+ CHECK(Math::snapped(0.5, -1.0) == doctest::Approx(0));
+ CHECK(Math::snapped(-0.5, -1.0) == doctest::Approx(-1.0));
+ CHECK(Math::snapped(0.0, -1.0) == doctest::Approx(0));
+ CHECK(Math::snapped(128'000.025, -1.0) == doctest::Approx(128'000.0));
+}
+
+TEST_CASE("[Math] larger_prime") {
+ CHECK(Math::larger_prime(0) == 5);
+ CHECK(Math::larger_prime(1) == 5);
+ CHECK(Math::larger_prime(2) == 5);
+ CHECK(Math::larger_prime(5) == 13);
+ CHECK(Math::larger_prime(500) == 769);
+ CHECK(Math::larger_prime(1'000'000) == 1'572'869);
+ CHECK(Math::larger_prime(1'000'000'000) == 1'610'612'741);
+
+ // The next prime is larger than `INT32_MAX` and is not present in the built-in prime table.
+ ERR_PRINT_OFF;
+ CHECK(Math::larger_prime(2'000'000'000) == 0);
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[Math] fmod") {
+ CHECK(Math::fmod(-2.0, 0.3) == doctest::Approx(-0.2));
+ CHECK(Math::fmod(0.0, 0.3) == doctest::Approx(0.0));
+ CHECK(Math::fmod(2.0, 0.3) == doctest::Approx(0.2));
+
+ CHECK(Math::fmod(-2.0, -0.3) == doctest::Approx(-0.2));
+ CHECK(Math::fmod(0.0, -0.3) == doctest::Approx(0.0));
+ CHECK(Math::fmod(2.0, -0.3) == doctest::Approx(0.2));
+}
+
+TEST_CASE("[Math] fposmod") {
+ CHECK(Math::fposmod(-2.0, 0.3) == doctest::Approx(0.1));
+ CHECK(Math::fposmod(0.0, 0.3) == doctest::Approx(0.0));
+ CHECK(Math::fposmod(2.0, 0.3) == doctest::Approx(0.2));
+
+ CHECK(Math::fposmod(-2.0, -0.3) == doctest::Approx(-0.2));
+ CHECK(Math::fposmod(0.0, -0.3) == doctest::Approx(0.0));
+ CHECK(Math::fposmod(2.0, -0.3) == doctest::Approx(-0.1));
+}
+
+TEST_CASE("[Math] fposmodp") {
+ CHECK(Math::fposmodp(-2.0, 0.3) == doctest::Approx(0.1));
+ CHECK(Math::fposmodp(0.0, 0.3) == doctest::Approx(0.0));
+ CHECK(Math::fposmodp(2.0, 0.3) == doctest::Approx(0.2));
+
+ CHECK(Math::fposmodp(-2.0, -0.3) == doctest::Approx(-0.5));
+ CHECK(Math::fposmodp(0.0, -0.3) == doctest::Approx(0.0));
+ CHECK(Math::fposmodp(2.0, -0.3) == doctest::Approx(0.2));
+}
+
+TEST_CASE("[Math] posmod") {
+ CHECK(Math::posmod(-20, 3) == 1);
+ CHECK(Math::posmod(0, 3) == 0);
+ CHECK(Math::posmod(20, 3) == 2);
+ CHECK(Math::posmod(-20, -3) == -2);
+ CHECK(Math::posmod(0, -3) == 0);
+ CHECK(Math::posmod(20, -3) == -1);
+}
+
+TEST_CASE("[Math] wrapi") {
+ CHECK(Math::wrapi(-30, -20, 160) == 150);
+ CHECK(Math::wrapi(30, -20, 160) == 30);
+ CHECK(Math::wrapi(300, -20, 160) == 120);
+ CHECK(Math::wrapi(300'000'000'000, -20, 160) == 120);
+}
+
+TEST_CASE("[Math] wrapf") {
+ CHECK(Math::wrapf(-30.0, -20.0, 160.0) == doctest::Approx(150.0));
+ CHECK(Math::wrapf(30.0, -2.0, 160.0) == doctest::Approx(30.0));
+ CHECK(Math::wrapf(300.0, -20.0, 160.0) == doctest::Approx(120.0));
+ CHECK(Math::wrapf(300'000'000'000.0, -20.0, 160.0) == doctest::Approx(120.0));
+}
+
+TEST_CASE("[Math] fract") {
+ CHECK(Math::fract(1.0) == doctest::Approx(0.0));
+ CHECK(Math::fract(77.8) == doctest::Approx(0.8));
+ CHECK(Math::fract(-10.1) == doctest::Approx(0.9));
+}
+
+TEST_CASE("[Math] pingpong") {
+ CHECK(Math::pingpong(0.0, 0.0) == doctest::Approx(0.0));
+ CHECK(Math::pingpong(1.0, 1.0) == doctest::Approx(1.0));
+ CHECK(Math::pingpong(0.5, 2.0) == doctest::Approx(0.5));
+ CHECK(Math::pingpong(3.5, 2.0) == doctest::Approx(0.5));
+ CHECK(Math::pingpong(11.5, 2.0) == doctest::Approx(0.5));
+ CHECK(Math::pingpong(-2.5, 2.0) == doctest::Approx(1.5));
+}
+
+TEST_CASE("[Math] deg_to_rad/rad_to_deg") {
+ CHECK(Math::deg_to_rad(180.0) == doctest::Approx(Math_PI));
+ CHECK(Math::deg_to_rad(-27.0) == doctest::Approx(-0.471239));
+
+ CHECK(Math::rad_to_deg(Math_PI) == doctest::Approx(180.0));
+ CHECK(Math::rad_to_deg(-1.5) == doctest::Approx(-85.94366927));
+}
+
+TEST_CASE("[Math] cubic_interpolate") {
+ CHECK(Math::cubic_interpolate(0.2, 0.8, 0.0, 1.0, 0.0) == doctest::Approx(0.2));
+ CHECK(Math::cubic_interpolate(0.2, 0.8, 0.0, 1.0, 0.25) == doctest::Approx(0.33125));
+ CHECK(Math::cubic_interpolate(0.2, 0.8, 0.0, 1.0, 0.5) == doctest::Approx(0.5));
+ CHECK(Math::cubic_interpolate(0.2, 0.8, 0.0, 1.0, 0.75) == doctest::Approx(0.66875));
+ CHECK(Math::cubic_interpolate(0.2, 0.8, 0.0, 1.0, 1.0) == doctest::Approx(0.8));
+
+ CHECK(Math::cubic_interpolate(20.2, 30.1, -100.0, 32.0, -50.0) == doctest::Approx(-6662732.3));
+ CHECK(Math::cubic_interpolate(20.2, 30.1, -100.0, 32.0, -5.0) == doctest::Approx(-9356.3));
+ CHECK(Math::cubic_interpolate(20.2, 30.1, -100.0, 32.0, 0.0) == doctest::Approx(20.2));
+ CHECK(Math::cubic_interpolate(20.2, 30.1, -100.0, 32.0, 1.0) == doctest::Approx(30.1));
+ CHECK(Math::cubic_interpolate(20.2, 30.1, -100.0, 32.0, 4.0) == doctest::Approx(1853.2));
+}
+
+TEST_CASE("[Math] cubic_interpolate_angle") {
+ CHECK(Math::cubic_interpolate_angle(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 0.0) == doctest::Approx(Math_PI * (1.0 / 6.0)));
+ CHECK(Math::cubic_interpolate_angle(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 0.25) == doctest::Approx(0.973566));
+ CHECK(Math::cubic_interpolate_angle(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 0.5) == doctest::Approx(Math_PI / 2.0));
+ CHECK(Math::cubic_interpolate_angle(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 0.75) == doctest::Approx(2.16803));
+ CHECK(Math::cubic_interpolate_angle(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 1.0) == doctest::Approx(Math_PI * (5.0 / 6.0)));
+}
+
+TEST_CASE("[Math] cubic_interpolate_in_time") {
+ CHECK(Math::cubic_interpolate_in_time(0.2, 0.8, 0.0, 1.0, 0.0, 0.5, 0.0, 1.0) == doctest::Approx(0.0));
+ CHECK(Math::cubic_interpolate_in_time(0.2, 0.8, 0.0, 1.0, 0.25, 0.5, 0.0, 1.0) == doctest::Approx(0.1625));
+ CHECK(Math::cubic_interpolate_in_time(0.2, 0.8, 0.0, 1.0, 0.5, 0.5, 0.0, 1.0) == doctest::Approx(0.4));
+ CHECK(Math::cubic_interpolate_in_time(0.2, 0.8, 0.0, 1.0, 0.75, 0.5, 0.0, 1.0) == doctest::Approx(0.6375));
+ CHECK(Math::cubic_interpolate_in_time(0.2, 0.8, 0.0, 1.0, 1.0, 0.5, 0.0, 1.0) == doctest::Approx(0.8));
+}
+
+TEST_CASE("[Math] cubic_interpolate_angle_in_time") {
+ CHECK(Math::cubic_interpolate_angle_in_time(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 0.0, 0.5, 0.0, 1.0) == doctest::Approx(0.0));
+ CHECK(Math::cubic_interpolate_angle_in_time(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 0.25, 0.5, 0.0, 1.0) == doctest::Approx(0.494964));
+ CHECK(Math::cubic_interpolate_angle_in_time(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 0.5, 0.5, 0.0, 1.0) == doctest::Approx(1.27627));
+ CHECK(Math::cubic_interpolate_angle_in_time(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 0.75, 0.5, 0.0, 1.0) == doctest::Approx(2.07394));
+ CHECK(Math::cubic_interpolate_angle_in_time(Math_PI * (1.0 / 6.0), Math_PI * (5.0 / 6.0), 0.0, Math_PI, 1.0, 0.5, 0.0, 1.0) == doctest::Approx(Math_PI * (5.0 / 6.0)));
+}
+
+TEST_CASE("[Math] bezier_interpolate") {
+ CHECK(Math::bezier_interpolate(0.0, 0.2, 0.8, 1.0, 0.0) == doctest::Approx(0.0));
+ CHECK(Math::bezier_interpolate(0.0, 0.2, 0.8, 1.0, 0.25) == doctest::Approx(0.2125));
+ CHECK(Math::bezier_interpolate(0.0, 0.2, 0.8, 1.0, 0.5) == doctest::Approx(0.5));
+ CHECK(Math::bezier_interpolate(0.0, 0.2, 0.8, 1.0, 0.75) == doctest::Approx(0.7875));
+ CHECK(Math::bezier_interpolate(0.0, 0.2, 0.8, 1.0, 1.0) == doctest::Approx(1.0));
+}
+
+} // namespace TestMath
+
+#endif // TEST_MATH_FUNCS_H
diff --git a/tests/core/math/test_quaternion.h b/tests/core/math/test_quaternion.h
index 909fc2499f..c3ae322991 100644
--- a/tests/core/math/test_quaternion.h
+++ b/tests/core/math/test_quaternion.h
@@ -169,10 +169,9 @@ TEST_CASE("[Quaternion] Construct Euler YXZ dynamic axes") {
Vector3 euler_r(0.0, 0.0, roll);
Quaternion q_r = Quaternion::from_euler(euler_r);
- // Roll-Z is followed by Pitch-X.
- Quaternion check_xz = q_p * q_r;
- // Then Yaw-Y follows both.
- Quaternion check_yxz = q_y * check_xz;
+ // Instrinsically, Yaw-Y then Pitch-X then Roll-Z.
+ // Extrinsically, Roll-Z is followed by Pitch-X, then Yaw-Y.
+ Quaternion check_yxz = q_y * q_p * q_r;
// Test construction from YXZ Euler angles.
Vector3 euler_yxz(pitch, yaw, roll);
@@ -182,8 +181,9 @@ TEST_CASE("[Quaternion] Construct Euler YXZ dynamic axes") {
CHECK(q[2] == doctest::Approx(check_yxz[2]));
CHECK(q[3] == doctest::Approx(check_yxz[3]));
- // Sneak in a test of is_equal_approx.
CHECK(q.is_equal_approx(check_yxz));
+ CHECK(q.get_euler().is_equal_approx(euler_yxz));
+ CHECK(check_yxz.get_euler().is_equal_approx(euler_yxz));
}
TEST_CASE("[Quaternion] Construct Basis Euler") {
@@ -235,6 +235,23 @@ TEST_CASE("[Quaternion] Construct Basis Axes") {
CHECK(q[3] == doctest::Approx(0.8582598));
}
+TEST_CASE("[Quaternion] Get Euler Orders") {
+ double x = Math::deg_to_rad(30.0);
+ double y = Math::deg_to_rad(45.0);
+ double z = Math::deg_to_rad(10.0);
+ Vector3 euler(x, y, z);
+ for (int i = 0; i < 6; i++) {
+ EulerOrder order = (EulerOrder)i;
+ Basis basis = Basis::from_euler(euler, order);
+ Quaternion q = Quaternion(basis);
+ Vector3 check = q.get_euler(order);
+ CHECK_MESSAGE(check.is_equal_approx(euler),
+ "Quaternion get_euler method should return the original angles.");
+ CHECK_MESSAGE(check.is_equal_approx(basis.get_euler(order)),
+ "Quaternion get_euler method should behave the same as Basis get_euler.");
+ }
+}
+
TEST_CASE("[Quaternion] Product (book)") {
// Example from "Quaternions and Rotation Sequences" by Jack Kuipers, p. 108.
Quaternion p(1.0, -2.0, 1.0, 3.0);
diff --git a/tests/core/math/test_rect2.h b/tests/core/math/test_rect2.h
index d784875c1c..9984823331 100644
--- a/tests/core/math/test_rect2.h
+++ b/tests/core/math/test_rect2.h
@@ -102,16 +102,16 @@ TEST_CASE("[Rect2] Basic setters") {
TEST_CASE("[Rect2] Area getters") {
CHECK_MESSAGE(
- Math::is_equal_approx(Rect2(0, 100, 1280, 720).get_area(), 921'600),
+ Rect2(0, 100, 1280, 720).get_area() == doctest::Approx(921'600),
"get_area() should return the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Rect2(0, 100, -1280, -720).get_area(), 921'600),
+ Rect2(0, 100, -1280, -720).get_area() == doctest::Approx(921'600),
"get_area() should return the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Rect2(0, 100, 1280, -720).get_area(), -921'600),
+ Rect2(0, 100, 1280, -720).get_area() == doctest::Approx(-921'600),
"get_area() should return the expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Rect2(0, 100, -1280, 720).get_area(), -921'600),
+ Rect2(0, 100, -1280, 720).get_area() == doctest::Approx(-921'600),
"get_area() should return the expected value.");
CHECK_MESSAGE(
Math::is_zero_approx(Rect2(0, 100, 0, 720).get_area()),
diff --git a/tests/core/math/test_vector2.h b/tests/core/math/test_vector2.h
index f7e9259329..8f8fccd717 100644
--- a/tests/core/math/test_vector2.h
+++ b/tests/core/math/test_vector2.h
@@ -49,16 +49,16 @@ TEST_CASE("[Vector2] Angle methods") {
const Vector2 vector_x = Vector2(1, 0);
const Vector2 vector_y = Vector2(0, 1);
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.angle_to(vector_y), (real_t)Math_TAU / 4),
+ vector_x.angle_to(vector_y) == doctest::Approx((real_t)Math_TAU / 4),
"Vector2 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_y.angle_to(vector_x), (real_t)-Math_TAU / 4),
+ vector_y.angle_to(vector_x) == doctest::Approx((real_t)-Math_TAU / 4),
"Vector2 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.angle_to_point(vector_y), (real_t)Math_TAU * 3 / 8),
+ vector_x.angle_to_point(vector_y) == doctest::Approx((real_t)Math_TAU * 3 / 8),
"Vector2 angle_to_point should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_y.angle_to_point(vector_x), (real_t)-Math_TAU / 8),
+ vector_y.angle_to_point(vector_x) == doctest::Approx((real_t)-Math_TAU / 8),
"Vector2 angle_to_point should work as expected.");
}
@@ -113,10 +113,10 @@ TEST_CASE("[Vector2] Interpolation methods") {
Vector2(4, 6).slerp(Vector2(8, 10), 0.5).is_equal_approx(Vector2(5.9076470794008017626, 8.07918879020090480697)),
"Vector2 slerp should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.slerp(vector2, 0.5).length(), (real_t)4.31959610746631919),
+ vector1.slerp(vector2, 0.5).length() == doctest::Approx((real_t)4.31959610746631919),
"Vector2 slerp with different length input should return a vector with an interpolated length.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2, vector1.angle_to(vector2)),
+ vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2 == doctest::Approx(vector1.angle_to(vector2)),
"Vector2 slerp with different length input should return a vector with an interpolated angle.");
CHECK_MESSAGE(
vector1.cubic_interpolate(vector2, Vector2(), Vector2(7, 7), 0.5) == Vector2(2.375, 3.5),
@@ -136,19 +136,19 @@ TEST_CASE("[Vector2] Length methods") {
vector1.length_squared() == 200,
"Vector2 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 10 * (real_t)Math_SQRT2),
+ vector1.length() == doctest::Approx(10 * (real_t)Math_SQRT2),
"Vector2 length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 1300,
"Vector2 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), (real_t)36.05551275463989293119),
+ vector2.length() == doctest::Approx((real_t)36.05551275463989293119),
"Vector2 length should work as expected.");
CHECK_MESSAGE(
vector1.distance_squared_to(vector2) == 500,
"Vector2 distance_squared_to should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.distance_to(vector2), (real_t)22.36067977499789696409),
+ vector1.distance_to(vector2) == doctest::Approx((real_t)22.36067977499789696409),
"Vector2 distance_to should work as expected.");
}
@@ -294,7 +294,7 @@ TEST_CASE("[Vector2] Operators") {
TEST_CASE("[Vector2] Other methods") {
const Vector2 vector = Vector2(1.2, 3.4);
CHECK_MESSAGE(
- Math::is_equal_approx(vector.aspect(), (real_t)1.2 / (real_t)3.4),
+ vector.aspect() == doctest::Approx((real_t)1.2 / (real_t)3.4),
"Vector2 aspect should work as expected.");
CHECK_MESSAGE(
@@ -443,10 +443,10 @@ TEST_CASE("[Vector2] Linear algebra methods") {
vector_y.cross(vector_x) == -1,
"Vector2 cross product of Y and X should give negative 1.");
CHECK_MESSAGE(
- Math::is_equal_approx(a.cross(b), (real_t)-28.1),
+ a.cross(b) == doctest::Approx((real_t)-28.1),
"Vector2 cross should return expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Vector2(-a.x, a.y).cross(Vector2(b.x, -b.y)), (real_t)-28.1),
+ Vector2(-a.x, a.y).cross(Vector2(b.x, -b.y)) == doctest::Approx((real_t)-28.1),
"Vector2 cross should return expected value.");
CHECK_MESSAGE(
@@ -459,10 +459,10 @@ TEST_CASE("[Vector2] Linear algebra methods") {
(vector_x * 10).dot(vector_x * 10) == 100.0,
"Vector2 dot product of same direction vectors should behave as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(a.dot(b), (real_t)57.3),
+ a.dot(b) == doctest::Approx((real_t)57.3),
"Vector2 dot should return expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Vector2(-a.x, a.y).dot(Vector2(b.x, -b.y)), (real_t)-57.3),
+ Vector2(-a.x, a.y).dot(Vector2(b.x, -b.y)) == doctest::Approx((real_t)-57.3),
"Vector2 dot should return expected value.");
}
diff --git a/tests/core/math/test_vector2i.h b/tests/core/math/test_vector2i.h
index 49b0632e3c..c7a0dccdcc 100644
--- a/tests/core/math/test_vector2i.h
+++ b/tests/core/math/test_vector2i.h
@@ -79,13 +79,13 @@ TEST_CASE("[Vector2i] Length methods") {
vector1.length_squared() == 200,
"Vector2i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 10 * Math_SQRT2),
+ vector1.length() == doctest::Approx(10 * Math_SQRT2),
"Vector2i length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 1300,
"Vector2i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), 36.05551275463989293119),
+ vector2.length() == doctest::Approx(36.05551275463989293119),
"Vector2i length should work as expected.");
}
@@ -127,7 +127,7 @@ TEST_CASE("[Vector2i] Operators") {
TEST_CASE("[Vector2i] Other methods") {
const Vector2i vector = Vector2i(1, 3);
CHECK_MESSAGE(
- Math::is_equal_approx(vector.aspect(), (real_t)1.0 / (real_t)3.0),
+ vector.aspect() == doctest::Approx((real_t)1.0 / (real_t)3.0),
"Vector2i aspect should work as expected.");
CHECK_MESSAGE(
diff --git a/tests/core/math/test_vector3.h b/tests/core/math/test_vector3.h
index 77d3a9d93c..89d73ee6de 100644
--- a/tests/core/math/test_vector3.h
+++ b/tests/core/math/test_vector3.h
@@ -52,26 +52,26 @@ TEST_CASE("[Vector3] Angle methods") {
const Vector3 vector_y = Vector3(0, 1, 0);
const Vector3 vector_yz = Vector3(0, 1, 1);
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.angle_to(vector_y), (real_t)Math_TAU / 4),
+ vector_x.angle_to(vector_y) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.angle_to(vector_yz), (real_t)Math_TAU / 4),
+ vector_x.angle_to(vector_yz) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_yz.angle_to(vector_x), (real_t)Math_TAU / 4),
+ vector_yz.angle_to(vector_x) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_y.angle_to(vector_yz), (real_t)Math_TAU / 8),
+ vector_y.angle_to(vector_yz) == doctest::Approx((real_t)Math_TAU / 8),
"Vector3 angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.signed_angle_to(vector_y, vector_y), (real_t)Math_TAU / 4),
+ vector_x.signed_angle_to(vector_y, vector_y) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 signed_angle_to edge case should be positive.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_x.signed_angle_to(vector_yz, vector_y), (real_t)Math_TAU / -4),
+ vector_x.signed_angle_to(vector_yz, vector_y) == doctest::Approx((real_t)Math_TAU / -4),
"Vector3 signed_angle_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector_yz.signed_angle_to(vector_x, vector_y), (real_t)Math_TAU / 4),
+ vector_yz.signed_angle_to(vector_x, vector_y) == doctest::Approx((real_t)Math_TAU / 4),
"Vector3 signed_angle_to should work as expected.");
}
@@ -130,10 +130,10 @@ TEST_CASE("[Vector3] Interpolation methods") {
Vector3(4, 6, 2).slerp(Vector3(8, 10, 3), 0.5).is_equal_approx(Vector3(5.90194219811429941053, 8.06758688849378394534, 2.558307894718317120038)),
"Vector3 slerp should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.slerp(vector2, 0.5).length(), (real_t)6.25831088708303172),
+ vector1.slerp(vector2, 0.5).length() == doctest::Approx((real_t)6.25831088708303172),
"Vector3 slerp with different length input should return a vector with an interpolated length.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2, vector1.angle_to(vector2)),
+ vector1.angle_to(vector1.slerp(vector2, 0.5)) * 2 == doctest::Approx(vector1.angle_to(vector2)),
"Vector3 slerp with different length input should return a vector with an interpolated angle.");
CHECK_MESSAGE(
vector1.cubic_interpolate(vector2, Vector3(), Vector3(7, 7, 7), 0.5) == Vector3(2.375, 3.5, 4.625),
@@ -153,19 +153,19 @@ TEST_CASE("[Vector3] Length methods") {
vector1.length_squared() == 300,
"Vector3 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 10 * (real_t)Math_SQRT3),
+ vector1.length() == doctest::Approx(10 * (real_t)Math_SQRT3),
"Vector3 length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 2900,
"Vector3 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), (real_t)53.8516480713450403125),
+ vector2.length() == doctest::Approx((real_t)53.8516480713450403125),
"Vector3 length should work as expected.");
CHECK_MESSAGE(
vector1.distance_squared_to(vector2) == 1400,
"Vector3 distance_squared_to should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.distance_to(vector2), (real_t)37.41657386773941385584),
+ vector1.distance_to(vector2) == doctest::Approx((real_t)37.41657386773941385584),
"Vector3 distance_to should work as expected.");
}
@@ -473,10 +473,10 @@ TEST_CASE("[Vector3] Linear algebra methods") {
(vector_x * 10).dot(vector_x * 10) == 100.0,
"Vector3 dot product of same direction vectors should behave as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(a.dot(b), (real_t)75.24),
+ a.dot(b) == doctest::Approx((real_t)75.24),
"Vector3 dot should return expected value.");
CHECK_MESSAGE(
- Math::is_equal_approx(Vector3(-a.x, a.y, -a.z).dot(Vector3(b.x, -b.y, b.z)), (real_t)-75.24),
+ Vector3(-a.x, a.y, -a.z).dot(Vector3(b.x, -b.y, b.z)) == doctest::Approx((real_t)-75.24),
"Vector3 dot should return expected value.");
}
diff --git a/tests/core/math/test_vector3i.h b/tests/core/math/test_vector3i.h
index 2050b222d0..56578f99eb 100644
--- a/tests/core/math/test_vector3i.h
+++ b/tests/core/math/test_vector3i.h
@@ -82,13 +82,13 @@ TEST_CASE("[Vector3i] Length methods") {
vector1.length_squared() == 300,
"Vector3i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 10 * Math_SQRT3),
+ vector1.length() == doctest::Approx(10 * Math_SQRT3),
"Vector3i length should work as expected.");
CHECK_MESSAGE(
vector2.length_squared() == 2900,
"Vector3i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector2.length(), 53.8516480713450403125),
+ vector2.length() == doctest::Approx(53.8516480713450403125),
"Vector3i length should work as expected.");
}
diff --git a/tests/core/math/test_vector4.h b/tests/core/math/test_vector4.h
index b31db56f67..6ed85661cb 100644
--- a/tests/core/math/test_vector4.h
+++ b/tests/core/math/test_vector4.h
@@ -91,19 +91,19 @@ TEST_CASE("[Vector4] Length methods") {
vector1.length_squared() == 400,
"Vector4 length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 20),
+ vector1.length() == doctest::Approx(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),
+ vector2.length() == doctest::Approx((real_t)73.484692283495),
"Vector4 length should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.distance_to(vector2), (real_t)54.772255750517),
+ vector1.distance_to(vector2) == doctest::Approx((real_t)54.772255750517),
"Vector4 distance_to should work as expected.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.distance_squared_to(vector2), 3000),
+ vector1.distance_squared_to(vector2) == doctest::Approx(3000),
"Vector4 distance_squared_to should work as expected.");
}
@@ -311,7 +311,7 @@ TEST_CASE("[Vector4] Linear algebra methods") {
(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),
+ (vector1 * 2).dot(vector2 * 4) == doctest::Approx((real_t)-25.9 * 8),
"Vector4 dot product should work as expected.");
}
diff --git a/tests/core/math/test_vector4i.h b/tests/core/math/test_vector4i.h
index 309162c3f7..30d38607dd 100644
--- a/tests/core/math/test_vector4i.h
+++ b/tests/core/math/test_vector4i.h
@@ -82,13 +82,13 @@ TEST_CASE("[Vector4i] Length methods") {
vector1.length_squared() == 400,
"Vector4i length_squared should work as expected and return exact result.");
CHECK_MESSAGE(
- Math::is_equal_approx(vector1.length(), 20),
+ vector1.length() == doctest::Approx(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),
+ vector2.length() == doctest::Approx(73.4846922835),
"Vector4i length should work as expected.");
}
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h
index cd1b421ce8..7e4e3aa9f0 100644
--- a/tests/core/string/test_string.h
+++ b/tests/core/string/test_string.h
@@ -485,6 +485,7 @@ TEST_CASE("[String] Splitting") {
const char *slices_l[3] = { "Mars", "Jupiter", "Saturn,Uranus" };
const char *slices_r[3] = { "Mars,Jupiter", "Saturn", "Uranus" };
+ const char *slices_3[4] = { "t", "e", "s", "t" };
l = s.split(",", true, 2);
CHECK(l.size() == 3);
@@ -498,6 +499,13 @@ TEST_CASE("[String] Splitting") {
CHECK(l[i] == slices_r[i]);
}
+ s = "test";
+ l = s.split();
+ CHECK(l.size() == 4);
+ for (int i = 0; i < l.size(); i++) {
+ CHECK(l[i] == slices_3[i]);
+ }
+
s = "Mars Jupiter Saturn Uranus";
const char *slices_s[4] = { "Mars", "Jupiter", "Saturn", "Uranus" };
l = s.split_spaces();
diff --git a/tests/scene/test_animation.h b/tests/scene/test_animation.h
index ca80f0ecab..e921779c23 100644
--- a/tests/scene/test_animation.h
+++ b/tests/scene/test_animation.h
@@ -40,8 +40,8 @@ namespace TestAnimation {
TEST_CASE("[Animation] Empty animation getters") {
const Ref<Animation> animation = memnew(Animation);
- CHECK(Math::is_equal_approx(animation->get_length(), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->get_step(), real_t(0.1)));
+ CHECK(animation->get_length() == doctest::Approx(real_t(1.0)));
+ CHECK(animation->get_step() == doctest::Approx(real_t(0.1)));
}
TEST_CASE("[Animation] Create value track") {
@@ -59,33 +59,33 @@ TEST_CASE("[Animation] Create value track") {
CHECK(int(animation->track_get_key_value(0, 0)) == 0);
CHECK(int(animation->track_get_key_value(0, 1)) == 100);
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, -0.2), 0.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.0), 0.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.2), 40.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.4), 80.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.5), 100.0));
- CHECK(Math::is_equal_approx(animation->value_track_interpolate(0, 0.6), 100.0));
+ CHECK(animation->value_track_interpolate(0, -0.2) == doctest::Approx(0.0));
+ CHECK(animation->value_track_interpolate(0, 0.0) == doctest::Approx(0.0));
+ CHECK(animation->value_track_interpolate(0, 0.2) == doctest::Approx(40.0));
+ CHECK(animation->value_track_interpolate(0, 0.4) == doctest::Approx(80.0));
+ CHECK(animation->value_track_interpolate(0, 0.5) == doctest::Approx(100.0));
+ CHECK(animation->value_track_interpolate(0, 0.6) == doctest::Approx(100.0));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(real_t(1.0)));
ERR_PRINT_OFF;
// Nonexistent keys.
CHECK(animation->track_get_key_value(0, 2).is_null());
CHECK(animation->track_get_key_value(0, -1).is_null());
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 2), real_t(-1.0)));
+ CHECK(animation->track_get_key_transition(0, 2) == doctest::Approx(real_t(-1.0)));
// Nonexistent track (and keys).
CHECK(animation->track_get_key_value(1, 0).is_null());
CHECK(animation->track_get_key_value(1, 1).is_null());
CHECK(animation->track_get_key_value(1, 2).is_null());
CHECK(animation->track_get_key_value(1, -1).is_null());
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(1, 0), real_t(-1.0)));
+ CHECK(animation->track_get_key_transition(1, 0) == doctest::Approx(real_t(-1.0)));
// This is a value track, so the methods below should return errors.
CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(0.0));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
ERR_PRINT_ON;
}
@@ -123,15 +123,15 @@ TEST_CASE("[Animation] Create 3D position track") {
CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5)));
// 3D position tracks always use linear interpolation for performance reasons.
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(real_t(1.0)));
// This is a 3D position track, so the methods below should return errors.
ERR_PRINT_OFF;
CHECK(animation->value_track_interpolate(0, 0.0).is_null());
CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(0.0));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
ERR_PRINT_ON;
}
@@ -169,15 +169,15 @@ TEST_CASE("[Animation] Create 3D rotation track") {
CHECK(r_interpolation.is_equal_approx(Quaternion(0.231055, 0.374912, 0.761204, 0.476048)));
// 3D rotation tracks always use linear interpolation for performance reasons.
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(real_t(1.0)));
// This is a 3D rotation track, so the methods below should return errors.
ERR_PRINT_OFF;
CHECK(animation->value_track_interpolate(0, 0.0).is_null());
CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(real_t(0.0)));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
ERR_PRINT_ON;
}
@@ -215,15 +215,15 @@ TEST_CASE("[Animation] Create 3D scale track") {
CHECK(r_interpolation.is_equal_approx(Vector3(3.5, 4, 5)));
// 3D scale tracks always use linear interpolation for performance reasons.
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(1.0));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(1.0));
// This is a 3D scale track, so the methods below should return errors.
ERR_PRINT_OFF;
CHECK(animation->value_track_interpolate(0, 0.0).is_null());
CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(0.0));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
ERR_PRINT_ON;
}
@@ -242,32 +242,32 @@ TEST_CASE("[Animation] Create blend shape track") {
float r_blend = 0.0f;
CHECK(animation->blend_shape_track_get_key(0, 0, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, -1.0f));
+ CHECK(r_blend == doctest::Approx(-1.0f));
CHECK(animation->blend_shape_track_get_key(0, 1, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, 1.0f));
+ CHECK(r_blend == doctest::Approx(1.0f));
CHECK(animation->blend_shape_track_interpolate(0, -0.2, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, -1.0f));
+ CHECK(r_blend == doctest::Approx(-1.0f));
CHECK(animation->blend_shape_track_interpolate(0, 0.0, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, -1.0f));
+ CHECK(r_blend == doctest::Approx(-1.0f));
CHECK(animation->blend_shape_track_interpolate(0, 0.2, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, -0.2f));
+ CHECK(r_blend == doctest::Approx(-0.2f));
CHECK(animation->blend_shape_track_interpolate(0, 0.4, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, 0.6f));
+ CHECK(r_blend == doctest::Approx(0.6f));
CHECK(animation->blend_shape_track_interpolate(0, 0.5, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, 1.0f));
+ CHECK(r_blend == doctest::Approx(1.0f));
CHECK(animation->blend_shape_track_interpolate(0, 0.6, &r_blend) == OK);
- CHECK(Math::is_equal_approx(r_blend, 1.0f));
+ CHECK(r_blend == doctest::Approx(1.0f));
// Blend shape tracks always use linear interpolation for performance reasons.
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 0), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->track_get_key_transition(0, 1), real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 0) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->track_get_key_transition(0, 1) == doctest::Approx(real_t(1.0)));
// This is a blend shape track, so the methods below should return errors.
ERR_PRINT_OFF;
@@ -275,7 +275,7 @@ TEST_CASE("[Animation] Create blend shape track") {
CHECK(animation->position_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->rotation_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
CHECK(animation->scale_track_interpolate(0, 0.0, nullptr) == ERR_INVALID_PARAMETER);
- CHECK(Math::is_zero_approx(animation->bezier_track_interpolate(0, 0.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(0.0));
ERR_PRINT_ON;
}
@@ -289,15 +289,15 @@ TEST_CASE("[Animation] Create Bezier track") {
CHECK(animation->get_track_count() == 1);
CHECK(!animation->track_is_compressed(0));
- CHECK(Math::is_equal_approx(animation->bezier_track_get_key_value(0, 0), real_t(-1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_get_key_value(0, 1), real_t(1.0)));
+ CHECK(animation->bezier_track_get_key_value(0, 0) == doctest::Approx(real_t(-1.0)));
+ CHECK(animation->bezier_track_get_key_value(0, 1) == doctest::Approx(real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, -0.2), real_t(-1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.0), real_t(-1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.2), real_t(-0.76057207584381)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.4), real_t(-0.39975279569626)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.5), real_t(1.0)));
- CHECK(Math::is_equal_approx(animation->bezier_track_interpolate(0, 0.6), real_t(1.0)));
+ CHECK(animation->bezier_track_interpolate(0, -0.2) == doctest::Approx(real_t(-1.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.0) == doctest::Approx(real_t(-1.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.2) == doctest::Approx(real_t(-0.76057207584381)));
+ CHECK(animation->bezier_track_interpolate(0, 0.4) == doctest::Approx(real_t(-0.39975279569626)));
+ CHECK(animation->bezier_track_interpolate(0, 0.5) == doctest::Approx(real_t(1.0)));
+ CHECK(animation->bezier_track_interpolate(0, 0.6) == doctest::Approx(real_t(1.0)));
// This is a bezier track, so the methods below should return errors.
ERR_PRINT_OFF;
diff --git a/tests/scene/test_audio_stream_wav.h b/tests/scene/test_audio_stream_wav.h
index 4ba431dfc2..c84c66b0e6 100644
--- a/tests/scene/test_audio_stream_wav.h
+++ b/tests/scene/test_audio_stream_wav.h
@@ -138,7 +138,7 @@ void run_test(String file_name, AudioStreamWAV::Format data_format, bool stereo,
CHECK(stream->get_data() == test_data);
SUBCASE("Stream length is computed properly") {
- CHECK(Math::is_equal_approx(stream->get_length(), double(wav_count / wav_rate)));
+ CHECK(stream->get_length() == doctest::Approx(double(wav_count / wav_rate)));
}
SUBCASE("Stream can be saved as .wav") {
diff --git a/tests/scene/test_curve.h b/tests/scene/test_curve.h
index ad7625ddc5..36ec0c0a4d 100644
--- a/tests/scene/test_curve.h
+++ b/tests/scene/test_curve.h
@@ -83,54 +83,54 @@ TEST_CASE("[Curve] Custom curve with free tangents") {
Math::is_zero_approx(curve->sample(-0.1)),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.1), (real_t)0.352),
+ curve->sample(0.1) == doctest::Approx((real_t)0.352),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.4), (real_t)0.352),
+ curve->sample(0.4) == doctest::Approx((real_t)0.352),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.7), (real_t)0.896),
+ curve->sample(0.7) == doctest::Approx((real_t)0.896),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(1), 1),
+ curve->sample(1) == doctest::Approx(1),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(2), 1),
+ curve->sample(2) == doctest::Approx(1),
"Custom free curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
Math::is_zero_approx(curve->sample_baked(-0.1)),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.1), (real_t)0.352),
+ curve->sample_baked(0.1) == doctest::Approx((real_t)0.352),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.4), (real_t)0.352),
+ curve->sample_baked(0.4) == doctest::Approx((real_t)0.352),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.7), (real_t)0.896),
+ curve->sample_baked(0.7) == doctest::Approx((real_t)0.896),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(1), 1),
+ curve->sample_baked(1) == doctest::Approx(1),
"Custom free curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(2), 1),
+ curve->sample_baked(2) == doctest::Approx(1),
"Custom free curve should return the expected baked value at offset 0.1.");
curve->remove_point(1);
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.1), 0),
+ curve->sample(0.1) == doctest::Approx(0),
"Custom free curve should return the expected value at offset 0.1 after removing point at index 1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.1), 0),
+ curve->sample_baked(0.1) == doctest::Approx(0),
"Custom free curve should return the expected baked value at offset 0.1 after removing point at index 1.");
curve->clear_points();
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.6), 0),
+ curve->sample(0.6) == doctest::Approx(0),
"Custom free curve should return the expected value at offset 0.6 after clearing all points.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.6), 0),
+ curve->sample_baked(0.6) == doctest::Approx(0),
"Custom free curve should return the expected baked value at offset 0.6 after clearing all points.");
}
@@ -143,7 +143,7 @@ TEST_CASE("[Curve] Custom curve with linear tangents") {
curve->add_point(Vector2(0.75, 1), 0, 0, Curve::TangentMode::TANGENT_LINEAR, Curve::TangentMode::TANGENT_LINEAR);
CHECK_MESSAGE(
- Math::is_equal_approx(curve->get_point_left_tangent(3), 4),
+ curve->get_point_left_tangent(3) == doctest::Approx(4),
"get_point_left_tangent() should return the expected value for point index 3.");
CHECK_MESSAGE(
Math::is_zero_approx(curve->get_point_right_tangent(3)),
@@ -172,48 +172,48 @@ TEST_CASE("[Curve] Custom curve with linear tangents") {
Math::is_zero_approx(curve->sample(-0.1)),
"Custom linear curve should return the expected value at offset -0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.1), (real_t)0.4),
+ curve->sample(0.1) == doctest::Approx((real_t)0.4),
"Custom linear curve should return the expected value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.4), (real_t)0.4),
+ curve->sample(0.4) == doctest::Approx((real_t)0.4),
"Custom linear curve should return the expected value at offset 0.4.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.7), (real_t)0.8),
+ curve->sample(0.7) == doctest::Approx((real_t)0.8),
"Custom linear curve should return the expected value at offset 0.7.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(1), 1),
+ curve->sample(1) == doctest::Approx(1),
"Custom linear curve should return the expected value at offset 1.0.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(2), 1),
+ curve->sample(2) == doctest::Approx(1),
"Custom linear curve should return the expected value at offset 2.0.");
CHECK_MESSAGE(
Math::is_zero_approx(curve->sample_baked(-0.1)),
"Custom linear curve should return the expected baked value at offset -0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.1), (real_t)0.4),
+ curve->sample_baked(0.1) == doctest::Approx((real_t)0.4),
"Custom linear curve should return the expected baked value at offset 0.1.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.4), (real_t)0.4),
+ curve->sample_baked(0.4) == doctest::Approx((real_t)0.4),
"Custom linear curve should return the expected baked value at offset 0.4.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.7), (real_t)0.8),
+ curve->sample_baked(0.7) == doctest::Approx((real_t)0.8),
"Custom linear curve should return the expected baked value at offset 0.7.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(1), 1),
+ curve->sample_baked(1) == doctest::Approx(1),
"Custom linear curve should return the expected baked value at offset 1.0.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(2), 1),
+ curve->sample_baked(2) == doctest::Approx(1),
"Custom linear curve should return the expected baked value at offset 2.0.");
ERR_PRINT_OFF;
curve->remove_point(10);
ERR_PRINT_ON;
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample(0.7), (real_t)0.8),
+ curve->sample(0.7) == doctest::Approx((real_t)0.8),
"Custom free curve should return the expected value at offset 0.7 after removing point at invalid index 10.");
CHECK_MESSAGE(
- Math::is_equal_approx(curve->sample_baked(0.7), (real_t)0.8),
+ curve->sample_baked(0.7) == doctest::Approx((real_t)0.8),
"Custom free curve should return the expected baked value at offset 0.7 after removing point at invalid index 10.");
}
diff --git a/tests/scene/test_primitives.h b/tests/scene/test_primitives.h
index ceec117700..8bac903d93 100644
--- a/tests/scene/test_primitives.h
+++ b/tests/scene/test_primitives.h
@@ -57,9 +57,9 @@ TEST_CASE("[SceneTree][Primitive][Capsule] Capsule Primitive") {
capsule->set_radial_segments(16);
capsule->set_rings(32);
- CHECK_MESSAGE(Math::is_equal_approx(capsule->get_radius(), 1.3f),
+ CHECK_MESSAGE(capsule->get_radius() == doctest::Approx(1.3f),
"Get/Set radius work with one set.");
- CHECK_MESSAGE(Math::is_equal_approx(capsule->get_height(), 7.1f),
+ CHECK_MESSAGE(capsule->get_height() == doctest::Approx(7.1f),
"Get/Set radius work with one set.");
CHECK_MESSAGE(capsule->get_radial_segments() == 16,
"Get/Set radius work with one set.");
@@ -129,7 +129,7 @@ TEST_CASE("[SceneTree][Primitive][Capsule] Capsule Primitive") {
if (normals[ii].y == 0.f) {
float mag_of_normal = Math::sqrt(normals[ii].x * normals[ii].x + normals[ii].z * normals[ii].z);
Vector3 normalized_normal = normals[ii] / mag_of_normal;
- CHECK_MESSAGE(Math::is_equal_approx(point_dist_from_yaxis, radius),
+ CHECK_MESSAGE(point_dist_from_yaxis == doctest::Approx(radius),
"Points on the tube of the capsule are radius away from y-axis.");
CHECK_MESSAGE(normalized_normal.is_equal_approx(yaxis_to_point),
"Normal points orthogonal from mid cylinder.");
@@ -244,9 +244,9 @@ TEST_CASE("[SceneTree][Primitive][Cylinder] Cylinder Primitive") {
cylinder->set_cap_top(false);
cylinder->set_cap_bottom(false);
- CHECK(Math::is_equal_approx(cylinder->get_top_radius(), 4.3f));
- CHECK(Math::is_equal_approx(cylinder->get_bottom_radius(), 1.2f));
- CHECK(Math::is_equal_approx(cylinder->get_height(), 9.77f));
+ CHECK(cylinder->get_top_radius() == doctest::Approx(4.3f));
+ CHECK(cylinder->get_bottom_radius() == doctest::Approx(1.2f));
+ CHECK(cylinder->get_height() == doctest::Approx(9.77f));
CHECK(cylinder->get_radial_segments() == 12);
CHECK(cylinder->get_rings() == 16);
CHECK(!cylinder->is_cap_top());
@@ -478,7 +478,7 @@ TEST_CASE("[SceneTree][Primitive][Prism] Prism Primitive") {
prism->set_subdivide_height(5);
prism->set_subdivide_depth(64);
- CHECK(Math::is_equal_approx(prism->get_left_to_right(), 3.4f));
+ CHECK(prism->get_left_to_right() == doctest::Approx(3.4f));
CHECK(prism->get_size().is_equal_approx(size));
CHECK(prism->get_subdivide_width() == 36);
CHECK(prism->get_subdivide_height() == 5);
@@ -513,8 +513,8 @@ TEST_CASE("[SceneTree][Primitive][Sphere] Sphere Primitive") {
sphere->set_rings(5);
sphere->set_is_hemisphere(true);
- CHECK(Math::is_equal_approx(sphere->get_radius(), 3.4f));
- CHECK(Math::is_equal_approx(sphere->get_height(), 2.2f));
+ CHECK(sphere->get_radius() == doctest::Approx(3.4f));
+ CHECK(sphere->get_height() == doctest::Approx(2.2f));
CHECK(sphere->get_radial_segments() == 36);
CHECK(sphere->get_rings() == 5);
CHECK(sphere->get_is_hemisphere());
@@ -581,8 +581,8 @@ TEST_CASE("[SceneTree][Primitive][Torus] Torus Primitive") {
torus->set_rings(19);
torus->set_ring_segments(43);
- CHECK(Math::is_equal_approx(torus->get_inner_radius(), 3.2f));
- CHECK(Math::is_equal_approx(torus->get_outer_radius(), 9.5f));
+ CHECK(torus->get_inner_radius() == doctest::Approx(3.2f));
+ CHECK(torus->get_outer_radius() == doctest::Approx(9.5f));
CHECK(torus->get_rings() == 19);
CHECK(torus->get_ring_segments() == 43);
}
@@ -610,8 +610,8 @@ TEST_CASE("[SceneTree][Primitive][TubeTrail] TubeTrail Primitive") {
Ref<Curve> curve = memnew(Curve);
tube->set_curve(curve);
- CHECK(Math::is_equal_approx(tube->get_radius(), 7.2f));
- CHECK(Math::is_equal_approx(tube->get_section_length(), 5.5f));
+ CHECK(tube->get_radius() == doctest::Approx(7.2f));
+ CHECK(tube->get_section_length() == doctest::Approx(5.5f));
CHECK(tube->get_radial_steps() == 9);
CHECK(tube->get_sections() == 33);
CHECK(tube->get_section_rings() == 12);
@@ -670,8 +670,8 @@ TEST_CASE("[SceneTree][Primitive][RibbonTrail] RibbonTrail Primitive") {
ribbon->set_section_segments(9);
ribbon->set_curve(curve);
- CHECK(Math::is_equal_approx(ribbon->get_size(), 4.3f));
- CHECK(Math::is_equal_approx(ribbon->get_section_length(), 1.3f));
+ CHECK(ribbon->get_size() == doctest::Approx(4.3f));
+ CHECK(ribbon->get_section_length() == doctest::Approx(1.3f));
CHECK(ribbon->get_sections() == 16);
CHECK(ribbon->get_section_segments() == 9);
CHECK(ribbon->get_curve() == curve);
@@ -781,11 +781,11 @@ TEST_CASE("[SceneTree][Primitive][Text] Text Primitive") {
CHECK(text->get_structured_text_bidi_override_options() == options);
CHECK(text->is_uppercase() == true);
CHECK(text->get_offset() == offset);
- CHECK(Math::is_equal_approx(text->get_line_spacing(), 1.7f));
- CHECK(Math::is_equal_approx(text->get_width(), width));
- CHECK(Math::is_equal_approx(text->get_depth(), depth));
- CHECK(Math::is_equal_approx(text->get_curve_step(), curve_step));
- CHECK(Math::is_equal_approx(text->get_pixel_size(), pixel_size));
+ CHECK(text->get_line_spacing() == doctest::Approx(1.7f));
+ CHECK(text->get_width() == doctest::Approx(width));
+ CHECK(text->get_depth() == doctest::Approx(depth));
+ CHECK(text->get_curve_step() == doctest::Approx(curve_step));
+ CHECK(text->get_pixel_size() == doctest::Approx(pixel_size));
}
SUBCASE("[Primitive][Text] Set objects multiple times.") {
diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h
index e34f2970d4..5dad7d06e1 100644
--- a/tests/scene/test_text_edit.h
+++ b/tests/scene/test_text_edit.h
@@ -734,13 +734,20 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
}
SUBCASE("[TextEdit] add selection for next occurrence") {
- text_edit->set_text("\ntest other_test\nrandom test\nword test word");
+ text_edit->set_text("\ntest other_test\nrandom test\nword test word nonrandom");
text_edit->set_caret_column(0);
text_edit->set_caret_line(1);
- text_edit->select_word_under_caret();
- CHECK(text_edit->has_selection(0));
+ // First selection made by the implicit select_word_under_caret call
+ text_edit->add_selection_for_next_occurrence();
+ CHECK(text_edit->get_caret_count() == 1);
CHECK(text_edit->get_selected_text(0) == "test");
+ CHECK(text_edit->get_selection_from_line(0) == 1);
+ CHECK(text_edit->get_selection_from_column(0) == 0);
+ CHECK(text_edit->get_selection_to_line(0) == 1);
+ CHECK(text_edit->get_selection_to_column(0) == 4);
+ CHECK(text_edit->get_caret_line(0) == 1);
+ CHECK(text_edit->get_caret_column(0) == 4);
text_edit->add_selection_for_next_occurrence();
CHECK(text_edit->get_caret_count() == 2);
@@ -771,6 +778,27 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
CHECK(text_edit->get_selection_to_column(3) == 9);
CHECK(text_edit->get_caret_line(3) == 3);
CHECK(text_edit->get_caret_column(3) == 9);
+
+ // A different word with a new manually added caret
+ text_edit->add_caret(2, 1);
+ text_edit->select(2, 0, 2, 4, 4);
+ CHECK(text_edit->get_selected_text(4) == "rand");
+
+ text_edit->add_selection_for_next_occurrence();
+ CHECK(text_edit->get_caret_count() == 6);
+ CHECK(text_edit->get_selected_text(5) == "rand");
+ CHECK(text_edit->get_selection_from_line(5) == 3);
+ CHECK(text_edit->get_selection_from_column(5) == 18);
+ CHECK(text_edit->get_selection_to_line(5) == 3);
+ CHECK(text_edit->get_selection_to_column(5) == 22);
+ CHECK(text_edit->get_caret_line(5) == 3);
+ CHECK(text_edit->get_caret_column(5) == 22);
+
+ // Make sure the previous selections are still active
+ CHECK(text_edit->get_selected_text(0) == "test");
+ CHECK(text_edit->get_selected_text(1) == "test");
+ CHECK(text_edit->get_selected_text(2) == "test");
+ CHECK(text_edit->get_selected_text(3) == "test");
}
SUBCASE("[TextEdit] deselect on focus loss") {
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index 45d6a16cb4..d58c19ac32 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -47,6 +47,7 @@
#include "tests/core/math/test_expression.h"
#include "tests/core/math/test_geometry_2d.h"
#include "tests/core/math/test_geometry_3d.h"
+#include "tests/core/math/test_math_funcs.h"
#include "tests/core/math/test_plane.h"
#include "tests/core/math/test_quaternion.h"
#include "tests/core/math/test_random_number_generator.h"
@@ -191,11 +192,8 @@ struct GodotTestCaseListener : public doctest::IReporter {
String name = String(p_in.m_name);
if (name.find("[SceneTree]") != -1) {
- GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60);
memnew(MessageQueue);
- GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false);
-
memnew(Input);
Error err = OK;