140 lines
6.3 KiB
C++
140 lines
6.3 KiB
C++
#include "../app/Gallery_Plot_Session.h"
|
|
#include "../app/Gallery_Protocol.h"
|
|
#include "../app/Web_Event_Adapter.h"
|
|
#include "../app/Web_Plot_Session.h"
|
|
#include "../app/common/Pixel_Frame.h"
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <variant>
|
|
|
|
namespace renderive::web {
|
|
namespace {
|
|
std::uint32_t read_u32_le(const std::string& value, std::size_t offset) {
|
|
return static_cast<std::uint8_t>(value[offset]) |
|
|
(static_cast<std::uint32_t>(static_cast<std::uint8_t>(value[offset + 1])) << 8U) |
|
|
(static_cast<std::uint32_t>(static_cast<std::uint8_t>(value[offset + 2])) << 16U) |
|
|
(static_cast<std::uint32_t>(static_cast<std::uint8_t>(value[offset + 3])) << 24U);
|
|
}
|
|
|
|
TEST(RenderiveWebBridge, DecodesTransportAndPointerEvents) {
|
|
const auto resize = Web_Event_Adapter::decode(
|
|
R"({"category":"event","type":"resize","width":640,"height":360})");
|
|
ASSERT_TRUE(resize);
|
|
ASSERT_TRUE(std::holds_alternative<Viewport_Resize>(*resize));
|
|
EXPECT_EQ(std::get<Viewport_Resize>(*resize).size.width, 640);
|
|
EXPECT_EQ(std::get<Viewport_Resize>(*resize).size.height, 360);
|
|
|
|
const auto pointer = Web_Event_Adapter::decode(
|
|
R"({"category":"event","type":"pointer_move","x":12.5,"y":7.25})");
|
|
ASSERT_TRUE(pointer);
|
|
ASSERT_TRUE(std::holds_alternative<Pointer_Event>(*pointer));
|
|
EXPECT_DOUBLE_EQ(std::get<Pointer_Event>(*pointer).position.x, 12.5);
|
|
EXPECT_FALSE(Web_Event_Adapter::decode(R"({"type":"frame"})"));
|
|
}
|
|
|
|
TEST(RenderiveWebBridge, EncodesRvp2PixelFrames) {
|
|
const std::string frame = make_rgba8_pixel_frame(4, 3, 9);
|
|
ASSERT_EQ(frame.size(), pixel_frame_header_size + 4U * 3U * 4U);
|
|
EXPECT_EQ(frame.substr(0, 4), "RVP2");
|
|
EXPECT_EQ(read_u32_le(frame, 4), 4U);
|
|
EXPECT_EQ(read_u32_le(frame, 8), 3U);
|
|
EXPECT_EQ(read_u32_le(frame, 12), 16U);
|
|
}
|
|
|
|
TEST(RenderiveWebBridge, CurrentTwoDimensionalSceneRendersAfterResize) {
|
|
Web_Plot_Session session;
|
|
EXPECT_FALSE(session.handle(Viewport_Resize{{320, 200}}));
|
|
const auto response = session.handle(Frame_Request{});
|
|
ASSERT_TRUE(response);
|
|
ASSERT_EQ(response->type, Web_Response_Type::Pixels);
|
|
ASSERT_GE(response->payload.size(), pixel_frame_header_size);
|
|
EXPECT_EQ(response->payload.substr(0, 4), "RVP2");
|
|
EXPECT_EQ(read_u32_le(response->payload, 4), 320U);
|
|
EXPECT_EQ(read_u32_le(response->payload, 8), 200U);
|
|
}
|
|
|
|
TEST(RenderiveWebGallery, CatalogUsesOneDefaultPageAndThreeDynamicStrategies) {
|
|
const auto catalog = nlohmann::json::parse(Gallery_Protocol::catalog_json());
|
|
ASSERT_EQ(catalog.at("type"), "catalog");
|
|
EXPECT_EQ(catalog.at("cases").size(), 23U);
|
|
EXPECT_EQ(catalog.at("frame_modes").size(), 3U);
|
|
EXPECT_EQ(catalog.at("coverage").at("page_count"), 1U);
|
|
EXPECT_EQ(catalog.at("coverage").at("canvas_count"), 23U);
|
|
|
|
const auto request = Gallery_Protocol::open_request(
|
|
R"({"category":"event","type":"gallery_open","case":"spectrum","frame_mode":"low_latency"})");
|
|
ASSERT_TRUE(request);
|
|
EXPECT_EQ(request->case_id, "spectrum");
|
|
EXPECT_EQ(request->frame_mode, Gallery_Frame_Mode::Low_Latency);
|
|
EXPECT_FALSE(Gallery_Protocol::open_request(
|
|
R"({"category":"event","type":"gallery_open","case":"unknown","frame_mode":"low_latency"})"));
|
|
}
|
|
|
|
TEST(RenderiveWebGallery, TwoDimensionalGalleryPublishesStateAndPixels) {
|
|
Gallery_Plot_Session session;
|
|
const std::string open =
|
|
R"({"category":"event","type":"gallery_open","case":"spectrum","frame_mode":"low_latency"})";
|
|
const auto opened = session.handle(Gallery_Request{Gallery_Request_Kind::Open, open});
|
|
ASSERT_TRUE(opened);
|
|
ASSERT_EQ(opened->type, Web_Response_Type::Json);
|
|
const auto state = nlohmann::json::parse(opened->payload);
|
|
EXPECT_EQ(state.at("type"), "case_state");
|
|
EXPECT_EQ(state.at("case"), "spectrum");
|
|
const auto& controls = state.at("controls");
|
|
EXPECT_FALSE(controls.at("render_plan").at("nodes").empty());
|
|
EXPECT_TRUE(controls.at("performance_capture").at("controller").is_object());
|
|
EXPECT_TRUE(controls.at("performance_capture").at("sessions").is_array());
|
|
EXPECT_TRUE(controls.at("performance_capture").at("plans").is_array());
|
|
const auto& observer = state.at("telemetry").at("kernel_observer");
|
|
EXPECT_EQ(observer.at("state").at("viewport").at("width"), 560);
|
|
EXPECT_EQ(observer.at("renderable_count"), 4U);
|
|
|
|
const auto switched = session.handle(Gallery_Request{
|
|
Gallery_Request_Kind::Action,
|
|
R"({"category":"event","type":"gallery_action","action":"frame_strategy_manual"})"});
|
|
ASSERT_TRUE(switched);
|
|
const auto switched_state = nlohmann::json::parse(switched->payload);
|
|
EXPECT_EQ(switched_state.at("frame_mode"), "manual");
|
|
EXPECT_EQ(switched_state.at("telemetry").at("kernel_observer").at("mode"),
|
|
"manual");
|
|
|
|
const std::string render =
|
|
R"({"category":"event","type":"gallery_action","action":"mode_render"})";
|
|
const auto rendered = session.handle(
|
|
Gallery_Request{Gallery_Request_Kind::Action, render});
|
|
ASSERT_TRUE(rendered);
|
|
EXPECT_EQ(nlohmann::json::parse(rendered->payload).at("type"), "case_state");
|
|
|
|
const std::string capture =
|
|
R"({"category":"event","type":"gallery_action","action":"capture_next_frame"})";
|
|
const auto captured = session.handle(
|
|
Gallery_Request{Gallery_Request_Kind::Action, capture});
|
|
ASSERT_TRUE(captured);
|
|
const auto capture_state = nlohmann::json::parse(captured->payload);
|
|
const auto& sessions = capture_state.at("controls")
|
|
.at("performance_capture").at("sessions");
|
|
ASSERT_EQ(sessions.size(), 1U);
|
|
EXPECT_EQ(sessions.front().at("captured_count"), 1U);
|
|
|
|
const auto pixels = session.handle(Frame_Request{});
|
|
ASSERT_TRUE(pixels);
|
|
ASSERT_EQ(pixels->type, Web_Response_Type::Pixels);
|
|
EXPECT_EQ(pixels->payload.substr(0, 4), "RVP2");
|
|
const auto first_pixel = pixels->payload.substr(pixel_frame_header_size, 4);
|
|
bool contains_drawn_pixel = false;
|
|
for (std::size_t offset = pixel_frame_header_size;
|
|
offset + 4 <= pixels->payload.size(); offset += 4) {
|
|
if (pixels->payload.compare(offset, 4, first_pixel) != 0) {
|
|
contains_drawn_pixel = true;
|
|
break;
|
|
}
|
|
}
|
|
EXPECT_TRUE(contains_drawn_pixel);
|
|
}
|
|
} // namespace
|
|
} // namespace renderive::web
|