83 lines
2.4 KiB
C++
83 lines
2.4 KiB
C++
|
|
#include <gtest/gtest.h>
|
||
|
|
|
||
|
|
#include <XCEngine/UI/Runtime/UIScreenDocumentHost.h>
|
||
|
|
#include <XCEngine/UI/Runtime/UIScreenPlayer.h>
|
||
|
|
|
||
|
|
#include <chrono>
|
||
|
|
#include <filesystem>
|
||
|
|
#include <fstream>
|
||
|
|
#include <string>
|
||
|
|
|
||
|
|
namespace {
|
||
|
|
|
||
|
|
using XCEngine::UI::UIRect;
|
||
|
|
using XCEngine::UI::Runtime::UIScreenAsset;
|
||
|
|
using XCEngine::UI::Runtime::UIScreenFrameInput;
|
||
|
|
using XCEngine::UI::Runtime::UIScreenPlayer;
|
||
|
|
using XCEngine::UI::Runtime::UIDocumentScreenHost;
|
||
|
|
|
||
|
|
namespace fs = std::filesystem;
|
||
|
|
|
||
|
|
class TempFileScope {
|
||
|
|
public:
|
||
|
|
TempFileScope(std::string stem, std::string extension, std::string contents) {
|
||
|
|
const auto uniqueId = std::to_string(
|
||
|
|
std::chrono::steady_clock::now().time_since_epoch().count());
|
||
|
|
m_path = fs::temp_directory_path() / (std::move(stem) + "_" + uniqueId + std::move(extension));
|
||
|
|
std::ofstream output(m_path, std::ios::binary | std::ios::trunc);
|
||
|
|
output << contents;
|
||
|
|
}
|
||
|
|
|
||
|
|
~TempFileScope() {
|
||
|
|
std::error_code ec;
|
||
|
|
fs::remove(m_path, ec);
|
||
|
|
}
|
||
|
|
|
||
|
|
const fs::path& Path() const {
|
||
|
|
return m_path;
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
fs::path m_path = {};
|
||
|
|
};
|
||
|
|
|
||
|
|
UIScreenAsset BuildScreenAsset(const fs::path& viewPath, const char* screenId) {
|
||
|
|
UIScreenAsset screen = {};
|
||
|
|
screen.screenId = screenId;
|
||
|
|
screen.documentPath = viewPath.string();
|
||
|
|
return screen;
|
||
|
|
}
|
||
|
|
|
||
|
|
UIScreenFrameInput BuildInputState(std::uint64_t frameIndex = 1u) {
|
||
|
|
UIScreenFrameInput input = {};
|
||
|
|
input.viewportRect = UIRect(0.0f, 0.0f, 960.0f, 720.0f);
|
||
|
|
input.frameIndex = frameIndex;
|
||
|
|
input.focused = true;
|
||
|
|
return input;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace
|
||
|
|
|
||
|
|
TEST(UIRuntimeSplitterValidationTest, InvalidSplitterArityProducesExplicitFrameError) {
|
||
|
|
TempFileScope viewFile(
|
||
|
|
"xcui_runtime_invalid_splitter",
|
||
|
|
".xcui",
|
||
|
|
"<View name=\"Invalid Splitter Test\">\n"
|
||
|
|
" <Column padding=\"16\" gap=\"10\">\n"
|
||
|
|
" <Splitter id=\"broken-splitter\" axis=\"horizontal\" splitRatio=\"0.5\">\n"
|
||
|
|
" <Card title=\"Only Child\" />\n"
|
||
|
|
" </Splitter>\n"
|
||
|
|
" </Column>\n"
|
||
|
|
"</View>\n");
|
||
|
|
|
||
|
|
UIDocumentScreenHost host = {};
|
||
|
|
UIScreenPlayer player(host);
|
||
|
|
|
||
|
|
ASSERT_TRUE(player.Load(BuildScreenAsset(viewFile.Path(), "runtime.invalid_splitter")));
|
||
|
|
|
||
|
|
const auto& frame = player.Update(BuildInputState());
|
||
|
|
EXPECT_FALSE(frame.errorMessage.empty());
|
||
|
|
EXPECT_NE(frame.errorMessage.find("broken-splitter"), std::string::npos);
|
||
|
|
EXPECT_NE(frame.errorMessage.find("exactly 2 child elements"), std::string::npos);
|
||
|
|
}
|