Files
Aethera/web_server/tests/Gallery_Frame_Atlas_Tests.cpp
T
2026-08-29 20:24:11 +08:00

91 lines
3.7 KiB
C++

#include <gtest/gtest.h>
#include <web_server/src/media/detail/Gallery_Frame_Atlas.hpp>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>
namespace aethera::web::media::detail {
namespace {
std::shared_ptr<const Plot_Pixel_Frame> solid_frame(
std::uint64_t sequence, std::uint32_t width,
std::uint32_t height, std::byte value) {
auto pixels = std::make_shared<std::vector<std::byte>>(
static_cast<std::size_t>(width) * height * 4U);
for (std::size_t offset = 0; offset < pixels->size(); offset += 4U) {
(*pixels)[offset] = value;
(*pixels)[offset + 3U] = std::byte{255};
}
return std::make_shared<const Plot_Pixel_Frame>(Plot_Pixel_Frame{
std::move(pixels), Plot_Pixel_Layout::rgba8, {}, sequence,
sequence, sequence, sequence, width, height});
}
std::shared_ptr<const Plot_Pixel_Frame> completion_frame(
std::uint64_t sequence, std::uint64_t rendered_sequence,
std::uint32_t width, std::uint32_t height) {
return std::make_shared<const Plot_Pixel_Frame>(Plot_Pixel_Frame{
{}, Plot_Pixel_Layout::rgba8, {}, sequence, sequence,
rendered_sequence, rendered_sequence, width, height});
}
}
TEST(Gallery_Frame_Atlas, Composes_Stable_Layout_And_Retains_Static_Image) {
Gallery_Frame_Atlas atlas(2, 2, 2, {"alpha", "beta", "gamma"});
const auto description = atlas.describe();
ASSERT_EQ(description.columns, 2U);
ASSERT_EQ(description.rows, 2U);
ASSERT_EQ(description.width, 4U);
ASSERT_EQ(description.height, 4U);
ASSERT_EQ(atlas.accept_frame(
0, solid_frame(1, 2, 2, std::byte{17})),
Gallery_Frame_Atlas::Accept_Frame_Result::accepted);
const auto first = atlas.compose();
EXPECT_EQ(first.fresh_tile_count, 1U);
EXPECT_EQ(first.pixels[0], std::byte{17});
const auto repeated = atlas.compose();
EXPECT_EQ(repeated.fresh_tile_count, 0U);
EXPECT_EQ(repeated.pixels[0], std::byte{17});
}
TEST(Gallery_Frame_Atlas,
Completion_Progress_Does_Not_Replace_The_Authoritative_Pixels) {
Gallery_Frame_Atlas atlas(2, 2, 1, {"alpha"});
ASSERT_EQ(atlas.accept_frame(
0, solid_frame(1, 2, 2, std::byte{23})),
Gallery_Frame_Atlas::Accept_Frame_Result::accepted);
static_cast<void>(atlas.compose());
ASSERT_EQ(atlas.accept_frame(
0, completion_frame(2, 1, 2, 2)),
Gallery_Frame_Atlas::Accept_Frame_Result::accepted);
const auto composition = atlas.compose();
ASSERT_EQ(composition.sources.size(), 1U);
EXPECT_EQ(composition.fresh_tile_count, 0U);
EXPECT_EQ(composition.missing_tile_count, 0U);
EXPECT_EQ(composition.pixels[0], std::byte{23});
EXPECT_EQ(composition.sources[0].completion_sequence, 2U);
EXPECT_EQ(composition.sources[0].rendered_sequence, 1U);
EXPECT_EQ(composition.sources[0].completion_count, 2U);
EXPECT_EQ(composition.sources[0].rendered_frame_count, 1U);
}
TEST(Gallery_Frame_Atlas, Applies_Out_Of_Order_Completions_In_Arrival_Order) {
Gallery_Frame_Atlas atlas(2, 2, 1, {"alpha"});
ASSERT_EQ(atlas.accept_frame(
0, solid_frame(2, 2, 2, std::byte{31})),
Gallery_Frame_Atlas::Accept_Frame_Result::accepted);
static_cast<void>(atlas.compose());
ASSERT_EQ(atlas.accept_frame(
0, solid_frame(1, 2, 2, std::byte{47})),
Gallery_Frame_Atlas::Accept_Frame_Result::accepted);
const auto composition = atlas.compose();
ASSERT_EQ(composition.sources.size(), 1U);
EXPECT_EQ(composition.rejected_frame_count, 0U);
EXPECT_EQ(composition.sources[0].completion_sequence, 1U);
EXPECT_EQ(composition.sources[0].completion_count, 2U);
EXPECT_EQ(composition.pixels[0], std::byte{47});
}
}