zecsy/tests/zecsy.cpp
2025-02-15 22:33:02 +03:00

239 lines
4.7 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 <concepts>
#include <string>
#define CATCH_CONFIG_MAIN
#include <catch2/catch_all.hpp>
#include "../zecsy.hpp"
using namespace zecsy;
TEST_CASE("Create a single entity and verify its existence")
{
world w;
auto e = w.make_entity();
REQUIRE(w.is_alive(e));
}
TEST_CASE("Destroy an entity and ensure it no longer exists in the world")
{
world w;
auto e = w.make_entity();
w.destroy_entity(e);
REQUIRE_FALSE(w.is_alive(e));
}
TEST_CASE("Entity #0 should be reserved and never used")
{
world w;
auto e = w.make_entity();
REQUIRE(e != 0);
REQUIRE_FALSE(w.is_alive(0));
}
struct ChoosenOne
{
};
TEST_CASE("Entity shouldn't have a component that wasn't attached to it")
{
world w;
auto e = w.make_entity();
REQUIRE_FALSE(w.has<ChoosenOne>(e));
}
TEST_CASE("Attempt of getting non-owned component should throw")
{
world w;
auto e = w.make_entity();
REQUIRE_THROWS(w.get<ChoosenOne>(e));
}
TEST_CASE("Attach a simple component to an entity and verify it is correctly associated")
{
world w;
auto e1 = w.make_entity();
w.set(e1, ChoosenOne{});
REQUIRE(w.has<ChoosenOne>(e1));
auto e2 = w.make_entity();
w.set(e2, ChoosenOne{});
REQUIRE(w.has<ChoosenOne>(e2));
}
struct Name
{
std::string value;
};
TEST_CASE("Retrieve a component from an entity and verify its data matches what was set")
{
world w;
auto e = w.make_entity();
w.set(e, Name{"zecsy!"});
REQUIRE(w.get<Name>(e).value == "zecsy!");
w.get<Name>(e).value = "super-zecsy!";
REQUIRE(w.get<Name>(e).value == "super-zecsy!");
}
TEST_CASE("Remove a component from an entity and verify it is no longer attached")
{
world w;
auto e = w.make_entity();
w.set(e, ChoosenOne{});
REQUIRE_NOTHROW(w.remove<ChoosenOne>(e));
REQUIRE_FALSE(w.has<ChoosenOne>(e));
w.set(e, ChoosenOne{});
REQUIRE_NOTHROW(w.remove<ChoosenOne>(e));
REQUIRE_FALSE(w.has<ChoosenOne>(e));
}
TEST_CASE("Addresses of removed components should be reused")
{
world w;
std::vector<entity_id> entities;
std::vector<ChoosenOne*> addr;
const int N = 4;
for(int i = 0; i < 2; ++i)
{
for(int j = 0; j < N; ++j)
{
entities.emplace_back(w.make_entity());
w.set<ChoosenOne>(entities.back());
}
if(addr.empty())
{
for(int j = 0; j < N; ++j)
{
addr.emplace_back(&w.get<ChoosenOne>(entities[j]));
}
}
else
{
for(int j = 0; j < N; ++j)
{
REQUIRE(&w.get<ChoosenOne>(entities[j]) == addr[j]);
}
}
for(auto e: entities)
{
w.remove<ChoosenOne>(e);
}
entities.clear();
}
}
TEST_CASE("Attach multiple components to an entity and verify all are correctly stored and retrievable")
{
world w;
auto e = w.make_entity();
w.set(e, ChoosenOne{}, Name{"zecsy"});
REQUIRE(w.has<ChoosenOne, Name>(e));
w.remove<ChoosenOne, Name>(e);
REQUIRE_FALSE(w.has<ChoosenOne, Name>(e));
REQUIRE_FALSE(w.has<ChoosenOne>(e));
REQUIRE_FALSE(w.has<Name>(e));
}
TEST_CASE("Create a simple system that processes entities with a specific component and verify it executes correctly")
{
struct Component
{
int value = 0;
};
world w;
auto e0 = w.make_entity(), e1 = w.make_entity();
w.set<Component>(e0); //or e0.set(Component{})
w.set(e1, Component{20});
REQUIRE(w.get<Component>(e0).value == 0);
REQUIRE(w.get<Component>(e1).value == 20);
/*
* Really wanna deduce it to w.query([](Component&){}),
* but I have some troubles with it
*/
w.query<Component>([](Component& c)
{
c.value++;
});
REQUIRE(w.get<Component>(e0).value == 1);
REQUIRE(w.get<Component>(e1).value == 21);
}
TEST_CASE("Test a systems ability to query and process only entities with a specific combination of components")
{
struct C0
{
int value = 0;
};
struct C1
{
int value = 10;
};
world w;
auto e0 = w.make_entity();
w.set(e0, C0{}, C1{});
auto e1 = w.make_entity();
w.set(e1, C0{});
auto e2 = w.make_entity();
w.set(e2, C1{});
int count = 0;
REQUIRE(w.get<C0>(e0).value == 0);
REQUIRE(w.get<C1>(e0).value == 10);
w.query<C0, C1>([&count](C0& c0, C1& c1)
{
c0.value++;
c1.value++;
});
REQUIRE(w.get<C0>(e0).value == 1);
REQUIRE(w.get<C1>(e0).value == 11);
REQUIRE(w.get<C0>(e1).value == 0);
REQUIRE(w.get<C1>(e2).value == 10);
REQUIRE_FALSE(w.has<C1>(e1));
REQUIRE_FALSE(w.has<C0>(e2));
}