test(entity-manager): smoke del comptador player_exited i level_complete agregat

This commit is contained in:
JailDesigner committed 2026-04-26 10:32:20 +02:00
1 parent 811c6c482d
commit 178ce486c2
1 file changed
+45
+45
View File
@@ -22,6 +22,10 @@
// sprite sencer (pixel_rect).
// T13 mummy step — camina en línia recta pel playfield i gira en topar
// un mur (insidePlayfield=false) o sarc (Map::collides).
// T14 exited aggregator — EntityManager compta `player_exited` i emet
// `level_complete` quan iguala `expected_players`. Verifica
// idempotència (3r event no re-emet) i reset del comptador
// via `setExpectedPlayerCount` (cicle següent torna a emetre).
//
// Execució (des de la ruta del repo):
// make build && cd build && ctest --output-on-failure
@@ -449,6 +453,46 @@ namespace {
REQUIRE(torch.getAnimation()->currentFrame() == 2);
}
void testExitedAggregator() {
std::cout << "[T14] EntityManager: player_exited → level_complete\n";
EntityManager manager;
// Comptador inicialitzat per a 2 jugadors. Sense aquesta crida,
// l'agregador no faria res (expected_players_ = 0).
manager.setExpectedPlayerCount(2);
int level_complete_count = 0;
manager.getBus().subscribe("level_complete", [&](const Event& ev) {
++level_complete_count;
// Event d'agregat: no atribuïble a un jugador concret.
REQUIRE(ev.player_id == -1);
});
// Primer player_exited: comptador a 1 < 2, no emet encara.
manager.getBus().publish(Event{.name = "player_exited", .payload = std::monostate{}, .player_id = 0});
REQUIRE(manager.exitedPlayerCount() == 1);
REQUIRE(level_complete_count == 0);
// Segon player_exited: comptador a 2 == expected, emet una vegada.
manager.getBus().publish(Event{.name = "player_exited", .payload = std::monostate{}, .player_id = 1});
REQUIRE(manager.exitedPlayerCount() == 2);
REQUIRE(level_complete_count == 1);
// Un tercer player_exited (no hauria de passar amb 2 jugadors,
// però defensa contra publicacions extra): no torna a emetre.
manager.getBus().publish(Event{.name = "player_exited", .payload = std::monostate{}, .player_id = 0});
REQUIRE(level_complete_count == 1);
// setExpectedPlayerCount torna a obrir el cicle (això simularia
// el que fa GameScene després d'un reload de sala). El comptador
// d'EXITED es reinicia a 0 i el flag d'emissió també.
manager.setExpectedPlayerCount(2);
REQUIRE(manager.exitedPlayerCount() == 0);
manager.getBus().publish(Event{.name = "player_exited", .payload = std::monostate{}, .player_id = 0});
manager.getBus().publish(Event{.name = "player_exited", .payload = std::monostate{}, .player_id = 1});
REQUIRE(level_complete_count == 2); // segon cicle ha emès una vegada més
}
} // namespace
auto main() -> int {
@@ -467,6 +511,7 @@ auto main() -> int {
testCollisionBox();
testMummyStep();
testTorchAnimation();
testExitedAggregator();
if (g_failures == 0) {
std::cout << "ALL OK\n";