diff --git a/src/ffi/point.rs b/src/ffi/point.rs index 94afd7b..44ead9b 100644 --- a/src/ffi/point.rs +++ b/src/ffi/point.rs @@ -86,66 +86,24 @@ mod ffi_point { pub use ffi_point::Point; -// Basic tests +// FFI API tests #[cfg(test)] mod tests { use super::*; use std::os::raw::c_double; #[test] - fn point_debug_precision() { - let p = Point::new(1.123456789, 2.987654321, -3.555555555).expect("Failed to create point"); - let debug_str = format!("{:?}", p); - - let coords = p.coordinates(); - assert!(debug_str.contains(&coords.0.to_string())); - assert!(debug_str.contains(&coords.1.to_string())); - assert!(debug_str.contains(&coords.2.to_string())); - } - - #[test] - fn point_null_pointer_safety() { - let result = Point::new(1.0, 2.0, 3.0); - assert!(result.is_ok()); - - let p = result.unwrap(); - let coords = p.coordinates(); - - assert_eq!(coords, (1.0, 2.0, 3.0)); - } - - #[test] - fn point_drop_impl_safety() { - { - let p = Point::new(1.0, 2.0, 3.0).expect("Failed to create point"); - // p goes out of scope here and should be dropped - } - let p2 = Point::new(4.0, 5.0, 6.0).expect("Failed to create point after drop"); - assert_eq!(p2.coordinates(), (4.0, 5.0, 6.0)); - } - - #[test] - fn point_ffi_repr_c() { + fn types_compatibility() { use std::mem; - // PointShape should be repr(C) and zero-sized in Rust assert_eq!(mem::size_of::(), 0); - - // c_double should match f64 assert_eq!(mem::size_of::(), mem::size_of::()); assert_eq!(mem::align_of::(), mem::align_of::()); } #[test] - fn point_coordinates_after_multiple_uses() { - let p = Point::new(1.1, 2.2, 3.3).expect("Failed to create point"); - - let _coords1 = p.coordinates(); - let _debug1 = format!("{:?}", p); - let _coords2 = p.coordinates(); - let _debug2 = format!("{:?}", p); - let final_coords = p.coordinates(); - - assert_eq!(final_coords, (1.1, 2.2, 3.3)); + fn basic_lifecycle() { + let p = Point::new(1.0, 2.0, 3.0).expect("FFI creation failed"); + assert_eq!(p.coordinates(), (1.0, 2.0, 3.0)); } } diff --git a/tests/occt/point-test.cpp b/tests/occt/point-test.cpp index b74b876..df27aa3 100644 --- a/tests/occt/point-test.cpp +++ b/tests/occt/point-test.cpp @@ -4,11 +4,10 @@ */ #include -#include #include #include "point.hpp" -TEST_CASE("Test point creation, query and deletion behaviour", "[point]") { +TEST_CASE("Point lifecycle and coordinate operations", "[point]") { auto check_coords = [](const point_shape_t* p, const double expected[3]) { double x, y, z; coord_point(p, &x, &y, &z); @@ -17,65 +16,34 @@ TEST_CASE("Test point creation, query and deletion behaviour", "[point]") { REQUIRE(z == Catch::Approx(expected[2])); }; - SECTION("Accept integer coordinates") { - double coords[3] = {3, -7, 2}; - point_shape_t* p = make_point(coords[0], coords[1], coords[2]); - check_coords(p, coords); - delete_point(p); - } - - SECTION("Accept float coordinates") { + SECTION("Basic creation and coordinate retrieval") { double coords[3] = {3.2352, 7.124662, -2.5}; point_shape_t* p = make_point(coords[0], coords[1], coords[2]); check_coords(p, coords); delete_point(p); } - SECTION("XYZ Origin") { - double coords[3] = {0, 0, 0}; - point_shape_t* p = make_point(coords[0], coords[1], coords[2]); - check_coords(p, coords); - delete_point(p); - } - - SECTION("Large magnitude values") { - double coords[3] = {6.5186415e7, 9.48156654e8, -6.516515e6}; - point_shape_t* p = make_point(coords[0], coords[1], coords[2]); - check_coords(p, coords); - delete_point(p); - } - - SECTION("Multiple points") { - const double points[5][3] = { - {3, 7, 2}, - {3, 7, 2}, - {-5, 3.7, 8}, - {-3, -7, -2}, - {0, 0, 1} + SECTION("Extreme double values") { + double coords[3] = { + std::numeric_limits::max(), + std::numeric_limits::lowest(), + std::numeric_limits::min() }; - - for (const auto& c : points) { - point_shape_t* p = make_point(c[0], c[1], c[2]); - check_coords(p, c); - delete_point(p); - } - } - - SECTION("Extreme double limits") { - double coords[3] = {std::numeric_limits::max(), - std::numeric_limits::lowest(), - std::numeric_limits::min()}; point_shape_t* p = make_point(coords[0], coords[1], coords[2]); check_coords(p, coords); delete_point(p); } - SECTION("NaN and Infinity") { - double coords[3] = {std::numeric_limits::quiet_NaN(), std::numeric_limits::infinity(), -std::numeric_limits::infinity()}; + SECTION("Special floating-point values") { + double coords[3] = { + std::numeric_limits::quiet_NaN(), + std::numeric_limits::infinity(), + -std::numeric_limits::infinity() + }; point_shape_t* p = make_point(coords[0], coords[1], coords[2]); + double x, y, z; coord_point(p, &x, &y, &z); - REQUIRE(std::isnan(x)); REQUIRE(std::isinf(y)); REQUIRE(std::isinf(z)); @@ -85,87 +53,35 @@ TEST_CASE("Test point creation, query and deletion behaviour", "[point]") { delete_point(p); } - SECTION("Denormal values") { - double coords[3] = {std::numeric_limits::denorm_min(), - -std::numeric_limits::denorm_min(), - 0.0}; - point_shape_t* p = make_point(coords[0], coords[1], coords[2]); - check_coords(p, coords); - delete_point(p); - } - - SECTION("Clear single point") { - point_shape_t* p = make_point(1.0, 2.0, 3.0); - - double x, y, z; - coord_point(p, &x, &y, &z); - REQUIRE(x == Catch::Approx(1.0)); - REQUIRE(y == Catch::Approx(2.0)); - REQUIRE(z == Catch::Approx(3.0)); - - delete_point(p); - } - - SECTION("Clear multiple points") { - const int num_points = 5; - point_shape_t* p[num_points]; - - for (int i = 0; i < num_points; ++i) { - p[i] = make_point(i * 1.0, i * 2.0, i * 3.0); - } - - for (int i = 0; i < num_points; ++i) { - delete_point(p[i]); - } - } - - SECTION("Clear already null shape") { - point_shape_t* null_p = nullptr; - REQUIRE(null_p == nullptr); - delete_point(null_p); - } - - SECTION("Memory efficiency - multiple clear calls") { - for (int i = 0; i < 100; ++i) { - point_shape_t* tmp_p = make_point(1.0, 1.0, 1.0); - delete_point(tmp_p); - } - } - - SECTION("Pointer validity after operations") { - point_shape_t* p = make_point(1.0, 2.0, 3.0); - REQUIRE(p != nullptr); - - double x, y, z; - coord_point(p, &x, &y, &z); - - delete_point(p); - } -} - -TEST_CASE("Benchmark point operations") { - SECTION("make_point performance") { - point_shape_t* p = nullptr; - BENCHMARK("Create point") { - return p = make_point(1.0, 2.0, 3.0); + SECTION("Multiple independent instances") { + const double points[3][3] = { + {3, 7, 2}, + {-5, 3.7, 8}, + {-3, -7, -2} }; - delete_point(p); - } - SECTION("coord_point performance") { - point_shape_t* p = make_point(1.0, 2.0, 3.0); - double x, y, z; - - BENCHMARK("Extract coordinates") { - coord_point(p, &x, &y, &z); - }; - delete_point(p); - } - - SECTION("delete_point performance") { - BENCHMARK("Delete point") { - point_shape_t* p = make_point(1.0, 2.0, 3.0); + for (const auto& coords : points) { + point_shape_t* p = make_point(coords[0], coords[1], coords[2]); + check_coords(p, coords); delete_point(p); - }; + } + } + + SECTION("Null pointer safety") { + point_shape_t* null_p = nullptr; + delete_point(null_p); + + double x, y, z; + coord_point(null_p, &x, &y, &z); + } +} + +TEST_CASE("Point memory management", "[point]") { + SECTION("Rapid allocation/deallocation cycle") { + for (int i = 0; i < 50; ++i) { + point_shape_t* p = make_point(1.0, 2.0, 3.0); + REQUIRE(p != nullptr); + delete_point(p); + } } } diff --git a/tests/point_test.rs b/tests/point_test.rs index e11c9eb..c269b77 100644 --- a/tests/point_test.rs +++ b/tests/point_test.rs @@ -5,108 +5,59 @@ use arc_core::ffi::point::Point; +// Safe wrapper tests #[cfg(test)] mod tests { use super::*; #[test] - fn point_creation() { - let p = Point::new(1.0, 2.0, -3.0).expect("Failed to create point"); - let coords = p.coordinates(); - assert_eq!(coords, (1.0, 2.0, -3.0)); + fn creation_and_query() { + let p = Point::new(1.0, 2.0, -3.0).expect("Safe creation failed"); + assert_eq!(p.coordinates(), (1.0, 2.0, -3.0)); } #[test] - fn point_query() { - let p = Point::new(5.5, 3.15, -0.001).expect("Failed to create point"); - let coords = p.coordinates(); - assert_eq!(coords, (5.5, 3.15, -0.001)); + fn manual_deletion() { + let p = Point::new(1.0, 2.0, 3.0).expect("Creation failed"); + p.delete().expect("Manual deletion failed"); } #[test] - fn point_deletion() { - let p = Point::new(1.0, 2.0, 3.0).expect("Failed to create point"); - let result = p.delete(); - assert!(result.is_ok(), "Deletion should succeed for valid point"); - } - - #[test] - fn point_creation_extreme_values() { - let cases = [ - (f64::MAX, f64::MIN, 0.0), - (0.0, 0.0, 0.0), - (-f64::MAX, -f64::MIN, f64::EPSILON), - ]; - - for (x, y, z) in cases { - let p = Point::new(x, y, z).expect("Failed to create point with extreme values"); - let coords = p.coordinates(); - assert_eq!(coords, (x, y, z)); - p.delete().expect("Failed to delete point"); - } - } - - #[test] - fn point_coordinates_immutability() { - let p = Point::new(1.5, 2.5, 3.5).expect("Failed to create point"); - - let coords1 = p.coordinates(); - let coords2 = p.coordinates(); - let coords3 = p.coordinates(); - - assert_eq!(coords1, coords2); - assert_eq!(coords2, coords3); - assert_eq!(coords1, (1.5, 2.5, 3.5)); - } - - #[test] - fn point_automatic_cleanup_on_drop() { + fn automatic_cleanup() { let coords = { - let p = Point::new(7.0, 8.0, 9.0).expect("Failed to create point"); + let p = Point::new(7.0, 8.0, 9.0).expect("Creation failed"); p.coordinates() }; - assert_eq!(coords, (7.0, 8.0, 9.0)); - - // Verify we can still create points after automatic cleanup - let p2 = Point::new(10.0, 11.0, 12.0).expect("Failed to create point after drop"); - assert_eq!(p2.coordinates(), (10.0, 11.0, 12.0)); } #[test] - fn point_multiple_instances_independent() { - let p1 = Point::new(1.0, 1.0, 1.0).expect("Failed to create point 1"); - let p2 = Point::new(2.0, 2.0, 2.0).expect("Failed to create point 2"); - let p3 = Point::new(3.0, 3.0, 3.0).expect("Failed to create point 3"); + fn multiple_instances() { + let p1 = Point::new(1.0, 1.0, 1.0).expect("Creation failed"); + let p2 = Point::new(2.0, 2.0, 2.0).expect("Creation failed"); assert_eq!(p1.coordinates(), (1.0, 1.0, 1.0)); assert_eq!(p2.coordinates(), (2.0, 2.0, 2.0)); - assert_eq!(p3.coordinates(), (3.0, 3.0, 3.0)); - - p2.delete().expect("Failed to delete p2"); - p1.delete().expect("Failed to delete p1"); - p3.delete().expect("Failed to delete p3"); } #[test] - fn point_debug_format() { - let p = Point::new(1.1, 2.2, 3.3).expect("Failed to create point"); + fn debug_format() { + let p = Point::new(1.1, 2.2, 3.3).expect("Creation failed"); let debug_output = format!("{:?}", p); - assert!(debug_output.contains("Point")); + assert!(debug_output.starts_with("Point(")); assert!(debug_output.contains("1.1")); assert!(debug_output.contains("2.2")); assert!(debug_output.contains("3.3")); } #[test] - fn point_rapid_creation_deletion_cycle_stress_test() { - for i in 0..100 { - let p = Point::new(i as f64, i as f64, i as f64) - .expect(&format!("Failed to create point in iteration {}", i)); - assert_eq!(p.coordinates(), (i as f64, i as f64, i as f64)); - p.delete() - .expect(&format!("Failed to delete point in iteration {}", i)); + fn boundary_values() { + let cases = [(0.0, 0.0, 0.0), (f64::MAX, f64::MIN, 0.0)]; + + for (x, y, z) in cases { + let p = Point::new(x, y, z).expect("Creation with boundary values failed"); + assert_eq!(p.coordinates(), (x, y, z)); } } }