Dicewars-Siedler/tests/layout/LayoutEngineTest.cpp
2026-04-17 11:02:22 +02:00

127 lines
5.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_floating_point.hpp>
#include "engine/core/gui/uiComponent/layout/LayoutEngine.h"
using namespace LayoutEngine;
using Catch::Matchers::WithinAbs;
const float EPS = 0.001f;
static NodeLayout makeNode(float x, float y, float w, float h) {
NodeLayout n;
n.layoutStyle.width = { w, SizeUnit::Percent };
n.layoutStyle.height = { h, SizeUnit::Percent };
n.layoutStyle.margin.left = { x, SizeUnit::Percent };
n.layoutStyle.margin.top = { y, SizeUnit::Percent };
return n;
}
static Dimensions screen800x600() {
return { 0.f, 0.f, 1.0f, 1.0f };
}
// ── Basisfälle ───────────────────────────────────────────────────────────────
TEST_CASE("SizeUnit::Pixels wird korrekt normalisiert", "[layout][pixels]") {
NodeLayout root;
root.layoutStyle.width = { 400.f, SizeUnit::Pixels };
root.layoutStyle.height = { 300.f, SizeUnit::Pixels };
auto result = compute(root, screen800x600(), 800.f, 600.f);
REQUIRE_THAT(result.self.width, WithinAbs(0.5f, EPS)); // 400/800
REQUIRE_THAT(result.self.height, WithinAbs(0.5f, EPS)); // 300/600
}
TEST_CASE("Eigene Dimensionen werden korrekt berechnet", "[layout][self]") {
NodeLayout root = makeNode(0.1f, 0.2f, 0.5f, 0.4f);
auto result = compute(root, screen800x600(), 800.f, 600.f);
REQUIRE_THAT(result.self.x, WithinAbs(0.1f, EPS));
REQUIRE_THAT(result.self.y, WithinAbs(0.2f, EPS));
REQUIRE_THAT(result.self.width, WithinAbs(0.5f, EPS));
REQUIRE_THAT(result.self.height, WithinAbs(0.4f, EPS));
}
TEST_CASE("Kein Kind → leere children-Liste", "[layout][children]") {
NodeLayout root = makeNode(0.f, 0.f, 0.5f, 0.5f);
auto result = compute(root, screen800x600(), 800.f, 600.f);
REQUIRE(result.children.empty());
}
// ── JustifyContent ───────────────────────────────────────────────────────────
TEST_CASE("JustifyContent::Start Kinder beginnen bei 0", "[layout][justify]") {
NodeLayout root = makeNode(0.f, 0.f, 1.0f, 1.0f);
root.layoutStyle.flexDirection = FlexDirection::Row;
root.layoutStyle.justifyContent = JustifyContent::Start;
root.children.push_back(makeNode(0.f, 0.f, 0.2f, 1.0f));
root.children.push_back(makeNode(0.f, 0.f, 0.2f, 1.0f));
auto result = compute(root, screen800x600(), 800.f, 600.f);
REQUIRE_THAT(result.children[0].self.x, WithinAbs(0.0f, EPS));
REQUIRE_THAT(result.children[1].self.x, WithinAbs(0.2f, EPS));
}
TEST_CASE("JustifyContent::Center Kind horizontal zentriert", "[layout][justify]") {
NodeLayout root = makeNode(0.f, 0.f, 1.0f, 1.0f);
root.layoutStyle.flexDirection = FlexDirection::Row;
root.layoutStyle.justifyContent = JustifyContent::Center;
root.children.push_back(makeNode(0.f, 0.f, 0.4f, 1.0f));
auto result = compute(root, screen800x600(), 800.f, 600.f);
// remaining = 1.0 - 0.4 = 0.6 → offset = 0.3
REQUIRE_THAT(result.children[0].self.x, WithinAbs(0.3f, EPS));
}
TEST_CASE("JustifyContent::SpaceBetween Gap korrekt verteilt", "[layout][justify]") {
NodeLayout root = makeNode(0.f, 0.f, 1.0f, 1.0f);
root.layoutStyle.flexDirection = FlexDirection::Row;
root.layoutStyle.justifyContent = JustifyContent::SpaceBetween;
root.children.push_back(makeNode(0.f, 0.f, 0.2f, 1.0f));
root.children.push_back(makeNode(0.f, 0.f, 0.2f, 1.0f));
root.children.push_back(makeNode(0.f, 0.f, 0.2f, 1.0f));
auto result = compute(root, screen800x600(), 800.f, 600.f);
// remaining = 1.0 - 0.6 = 0.4, gap = 0.2
REQUIRE_THAT(result.children[0].self.x, WithinAbs(0.0f, EPS));
REQUIRE_THAT(result.children[1].self.x, WithinAbs(0.4f, EPS));
REQUIRE_THAT(result.children[2].self.x, WithinAbs(0.8f, EPS));
}
// ── AlignItems ───────────────────────────────────────────────────────────────
TEST_CASE("AlignItems::Center Kind vertikal zentriert (Row)", "[layout][align]") {
NodeLayout root = makeNode(0.f, 0.f, 1.0f, 1.0f);
root.layoutStyle.flexDirection = FlexDirection::Row;
root.layoutStyle.alignItems = AlignItems::Center;
root.children.push_back(makeNode(0.f, 0.f, 0.5f, 0.4f));
auto result = compute(root, screen800x600(), 800.f, 600.f);
// remaining = 1.0 - 0.4 = 0.6 → y = 0.3
REQUIRE_THAT(result.children[0].self.y, WithinAbs(0.3f, EPS));
}
TEST_CASE("AlignItems::End Kind am unteren Rand (Row)", "[layout][align]") {
NodeLayout root = makeNode(0.f, 0.f, 1.0f, 1.0f);
root.layoutStyle.flexDirection = FlexDirection::Row;
root.layoutStyle.alignItems = AlignItems::End;
root.children.push_back(makeNode(0.f, 0.f, 0.5f, 0.4f));
auto result = compute(root, screen800x600(), 800.f, 600.f);
// remaining = 1.0 - 0.4 = 0.6 → y = 0.6
REQUIRE_THAT(result.children[0].self.y, WithinAbs(0.6f, EPS));
}
// ── FlexDirection::Column ────────────────────────────────────────────────────
TEST_CASE("Column: Kinder werden vertikal gestapelt", "[layout][column]") {
NodeLayout root = makeNode(0.f, 0.f, 1.0f, 1.0f);
root.layoutStyle.flexDirection = FlexDirection::Column;
root.layoutStyle.justifyContent = JustifyContent::Start;
root.children.push_back(makeNode(0.f, 0.f, 1.0f, 0.3f));
root.children.push_back(makeNode(0.f, 0.f, 1.0f, 0.3f));
auto result = compute(root, screen800x600(), 800.f, 600.f);
REQUIRE_THAT(result.children[0].self.y, WithinAbs(0.0f, EPS));
REQUIRE_THAT(result.children[1].self.y, WithinAbs(0.3f, EPS));
}