diff options
Diffstat (limited to 'tests/core')
-rw-r--r-- | tests/core/io/test_config_file.h | 2 | ||||
-rw-r--r-- | tests/core/io/test_file_access.h | 4 | ||||
-rw-r--r-- | tests/core/io/test_image.h | 10 | ||||
-rw-r--r-- | tests/core/io/test_pck_packer.h | 4 | ||||
-rw-r--r-- | tests/core/math/test_basis.h | 12 | ||||
-rw-r--r-- | tests/core/math/test_color.h | 8 | ||||
-rw-r--r-- | tests/core/math/test_geometry_2d.h | 301 | ||||
-rw-r--r-- | tests/core/math/test_geometry_3d.h | 4 | ||||
-rw-r--r-- | tests/core/math/test_math.cpp | 690 | ||||
-rw-r--r-- | tests/core/math/test_math.h | 41 | ||||
-rw-r--r-- | tests/core/object/test_class_db.h | 31 | ||||
-rw-r--r-- | tests/core/string/test_string.h | 40 | ||||
-rw-r--r-- | tests/core/string/test_translation.h | 2 | ||||
-rw-r--r-- | tests/core/templates/test_hash_map.h (renamed from tests/core/templates/test_ordered_hash_map.h) | 66 | ||||
-rw-r--r-- | tests/core/templates/test_oa_hash_map.cpp | 301 | ||||
-rw-r--r-- | tests/core/templates/test_oa_hash_map.h | 41 | ||||
-rw-r--r-- | tests/core/test_time.h | 10 |
17 files changed, 413 insertions, 1154 deletions
diff --git a/tests/core/io/test_config_file.h b/tests/core/io/test_config_file.h index 6e393c7a2d..355aca479e 100644 --- a/tests/core/io/test_config_file.h +++ b/tests/core/io/test_config_file.h @@ -155,7 +155,7 @@ antiAliasing=false "a=b"=7 )"); - FileAccessRef file = FileAccess::open(config_path, FileAccess::READ); + Ref<FileAccess> file = FileAccess::open(config_path, FileAccess::READ); CHECK_MESSAGE(file->get_as_utf8_string() == contents, "The saved configuration file should match the expected format."); } diff --git a/tests/core/io/test_file_access.h b/tests/core/io/test_file_access.h index eee57048cf..f0e1cceacf 100644 --- a/tests/core/io/test_file_access.h +++ b/tests/core/io/test_file_access.h @@ -38,7 +38,7 @@ namespace TestFileAccess { TEST_CASE("[FileAccess] CSV read") { - FileAccessRef f = FileAccess::open(TestUtils::get_data_path("translations.csv"), FileAccess::READ); + Ref<FileAccess> f = FileAccess::open(TestUtils::get_data_path("translations.csv"), FileAccess::READ); Vector<String> header = f->get_csv_line(); // Default delimiter: ",". REQUIRE(header.size() == 3); @@ -77,8 +77,6 @@ TEST_CASE("[FileAccess] CSV read") { CHECK(row5[0] == "What about"); CHECK(row5[1] == "tab separated"); CHECK(row5[2] == "lines, good?"); - - f->close(); } } // namespace TestFileAccess diff --git a/tests/core/io/test_image.h b/tests/core/io/test_image.h index dcf21dd7b0..1c778c3228 100644 --- a/tests/core/io/test_image.h +++ b/tests/core/io/test_image.h @@ -106,7 +106,7 @@ TEST_CASE("[Image] Saving and loading") { // Load BMP Ref<Image> image_bmp = memnew(Image()); - FileAccessRef f_bmp = FileAccess::open(TestUtils::get_data_path("images/icon.bmp"), FileAccess::READ, &err); + Ref<FileAccess> f_bmp = FileAccess::open(TestUtils::get_data_path("images/icon.bmp"), FileAccess::READ, &err); PackedByteArray data_bmp; data_bmp.resize(f_bmp->get_length() + 1); f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_length()); @@ -116,7 +116,7 @@ TEST_CASE("[Image] Saving and loading") { // Load JPG Ref<Image> image_jpg = memnew(Image()); - FileAccessRef f_jpg = FileAccess::open(TestUtils::get_data_path("images/icon.jpg"), FileAccess::READ, &err); + Ref<FileAccess> f_jpg = FileAccess::open(TestUtils::get_data_path("images/icon.jpg"), FileAccess::READ, &err); PackedByteArray data_jpg; data_jpg.resize(f_jpg->get_length() + 1); f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_length()); @@ -126,7 +126,7 @@ TEST_CASE("[Image] Saving and loading") { // Load WEBP Ref<Image> image_webp = memnew(Image()); - FileAccessRef f_webp = FileAccess::open(TestUtils::get_data_path("images/icon.webp"), FileAccess::READ, &err); + Ref<FileAccess> f_webp = FileAccess::open(TestUtils::get_data_path("images/icon.webp"), FileAccess::READ, &err); PackedByteArray data_webp; data_webp.resize(f_webp->get_length() + 1); f_webp->get_buffer(data_webp.ptrw(), f_webp->get_length()); @@ -136,7 +136,7 @@ TEST_CASE("[Image] Saving and loading") { // Load PNG Ref<Image> image_png = memnew(Image()); - FileAccessRef f_png = FileAccess::open(TestUtils::get_data_path("images/icon.png"), FileAccess::READ, &err); + Ref<FileAccess> f_png = FileAccess::open(TestUtils::get_data_path("images/icon.png"), FileAccess::READ, &err); PackedByteArray data_png; data_png.resize(f_png->get_length() + 1); f_png->get_buffer(data_png.ptrw(), f_png->get_length()); @@ -146,7 +146,7 @@ TEST_CASE("[Image] Saving and loading") { // Load TGA Ref<Image> image_tga = memnew(Image()); - FileAccessRef f_tga = FileAccess::open(TestUtils::get_data_path("images/icon.tga"), FileAccess::READ, &err); + Ref<FileAccess> f_tga = FileAccess::open(TestUtils::get_data_path("images/icon.tga"), FileAccess::READ, &err); PackedByteArray data_tga; data_tga.resize(f_tga->get_length() + 1); f_tga->get_buffer(data_tga.ptrw(), f_tga->get_length()); diff --git a/tests/core/io/test_pck_packer.h b/tests/core/io/test_pck_packer.h index 95adca6d68..d21fbdaf50 100644 --- a/tests/core/io/test_pck_packer.h +++ b/tests/core/io/test_pck_packer.h @@ -52,7 +52,7 @@ TEST_CASE("[PCKPacker] Pack an empty PCK file") { "Flushing the PCK should return an OK error code."); Error err; - FileAccessRef f = FileAccess::open(output_pck_path, FileAccess::READ, &err); + Ref<FileAccess> f = FileAccess::open(output_pck_path, FileAccess::READ, &err); CHECK_MESSAGE( err == OK, "The generated empty PCK file should be opened successfully."); @@ -106,7 +106,7 @@ TEST_CASE("[PCKPacker] Pack a PCK file with some files and directories") { "Flushing the PCK should return an OK error code."); Error err; - FileAccessRef f = FileAccess::open(output_pck_path, FileAccess::READ, &err); + Ref<FileAccess> f = FileAccess::open(output_pck_path, FileAccess::READ, &err); CHECK_MESSAGE( err == OK, "The generated non-empty PCK file should be opened successfully."); diff --git a/tests/core/math/test_basis.h b/tests/core/math/test_basis.h index 257e41e82c..ec58d95eed 100644 --- a/tests/core/math/test_basis.h +++ b/tests/core/math/test_basis.h @@ -164,9 +164,9 @@ void test_rotation(Vector3 deg_original_euler, RotOrder rot_order) { Basis res = to_rotation.inverse() * rotation_from_computed_euler; - CHECK_MESSAGE((res.get_axis(0) - Vector3(1.0, 0.0, 0.0)).length() <= 0.1, vformat("Fail due to X %s\n", String(res.get_axis(0))).utf8().ptr()); - CHECK_MESSAGE((res.get_axis(1) - Vector3(0.0, 1.0, 0.0)).length() <= 0.1, vformat("Fail due to Y %s\n", String(res.get_axis(1))).utf8().ptr()); - CHECK_MESSAGE((res.get_axis(2) - Vector3(0.0, 0.0, 1.0)).length() <= 0.1, vformat("Fail due to Z %s\n", String(res.get_axis(2))).utf8().ptr()); + CHECK_MESSAGE((res.get_column(0) - Vector3(1.0, 0.0, 0.0)).length() <= 0.1, vformat("Fail due to X %s\n", String(res.get_column(0))).utf8().ptr()); + CHECK_MESSAGE((res.get_column(1) - Vector3(0.0, 1.0, 0.0)).length() <= 0.1, vformat("Fail due to Y %s\n", String(res.get_column(1))).utf8().ptr()); + CHECK_MESSAGE((res.get_column(2) - Vector3(0.0, 0.0, 1.0)).length() <= 0.1, vformat("Fail due to Z %s\n", String(res.get_column(2))).utf8().ptr()); // Double check `to_rotation` decomposing with XYZ rotation order. const Vector3 euler_xyz_from_rotation = to_rotation.get_euler(Basis::EULER_ORDER_XYZ); @@ -175,9 +175,9 @@ void test_rotation(Vector3 deg_original_euler, RotOrder rot_order) { res = to_rotation.inverse() * rotation_from_xyz_computed_euler; - CHECK_MESSAGE((res.get_axis(0) - Vector3(1.0, 0.0, 0.0)).length() <= 0.1, vformat("Double check with XYZ rot order failed, due to X %s\n", String(res.get_axis(0))).utf8().ptr()); - CHECK_MESSAGE((res.get_axis(1) - Vector3(0.0, 1.0, 0.0)).length() <= 0.1, vformat("Double check with XYZ rot order failed, due to Y %s\n", String(res.get_axis(1))).utf8().ptr()); - CHECK_MESSAGE((res.get_axis(2) - Vector3(0.0, 0.0, 1.0)).length() <= 0.1, vformat("Double check with XYZ rot order failed, due to Z %s\n", String(res.get_axis(2))).utf8().ptr()); + CHECK_MESSAGE((res.get_column(0) - Vector3(1.0, 0.0, 0.0)).length() <= 0.1, vformat("Double check with XYZ rot order failed, due to X %s\n", String(res.get_column(0))).utf8().ptr()); + CHECK_MESSAGE((res.get_column(1) - Vector3(0.0, 1.0, 0.0)).length() <= 0.1, vformat("Double check with XYZ rot order failed, due to Y %s\n", String(res.get_column(1))).utf8().ptr()); + CHECK_MESSAGE((res.get_column(2) - Vector3(0.0, 0.0, 1.0)).length() <= 0.1, vformat("Double check with XYZ rot order failed, due to Z %s\n", String(res.get_column(2))).utf8().ptr()); INFO(vformat("Rotation order: %s\n.", get_rot_order_name(rot_order)).utf8().ptr()); INFO(vformat("Original Rotation: %s\n", String(deg_original_euler)).utf8().ptr()); diff --git a/tests/core/math/test_color.h b/tests/core/math/test_color.h index 6f40f8ecc0..51c3bc8bdc 100644 --- a/tests/core/math/test_color.h +++ b/tests/core/math/test_color.h @@ -146,8 +146,8 @@ TEST_CASE("[Color] Conversion methods") { TEST_CASE("[Color] Linear <-> sRGB conversion") { const Color color = Color(0.35, 0.5, 0.6, 0.7); - const Color color_linear = color.to_linear(); - const Color color_srgb = color.to_srgb(); + const Color color_linear = color.srgb_to_linear(); + const Color color_srgb = color.linear_to_srgb(); CHECK_MESSAGE( color_linear.is_equal_approx(Color(0.100481, 0.214041, 0.318547, 0.7)), "The color converted to linear color space should match the expected value."); @@ -155,10 +155,10 @@ TEST_CASE("[Color] Linear <-> sRGB conversion") { color_srgb.is_equal_approx(Color(0.62621, 0.735357, 0.797738, 0.7)), "The color converted to sRGB color space should match the expected value."); CHECK_MESSAGE( - color_linear.to_srgb().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)), + color_linear.linear_to_srgb().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)), "The linear color converted back to sRGB color space should match the expected value."); CHECK_MESSAGE( - color_srgb.to_linear().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)), + color_srgb.srgb_to_linear().is_equal_approx(Color(0.35, 0.5, 0.6, 0.7)), "The sRGB color converted back to linear color space should match the expected value."); } diff --git a/tests/core/math/test_geometry_2d.h b/tests/core/math/test_geometry_2d.h index 3487e4d7e8..db4e6e2177 100644 --- a/tests/core/math/test_geometry_2d.h +++ b/tests/core/math/test_geometry_2d.h @@ -135,7 +135,7 @@ TEST_CASE("[Geometry2D] Line intersection") { "Parallel lines should not intersect."); } -TEST_CASE("[Geometry2D] Segment intersection.") { +TEST_CASE("[Geometry2D] Segment intersection") { Vector2 r; CHECK(Geometry2D::segment_intersects_segment(Vector2(-1, 1), Vector2(1, -1), Vector2(1, 1), Vector2(-1, -1), &r)); @@ -148,6 +148,10 @@ TEST_CASE("[Geometry2D] Segment intersection.") { Geometry2D::segment_intersects_segment(Vector2(-1, 1), Vector2(1, -1), Vector2(0, 1), Vector2(2, -1), &r), "Parallel segments should not intersect."); + CHECK_FALSE_MESSAGE( + Geometry2D::segment_intersects_segment(Vector2(1, 2), Vector2(3, 2), Vector2(0, 2), Vector2(-2, 2), &r), + "Non-overlapping collinear segments should not intersect."); + CHECK_MESSAGE( Geometry2D::segment_intersects_segment(Vector2(0, 0), Vector2(0, 1), Vector2(0, 0), Vector2(1, 0), &r), "Touching segments should intersect."); @@ -159,11 +163,114 @@ TEST_CASE("[Geometry2D] Segment intersection.") { CHECK(r.is_equal_approx(Vector2(0, 0))); } +TEST_CASE("[Geometry2D] Segment intersection with circle") { + real_t minus_one = -1.0; + real_t zero = 0.0; + real_t one_quarter = 0.25; + real_t three_quarters = 0.75; + 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), + "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), + "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), + "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), + "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), + "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), + "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), + "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), + "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), + "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), + "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), + "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), + "Segment completely outside the circle should not intersect it"); +} + +TEST_CASE("[Geometry2D] Segment intersection with polygon") { + Vector<Point2> a; + + a.push_back(Point2(-2, 2)); + a.push_back(Point2(3, 4)); + a.push_back(Point2(1, 1)); + a.push_back(Point2(2, -2)); + a.push_back(Point2(-1, -1)); + + CHECK_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(0, 2), Vector2(2, 2), a), + "Segment from inside to outside of polygon should intersect it."); + CHECK_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(2, 2), Vector2(0, 2), a), + "Segment from outside to inside of polygon should intersect it."); + + CHECK_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(2, 4), Vector2(3, 3), a), + "Segment running through polygon should intersect it."); + CHECK_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(3, 3), Vector2(2, 4), a), + "Segment running through polygon should intersect it."); + + CHECK_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(0, 0), Vector2(1, 1), a), + "Segment starting inside the polygon and ending on the polygon should intersect it"); + CHECK_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(1, 1), Vector2(0, 0), a), + "Segment starting on the polygon and going inwards should intersect it"); + CHECK_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(-2, 2), Vector2(-2, -1), a), + "Segment starting on the polygon and going outwards should intersect it"); + CHECK_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(-2, 1), Vector2(-2, 2), a), + "Segment starting outside the polygon and ending on the polygon intersect it"); + + CHECK_FALSE_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(-1, 2), Vector2(1, -1), a), + "Segment completely within the polygon should not intersect it"); + CHECK_FALSE_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(1, -1), Vector2(-1, 2), a), + "Segment completely within the polygon should not intersect it"); + CHECK_FALSE_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(2, 2), Vector2(2, -1), a), + "Segment completely outside the polygon should not intersect it"); + CHECK_FALSE_MESSAGE( + Geometry2D::is_segment_intersecting_polygon(Vector2(2, -1), Vector2(2, 2), a), + "Segment completely outside the polygon should not intersect it"); +} + TEST_CASE("[Geometry2D] Closest point to segment") { Vector2 s[] = { Vector2(-4, -4), Vector2(4, 4) }; CHECK(Geometry2D::get_closest_point_to_segment(Vector2(4.1, 4.1), s).is_equal_approx(Vector2(4, 4))); CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-4.1, -4.1), s).is_equal_approx(Vector2(-4, -4))); CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-1, 1), s).is_equal_approx(Vector2(0, 0))); + + Vector2 t[] = { Vector2(1, -2), Vector2(1, -2) }; + CHECK_MESSAGE( + Geometry2D::get_closest_point_to_segment(Vector2(-3, 4), t).is_equal_approx(Vector2(1, -2)), + "Line segment is only a single point. This point should be the closest."); } TEST_CASE("[Geometry2D] Closest point to uncapped segment") { @@ -186,6 +293,30 @@ TEST_CASE("[Geometry2D] Closest points between segments") { Geometry2D::get_closest_points_between_segments(Vector2(-1, 1), Vector2(1, -1), Vector2(1, 1), Vector2(-1, -1), c1, c2); CHECK(c1.is_equal_approx(Vector2(0, 0))); CHECK(c2.is_equal_approx(Vector2(0, 0))); + + Geometry2D::get_closest_points_between_segments(Vector2(-3, 4), Vector2(-3, 4), Vector2(-4, 3), Vector2(-2, 3), c1, c2); + CHECK_MESSAGE( + c1.is_equal_approx(Vector2(-3, 4)), + "1st line segment is only a point, this point should be the closest point to the 2nd line segment."); + CHECK_MESSAGE( + c2.is_equal_approx(Vector2(-3, 3)), + "1st line segment is only a point, this should not matter when determining the closest point on the 2nd line segment."); + + Geometry2D::get_closest_points_between_segments(Vector2(-4, 3), Vector2(-2, 3), Vector2(-3, 4), Vector2(-3, 4), c1, c2); + CHECK_MESSAGE( + c1.is_equal_approx(Vector2(-3, 3)), + "2nd line segment is only a point, this should not matter when determining the closest point on the 1st line segment."); + CHECK_MESSAGE( + c2.is_equal_approx(Vector2(-3, 4)), + "2nd line segment is only a point, this point should be the closest point to the 1st line segment."); + + Geometry2D::get_closest_points_between_segments(Vector2(5, -4), Vector2(5, -4), Vector2(-2, 1), Vector2(-2, 1), c1, c2); + CHECK_MESSAGE( + c1.is_equal_approx(Vector2(5, -4)), + "Both line segments are only a point. On the 1st line segment, that point should be the closest point to the 2nd line segment."); + CHECK_MESSAGE( + c2.is_equal_approx(Vector2(-2, 1)), + "Both line segments are only a point. On the 2nd line segment, that point should be the closest point to the 1st line segment."); } TEST_CASE("[Geometry2D] Make atlas") { @@ -562,6 +693,174 @@ TEST_CASE("[Geometry2D] Clip polyline with polygon") { CHECK(r[1][1].is_equal_approx(Vector2(55, 70))); } } + +TEST_CASE("[Geometry2D] Convex hull") { + Vector<Point2> a; + Vector<Point2> r; + + a.push_back(Point2(-4, -8)); + a.push_back(Point2(-10, -4)); + a.push_back(Point2(8, 2)); + a.push_back(Point2(-6, 10)); + a.push_back(Point2(-12, 4)); + a.push_back(Point2(10, -8)); + a.push_back(Point2(4, 8)); + + SUBCASE("[Geometry2D] No points") { + r = Geometry2D::convex_hull(Vector<Vector2>()); + + CHECK_MESSAGE(r.is_empty(), "The convex hull should be empty if there are no input points."); + } + + SUBCASE("[Geometry2D] Single point") { + Vector<Point2> b; + b.push_back(Point2(4, -3)); + + r = Geometry2D::convex_hull(b); + REQUIRE_MESSAGE(r.size() == 1, "Convex hull should contain 1 point."); + CHECK(r[0].is_equal_approx(b[0])); + } + + SUBCASE("[Geometry2D] All points form the convex hull") { + r = Geometry2D::convex_hull(a); + REQUIRE_MESSAGE(r.size() == 8, "Convex hull should contain 8 points."); + CHECK(r[0].is_equal_approx(Point2(-12, 4))); + CHECK(r[1].is_equal_approx(Point2(-10, -4))); + CHECK(r[2].is_equal_approx(Point2(-4, -8))); + CHECK(r[3].is_equal_approx(Point2(10, -8))); + CHECK(r[4].is_equal_approx(Point2(8, 2))); + CHECK(r[5].is_equal_approx(Point2(4, 8))); + CHECK(r[6].is_equal_approx(Point2(-6, 10))); + CHECK(r[7].is_equal_approx(Point2(-12, 4))); + } + + SUBCASE("[Geometry2D] Add extra points inside original convex hull") { + a.push_back(Point2(-4, -8)); + a.push_back(Point2(0, 0)); + a.push_back(Point2(0, 8)); + a.push_back(Point2(-10, -3)); + a.push_back(Point2(9, -4)); + a.push_back(Point2(6, 4)); + + r = Geometry2D::convex_hull(a); + REQUIRE_MESSAGE(r.size() == 8, "Convex hull should contain 8 points."); + CHECK(r[0].is_equal_approx(Point2(-12, 4))); + CHECK(r[1].is_equal_approx(Point2(-10, -4))); + CHECK(r[2].is_equal_approx(Point2(-4, -8))); + CHECK(r[3].is_equal_approx(Point2(10, -8))); + CHECK(r[4].is_equal_approx(Point2(8, 2))); + CHECK(r[5].is_equal_approx(Point2(4, 8))); + CHECK(r[6].is_equal_approx(Point2(-6, 10))); + CHECK(r[7].is_equal_approx(Point2(-12, 4))); + } + + SUBCASE("[Geometry2D] Add extra points on border of original convex hull") { + a.push_back(Point2(9, -3)); + a.push_back(Point2(-2, -8)); + + r = Geometry2D::convex_hull(a); + REQUIRE_MESSAGE(r.size() == 8, "Convex hull should contain 8 points."); + CHECK(r[0].is_equal_approx(Point2(-12, 4))); + CHECK(r[1].is_equal_approx(Point2(-10, -4))); + CHECK(r[2].is_equal_approx(Point2(-4, -8))); + CHECK(r[3].is_equal_approx(Point2(10, -8))); + CHECK(r[4].is_equal_approx(Point2(8, 2))); + CHECK(r[5].is_equal_approx(Point2(4, 8))); + CHECK(r[6].is_equal_approx(Point2(-6, 10))); + CHECK(r[7].is_equal_approx(Point2(-12, 4))); + } + + SUBCASE("[Geometry2D] Add extra points outside border of original convex hull") { + a.push_back(Point2(-11, -1)); + a.push_back(Point2(7, 6)); + + r = Geometry2D::convex_hull(a); + REQUIRE_MESSAGE(r.size() == 10, "Convex hull should contain 10 points."); + CHECK(r[0].is_equal_approx(Point2(-12, 4))); + CHECK(r[1].is_equal_approx(Point2(-11, -1))); + CHECK(r[2].is_equal_approx(Point2(-10, -4))); + CHECK(r[3].is_equal_approx(Point2(-4, -8))); + CHECK(r[4].is_equal_approx(Point2(10, -8))); + CHECK(r[5].is_equal_approx(Point2(8, 2))); + CHECK(r[6].is_equal_approx(Point2(7, 6))); + CHECK(r[7].is_equal_approx(Point2(4, 8))); + CHECK(r[8].is_equal_approx(Point2(-6, 10))); + CHECK(r[9].is_equal_approx(Point2(-12, 4))); + } +} + +TEST_CASE("[Geometry2D] Bresenham line") { + Vector<Vector2i> r; + + SUBCASE("[Geometry2D] Single point") { + r = Geometry2D::bresenham_line(Point2i(0, 0), Point2i(0, 0)); + + REQUIRE_MESSAGE(r.size() == 1, "The Bresenham line should contain exactly one point."); + CHECK(r[0] == Vector2i(0, 0)); + } + + SUBCASE("[Geometry2D] Line parallel to x-axis") { + r = Geometry2D::bresenham_line(Point2i(1, 2), Point2i(5, 2)); + + REQUIRE_MESSAGE(r.size() == 5, "The Bresenham line should contain exactly five points."); + CHECK(r[0] == Vector2i(1, 2)); + CHECK(r[1] == Vector2i(2, 2)); + CHECK(r[2] == Vector2i(3, 2)); + CHECK(r[3] == Vector2i(4, 2)); + CHECK(r[4] == Vector2i(5, 2)); + } + + SUBCASE("[Geometry2D] 45 degree line from the origin") { + r = Geometry2D::bresenham_line(Point2i(0, 0), Point2i(4, 4)); + + REQUIRE_MESSAGE(r.size() == 5, "The Bresenham line should contain exactly five points."); + CHECK(r[0] == Vector2i(0, 0)); + CHECK(r[1] == Vector2i(1, 1)); + CHECK(r[2] == Vector2i(2, 2)); + CHECK(r[3] == Vector2i(3, 3)); + CHECK(r[4] == Vector2i(4, 4)); + } + + SUBCASE("[Geometry2D] Sloped line going up one unit") { + r = Geometry2D::bresenham_line(Point2i(0, 0), Point2i(4, 1)); + + REQUIRE_MESSAGE(r.size() == 5, "The Bresenham line should contain exactly five points."); + CHECK(r[0] == Vector2i(0, 0)); + CHECK(r[1] == Vector2i(1, 0)); + CHECK(r[2] == Vector2i(2, 0)); + CHECK(r[3] == Vector2i(3, 1)); + CHECK(r[4] == Vector2i(4, 1)); + } + + SUBCASE("[Geometry2D] Sloped line going up two units") { + r = Geometry2D::bresenham_line(Point2i(0, 0), Point2i(4, 2)); + + REQUIRE_MESSAGE(r.size() == 5, "The Bresenham line should contain exactly five points."); + CHECK(r[0] == Vector2i(0, 0)); + CHECK(r[1] == Vector2i(1, 0)); + CHECK(r[2] == Vector2i(2, 1)); + CHECK(r[3] == Vector2i(3, 1)); + CHECK(r[4] == Vector2i(4, 2)); + } + + SUBCASE("[Geometry2D] Long sloped line") { + r = Geometry2D::bresenham_line(Point2i(0, 0), Point2i(11, 5)); + + REQUIRE_MESSAGE(r.size() == 12, "The Bresenham line should contain exactly twelve points."); + CHECK(r[0] == Vector2i(0, 0)); + CHECK(r[1] == Vector2i(1, 0)); + CHECK(r[2] == Vector2i(2, 1)); + CHECK(r[3] == Vector2i(3, 1)); + CHECK(r[4] == Vector2i(4, 2)); + CHECK(r[5] == Vector2i(5, 2)); + CHECK(r[6] == Vector2i(6, 3)); + CHECK(r[7] == Vector2i(7, 3)); + CHECK(r[8] == Vector2i(8, 4)); + CHECK(r[9] == Vector2i(9, 4)); + CHECK(r[10] == Vector2i(10, 5)); + CHECK(r[11] == Vector2i(11, 5)); + } +} } // namespace TestGeometry2D #endif // TEST_GEOMETRY_2D_H diff --git a/tests/core/math/test_geometry_3d.h b/tests/core/math/test_geometry_3d.h index 1b8d2eee34..99a4ef2d46 100644 --- a/tests/core/math/test_geometry_3d.h +++ b/tests/core/math/test_geometry_3d.h @@ -288,7 +288,7 @@ TEST_CASE("[Geometry3D] Is Point in Projected Triangle") { TEST_CASE("[Geometry3D] Does Ray Intersect Triangle") { struct Case { Vector3 from, direction, v_1, v_2, v_3; - Vector3 *result; + Vector3 *result = nullptr; bool want; Case(){}; Case(Vector3 p_from, Vector3 p_direction, Vector3 p_v_1, Vector3 p_v_2, Vector3 p_v_3, bool p_want) : @@ -390,7 +390,7 @@ TEST_CASE("[Geometry3D] Triangle and Box Overlap") { struct Case { Vector3 box_centre; Vector3 box_half_size; - Vector3 *tri_verts; + Vector3 *tri_verts = nullptr; bool want; Case(){}; Case(Vector3 p_centre, Vector3 p_half_size, Vector3 *p_verts, bool p_want) : diff --git a/tests/core/math/test_math.cpp b/tests/core/math/test_math.cpp deleted file mode 100644 index 4182455b7a..0000000000 --- a/tests/core/math/test_math.cpp +++ /dev/null @@ -1,690 +0,0 @@ -/*************************************************************************/ -/* test_math.cpp */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ - -#include "test_math.h" - -#include "core/math/camera_matrix.h" -#include "core/math/delaunay_3d.h" -#include "core/math/geometry_2d.h" -#include "core/os/main_loop.h" -#include "core/os/os.h" - -namespace TestMath { - -class GetClassAndNamespace { - String code; - int idx; - int line; - String error_str; - bool error; - Variant value; - - String class_name; - - enum Token { - TK_BRACKET_OPEN, - TK_BRACKET_CLOSE, - TK_CURLY_BRACKET_OPEN, - TK_CURLY_BRACKET_CLOSE, - TK_PERIOD, - TK_COLON, - TK_COMMA, - TK_SYMBOL, - TK_IDENTIFIER, - TK_STRING, - TK_NUMBER, - TK_EOF, - TK_ERROR - }; - - Token get_token() { - while (true) { - switch (code[idx]) { - case '\n': { - line++; - idx++; - break; - }; - case 0: { - return TK_EOF; - - } break; - case '{': { - idx++; - return TK_CURLY_BRACKET_OPEN; - }; - case '}': { - idx++; - return TK_CURLY_BRACKET_CLOSE; - }; - case '[': { - idx++; - return TK_BRACKET_OPEN; - }; - case ']': { - idx++; - return TK_BRACKET_CLOSE; - }; - case ':': { - idx++; - return TK_COLON; - }; - case ',': { - idx++; - return TK_COMMA; - }; - case '.': { - idx++; - return TK_PERIOD; - }; - case '#': { - //compiler directive - while (code[idx] != '\n' && code[idx] != 0) { - idx++; - } - continue; - } break; - case '/': { - switch (code[idx + 1]) { - case '*': { // block comment - - idx += 2; - while (true) { - if (code[idx] == 0) { - error_str = "Unterminated comment"; - error = true; - return TK_ERROR; - } else if (code[idx] == '*' && code[idx + 1] == '/') { - idx += 2; - break; - } else if (code[idx] == '\n') { - line++; - } - - idx++; - } - - } break; - case '/': { // line comment skip - - while (code[idx] != '\n' && code[idx] != 0) { - idx++; - } - - } break; - default: { - value = "/"; - idx++; - return TK_SYMBOL; - } - } - - continue; // a comment - } break; - case '\'': - case '"': { - char32_t begin_str = code[idx]; - idx++; - String tk_string = String(); - while (true) { - if (code[idx] == 0) { - error_str = "Unterminated String"; - error = true; - return TK_ERROR; - } else if (code[idx] == begin_str) { - idx++; - break; - } else if (code[idx] == '\\') { - //escaped characters... - idx++; - char32_t next = code[idx]; - if (next == 0) { - error_str = "Unterminated String"; - error = true; - return TK_ERROR; - } - char32_t res = 0; - - switch (next) { - case 'b': - res = 8; - break; - case 't': - res = 9; - break; - case 'n': - res = 10; - break; - case 'f': - res = 12; - break; - case 'r': - res = 13; - break; - case '\"': - res = '\"'; - break; - case '\\': - res = '\\'; - break; - default: { - res = next; - } break; - } - - tk_string += res; - - } else { - if (code[idx] == '\n') { - line++; - } - tk_string += code[idx]; - } - idx++; - } - - value = tk_string; - - return TK_STRING; - - } break; - default: { - if (code[idx] <= 32) { - idx++; - break; - } - - if ((code[idx] >= 33 && code[idx] <= 47) || (code[idx] >= 58 && code[idx] <= 64) || (code[idx] >= 91 && code[idx] <= 96) || (code[idx] >= 123 && code[idx] <= 127)) { - value = String::chr(code[idx]); - idx++; - return TK_SYMBOL; - } - - if (code[idx] == '-' || is_digit(code[idx])) { - //a number - const char32_t *rptr; - double number = String::to_float(&code[idx], &rptr); - idx += (rptr - &code[idx]); - value = number; - return TK_NUMBER; - - } else if (is_ascii_char(code[idx]) || code[idx] > 127) { - String id; - - while (is_ascii_char(code[idx]) || code[idx] > 127) { - id += code[idx]; - idx++; - } - - value = id; - return TK_IDENTIFIER; - } else { - error_str = "Unexpected character."; - error = true; - return TK_ERROR; - } - } - } - } - } - -public: - Error parse(const String &p_code, const String &p_known_class_name = String()) { - code = p_code; - idx = 0; - line = 0; - error_str = String(); - error = false; - value = Variant(); - class_name = String(); - - bool use_next_class = false; - Token tk = get_token(); - - Map<int, String> namespace_stack; - int curly_stack = 0; - - while (!error || tk != TK_EOF) { - if (tk == TK_BRACKET_OPEN) { - tk = get_token(); - if (tk == TK_IDENTIFIER && String(value) == "ScriptClass") { - if (get_token() == TK_BRACKET_CLOSE) { - use_next_class = true; - } - } - } else if (tk == TK_IDENTIFIER && String(value) == "class") { - tk = get_token(); - if (tk == TK_IDENTIFIER) { - String name = value; - if (use_next_class || p_known_class_name == name) { - for (const KeyValue<int, String> &E : namespace_stack) { - class_name += E.value + "."; - } - class_name += String(value); - break; - } - } - - } else if (tk == TK_IDENTIFIER && String(value) == "namespace") { - String name; - int at_level = curly_stack; - while (true) { - tk = get_token(); - if (tk == TK_IDENTIFIER) { - name += String(value); - } - - tk = get_token(); - if (tk == TK_PERIOD) { - name += "."; - } else if (tk == TK_CURLY_BRACKET_OPEN) { - curly_stack++; - break; - } else { - break; //whatever else - } - } - - if (!name.is_empty()) { - namespace_stack[at_level] = name; - } - - } else if (tk == TK_CURLY_BRACKET_OPEN) { - curly_stack++; - } else if (tk == TK_CURLY_BRACKET_CLOSE) { - curly_stack--; - if (namespace_stack.has(curly_stack)) { - namespace_stack.erase(curly_stack); - } - } - - tk = get_token(); - } - - if (error) { - return ERR_PARSE_ERROR; - } - - return OK; - } - - String get_error() { - return error_str; - } - - String get_class() { - return class_name; - } -}; - -void test_vec(Plane p_vec) { - CameraMatrix cm; - cm.set_perspective(45, 1, 0, 100); - Plane v0 = cm.xform4(p_vec); - - print_line("out: " + v0); - v0.normal.z = (v0.d / 100.0 * 2.0 - 1.0) * v0.d; - print_line("out_F: " + v0); -} - -uint32_t ihash(uint32_t a) { - a = (a + 0x7ed55d16) + (a << 12); - a = (a ^ 0xc761c23c) ^ (a >> 19); - a = (a + 0x165667b1) + (a << 5); - a = (a + 0xd3a2646c) ^ (a << 9); - a = (a + 0xfd7046c5) + (a << 3); - a = (a ^ 0xb55a4f09) ^ (a >> 16); - return a; -} - -uint32_t ihash2(uint32_t a) { - a = (a ^ 61) ^ (a >> 16); - a = a + (a << 3); - a = a ^ (a >> 4); - a = a * 0x27d4eb2d; - a = a ^ (a >> 15); - return a; -} - -uint32_t ihash3(uint32_t a) { - a = (a + 0x479ab41d) + (a << 8); - a = (a ^ 0xe4aa10ce) ^ (a >> 5); - a = (a + 0x9942f0a6) - (a << 14); - a = (a ^ 0x5aedd67d) ^ (a >> 3); - a = (a + 0x17bea992) + (a << 7); - return a; -} - -MainLoop *test() { - { - Vector<Vector3> points; - points.push_back(Vector3(0, 0, 0)); - points.push_back(Vector3(0, 0, 1)); - points.push_back(Vector3(0, 1, 0)); - points.push_back(Vector3(0, 1, 1)); - points.push_back(Vector3(1, 1, 0)); - points.push_back(Vector3(1, 0, 0)); - points.push_back(Vector3(1, 0, 1)); - points.push_back(Vector3(1, 1, 1)); - - for (int i = 0; i < 800; i++) { - points.push_back(Vector3(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0) * Vector3(25, 30, 33)); - } - - Vector<Delaunay3D::OutputSimplex> os = Delaunay3D::tetrahedralize(points); - print_line("simplices in the end: " + itos(os.size())); - for (int i = 0; i < os.size(); i++) { - print_line("Simplex " + itos(i) + ": "); - print_line(points[os[i].points[0]]); - print_line(points[os[i].points[1]]); - print_line(points[os[i].points[2]]); - print_line(points[os[i].points[3]]); - } - - { - FileAccessRef f = FileAccess::open("res://bsp.obj", FileAccess::WRITE); - for (int i = 0; i < os.size(); i++) { - f->store_line("o Simplex" + itos(i)); - for (int j = 0; j < 4; j++) { - f->store_line(vformat("v %f %f %f", points[os[i].points[j]].x, points[os[i].points[j]].y, points[os[i].points[j]].z)); - } - static const int face_order[4][3] = { - { 1, 2, 3 }, - { 1, 3, 4 }, - { 1, 2, 4 }, - { 2, 3, 4 } - }; - - for (int j = 0; j < 4; j++) { - f->store_line(vformat("f %d %d %d", 4 * i + face_order[j][0], 4 * i + face_order[j][1], 4 * i + face_order[j][2])); - } - } - f->close(); - } - - return nullptr; - } - - { - float r = 1; - float g = 0.5; - float b = 0.1; - - const float pow2to9 = 512.0f; - const float B = 15.0f; - const float N = 9.0f; - - float sharedexp = 65408.000f; - - float cRed = MAX(0.0f, MIN(sharedexp, r)); - float cGreen = MAX(0.0f, MIN(sharedexp, g)); - float cBlue = MAX(0.0f, MIN(sharedexp, b)); - - float cMax = MAX(cRed, MAX(cGreen, cBlue)); - - float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B; - - float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f); - - float exps = expp + 1.0f; - - if (0.0 <= sMax && sMax < pow2to9) { - exps = expp; - } - - float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f); - float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f); - float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f); - - print_line("R: " + rtos(sRed) + " G: " + rtos(sGreen) + " B: " + rtos(sBlue) + " EXP: " + rtos(exps)); - - uint32_t rgbe = (Math::fast_ftoi(sRed) & 0x1FF) | ((Math::fast_ftoi(sGreen) & 0x1FF) << 9) | ((Math::fast_ftoi(sBlue) & 0x1FF) << 18) | ((Math::fast_ftoi(exps) & 0x1F) << 27); - - float rb = rgbe & 0x1ff; - float gb = (rgbe >> 9) & 0x1ff; - float bb = (rgbe >> 18) & 0x1ff; - float eb = (rgbe >> 27); - float mb = Math::pow(2.0, eb - 15.0 - 9.0); - float rd = rb * mb; - float gd = gb * mb; - float bd = bb * mb; - - print_line("RGBE: " + Color(rd, gd, bd)); - } - - Vector<int> ints; - ints.resize(20); - - { - int *w; - w = ints.ptrw(); - for (int i = 0; i < ints.size(); i++) { - w[i] = i; - } - } - - Vector<int> posho = ints; - - { - const int *r = posho.ptr(); - for (int i = 0; i < posho.size(); i++) { - print_line(itos(i) + " : " + itos(r[i])); - } - } - - List<String> cmdlargs = OS::get_singleton()->get_cmdline_args(); - - if (cmdlargs.is_empty()) { - //try editor! - return nullptr; - } - - String test = cmdlargs.back()->get(); - if (test == "math") { - // Not a file name but the test name, abort. - // FIXME: This test is ugly as heck, needs fixing :) - return nullptr; - } - - FileAccess *fa = FileAccess::open(test, FileAccess::READ); - ERR_FAIL_COND_V_MSG(!fa, nullptr, "Could not open file: " + test); - - Vector<uint8_t> buf; - uint64_t flen = fa->get_length(); - buf.resize(fa->get_length() + 1); - fa->get_buffer(buf.ptrw(), flen); - buf.write[flen] = 0; - - String code; - code.parse_utf8((const char *)&buf[0]); - - GetClassAndNamespace getclass; - if (getclass.parse(code)) { - print_line("Parse error: " + getclass.get_error()); - } else { - print_line("Found class: " + getclass.get_class()); - } - - { - Vector<int> hashes; - List<StringName> tl; - ClassDB::get_class_list(&tl); - - for (const StringName &E : tl) { - Vector<uint8_t> m5b = E.operator String().md5_buffer(); - hashes.push_back(hashes.size()); - } - - for (int i = nearest_shift(hashes.size()); i < 20; i++) { - bool success = true; - for (int s = 0; s < 10000; s++) { - Set<uint32_t> existing; - success = true; - - for (int j = 0; j < hashes.size(); j++) { - uint32_t eh = ihash2(ihash3(hashes[j] + ihash(s) + s)) & ((1 << i) - 1); - if (existing.has(eh)) { - success = false; - break; - } - existing.insert(eh); - } - - if (success) { - print_line("success at " + itos(i) + "/" + itos(nearest_shift(hashes.size())) + " shift " + itos(s)); - break; - } - } - if (success) { - break; - } - } - - print_line("DONE"); - } - - { - print_line("NUM: " + itos(-128)); - } - - { - Vector3 v(1, 2, 3); - v.normalize(); - real_t a = 0.3; - - Basis m(v, a); - - Vector3 v2(7, 3, 1); - v2.normalize(); - real_t a2 = 0.8; - - Basis m2(v2, a2); - - Quaternion q = m; - Quaternion q2 = m2; - - Basis m3 = m.inverse() * m2; - Quaternion q3 = (q.inverse() * q2); //.normalized(); - - print_line(Quaternion(m3)); - print_line(q3); - - print_line("before v: " + v + " a: " + rtos(a)); - q.get_axis_angle(v, a); - print_line("after v: " + v + " a: " + rtos(a)); - } - - String ret; - - List<String> args; - args.push_back("-l"); - Error err = OS::get_singleton()->execute("/bin/ls", args, &ret); - print_line("error: " + itos(err)); - print_line(ret); - - Basis m3; - m3.rotate(Vector3(1, 0, 0), 0.2); - m3.rotate(Vector3(0, 1, 0), 1.77); - m3.rotate(Vector3(0, 0, 1), 212); - Basis m32; - m32.set_euler(m3.get_euler()); - print_line("ELEULEEEEEEEEEEEEEEEEEER: " + m3.get_euler() + " vs " + m32.get_euler()); - - { - Dictionary d; - d["momo"] = 1; - Dictionary b = d; - b["44"] = 4; - } - - print_line("inters: " + rtos(Geometry2D::segment_intersects_circle(Vector2(-5, 0), Vector2(-2, 0), Vector2(), 1.0))); - - print_line("cross: " + Vector3(1, 2, 3).cross(Vector3(4, 5, 7))); - print_line("dot: " + rtos(Vector3(1, 2, 3).dot(Vector3(4, 5, 7)))); - print_line("abs: " + Vector3(-1, 2, -3).abs()); - print_line("distance_to: " + rtos(Vector3(1, 2, 3).distance_to(Vector3(4, 5, 7)))); - print_line("distance_squared_to: " + rtos(Vector3(1, 2, 3).distance_squared_to(Vector3(4, 5, 7)))); - print_line("plus: " + (Vector3(1, 2, 3) + Vector3(Vector3(4, 5, 7)))); - print_line("minus: " + (Vector3(1, 2, 3) - Vector3(Vector3(4, 5, 7)))); - print_line("mul: " + (Vector3(1, 2, 3) * Vector3(Vector3(4, 5, 7)))); - print_line("div: " + (Vector3(1, 2, 3) / Vector3(Vector3(4, 5, 7)))); - print_line("mul scalar: " + (Vector3(1, 2, 3) * 2.0)); - print_line("premul scalar: " + (2.0 * Vector3(1, 2, 3))); - print_line("div scalar: " + (Vector3(1, 2, 3) / 3.0)); - print_line("length: " + rtos(Vector3(1, 2, 3).length())); - print_line("length squared: " + rtos(Vector3(1, 2, 3).length_squared())); - print_line("normalized: " + Vector3(1, 2, 3).normalized()); - print_line("inverse: " + Vector3(1, 2, 3).inverse()); - - { - Vector3 v(4, 5, 7); - v.normalize(); - print_line("normalize: " + v); - } - - { - Vector3 v(4, 5, 7); - v += Vector3(1, 2, 3); - print_line("+=: " + v); - } - - { - Vector3 v(4, 5, 7); - v -= Vector3(1, 2, 3); - print_line("-=: " + v); - } - - { - Vector3 v(4, 5, 7); - v *= Vector3(1, 2, 3); - print_line("*=: " + v); - } - - { - Vector3 v(4, 5, 7); - v /= Vector3(1, 2, 3); - print_line("/=: " + v); - } - - { - Vector3 v(4, 5, 7); - v *= 2.0; - print_line("scalar *=: " + v); - } - - { - Vector3 v(4, 5, 7); - v /= 2.0; - print_line("scalar /=: " + v); - } - - return nullptr; -} -} // namespace TestMath diff --git a/tests/core/math/test_math.h b/tests/core/math/test_math.h deleted file mode 100644 index a8aa8f6847..0000000000 --- a/tests/core/math/test_math.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************/ -/* test_math.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_H -#define TEST_MATH_H - -class MainLoop; - -namespace TestMath { - -MainLoop *test(); -} - -#endif diff --git a/tests/core/object/test_class_db.h b/tests/core/object/test_class_db.h index 5cf5403a50..8aaca69d13 100644 --- a/tests/core/object/test_class_db.h +++ b/tests/core/object/test_class_db.h @@ -173,7 +173,7 @@ struct NamesCache { } }; -typedef OrderedHashMap<StringName, ExposedClass> ExposedClasses; +typedef HashMap<StringName, ExposedClass> ExposedClasses; struct Context { Vector<StringName> enum_types; @@ -183,13 +183,13 @@ struct Context { NamesCache names_cache; const ExposedClass *find_exposed_class(const StringName &p_name) const { - ExposedClasses::ConstElement elem = exposed_classes.find(p_name); - return elem ? &elem.value() : nullptr; + ExposedClasses::ConstIterator elem = exposed_classes.find(p_name); + return elem ? &elem->value : nullptr; } const ExposedClass *find_exposed_class(const TypeReference &p_type_ref) const { - ExposedClasses::ConstElement elem = exposed_classes.find(p_type_ref.name); - return elem ? &elem.value() : nullptr; + ExposedClasses::ConstIterator elem = exposed_classes.find(p_type_ref.name); + return elem ? &elem->value : nullptr; } bool has_type(const TypeReference &p_type_ref) const { @@ -519,7 +519,7 @@ void add_exposed_classes(Context &r_context) { List<PropertyInfo> property_list; ClassDB::get_property_list(class_name, &property_list, true); - Map<StringName, StringName> accessor_methods; + HashMap<StringName, StringName> accessor_methods; for (const PropertyInfo &property : property_list) { if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY || (property.type == Variant::NIL && property.usage & PROPERTY_USAGE_ARRAY)) { @@ -676,12 +676,11 @@ void add_exposed_classes(Context &r_context) { // Add signals const HashMap<StringName, MethodInfo> &signal_map = class_info->signal_map; - const StringName *k = nullptr; - while ((k = signal_map.next(k))) { + for (const KeyValue<StringName, MethodInfo> &K : signal_map) { SignalData signal; - const MethodInfo &method_info = signal_map.get(*k); + const MethodInfo &method_info = signal_map.get(K.key); signal.name = method_info.name; @@ -734,14 +733,12 @@ void add_exposed_classes(Context &r_context) { ClassDB::get_integer_constant_list(class_name, &constants, true); const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map; - k = nullptr; - while ((k = enum_map.next(k))) { + for (const KeyValue<StringName, List<StringName>> &K : enum_map) { EnumData enum_; - enum_.name = *k; + enum_.name = K.key; - const List<StringName> &enum_constants = enum_map.get(*k); - for (const StringName &E : enum_constants) { + for (const StringName &E : K.value) { const StringName &constant_name = E; TEST_FAIL_COND(String(constant_name).find("::") != -1, "Enum constant contains '::', check bindings to remove the scope: '", @@ -760,7 +757,7 @@ void add_exposed_classes(Context &r_context) { exposed_class.enums.push_back(enum_); - r_context.enum_types.push_back(String(class_name) + "." + String(*k)); + r_context.enum_types.push_back(String(class_name) + "." + String(K.key)); } for (const String &E : constants) { @@ -850,8 +847,8 @@ TEST_SUITE("[ClassDB]") { TEST_FAIL_COND(object_class->base != StringName(), "Object class derives from another class: '", object_class->base, "'."); - for (ExposedClasses::Element E = context.exposed_classes.front(); E; E = E.next()) { - validate_class(context, E.value()); + for (const KeyValue<StringName, ExposedClass> &E : context.exposed_classes) { + validate_class(context, E.value); } } } diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 87016dddf6..58372a0ed6 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -636,6 +636,38 @@ TEST_CASE("[String] sprintf") { REQUIRE(error == false); CHECK(output == String("fish -5 frog")); + // Negative int left padded with spaces. + format = "fish %5d frog"; + args.clear(); + args.push_back(-5); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -5 frog")); + + // Negative int left padded with zeros. + format = "fish %05d frog"; + args.clear(); + args.push_back(-5); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -0005 frog")); + + // Negative int right padded with spaces. + format = "fish %-5d frog"; + args.clear(); + args.push_back(-5); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -5 frog")); + + // Negative int right padded with zeros. (0 ignored) + format = "fish %-05d frog"; + args.clear(); + args.push_back(-5); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -5 frog")); + // Hex (lower) format = "fish %x frog"; args.clear(); @@ -726,6 +758,14 @@ TEST_CASE("[String] sprintf") { REQUIRE(error == false); CHECK(output == String("fish 100 frog")); + // Negative real right padded with zeros. (0 ignored) + format = "fish %-011f frog"; + args.clear(); + args.push_back(-99.99); + output = format.sprintf(args, &error); + REQUIRE(error == false); + CHECK(output == String("fish -99.990000 frog")); + /////// Strings. // String diff --git a/tests/core/string/test_translation.h b/tests/core/string/test_translation.h index 85ac639bec..0a1903ccbf 100644 --- a/tests/core/string/test_translation.h +++ b/tests/core/string/test_translation.h @@ -154,7 +154,7 @@ TEST_CASE("[OptimizedTranslation] Generate from Translation and read messages") TEST_CASE("[Translation] CSV import") { Ref<ResourceImporterCSVTranslation> import_csv_translation = memnew(ResourceImporterCSVTranslation); - Map<StringName, Variant> options; + HashMap<StringName, Variant> options; options["compress"] = false; options["delimiter"] = 0; diff --git a/tests/core/templates/test_ordered_hash_map.h b/tests/core/templates/test_hash_map.h index 08c5c9b72a..7a3d5f5d47 100644 --- a/tests/core/templates/test_ordered_hash_map.h +++ b/tests/core/templates/test_hash_map.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* test_ordered_hash_map.h */ +/* test_hash_map.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,56 +28,53 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TEST_ORDERED_HASH_MAP_H -#define TEST_ORDERED_HASH_MAP_H +#ifndef TEST_HASH_MAP_H +#define TEST_HASH_MAP_H -#include "core/templates/ordered_hash_map.h" +#include "core/templates/hash_map.h" #include "tests/test_macros.h" -namespace TestOrderedHashMap { +namespace TestHashMap { -TEST_CASE("[OrderedHashMap] Insert element") { - OrderedHashMap<int, int> map; - OrderedHashMap<int, int>::Element e = map.insert(42, 84); +TEST_CASE("[HashMap] Insert element") { + HashMap<int, int> map; + HashMap<int, int>::Iterator e = map.insert(42, 84); CHECK(e); - CHECK(e.key() == 42); - CHECK(e.get() == 84); - CHECK(e.value() == 84); + CHECK(e->key == 42); + CHECK(e->value == 84); CHECK(map[42] == 84); CHECK(map.has(42)); CHECK(map.find(42)); } -TEST_CASE("[OrderedHashMap] Overwrite element") { - OrderedHashMap<int, int> map; +TEST_CASE("[HashMap] Overwrite element") { + HashMap<int, int> map; map.insert(42, 84); map.insert(42, 1234); CHECK(map[42] == 1234); } -TEST_CASE("[OrderedHashMap] Erase via element") { - OrderedHashMap<int, int> map; - OrderedHashMap<int, int>::Element e = map.insert(42, 84); - - map.erase(e); - CHECK(!e); +TEST_CASE("[HashMap] Erase via element") { + HashMap<int, int> map; + HashMap<int, int>::Iterator e = map.insert(42, 84); + map.remove(e); CHECK(!map.has(42)); CHECK(!map.find(42)); } -TEST_CASE("[OrderedHashMap] Erase via key") { - OrderedHashMap<int, int> map; +TEST_CASE("[HashMap] Erase via key") { + HashMap<int, int> map; map.insert(42, 84); map.erase(42); CHECK(!map.has(42)); CHECK(!map.find(42)); } -TEST_CASE("[OrderedHashMap] Size") { - OrderedHashMap<int, int> map; +TEST_CASE("[HashMap] Size") { + HashMap<int, int> map; map.insert(42, 84); map.insert(123, 84); map.insert(123, 84); @@ -87,8 +84,8 @@ TEST_CASE("[OrderedHashMap] Size") { CHECK(map.size() == 4); } -TEST_CASE("[OrderedHashMap] Iteration") { - OrderedHashMap<int, int> map; +TEST_CASE("[HashMap] Iteration") { + HashMap<int, int> map; map.insert(42, 84); map.insert(123, 12385); map.insert(0, 12934); @@ -102,34 +99,35 @@ TEST_CASE("[OrderedHashMap] Iteration") { expected.push_back(Pair<int, int>(123485, 1238888)); int idx = 0; - for (OrderedHashMap<int, int>::Element E = map.front(); E; E = E.next()) { - CHECK(expected[idx] == Pair<int, int>(E.key(), E.value())); + for (const KeyValue<int, int> &E : map) { + CHECK(expected[idx] == Pair<int, int>(E.key, E.value)); ++idx; } } -TEST_CASE("[OrderedHashMap] Const iteration") { - OrderedHashMap<int, int> map; +TEST_CASE("[HashMap] Const iteration") { + HashMap<int, int> map; map.insert(42, 84); map.insert(123, 12385); map.insert(0, 12934); map.insert(123485, 1238888); map.insert(123, 111111); - const OrderedHashMap<int, int> const_map = map; + const HashMap<int, int> const_map = map; Vector<Pair<int, int>> expected; expected.push_back(Pair<int, int>(42, 84)); expected.push_back(Pair<int, int>(123, 111111)); expected.push_back(Pair<int, int>(0, 12934)); expected.push_back(Pair<int, int>(123485, 1238888)); + expected.push_back(Pair<int, int>(123, 111111)); int idx = 0; - for (OrderedHashMap<int, int>::ConstElement E = const_map.front(); E; E = E.next()) { - CHECK(expected[idx] == Pair<int, int>(E.key(), E.value())); + for (const KeyValue<int, int> &E : const_map) { + CHECK(expected[idx] == Pair<int, int>(E.key, E.value)); ++idx; } } -} // namespace TestOrderedHashMap +} // namespace TestHashMap -#endif // TEST_ORDERED_HASH_MAP_H +#endif // TEST_HASH_MAP_H diff --git a/tests/core/templates/test_oa_hash_map.cpp b/tests/core/templates/test_oa_hash_map.cpp deleted file mode 100644 index 87bf9feb83..0000000000 --- a/tests/core/templates/test_oa_hash_map.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/*************************************************************************/ -/* test_oa_hash_map.cpp */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ - -#include "test_oa_hash_map.h" - -#include "core/os/os.h" -#include "core/templates/oa_hash_map.h" - -namespace TestOAHashMap { - -struct CountedItem { - static int count; - - int id = -1; - bool destroyed = false; - - CountedItem() { - count++; - } - - CountedItem(int p_id) : - id(p_id) { - count++; - } - - CountedItem(const CountedItem &p_other) : - id(p_other.id) { - count++; - } - - void operator=(const CountedItem &p_other) { - id = p_other.id; - count++; - } - - ~CountedItem() { - CRASH_COND(destroyed); - count--; - destroyed = true; - } -}; - -int CountedItem::count; - -MainLoop *test() { - OS::get_singleton()->print("\n\n\nHello from test\n"); - - // test element tracking. - { - OAHashMap<int, int> map; - - map.set(42, 1337); - map.set(1337, 21); - map.set(42, 11880); - - int value = 0; - map.lookup(42, value); - - OS::get_singleton()->print("capacity %d\n", map.get_capacity()); - OS::get_singleton()->print("elements %d\n", map.get_num_elements()); - - OS::get_singleton()->print("map[42] = %d\n", value); - } - - // rehashing and deletion - { - OAHashMap<int, int> map; - - for (int i = 0; i < 500; i++) { - map.set(i, i * 2); - } - - for (int i = 0; i < 500; i += 2) { - map.remove(i); - } - - uint32_t num_elems = 0; - for (int i = 0; i < 500; i++) { - int tmp; - if (map.lookup(i, tmp) && tmp == i * 2) { - num_elems++; - } - } - - OS::get_singleton()->print("elements %d == %d.\n", map.get_num_elements(), num_elems); - } - - // iteration - { - OAHashMap<String, int> map; - - map.set("Hello", 1); - map.set("World", 2); - map.set("Godot rocks", 42); - - for (OAHashMap<String, int>::Iterator it = map.iter(); it.valid; it = map.next_iter(it)) { - OS::get_singleton()->print("map[\"%s\"] = %d\n", it.key->utf8().get_data(), *it.value); - } - } - - // stress test / test for issue #22928 - { - OAHashMap<int, int> map; - int dummy = 0; - const int N = 1000; - uint32_t *keys = new uint32_t[N]; - - Math::seed(0); - - // insert a couple of random keys (with a dummy value, which is ignored) - for (int i = 0; i < N; i++) { - keys[i] = Math::rand(); - map.set(keys[i], dummy); - - if (!map.lookup(keys[i], dummy)) { - OS::get_singleton()->print("could not find 0x%X despite it was just inserted!\n", unsigned(keys[i])); - } - } - - // check whether the keys are still present - for (int i = 0; i < N; i++) { - if (!map.lookup(keys[i], dummy)) { - OS::get_singleton()->print("could not find 0x%X despite it has been inserted previously! (not checking the other keys, breaking...)\n", unsigned(keys[i])); - break; - } - } - - delete[] keys; - } - - // regression test / test for issue related to #31402 - { - OS::get_singleton()->print("test for issue #31402 started...\n"); - - const int num_test_values = 12; - int test_values[num_test_values] = { 0, 24, 48, 72, 96, 120, 144, 168, 192, 216, 240, 264 }; - - int dummy = 0; - OAHashMap<int, int> map; - map.clear(); - - for (int i = 0; i < num_test_values; ++i) { - map.set(test_values[i], dummy); - } - - OS::get_singleton()->print("test for issue #31402 passed.\n"); - } - - // test collision resolution, should not crash or run indefinitely - { - OAHashMap<int, int> map(4); - map.set(1, 1); - map.set(5, 1); - map.set(9, 1); - map.set(13, 1); - map.remove(5); - map.remove(9); - map.remove(13); - map.set(5, 1); - } - - // test memory management of items, should not crash or leak items - { - // Exercise different patterns of removal - for (int i = 0; i < 4; ++i) { - { - OAHashMap<String, CountedItem> map; - int id = 0; - for (int j = 0; j < 100; ++j) { - map.insert(itos(j), CountedItem(id)); - } - if (i <= 1) { - for (int j = 0; j < 100; ++j) { - map.remove(itos(j)); - } - } - if (i % 2 == 0) { - map.clear(); - } - } - - if (CountedItem::count != 0) { - OS::get_singleton()->print("%d != 0 (not performing the other test sub-cases, breaking...)\n", CountedItem::count); - break; - } - } - } - - // Test map with 0 capacity. - { - OAHashMap<int, String> original_map(0); - original_map.set(1, "1"); - OS::get_singleton()->print("OAHashMap 0 capacity initialization passed.\n"); - } - - // Test copy constructor. - { - OAHashMap<int, String> original_map; - original_map.set(1, "1"); - original_map.set(2, "2"); - original_map.set(3, "3"); - original_map.set(4, "4"); - original_map.set(5, "5"); - - OAHashMap<int, String> map_copy(original_map); - - bool pass = true; - for ( - OAHashMap<int, String>::Iterator it = original_map.iter(); - it.valid; - it = original_map.next_iter(it)) { - if (map_copy.lookup_ptr(*it.key) == nullptr) { - pass = false; - } - if (*it.value != *map_copy.lookup_ptr(*it.key)) { - pass = false; - } - } - if (pass) { - OS::get_singleton()->print("OAHashMap copy constructor test passed.\n"); - } else { - OS::get_singleton()->print("OAHashMap copy constructor test FAILED.\n"); - } - - map_copy.set(1, "Random String"); - if (*map_copy.lookup_ptr(1) == *original_map.lookup_ptr(1)) { - OS::get_singleton()->print("OAHashMap copy constructor, atomic copy test FAILED.\n"); - } else { - OS::get_singleton()->print("OAHashMap copy constructor, atomic copy test passed.\n"); - } - } - - // Test assign operator. - { - OAHashMap<int, String> original_map; - original_map.set(1, "1"); - original_map.set(2, "2"); - original_map.set(3, "3"); - original_map.set(4, "4"); - original_map.set(5, "5"); - - OAHashMap<int, String> map_copy(100000); - map_copy.set(1, "Just a string."); - map_copy = original_map; - - bool pass = true; - for ( - OAHashMap<int, String>::Iterator it = map_copy.iter(); - it.valid; - it = map_copy.next_iter(it)) { - if (original_map.lookup_ptr(*it.key) == nullptr) { - pass = false; - } - if (*it.value != *original_map.lookup_ptr(*it.key)) { - pass = false; - } - } - if (pass) { - OS::get_singleton()->print("OAHashMap assign operation test passed.\n"); - } else { - OS::get_singleton()->print("OAHashMap assign operation test FAILED.\n"); - } - - map_copy.set(1, "Random String"); - if (*map_copy.lookup_ptr(1) == *original_map.lookup_ptr(1)) { - OS::get_singleton()->print("OAHashMap assign operation atomic copy test FAILED.\n"); - } else { - OS::get_singleton()->print("OAHashMap assign operation atomic copy test passed.\n"); - } - } - - return nullptr; -} -} // namespace TestOAHashMap diff --git a/tests/core/templates/test_oa_hash_map.h b/tests/core/templates/test_oa_hash_map.h deleted file mode 100644 index d4b72af2ac..0000000000 --- a/tests/core/templates/test_oa_hash_map.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************/ -/* test_oa_hash_map.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_OA_HASH_MAP_H -#define TEST_OA_HASH_MAP_H - -class MainLoop; - -namespace TestOAHashMap { - -MainLoop *test(); -} - -#endif // TEST_OA_HASH_MAP_H diff --git a/tests/core/test_time.h b/tests/core/test_time.h index bc341c73bd..177512c832 100644 --- a/tests/core/test_time.h +++ b/tests/core/test_time.h @@ -118,11 +118,11 @@ TEST_CASE("[Time] Datetime dictionary conversion methods") { CHECK_MESSAGE((Time::Weekday)(int)time->get_datetime_dict_from_unix_time(0)[WEEKDAY_KEY] == Time::Weekday::WEEKDAY_THURSDAY, "Time get_datetime_dict_from_unix_time: The weekday for the Unix epoch is a Thursday as expected."); CHECK_MESSAGE((Time::Weekday)(int)time->get_datetime_dict_from_unix_time(1391983830)[WEEKDAY_KEY] == Time::Weekday::WEEKDAY_SUNDAY, "Time get_datetime_dict_from_unix_time: The weekday for GODOT IS OPEN SOURCE is a Sunday as expected."); - CHECK_MESSAGE(time->get_datetime_dict_from_string("2014-02-09T22:10:30").hash() == datetime.hash(), "Time get_datetime_dict_from_string: The dictionary from string for GODOT IS OPEN SOURCE works as expected."); - CHECK_MESSAGE(!time->get_datetime_dict_from_string("2014-02-09T22:10:30", false).has(WEEKDAY_KEY), "Time get_datetime_dict_from_string: The dictionary from string for GODOT IS OPEN SOURCE without weekday doesn't contain the weekday key as expected."); - CHECK_MESSAGE(time->get_datetime_string_from_dict(datetime) == "2014-02-09T22:10:30", "Time get_datetime_string_from_dict: The string from dictionary for GODOT IS OPEN SOURCE works as expected."); - CHECK_MESSAGE(time->get_datetime_string_from_dict(time->get_datetime_dict_from_string("2014-02-09T22:10:30")) == "2014-02-09T22:10:30", "Time get_datetime_string_from_dict: The round-trip string to dict to string GODOT IS OPEN SOURCE works as expected."); - CHECK_MESSAGE(time->get_datetime_string_from_dict(time->get_datetime_dict_from_string("2014-02-09 22:10:30"), true) == "2014-02-09 22:10:30", "Time get_datetime_string_from_dict: The round-trip string to dict to string GODOT IS OPEN SOURCE with spaces works as expected."); + CHECK_MESSAGE(time->get_datetime_dict_from_datetime_string("2014-02-09T22:10:30").hash() == datetime.hash(), "Time get_datetime_dict_from_string: The dictionary from string for GODOT IS OPEN SOURCE works as expected."); + CHECK_MESSAGE(!time->get_datetime_dict_from_datetime_string("2014-02-09T22:10:30", false).has(WEEKDAY_KEY), "Time get_datetime_dict_from_string: The dictionary from string for GODOT IS OPEN SOURCE without weekday doesn't contain the weekday key as expected."); + CHECK_MESSAGE(time->get_datetime_string_from_datetime_dict(datetime) == "2014-02-09T22:10:30", "Time get_datetime_string_from_dict: The string from dictionary for GODOT IS OPEN SOURCE works as expected."); + CHECK_MESSAGE(time->get_datetime_string_from_datetime_dict(time->get_datetime_dict_from_datetime_string("2014-02-09T22:10:30")) == "2014-02-09T22:10:30", "Time get_datetime_string_from_dict: The round-trip string to dict to string GODOT IS OPEN SOURCE works as expected."); + CHECK_MESSAGE(time->get_datetime_string_from_datetime_dict(time->get_datetime_dict_from_datetime_string("2014-02-09 22:10:30"), true) == "2014-02-09 22:10:30", "Time get_datetime_string_from_dict: The round-trip string to dict to string GODOT IS OPEN SOURCE with spaces works as expected."); } TEST_CASE("[Time] System time methods") { |