Files
XCEngine/tests/math/test_vector.cpp

347 lines
8.9 KiB
C++
Raw Normal View History

#include <gtest/gtest.h>
#include <XCEngine/Math/Vector2.h>
#include <XCEngine/Math/Vector3.h>
#include <XCEngine/Math/Vector4.h>
#include <XCEngine/Math/Math.h>
using namespace XCEngine::Math;
namespace {
// ============================================================
// Vector2 Tests
// ============================================================
TEST(Math_Vector2, DefaultConstructor_InitializesToZero) {
Vector2 v;
EXPECT_FLOAT_EQ(v.x, 0.0f);
EXPECT_FLOAT_EQ(v.y, 0.0f);
}
TEST(Math_Vector2, ParameterConstructor) {
Vector2 v(3.0f, 4.0f);
EXPECT_FLOAT_EQ(v.x, 3.0f);
EXPECT_FLOAT_EQ(v.y, 4.0f);
}
TEST(Math_Vector2, StaticFactories) {
EXPECT_EQ(Vector2::Zero(), Vector2(0, 0));
EXPECT_EQ(Vector2::One(), Vector2(1, 1));
EXPECT_EQ(Vector2::Up(), Vector2(0, 1));
EXPECT_EQ(Vector2::Down(), Vector2(0, -1));
EXPECT_EQ(Vector2::Right(), Vector2(1, 0));
EXPECT_EQ(Vector2::Left(), Vector2(-1, 0));
}
TEST(Math_Vector2, Dot_Orthogonal_ReturnsZero) {
EXPECT_FLOAT_EQ(Vector2::Dot(Vector2::Right(), Vector2::Up()), 0.0f);
}
TEST(Math_Vector2, Dot_SameDirection_ReturnsMagnitudeProduct) {
EXPECT_FLOAT_EQ(Vector2::Dot(Vector2(1, 0), Vector2(2, 0)), 2.0f);
}
TEST(Math_Vector2, Cross_ReturnsScalar) {
EXPECT_FLOAT_EQ(Vector2::Cross(Vector2::Right(), Vector2::Up()), 1.0f);
}
TEST(Math_Vector2, Magnitude) {
EXPECT_FLOAT_EQ(Vector2(3, 4).Magnitude(), 5.0f);
}
TEST(Math_Vector2, SqrMagnitude) {
EXPECT_FLOAT_EQ(Vector2(3, 4).SqrMagnitude(), 25.0f);
}
TEST(Math_Vector2, Normalize_NonZero_ReturnsUnitVector) {
Vector2 v = Vector2(3, 4).Normalized();
EXPECT_NEAR(v.Magnitude(), 1.0f, 1e-6f);
}
TEST(Math_Vector2, Normalize_ZeroVector_ReturnsZeroVector) {
Vector2 v = Vector2::Zero();
Vector2 normalized = Vector2::Normalize(v);
EXPECT_FLOAT_EQ(normalized.x, 0.0f);
EXPECT_FLOAT_EQ(normalized.y, 0.0f);
}
TEST(Math_Vector2, Lerp) {
Vector2 a(0, 0);
Vector2 b(10, 10);
Vector2 result = Vector2::Lerp(a, b, 0.5f);
EXPECT_FLOAT_EQ(result.x, 5.0f);
EXPECT_FLOAT_EQ(result.y, 5.0f);
}
TEST(Math_Vector2, Lerp_ClampsToZero) {
Vector2 a(0, 0);
Vector2 b(10, 10);
Vector2 result = Vector2::Lerp(a, b, -0.5f);
EXPECT_FLOAT_EQ(result.x, 0.0f);
}
TEST(Math_Vector2, Lerp_ClampsToOne) {
Vector2 a(0, 0);
Vector2 b(10, 10);
Vector2 result = Vector2::Lerp(a, b, 1.5f);
EXPECT_FLOAT_EQ(result.x, 10.0f);
}
TEST(Math_Vector2, MoveTowards) {
Vector2 current(0, 0);
Vector2 target(10, 0);
Vector2 result = Vector2::MoveTowards(current, target, 3.0f);
EXPECT_FLOAT_EQ(result.x, 3.0f);
EXPECT_FLOAT_EQ(result.y, 0.0f);
}
TEST(Math_Vector2, MoveTowards_AlreadyAtTarget) {
Vector2 current(10, 10);
Vector2 target(10, 10);
Vector2 result = Vector2::MoveTowards(current, target, 5.0f);
EXPECT_EQ(result, target);
}
TEST(Math_Vector2, Operators) {
Vector2 a(1, 2);
Vector2 b(3, 4);
Vector2 sum = a + b;
EXPECT_FLOAT_EQ(sum.x, 4.0f);
EXPECT_FLOAT_EQ(sum.y, 6.0f);
Vector2 diff = b - a;
EXPECT_FLOAT_EQ(diff.x, 2.0f);
EXPECT_FLOAT_EQ(diff.y, 2.0f);
Vector2 scaled = a * 2.0f;
EXPECT_FLOAT_EQ(scaled.x, 2.0f);
EXPECT_FLOAT_EQ(scaled.y, 4.0f);
Vector2 divided = a / 2.0f;
EXPECT_FLOAT_EQ(divided.x, 0.5f);
EXPECT_FLOAT_EQ(divided.y, 1.0f);
}
TEST(Math_Vector2, Equality) {
Vector2 a(1.0f, 2.0f);
Vector2 b(1.0f, 2.0f);
Vector2 c(1.0f, 3.0f);
EXPECT_TRUE(a == b);
EXPECT_FALSE(a == c);
}
// ============================================================
// Vector3 Tests
// ============================================================
TEST(Math_Vector3, DefaultConstructor_InitializesToZero) {
Vector3 v;
EXPECT_FLOAT_EQ(v.x, 0.0f);
EXPECT_FLOAT_EQ(v.y, 0.0f);
EXPECT_FLOAT_EQ(v.z, 0.0f);
}
TEST(Math_Vector3, ParameterConstructor) {
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);
}
TEST(Math_Vector3, StaticFactories) {
EXPECT_EQ(Vector3::Zero(), Vector3(0, 0, 0));
EXPECT_EQ(Vector3::One(), Vector3(1, 1, 1));
EXPECT_EQ(Vector3::Forward(), Vector3(0, 0, 1));
EXPECT_EQ(Vector3::Back(), Vector3(0, 0, -1));
EXPECT_EQ(Vector3::Up(), Vector3(0, 1, 0));
EXPECT_EQ(Vector3::Down(), Vector3(0, -1, 0));
EXPECT_EQ(Vector3::Right(), Vector3(1, 0, 0));
EXPECT_EQ(Vector3::Left(), Vector3(-1, 0, 0));
}
TEST(Math_Vector3, Dot_Orthogonal_ReturnsZero) {
EXPECT_FLOAT_EQ(Vector3::Dot(Vector3::Right(), Vector3::Up()), 0.0f);
}
TEST(Math_Vector3, Cross_Orthogonal_ReturnsPerpendicular) {
Vector3 result = Vector3::Cross(Vector3::Right(), Vector3::Up());
EXPECT_FLOAT_EQ(result.x, 0.0f);
EXPECT_FLOAT_EQ(result.y, 0.0f);
EXPECT_FLOAT_EQ(result.z, 1.0f);
}
TEST(Math_Vector3, Cross_SameVector_ReturnsZero) {
Vector3 result = Vector3::Cross(Vector3::Right(), Vector3::Right());
EXPECT_FLOAT_EQ(result.x, 0.0f);
EXPECT_FLOAT_EQ(result.y, 0.0f);
EXPECT_FLOAT_EQ(result.z, 0.0f);
}
TEST(Math_Vector3, Magnitude) {
EXPECT_FLOAT_EQ(Vector3(1, 2, 2).Magnitude(), 3.0f);
}
TEST(Math_Vector3, SqrMagnitude) {
EXPECT_FLOAT_EQ(Vector3(1, 2, 2).SqrMagnitude(), 9.0f);
}
TEST(Math_Vector3, Normalize) {
Vector3 v = Vector3(3, 4, 0).Normalized();
EXPECT_NEAR(v.Magnitude(), 1.0f, 1e-6f);
}
TEST(Math_Vector3, Lerp) {
Vector3 a(0, 0, 0);
Vector3 b(10, 10, 10);
Vector3 result = Vector3::Lerp(a, b, 0.5f);
EXPECT_FLOAT_EQ(result.x, 5.0f);
EXPECT_FLOAT_EQ(result.y, 5.0f);
EXPECT_FLOAT_EQ(result.z, 5.0f);
}
TEST(Math_Vector3, Project_OntoNormal) {
Vector3 v(1, 1, 0);
Vector3 normal(1, 0, 0);
Vector3 result = Vector3::Project(v, normal);
EXPECT_FLOAT_EQ(result.x, 1.0f);
EXPECT_FLOAT_EQ(result.y, 0.0f);
EXPECT_FLOAT_EQ(result.z, 0.0f);
}
TEST(Math_Vector3, ProjectOnPlane) {
Vector3 v(1, 1, 1);
Vector3 planeNormal(0, 0, 1);
Vector3 result = Vector3::ProjectOnPlane(v, planeNormal);
EXPECT_FLOAT_EQ(result.x, 1.0f);
EXPECT_FLOAT_EQ(result.y, 1.0f);
EXPECT_FLOAT_EQ(result.z, 0.0f);
}
TEST(Math_Vector3, Angle) {
float angle = Vector3::Angle(Vector3::Right(), Vector3::Up());
EXPECT_NEAR(angle, 90.0f, 1e-5f);
}
TEST(Math_Vector3, Reflect) {
Vector3 direction(1, -1, 0);
Vector3 normal(0, 1, 0);
Vector3 result = Vector3::Reflect(direction, normal);
EXPECT_FLOAT_EQ(result.x, 1.0f);
EXPECT_FLOAT_EQ(result.y, 1.0f);
EXPECT_FLOAT_EQ(result.z, 0.0f);
}
TEST(Math_Vector3, MoveTowards) {
Vector3 current(0, 0, 0);
Vector3 target(10, 0, 0);
Vector3 result = Vector3::MoveTowards(current, target, 4.0f);
EXPECT_FLOAT_EQ(result.x, 4.0f);
}
TEST(Math_Vector3, Operators) {
Vector3 a(1, 2, 3);
Vector3 b(4, 5, 6);
Vector3 sum = a + b;
EXPECT_FLOAT_EQ(sum.x, 5.0f);
EXPECT_FLOAT_EQ(sum.y, 7.0f);
EXPECT_FLOAT_EQ(sum.z, 9.0f);
Vector3 diff = b - a;
EXPECT_FLOAT_EQ(diff.x, 3.0f);
EXPECT_FLOAT_EQ(diff.y, 3.0f);
EXPECT_FLOAT_EQ(diff.z, 3.0f);
Vector3 scaled = a * 2.0f;
EXPECT_FLOAT_EQ(scaled.x, 2.0f);
EXPECT_FLOAT_EQ(scaled.y, 4.0f);
EXPECT_FLOAT_EQ(scaled.z, 6.0f);
}
TEST(Math_Vector3, IndexOperator) {
Vector3 v(1, 2, 3);
EXPECT_FLOAT_EQ(v[0], 1.0f);
EXPECT_FLOAT_EQ(v[1], 2.0f);
EXPECT_FLOAT_EQ(v[2], 3.0f);
}
// ============================================================
// Vector4 Tests
// ============================================================
TEST(Math_Vector4, DefaultConstructor_InitializesToZero) {
Vector4 v;
EXPECT_FLOAT_EQ(v.x, 0.0f);
EXPECT_FLOAT_EQ(v.y, 0.0f);
EXPECT_FLOAT_EQ(v.z, 0.0f);
EXPECT_FLOAT_EQ(v.w, 0.0f);
}
TEST(Math_Vector4, ParameterConstructor) {
Vector4 v(1.0f, 2.0f, 3.0f, 4.0f);
EXPECT_FLOAT_EQ(v.x, 1.0f);
EXPECT_FLOAT_EQ(v.y, 2.0f);
EXPECT_FLOAT_EQ(v.z, 3.0f);
EXPECT_FLOAT_EQ(v.w, 4.0f);
}
TEST(Math_Vector4, ConstructFromVector3) {
Vector3 v3(1, 2, 3);
Vector4 v(v3, 4.0f);
EXPECT_FLOAT_EQ(v.x, 1.0f);
EXPECT_FLOAT_EQ(v.y, 2.0f);
EXPECT_FLOAT_EQ(v.z, 3.0f);
EXPECT_FLOAT_EQ(v.w, 4.0f);
}
TEST(Math_Vector4, StaticFactories) {
EXPECT_EQ(Vector4::Zero(), Vector4(0, 0, 0, 0));
EXPECT_EQ(Vector4::One(), Vector4(1, 1, 1, 1));
}
TEST(Math_Vector4, Dot) {
Vector4 a(1, 2, 3, 4);
Vector4 b(2, 3, 4, 5);
float result = Vector4::Dot(a, b);
EXPECT_FLOAT_EQ(result, 40.0f);
}
TEST(Math_Vector4, ToVector3) {
Vector4 v(1, 2, 3, 4);
Vector3 v3 = v.ToVector3();
EXPECT_FLOAT_EQ(v3.x, 1.0f);
EXPECT_FLOAT_EQ(v3.y, 2.0f);
EXPECT_FLOAT_EQ(v3.z, 3.0f);
}
TEST(Math_Vector4, Operators) {
Vector4 a(1, 2, 3, 4);
Vector4 b(5, 6, 7, 8);
Vector4 sum = a + b;
EXPECT_FLOAT_EQ(sum.x, 6.0f);
EXPECT_FLOAT_EQ(sum.y, 8.0f);
EXPECT_FLOAT_EQ(sum.z, 10.0f);
EXPECT_FLOAT_EQ(sum.w, 12.0f);
Vector4 scaled = a * 2.0f;
EXPECT_FLOAT_EQ(scaled.x, 2.0f);
}
} // namespace