#include "vec3.h" #include #include #include // Test fixture for Vec3 tests class Vec3Test : public ::testing::Test { protected: // Test vectors that will be used across multiple tests Vec3 intVec1, intVec2; Vec3 floatVec1, floatVec2; Vec3 doubleVec1, doubleVec2; void SetUp() override { // Initialize test vectors intVec1 = {1, 2, 3}; intVec2 = {4, 5, 6}; floatVec1 = {1.5f, 2.5f, 3.5f}; floatVec2 = {4.5f, 5.5f, 6.5f}; doubleVec1 = {1.5, 2.5, 3.5}; doubleVec2 = {4.5, 5.5, 6.5}; } }; // Test vector addition TEST_F(Vec3Test, Addition) { // Test integer vectors auto intResult = intVec1 + intVec2; EXPECT_EQ(intResult.x, 5); EXPECT_EQ(intResult.y, 7); EXPECT_EQ(intResult.z, 9); // Test float vectors auto floatResult = floatVec1 + floatVec2; EXPECT_FLOAT_EQ(floatResult.x, 6.0f); EXPECT_FLOAT_EQ(floatResult.y, 8.0f); EXPECT_FLOAT_EQ(floatResult.z, 10.0f); // Test double vectors auto doubleResult = doubleVec1 + doubleVec2; EXPECT_DOUBLE_EQ(doubleResult.x, 6.0); EXPECT_DOUBLE_EQ(doubleResult.y, 8.0); EXPECT_DOUBLE_EQ(doubleResult.z, 10.0); } // Test vector subtraction TEST_F(Vec3Test, Subtraction) { // Test integer vectors auto intResult = intVec2 - intVec1; EXPECT_EQ(intResult.x, 3); EXPECT_EQ(intResult.y, 3); EXPECT_EQ(intResult.z, 3); // Test float vectors auto floatResult = floatVec2 - floatVec1; EXPECT_FLOAT_EQ(floatResult.x, 3.0f); EXPECT_FLOAT_EQ(floatResult.y, 3.0f); EXPECT_FLOAT_EQ(floatResult.z, 3.0f); // Test double vectors auto doubleResult = doubleVec2 - doubleVec1; EXPECT_DOUBLE_EQ(doubleResult.x, 3.0); EXPECT_DOUBLE_EQ(doubleResult.y, 3.0); EXPECT_DOUBLE_EQ(doubleResult.z, 3.0); } // Test vector scaling TEST_F(Vec3Test, Scale) { // Test integer scaling Vec3 intVecScaled = intVec1; intVecScaled.scale(2); EXPECT_EQ(intVecScaled.x, 2); EXPECT_EQ(intVecScaled.y, 4); EXPECT_EQ(intVecScaled.z, 6); // Test float scaling Vec3 floatVecScaled = floatVec1; floatVecScaled.scale(2.0f); EXPECT_FLOAT_EQ(floatVecScaled.x, 3.0f); EXPECT_FLOAT_EQ(floatVecScaled.y, 5.0f); EXPECT_FLOAT_EQ(floatVecScaled.z, 7.0f); // Test double scaling Vec3 doubleVecScaled = doubleVec1; doubleVecScaled.scale(2.0); EXPECT_DOUBLE_EQ(doubleVecScaled.x, 3.0); EXPECT_DOUBLE_EQ(doubleVecScaled.y, 5.0); EXPECT_DOUBLE_EQ(doubleVecScaled.z, 7.0); // Test scaling by zero Vec3 zeroScaled = floatVec1; zeroScaled.scale(0.0f); EXPECT_FLOAT_EQ(zeroScaled.x, 0.0f); EXPECT_FLOAT_EQ(zeroScaled.y, 0.0f); EXPECT_FLOAT_EQ(zeroScaled.z, 0.0f); // Test scaling by negative number Vec3 negScaled = intVec1; negScaled.scale(-1); EXPECT_EQ(negScaled.x, -1); EXPECT_EQ(negScaled.y, -2); EXPECT_EQ(negScaled.z, -3); } // Test dot product TEST_F(Vec3Test, DotProduct) { // Test integer dot product int intDot = intVec1.dot(intVec2); EXPECT_EQ(intDot, 32); // 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32 // Test float dot product float floatDot = floatVec1.dot(floatVec2); EXPECT_FLOAT_EQ( floatDot, 43.25f); // 1.5*4.5 + 2.5*5.5 + 3.5*6.5 = 6.75 + 13.75 + 22.75 = 43.25 // Test double dot product double doubleDot = doubleVec1.dot(doubleVec2); EXPECT_DOUBLE_EQ(doubleDot, 43.25); // Same calculation as float // Test dot product with self (should equal squared length) int selfDot = intVec1.dot(intVec1); EXPECT_EQ(selfDot, 14); // 1*1 + 2*2 + 3*3 = 1 + 4 + 9 = 14 // Test dot product with zero vector Vec3 zeroVec = {0, 0, 0}; EXPECT_EQ(intVec1.dot(zeroVec), 0); } // Test cross product TEST_F(Vec3Test, CrossProduct) { // Test integer cross product auto intCross = intVec1.cross(intVec2); EXPECT_EQ(intCross.x, -3); // (2*6 - 3*5) = 12 - 15 = -3 EXPECT_EQ(intCross.y, 6); // (3*4 - 1*6) = 12 - 6 = 6 EXPECT_EQ(intCross.z, -3); // (1*5 - 2*4) = 5 - 8 = -3 // Test float cross product auto floatCross = floatVec1.cross(floatVec2); EXPECT_FLOAT_EQ(floatCross.x, -3.0f); // (2.5*6.5 - 3.5*5.5) = 16.25 - 19.25 = -3 EXPECT_FLOAT_EQ(floatCross.y, 6.0f); // (3.5*4.5 - 1.5*6.5) = 15.75 - 9.75 = 6 EXPECT_FLOAT_EQ(floatCross.z, -3.0f); // (1.5*5.5 - 2.5*4.5) = 8.25 - 11.25 = -3 // Test double cross product auto doubleCross = doubleVec1.cross(doubleVec2); EXPECT_DOUBLE_EQ(doubleCross.x, -3.0); EXPECT_DOUBLE_EQ(doubleCross.y, 6.0); EXPECT_DOUBLE_EQ(doubleCross.z, -3.0); // Test cross product with self (should be zero) auto selfCross = intVec1.cross(intVec1); EXPECT_EQ(selfCross.x, 0); EXPECT_EQ(selfCross.y, 0); EXPECT_EQ(selfCross.z, 0); // Test cross product of standard basis vectors (i × j = k) Vec3 i = {1, 0, 0}; Vec3 j = {0, 1, 0}; Vec3 k = {0, 0, 1}; auto i_cross_j = i.cross(j); EXPECT_EQ(i_cross_j.x, 0); EXPECT_EQ(i_cross_j.y, 0); EXPECT_EQ(i_cross_j.z, 1); auto j_cross_k = j.cross(k); EXPECT_EQ(j_cross_k.x, 1); EXPECT_EQ(j_cross_k.y, 0); EXPECT_EQ(j_cross_k.z, 0); auto k_cross_i = k.cross(i); EXPECT_EQ(k_cross_i.x, 0); EXPECT_EQ(k_cross_i.y, 1); EXPECT_EQ(k_cross_i.z, 0); } // Test with edge cases TEST_F(Vec3Test, EdgeCases) { // Test with max values Vec3 maxVec = {std::numeric_limits::max(), std::numeric_limits::max(), std::numeric_limits::max()}; // Addition with max values may overflow, but we want to test the operation // works auto maxAddition = maxVec + intVec1; // Test with min values Vec3 minVec = {std::numeric_limits::min(), std::numeric_limits::min(), std::numeric_limits::min()}; // Subtraction with min values may underflow, but we want to test the // operation works auto minSubtraction = minVec - intVec1; // Test with mixed values Vec3 mixedVec1 = {0.0, -1.0, std::numeric_limits::infinity()}; Vec3 mixedVec2 = {-0.0, 1.0, -std::numeric_limits::infinity()}; auto mixedAddition = mixedVec1 + mixedVec2; // 0.0 + (-0.0) = 0.0 EXPECT_DOUBLE_EQ(mixedAddition.x, 0.0); // -1.0 + 1.0 = 0.0 EXPECT_DOUBLE_EQ(mixedAddition.y, 0.0); // inf + (-inf) = NaN EXPECT_TRUE(std::isnan(mixedAddition.z)); // Test with NaN Vec3 nanVec = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; // Any operation with NaN should result in NaN auto nanResult = doubleVec1 + nanVec; EXPECT_TRUE(std::isnan(nanResult.x)); EXPECT_TRUE(std::isnan(nanResult.y)); EXPECT_TRUE(std::isnan(nanResult.z)); } // Main function that runs the tests int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }