Files
Renderive/Kernel/tests/renderive/renderable/Renderable_Inheritance_Test.cpp
T

176 lines
4.8 KiB
C++

#include <gtest/gtest.h>
#include "renderive/renderable/Inheritance.hpp"
#include <type_traits>
#include <vector>
namespace {
namespace renderable_chain = renderive::renderable_inheritance;
enum class Visit {
parent,
child
};
struct Event {};
struct Impl_Base : renderive::inheritance::Type_Root {
explicit Impl_Base(std::vector<Visit>& visits) : visits(&visits) {}
std::vector<Visit>* visits;
};
struct Parent_Impl
: renderable_chain::Impl_Root<Parent_Impl, Impl_Base, Event> {
using Impl_Root::Impl_Root;
struct Observer : renderable_chain::Observer_Root<Parent_Impl> {
static void handle(Parent_Impl& impl, const Event&) {
impl.visits->push_back(Visit::parent);
}
};
};
struct Child_Impl : renderable_chain::Impl_Node<Child_Impl, Parent_Impl> {
using Impl_Node::Impl_Node;
struct Observer
: renderable_chain::Observer_Node<Child_Impl,
Parent_Impl::Observer> {
static void handle(Child_Impl& impl, const Event&) {
impl.visits->push_back(Visit::child);
}
};
};
struct Parent_State : renderable_chain::State_Root<Parent_State> {};
struct Child_State
: renderable_chain::State_Node<Child_State, Parent_State> {};
struct Parent_Builder_Layer
: renderable_chain::Builder_Root<Parent_Builder_Layer> {};
struct Child_Builder_Layer
: renderable_chain::Builder_Node<Child_Builder_Layer,
Parent_Builder_Layer> {};
struct Business_Builder {
explicit Business_Builder(bool& initialized) : initialized(&initialized) {}
void build() const { *initialized = true; }
bool* initialized;
};
struct Final_Builder
: renderable_chain::Builder<Final_Builder, Child_Builder_Layer,
Business_Builder> {
using Builder::Builder;
};
struct Root_Base {
public:
explicit Root_Base(bool& constructed) : constructed(&constructed) {
constructed = true;
}
bool* constructed;
};
struct Renderable_Root
: renderive::renderable::render_base<Renderable_Root, Root_Base, true> {
using render_base::render_base;
struct Impl {};
};
struct Product_Properties {
bool enabled{};
};
template <class Product_Type, class Properties_Type>
struct Product_Business_Builder {
using Product = Product_Type;
using Properties = Properties_Type;
explicit Product_Business_Builder(bool& initialized)
: initialized(&initialized) {}
void build() const { *initialized = true; }
bool* initialized;
};
struct Visual_Control
: renderive::renderable::render_base<Visual_Control, Renderable_Root> {
using State = Product_Properties;
template <class Product, class Properties>
using Business_Builder = Product_Business_Builder<Product, Properties>;
using render_base::render_base;
protected:
template <class, auto Member, class Value>
void set_state(Value&& value) {
state.*Member = std::forward<Value>(value);
}
template <class, auto Member>
auto get_state() const {
return state.*Member;
}
private:
State state;
};
using Renderable_Product = renderive::renderable::attach<Visual_Control>;
TEST(renderable_inheritance_test, dispatches_nested_observers_parent_first) {
std::vector<Visit> visits;
Child_Impl impl(visits);
impl.dispatch(Event{});
EXPECT_EQ(visits, (std::vector{Visit::parent, Visit::child}));
}
TEST(renderable_inheritance_test, preserves_business_builder_capabilities) {
bool initialized{};
Final_Builder builder(initialized);
builder.build();
EXPECT_TRUE(initialized);
static_assert(std::same_as<
renderive::inheritance::Type_At_Position_T<
typename Final_Builder::Inheritance_Registry,
renderable_chain::Builder_Chain,
Final_Builder::Inheritance_Position>,
Final_Builder>);
static_assert(std::same_as<
renderive::inheritance::Type_At_Position_T<
typename Child_State::Inheritance_Registry,
renderable_chain::State_Chain,
Child_State::Inheritance_Position>,
Child_State>);
}
TEST(renderable_inheritance_test,
composes_root_control_and_product_without_business_boilerplate) {
bool constructed{};
Renderable_Product product(constructed);
EXPECT_TRUE(constructed);
bool initialized{};
Renderable_Product::Builder builder(initialized);
builder.build();
EXPECT_TRUE(initialized);
static_assert(std::same_as<Renderable_Product::Properties,
Product_Properties>);
static_assert(std::same_as<
typename Renderable_Product::Builder::Product,
Renderable_Product>);
}
} // namespace