diff --git a/tests/UnitTestVector2.cpp b/tests/UnitTestVector2.cpp index 3e9740d..eb4051c 100644 --- a/tests/UnitTestVector2.cpp +++ b/tests/UnitTestVector2.cpp @@ -1,11 +1,11 @@ // // Created by Vlad on 02.09.2024. // -// -// Created by Vlad on 01.09.2024. -// + #include #include +#include // For std::isinf and std::isnan +#include // For FLT_MAX and FLT_MIN using namespace omath; @@ -81,6 +81,13 @@ TEST_F(UnitTestVector2, DivisionOperator) EXPECT_FLOAT_EQ(v3.y, 2.5f); } +TEST_F(UnitTestVector2, NegationOperator) +{ + constexpr Vector2 v3 = -Vector2(1.0f, 2.0f); + EXPECT_FLOAT_EQ(v3.x, -1.0f); + EXPECT_FLOAT_EQ(v3.y, -2.0f); +} + // Test compound assignment operators TEST_F(UnitTestVector2, AdditionAssignmentOperator) { @@ -110,12 +117,36 @@ TEST_F(UnitTestVector2, DivisionAssignmentOperator) EXPECT_FLOAT_EQ(v1.y, 1.0f); } -TEST_F(UnitTestVector2, NegationOperator) +// New tests for compound assignment with vectors +TEST_F(UnitTestVector2, MultiplicationAssignmentOperator_Vector) { - constexpr Vector2 v3 = -Vector2(1.0f, 2.0f); - EXPECT_FLOAT_EQ(v3.x, -1.0f); - EXPECT_FLOAT_EQ(v3.y, -2.0f); + v1 *= v2; + EXPECT_FLOAT_EQ(v1.x, 1.0f * 4.0f); + EXPECT_FLOAT_EQ(v1.y, 2.0f * 5.0f); } + +TEST_F(UnitTestVector2, DivisionAssignmentOperator_Vector) +{ + v1 /= v2; + EXPECT_FLOAT_EQ(v1.x, 1.0f / 4.0f); + EXPECT_FLOAT_EQ(v1.y, 2.0f / 5.0f); +} + +// New tests for compound assignment with floats +TEST_F(UnitTestVector2, AdditionAssignmentOperator_Float) +{ + v1 += 3.0f; + EXPECT_FLOAT_EQ(v1.x, 4.0f); + EXPECT_FLOAT_EQ(v1.y, 5.0f); +} + +TEST_F(UnitTestVector2, SubtractionAssignmentOperator_Float) +{ + v1 -= 1.0f; + EXPECT_FLOAT_EQ(v1.x, 0.0f); + EXPECT_FLOAT_EQ(v1.y, 1.0f); +} + // Test other member functions TEST_F(UnitTestVector2, DistTo) { @@ -123,24 +154,62 @@ TEST_F(UnitTestVector2, DistTo) EXPECT_FLOAT_EQ(dist, std::sqrt(18.0f)); } +TEST_F(UnitTestVector2, DistTo_SamePoint) +{ + const float dist = v1.DistTo(v1); + EXPECT_FLOAT_EQ(dist, 0.0f); +} + TEST_F(UnitTestVector2, DistToSqr) { constexpr float distSqr = Vector2(1.0f, 2.0f).DistToSqr(Vector2(4.0f, 5.0f)); EXPECT_FLOAT_EQ(distSqr, 18.0f); } +TEST_F(UnitTestVector2, DistToSqr_SamePoint) +{ + constexpr float distSqr = Vector2(1.0f, 2.0f).DistToSqr(Vector2(1.0f, 2.0f)); + EXPECT_FLOAT_EQ(distSqr, 0.0f); +} + TEST_F(UnitTestVector2, DotProduct) { constexpr float dot = Vector2(1.0f, 2.0f).Dot(Vector2(4.0f, 5.0f)); EXPECT_FLOAT_EQ(dot, 14.0f); } +TEST_F(UnitTestVector2, DotProduct_PerpendicularVectors) +{ + constexpr float dot = Vector2(1.0f, 0.0f).Dot(Vector2(0.0f, 1.0f)); + EXPECT_FLOAT_EQ(dot, 0.0f); +} + +TEST_F(UnitTestVector2, DotProduct_ParallelVectors) +{ + constexpr float dot = Vector2(1.0f, 1.0f).Dot(Vector2(2.0f, 2.0f)); + EXPECT_FLOAT_EQ(dot, 4.0f); +} + TEST_F(UnitTestVector2, Length) { const float length = v1.Length(); EXPECT_FLOAT_EQ(length, std::sqrt(5.0f)); } +TEST_F(UnitTestVector2, Length_ZeroVector) +{ + Vector2 v_zero(0.0f, 0.0f); + const float length = v_zero.Length(); + EXPECT_FLOAT_EQ(length, 0.0f); +} + +TEST_F(UnitTestVector2, Length_LargeValues) +{ + Vector2 v_large(FLT_MAX, FLT_MAX); + const float length = v_large.Length(); + EXPECT_TRUE(std::isinf(length)); +} + TEST_F(UnitTestVector2, LengthSqr) { constexpr float lengthSqr = Vector2(1.0f, 2.0f).LengthSqr(); @@ -149,17 +218,40 @@ TEST_F(UnitTestVector2, LengthSqr) TEST_F(UnitTestVector2, Abs) { - constexpr Vector2 v3 = Vector2(-1.0f, -2.0f).Abs(); + Vector2 v3(-1.0f, -2.0f); + v3.Abs(); EXPECT_FLOAT_EQ(v3.x, 1.0f); EXPECT_FLOAT_EQ(v3.y, 2.0f); } +TEST_F(UnitTestVector2, Abs_PositiveValues) +{ + Vector2 v3(1.0f, 2.0f); + v3.Abs(); + EXPECT_FLOAT_EQ(v3.x, 1.0f); + EXPECT_FLOAT_EQ(v3.y, 2.0f); +} + +TEST_F(UnitTestVector2, Abs_ZeroValues) +{ + Vector2 v3(0.0f, 0.0f); + v3.Abs(); + EXPECT_FLOAT_EQ(v3.x, 0.0f); + EXPECT_FLOAT_EQ(v3.y, 0.0f); +} + TEST_F(UnitTestVector2, Sum) { constexpr float sum = Vector2(1.0f, 2.0f).Sum(); EXPECT_FLOAT_EQ(sum, 3.0f); } +TEST_F(UnitTestVector2, Sum_NegativeValues) +{ + constexpr float sum = Vector2(-1.0f, -2.0f).Sum(); + EXPECT_FLOAT_EQ(sum, -3.0f); +} + TEST_F(UnitTestVector2, Normalized) { const Vector2 v3 = v1.Normalized(); @@ -167,6 +259,94 @@ TEST_F(UnitTestVector2, Normalized) EXPECT_NEAR(v3.y, 0.89443f, 0.0001f); } +TEST_F(UnitTestVector2, Normalized_ZeroVector) +{ + Vector2 v_zero(0.0f, 0.0f); + Vector2 v_norm = v_zero.Normalized(); + EXPECT_FLOAT_EQ(v_norm.x, 0.0f); + EXPECT_FLOAT_EQ(v_norm.y, 0.0f); +} + +// Test AsTuple method +TEST_F(UnitTestVector2, AsTuple) +{ + auto tuple = v1.AsTuple(); + EXPECT_FLOAT_EQ(std::get<0>(tuple), v1.x); + EXPECT_FLOAT_EQ(std::get<1>(tuple), v1.y); +} + +// Test division by zero +TEST_F(UnitTestVector2, DivisionOperator_DivideByZero) +{ + Vector2 v(1.0f, 2.0f); + float zero = 0.0f; + Vector2 result = v / zero; + EXPECT_TRUE(std::isinf(result.x) || std::isnan(result.x)); + EXPECT_TRUE(std::isinf(result.y) || std::isnan(result.y)); +} + +TEST_F(UnitTestVector2, DivisionAssignmentOperator_DivideByZero) +{ + Vector2 v(1.0f, 2.0f); + float zero = 0.0f; + v /= zero; + EXPECT_TRUE(std::isinf(v.x) || std::isnan(v.x)); + EXPECT_TRUE(std::isinf(v.y) || std::isnan(v.y)); +} + +TEST_F(UnitTestVector2, DivisionAssignmentOperator_VectorWithZero) +{ + Vector2 v(1.0f, 2.0f); + Vector2 v_zero(0.0f, 1.0f); + v /= v_zero; + EXPECT_TRUE(std::isinf(v.x) || std::isnan(v.x)); + EXPECT_FLOAT_EQ(v.y, 2.0f / 1.0f); +} + +// Test operations with infinity and NaN +TEST_F(UnitTestVector2, Operator_WithInfinity) +{ + Vector2 v_inf(INFINITY, INFINITY); + Vector2 result = v1 + v_inf; + EXPECT_TRUE(std::isinf(result.x)); + EXPECT_TRUE(std::isinf(result.y)); +} + +TEST_F(UnitTestVector2, Operator_WithNaN) +{ + Vector2 v_nan(NAN, NAN); + Vector2 result = v1 + v_nan; + EXPECT_TRUE(std::isnan(result.x)); + EXPECT_TRUE(std::isnan(result.y)); +} + +// Test negative values in arithmetic operations +TEST_F(UnitTestVector2, AdditionOperator_NegativeValues) +{ + Vector2 v_neg(-1.0f, -2.0f); + Vector2 result = v1 + v_neg; + EXPECT_FLOAT_EQ(result.x, 0.0f); + EXPECT_FLOAT_EQ(result.y, 0.0f); +} + +TEST_F(UnitTestVector2, SubtractionOperator_NegativeValues) +{ + Vector2 v_neg(-1.0f, -2.0f); + Vector2 result = v1 - v_neg; + EXPECT_FLOAT_EQ(result.x, 2.0f); + EXPECT_FLOAT_EQ(result.y, 4.0f); +} + +// Test negation of zero vector +TEST_F(UnitTestVector2, NegationOperator_ZeroVector) +{ + Vector2 v_zero(0.0f, 0.0f); + Vector2 result = -v_zero; + EXPECT_FLOAT_EQ(result.x, -0.0f); + EXPECT_FLOAT_EQ(result.y, -0.0f); +} + +// Static assertions (compile-time checks) static_assert(Vector2(1.0f, 2.0f).LengthSqr() == 5.0f, "LengthSqr should be 5"); static_assert(Vector2(1.0f, 2.0f).Dot(Vector2(4.0f, 5.0f)) == 14.0f, "Dot product should be 14"); static_assert(Vector2(4.0f, 5.0f).DistToSqr(Vector2(1.0f, 2.0f)) == 18.0f, "DistToSqr should be 18"); diff --git a/tests/UnitTestVector3.cpp b/tests/UnitTestVector3.cpp index daa59dc..282bdce 100644 --- a/tests/UnitTestVector3.cpp +++ b/tests/UnitTestVector3.cpp @@ -1,9 +1,12 @@ // // Created by Vlad on 01.09.2024. // + #include #include #include +#include // For FLT_MAX, FLT_MIN +#include // For std::numeric_limits using namespace omath; @@ -13,7 +16,7 @@ protected: Vector3 v1; Vector3 v2; - constexpr void SetUp() override + void SetUp() override { v1 = Vector3(1.0f, 2.0f, 3.0f); v2 = Vector3(4.0f, 5.0f, 6.0f); @@ -23,7 +26,7 @@ protected: // Test constructor and default values TEST_F(UnitTestVector3, Constructor_Default) { - constexpr Vector3 v; + Vector3 v; EXPECT_FLOAT_EQ(v.x, 0.0f); EXPECT_FLOAT_EQ(v.y, 0.0f); EXPECT_FLOAT_EQ(v.z, 0.0f); @@ -31,7 +34,7 @@ TEST_F(UnitTestVector3, Constructor_Default) TEST_F(UnitTestVector3, Constructor_Values) { - constexpr Vector3 v(1.0f, 2.0f, 3.0f); + Vector3 v(1.0f, 2.0f, 3.0f); EXPECT_FLOAT_EQ(v.x, 1.0f); EXPECT_FLOAT_EQ(v.y, 2.0f); EXPECT_FLOAT_EQ(v.z, 3.0f); @@ -40,14 +43,14 @@ TEST_F(UnitTestVector3, Constructor_Values) // Test equality operators TEST_F(UnitTestVector3, EqualityOperator) { - constexpr Vector3 v3(1.0f, 2.0f, 3.0f); + Vector3 v3(1.0f, 2.0f, 3.0f); EXPECT_TRUE(v1 == v3); EXPECT_FALSE(v1 == v2); } TEST_F(UnitTestVector3, InequalityOperator) { - constexpr Vector3 v3(1.0f, 2.0f, 3.0f); + Vector3 v3(1.0f, 2.0f, 3.0f); EXPECT_FALSE(v1 != v3); EXPECT_TRUE(v1 != v2); } @@ -55,7 +58,7 @@ TEST_F(UnitTestVector3, InequalityOperator) // Test arithmetic operators TEST_F(UnitTestVector3, AdditionOperator) { - constexpr Vector3 v3 = Vector3(1.0f, 2.0f, 3.0f) + Vector3(4.0f, 5.0f, 6.0f); + Vector3 v3 = Vector3(1.0f, 2.0f, 3.0f) + Vector3(4.0f, 5.0f, 6.0f); EXPECT_FLOAT_EQ(v3.x, 5.0f); EXPECT_FLOAT_EQ(v3.y, 7.0f); EXPECT_FLOAT_EQ(v3.z, 9.0f); @@ -63,39 +66,39 @@ TEST_F(UnitTestVector3, AdditionOperator) TEST_F(UnitTestVector3, SubtractionOperator) { - constexpr Vector3 v3 = Vector3(4.0f, 5.0f, 6.0f) - Vector3(1.0f, 2.0f, 3.0f); + Vector3 v3 = Vector3(4.0f, 5.0f, 6.0f) - Vector3(1.0f, 2.0f, 3.0f); EXPECT_FLOAT_EQ(v3.x, 3.0f); EXPECT_FLOAT_EQ(v3.y, 3.0f); EXPECT_FLOAT_EQ(v3.z, 3.0f); } -TEST_F(UnitTestVector3, MultiplicationOperator) +TEST_F(UnitTestVector3, MultiplicationOperator_Scalar) { - constexpr Vector3 v3 = Vector3(1.0f, 2.0f, 3.0f) * 2.0f; + Vector3 v3 = Vector3(1.0f, 2.0f, 3.0f) * 2.0f; EXPECT_FLOAT_EQ(v3.x, 2.0f); EXPECT_FLOAT_EQ(v3.y, 4.0f); EXPECT_FLOAT_EQ(v3.z, 6.0f); } -TEST_F(UnitTestVector3, MultiplicationWithVectorOperator) +TEST_F(UnitTestVector3, MultiplicationOperator_Vector) { - constexpr Vector3 v3 = Vector3(1.0f, 2.0f, 3.0f) * Vector3(4.0f, 5.0f, 6.0f); + Vector3 v3 = Vector3(1.0f, 2.0f, 3.0f) * Vector3(4.0f, 5.0f, 6.0f); EXPECT_FLOAT_EQ(v3.x, 4.0f); EXPECT_FLOAT_EQ(v3.y, 10.0f); EXPECT_FLOAT_EQ(v3.z, 18.0f); } -TEST_F(UnitTestVector3, DivisionOperator) +TEST_F(UnitTestVector3, DivisionOperator_Scalar) { - constexpr Vector3 v3 = Vector3(4.0f, 5.0f, 6.0f) / 2.0f; + Vector3 v3 = Vector3(4.0f, 5.0f, 6.0f) / 2.0f; EXPECT_FLOAT_EQ(v3.x, 2.0f); EXPECT_FLOAT_EQ(v3.y, 2.5f); EXPECT_FLOAT_EQ(v3.z, 3.0f); } -TEST_F(UnitTestVector3, DivisionWithVectorOperator) +TEST_F(UnitTestVector3, DivisionOperator_Vector) { - constexpr Vector3 v3 = Vector3(4.0f, 5.0f, 6.0f) / Vector3(1.0f, 2.0f, 3.0f); + Vector3 v3 = Vector3(4.0f, 5.0f, 6.0f) / Vector3(1.0f, 2.0f, 3.0f); EXPECT_FLOAT_EQ(v3.x, 4.0f); EXPECT_FLOAT_EQ(v3.y, 2.5f); EXPECT_FLOAT_EQ(v3.z, 2.0f); @@ -118,7 +121,7 @@ TEST_F(UnitTestVector3, SubtractionAssignmentOperator) EXPECT_FLOAT_EQ(v1.z, -3.0f); } -TEST_F(UnitTestVector3, MultiplicationAssignmentOperator) +TEST_F(UnitTestVector3, MultiplicationAssignmentOperator_Scalar) { v1 *= 2.0f; EXPECT_FLOAT_EQ(v1.x, 2.0f); @@ -126,7 +129,7 @@ TEST_F(UnitTestVector3, MultiplicationAssignmentOperator) EXPECT_FLOAT_EQ(v1.z, 6.0f); } -TEST_F(UnitTestVector3, MultiplicationWithVectorAssignmentOperator) +TEST_F(UnitTestVector3, MultiplicationAssignmentOperator_Vector) { v1 *= v2; EXPECT_FLOAT_EQ(v1.x, 4.0f); @@ -134,7 +137,7 @@ TEST_F(UnitTestVector3, MultiplicationWithVectorAssignmentOperator) EXPECT_FLOAT_EQ(v1.z, 18.0f); } -TEST_F(UnitTestVector3, DivisionAssignmentOperator) +TEST_F(UnitTestVector3, DivisionAssignmentOperator_Scalar) { v1 /= 2.0f; EXPECT_FLOAT_EQ(v1.x, 0.5f); @@ -142,7 +145,7 @@ TEST_F(UnitTestVector3, DivisionAssignmentOperator) EXPECT_FLOAT_EQ(v1.z, 1.5f); } -TEST_F(UnitTestVector3, DivisionWithVectorAssignmentOperator) +TEST_F(UnitTestVector3, DivisionAssignmentOperator_Vector) { v1 /= v2; EXPECT_FLOAT_EQ(v1.x, 0.25f); @@ -152,7 +155,7 @@ TEST_F(UnitTestVector3, DivisionWithVectorAssignmentOperator) TEST_F(UnitTestVector3, NegationOperator) { - constexpr Vector3 v3 = -Vector3(1.0f, 2.0f, 3.0f); + Vector3 v3 = -Vector3(1.0f, 2.0f, 3.0f); EXPECT_FLOAT_EQ(v3.x, -1.0f); EXPECT_FLOAT_EQ(v3.y, -2.0f); EXPECT_FLOAT_EQ(v3.z, -3.0f); @@ -161,25 +164,26 @@ TEST_F(UnitTestVector3, NegationOperator) // Test other member functions TEST_F(UnitTestVector3, DistToSqr) { - constexpr float distSqr = Vector3(1.0f, 2.0f, 3.0f).DistToSqr(Vector3(4.0f, 5.0f, 6.0f)); + float distSqr = Vector3(1.0f, 2.0f, 3.0f).DistToSqr(Vector3(4.0f, 5.0f, 6.0f)); EXPECT_FLOAT_EQ(distSqr, 27.0f); } TEST_F(UnitTestVector3, DotProduct) { - constexpr float dot = Vector3(1.0f, 2.0f, 3.0f).Dot(Vector3(4.0f, 5.0f, 6.0f)); + float dot = Vector3(1.0f, 2.0f, 3.0f).Dot(Vector3(4.0f, 5.0f, 6.0f)); EXPECT_FLOAT_EQ(dot, 32.0f); } TEST_F(UnitTestVector3, LengthSqr) { - constexpr float lengthSqr = Vector3(1.0f, 2.0f, 3.0f).LengthSqr(); + float lengthSqr = Vector3(1.0f, 2.0f, 3.0f).LengthSqr(); EXPECT_FLOAT_EQ(lengthSqr, 14.0f); } TEST_F(UnitTestVector3, Abs) { - constexpr Vector3 v3 = Vector3(-1.0f, -2.0f, -3.0f).Abs(); + Vector3 v3 = Vector3(-1.0f, -2.0f, -3.0f); + v3.Abs(); EXPECT_FLOAT_EQ(v3.x, 1.0f); EXPECT_FLOAT_EQ(v3.y, 2.0f); EXPECT_FLOAT_EQ(v3.z, 3.0f); @@ -187,25 +191,203 @@ TEST_F(UnitTestVector3, Abs) TEST_F(UnitTestVector3, Sum) { - constexpr float sum = Vector3(1.0f, 2.0f, 3.0f).Sum(); + float sum = Vector3(1.0f, 2.0f, 3.0f).Sum(); EXPECT_FLOAT_EQ(sum, 6.0f); } TEST_F(UnitTestVector3, Sum2D) { - constexpr float sum2D = Vector3(1.0f, 2.0f, 3.0f).Sum2D(); + float sum2D = Vector3(1.0f, 2.0f, 3.0f).Sum2D(); EXPECT_FLOAT_EQ(sum2D, 3.0f); } TEST_F(UnitTestVector3, CrossProduct) { - constexpr Vector3 v3 = Vector3(1.0f, 2.0f, 3.0f).Cross(Vector3(4.0f, 5.0f, 6.0f)); + Vector3 v3 = Vector3(1.0f, 2.0f, 3.0f).Cross(Vector3(4.0f, 5.0f, 6.0f)); EXPECT_FLOAT_EQ(v3.x, -3.0f); EXPECT_FLOAT_EQ(v3.y, 6.0f); EXPECT_FLOAT_EQ(v3.z, -3.0f); } -// Test constexpr with static_assert +// New tests to cover corner cases + +// Test operations with zero vectors +TEST_F(UnitTestVector3, Addition_WithZeroVector) +{ + Vector3 v_zero(0.0f, 0.0f, 0.0f); + Vector3 result = v1 + v_zero; + EXPECT_FLOAT_EQ(result.x, v1.x); + EXPECT_FLOAT_EQ(result.y, v1.y); + EXPECT_FLOAT_EQ(result.z, v1.z); +} + +TEST_F(UnitTestVector3, Subtraction_WithZeroVector) +{ + Vector3 v_zero(0.0f, 0.0f, 0.0f); + Vector3 result = v1 - v_zero; + EXPECT_FLOAT_EQ(result.x, v1.x); + EXPECT_FLOAT_EQ(result.y, v1.y); + EXPECT_FLOAT_EQ(result.z, v1.z); +} + +TEST_F(UnitTestVector3, Multiplication_WithZeroVector) +{ + Vector3 v_zero(0.0f, 0.0f, 0.0f); + Vector3 result = v1 * v_zero; + EXPECT_FLOAT_EQ(result.x, 0.0f); + EXPECT_FLOAT_EQ(result.y, 0.0f); + EXPECT_FLOAT_EQ(result.z, 0.0f); +} + +TEST_F(UnitTestVector3, Division_ByZeroVector) +{ + Vector3 v_zero(0.0f, 0.0f, 0.0f); + Vector3 result = v1 / v_zero; + EXPECT_TRUE(std::isinf(result.x) || std::isnan(result.x)); + EXPECT_TRUE(std::isinf(result.y) || std::isnan(result.y)); + EXPECT_TRUE(std::isinf(result.z) || std::isnan(result.z)); +} + +TEST_F(UnitTestVector3, Division_ByZeroScalar) +{ + float zero = 0.0f; + Vector3 result = v1 / zero; + EXPECT_TRUE(std::isinf(result.x) || std::isnan(result.x)); + EXPECT_TRUE(std::isinf(result.y) || std::isnan(result.y)); + EXPECT_TRUE(std::isinf(result.z) || std::isnan(result.z)); +} + +// Test operations with infinity +TEST_F(UnitTestVector3, Addition_WithInfinity) +{ + Vector3 v_inf(INFINITY, INFINITY, INFINITY); + Vector3 result = v1 + v_inf; + EXPECT_TRUE(std::isinf(result.x)); + EXPECT_TRUE(std::isinf(result.y)); + EXPECT_TRUE(std::isinf(result.z)); +} + +TEST_F(UnitTestVector3, Subtraction_WithInfinity) +{ + Vector3 v_inf(INFINITY, INFINITY, INFINITY); + Vector3 result = v1 - v_inf; + EXPECT_TRUE(std::isinf(result.x)); + EXPECT_TRUE(std::isinf(result.y)); + EXPECT_TRUE(std::isinf(result.z)); +} + +// Test operations with NaN +TEST_F(UnitTestVector3, Multiplication_WithNaN) +{ + Vector3 v_nan(NAN, NAN, NAN); + Vector3 result = v1 * v_nan; + EXPECT_TRUE(std::isnan(result.x)); + EXPECT_TRUE(std::isnan(result.y)); + EXPECT_TRUE(std::isnan(result.z)); +} + +TEST_F(UnitTestVector3, Division_WithNaN) +{ + Vector3 v_nan(NAN, NAN, NAN); + Vector3 result = v1 / v_nan; + EXPECT_TRUE(std::isnan(result.x)); + EXPECT_TRUE(std::isnan(result.y)); + EXPECT_TRUE(std::isnan(result.z)); +} + +// Test Length, Length2D, and Normalized +TEST_F(UnitTestVector3, Length) +{ + float length = v1.Length(); + EXPECT_FLOAT_EQ(length, std::sqrt(14.0f)); +} + +TEST_F(UnitTestVector3, Length_ZeroVector) +{ + Vector3 v_zero(0.0f, 0.0f, 0.0f); + float length = v_zero.Length(); + EXPECT_FLOAT_EQ(length, 0.0f); +} + +TEST_F(UnitTestVector3, Length_LargeValues) +{ + Vector3 v_large(FLT_MAX, FLT_MAX, FLT_MAX); + float length = v_large.Length(); + EXPECT_TRUE(std::isinf(length)); +} + +TEST_F(UnitTestVector3, Length2D) +{ + float length2D = v1.Length2D(); + EXPECT_FLOAT_EQ(length2D, std::sqrt(5.0f)); +} + +TEST_F(UnitTestVector3, Normalized) +{ + Vector3 v_norm = v1.Normalized(); + float length = v_norm.Length(); + EXPECT_NEAR(length, 1.0f, 0.0001f); +} + +TEST_F(UnitTestVector3, Normalized_ZeroVector) +{ + Vector3 v_zero(0.0f, 0.0f, 0.0f); + Vector3 v_norm = v_zero.Normalized(); + EXPECT_FLOAT_EQ(v_norm.x, 0.0f); + EXPECT_FLOAT_EQ(v_norm.y, 0.0f); + EXPECT_FLOAT_EQ(v_norm.z, 0.0f); +} + +// Test Cross Product edge cases +TEST_F(UnitTestVector3, CrossProduct_ParallelVectors) +{ + Vector3 v_a(1.0f, 2.0f, 3.0f); + Vector3 v_b = v_a * 2.0f; // Parallel to v_a + Vector3 cross = v_a.Cross(v_b); + EXPECT_FLOAT_EQ(cross.x, 0.0f); + EXPECT_FLOAT_EQ(cross.y, 0.0f); + EXPECT_FLOAT_EQ(cross.z, 0.0f); +} + +TEST_F(UnitTestVector3, CrossProduct_OrthogonalVectors) +{ + Vector3 v_a(1.0f, 0.0f, 0.0f); + Vector3 v_b(0.0f, 1.0f, 0.0f); + Vector3 cross = v_a.Cross(v_b); + EXPECT_FLOAT_EQ(cross.x, 0.0f); + EXPECT_FLOAT_EQ(cross.y, 0.0f); + EXPECT_FLOAT_EQ(cross.z, 1.0f); +} + +// Test negative values +TEST_F(UnitTestVector3, Addition_NegativeValues) +{ + Vector3 v_neg(-1.0f, -2.0f, -3.0f); + Vector3 result = v1 + v_neg; + EXPECT_FLOAT_EQ(result.x, 0.0f); + EXPECT_FLOAT_EQ(result.y, 0.0f); + EXPECT_FLOAT_EQ(result.z, 0.0f); +} + +TEST_F(UnitTestVector3, Subtraction_NegativeValues) +{ + Vector3 v_neg(-1.0f, -2.0f, -3.0f); + Vector3 result = v1 - v_neg; + EXPECT_FLOAT_EQ(result.x, 2.0f); + EXPECT_FLOAT_EQ(result.y, 4.0f); + EXPECT_FLOAT_EQ(result.z, 6.0f); +} + +// Test AsTuple method +TEST_F(UnitTestVector3, AsTuple) +{ + auto tuple = v1.AsTuple(); + EXPECT_FLOAT_EQ(std::get<0>(tuple), v1.x); + EXPECT_FLOAT_EQ(std::get<1>(tuple), v1.y); + EXPECT_FLOAT_EQ(std::get<2>(tuple), v1.z); +} + +// Static assertions (compile-time checks) static_assert(Vector3(1.0f, 2.0f, 3.0f).LengthSqr() == 14.0f, "LengthSqr should be 14"); static_assert(Vector3(1.0f, 2.0f, 3.0f).Dot(Vector3(4.0f, 5.0f, 6.0f)) == 32.0f, "Dot product should be 32"); static_assert(Vector3(4.0f, 5.0f, 6.0f).DistToSqr(Vector3(1.0f, 2.0f, 3.0f)) == 27.0f, "DistToSqr should be 27");