/** * @file test_math.cpp * @brief math 模块单元测试(Math 命名空间) * * * @version 1.0 * @author CodeBuddy * @date 26-09-03 * * @note */ #include #include "math/dl_math.h" #include "math/dl_random.h" #include "math/dl_texture_pack.h" TEST(MathTest, Pow) { EXPECT_EQ(dl::Math::Pow(2, 10), 1024); EXPECT_EQ(dl::Math::Pow64(2, 10), 1024ull); EXPECT_EQ(dl::Math::Pow32(2, 10), 1024u); } TEST(MathTest, SubU) { EXPECT_EQ(dl::Math::SubU(5u, 3u), 2u); EXPECT_EQ(dl::Math::SubU(3u, 5u), 0u); } TEST(MathTest, DisU) { EXPECT_EQ(dl::Math::DisU(3u, 5u), 2u); EXPECT_EQ(dl::Math::DisU(5u, 3u), 2u); } TEST(MathTest, IsPow2) { EXPECT_TRUE(dl::Math::IsPow2(8)); EXPECT_TRUE(dl::Math::IsPow2(1)); EXPECT_FALSE(dl::Math::IsPow2(0)); EXPECT_FALSE(dl::Math::IsPow2(6)); } TEST(MathTest, AlignPow2) { EXPECT_EQ(dl::Math::AlignPow2(5u, 4u), 8u); EXPECT_EQ(dl::Math::AlignPow2(8u, 4u), 8u); EXPECT_EQ(dl::Math::AlignPow2(1u, 4u), 4u); // 非 2 的幂返回 0 EXPECT_EQ(dl::Math::AlignPow2(5u, 3u), 0u); } TEST(MathTest, DistancePow2) { dl::Position a{ 0.0f, 0.0f }; dl::Position b{ 3.0f, 4.0f }; EXPECT_FLOAT_EQ(dl::Math::DistancePow2(a, b), 25.0f); EXPECT_FLOAT_EQ(dl::Math::Distance(b - a), 5.0f); } TEST(MathTest, DotProduct) { dl::Position a{ 1.0f, 2.0f }; dl::Position b{ 3.0f, 4.0f }; EXPECT_FLOAT_EQ(dl::Math::DotProduct(a, b), 11.0f); // 1*3 + 2*4 } TEST(MathTest, CrossProduct) { dl::Position2 a{ 1.0f, 0.0f }; dl::Position2 b{ 0.0f, 1.0f }; EXPECT_FLOAT_EQ(dl::Math::CrossProduct(a, b), 1.0f); } TEST(MathTest, IsLeapYear) { EXPECT_TRUE(dl::Math::IsLeapYear(2000)); EXPECT_TRUE(dl::Math::IsLeapYear(2024)); EXPECT_FALSE(dl::Math::IsLeapYear(1900)); EXPECT_FALSE(dl::Math::IsLeapYear(2023)); } TEST(MathTest, GetMouthDayNum) { EXPECT_EQ(dl::Math::GetMouthDayNum(2024, 2), 29); // 闰年二月 EXPECT_EQ(dl::Math::GetMouthDayNum(2023, 2), 28); // 平年二月 EXPECT_EQ(dl::Math::GetMouthDayNum(2024, 1), 31); EXPECT_EQ(dl::Math::GetMouthDayNum(2024, 4), 30); } //------------------------------算法------------------------------ TEST(MathTest, Clamp) { EXPECT_EQ(dl::clamp(5, 1, 3), 3); // 上界 EXPECT_EQ(dl::clamp(0, 1, 3), 1); // 下界 EXPECT_EQ(dl::clamp(2, 1, 3), 2); // 中间 EXPECT_FLOAT_EQ(dl::clamp(1.5f, 0.0f, 1.0f), 1.0f); EXPECT_FLOAT_EQ(dl::clamp(-0.5f, 0.0f, 1.0f), 0.0f); } TEST(MathTest, Saturate) { EXPECT_FLOAT_EQ(dl::saturate(0.5f), 0.5f); EXPECT_FLOAT_EQ(dl::saturate(2.0f), 1.0f); EXPECT_FLOAT_EQ(dl::saturate(-1.0f), 0.0f); EXPECT_TRUE(dl::is_saturate(0.5f)); EXPECT_FALSE(dl::is_saturate(1.5f)); } TEST(MathTest, Sign) { EXPECT_EQ(dl::sign(5), 1); EXPECT_EQ(dl::sign(-5), -1); EXPECT_EQ(dl::sign(0), 0); } TEST(MathTest, Cross3) { dl::Position3 a{ 1.0f, 0.0f, 0.0f }; dl::Position3 b{ 0.0f, 1.0f, 0.0f }; auto c = dl::cross(a, b); EXPECT_FLOAT_EQ(c[0], 0.0f); EXPECT_FLOAT_EQ(c[1], 0.0f); EXPECT_FLOAT_EQ(c[2], 1.0f); } TEST(MathTest, InsertPerNum) { EXPECT_EQ(dl::insert_per_num(std::string("1234567890"), ',', 3), "123,456,789,0"); EXPECT_EQ(dl::r_insert_per_num(std::string("123456789"), ',', 3), "123,456,789"); } TEST(MathTest, MakeSequence) { std::vector v; dl::make_sequence, int>(v, { {0, 3}, {5, 7} }); ASSERT_EQ(v.size(), 5u); EXPECT_EQ(v[0], 0); EXPECT_EQ(v[1], 1); EXPECT_EQ(v[2], 2); EXPECT_EQ(v[3], 5); EXPECT_EQ(v[4], 6); } //------------------------------Random------------------------------ TEST(RandomTest, SetSeed) { dl::Random::SetSeed(42); int a = dl::Random::Int(0, 100); dl::Random::SetSeed(42); int b = dl::Random::Int(0, 100); EXPECT_EQ(a, b); // 同种子结果一致 } TEST(RandomTest, IntRange) { dl::Random::SetSeed(1); for (int i = 0; i < 100; ++i) { int v = dl::Random::Int(10, 20); EXPECT_GE(v, 10); EXPECT_LE(v, 20); } } TEST(RandomTest, FloatRange) { dl::Random::SetSeed(1); for (int i = 0; i < 100; ++i) { float v = dl::Random::Float(0.0f, 1.0f); EXPECT_GE(v, 0.0f); EXPECT_LT(v, 1.0f); } } TEST(RandomTest, Percent) { dl::Random::SetSeed(1); EXPECT_TRUE(dl::Random::Percent(100)); EXPECT_FALSE(dl::Random::Percent(0)); } TEST(RandomTest, Select) { std::vector v = { 1, 2, 3, 4, 5 }; dl::Random::SetSeed(1); int sel = dl::Random::Select(v); EXPECT_GE(sel, 1); EXPECT_LE(sel, 5); } //------------------------------TexturePack------------------------------ TEST(TexturePackTest, Dynamic) { dl::TexturePack::Dynamic<2> pack; pack.Reset({ 100, 100 }); dl::RectU r1; EXPECT_TRUE(pack.Add({ 30, 30 }, r1)); EXPECT_EQ(r1[0], 0u); EXPECT_EQ(r1[1], 0u); EXPECT_EQ(r1[2], 30u); EXPECT_EQ(r1[3], 30u); dl::RectU r2; EXPECT_TRUE(pack.Add({ 30, 30 }, r2)); EXPECT_EQ(r2[0], 30u); // 同一行,x 偏移 EXPECT_EQ(r2[1], 0u); dl::RectU r3; EXPECT_TRUE(pack.Add({ 30, 30 }, r3)); EXPECT_EQ(r3[0], 60u); EXPECT_EQ(r3[1], 0u); dl::RectU r4; EXPECT_TRUE(pack.Add({ 30, 30 }, r4)); EXPECT_EQ(r4[0], 0u); // 换行 EXPECT_EQ(r4[1], 30u); } TEST(TexturePackTest, Static) { dl::TexturePack::Static pack; pack.SetSize({ 100, 100 }); std::list boxes = { {50, 50}, {50, 50}, {100, 50} }; std::vector results; pack.Calc(boxes, [](const dl::Size& s) { return s; }, [&](const dl::Size& s, const dl::PointU& lt) { results.push_back(lt); }); // 3 个箱子总面积 10000 = 100*100,能全部放下 EXPECT_TRUE(boxes.empty()); EXPECT_EQ(results.size(), 3u); }