| 
									
										
										
										
											2025-02-14 21:35:40 +03:00
										 |  |  | #include <catch2/catch_test_macros.hpp>
 | 
					
						
							| 
									
										
										
										
											2025-02-14 23:56:01 +03:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2025-02-14 21:01:46 +03:00
										 |  |  | #define CATCH_CONFIG_MAIN
 | 
					
						
							|  |  |  | #include <catch2/catch_all.hpp>
 | 
					
						
							| 
									
										
										
										
											2025-02-14 22:18:00 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-14 21:35:40 +03:00
										 |  |  | #include "../zecsy.hpp"
 | 
					
						
							| 
									
										
										
										
											2025-02-14 21:01:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-14 21:35:40 +03:00
										 |  |  | using namespace zecsy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Create a single entity and verify its existence") | 
					
						
							| 
									
										
										
										
											2025-02-14 21:01:46 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-02-14 21:35:40 +03:00
										 |  |  |     world w; | 
					
						
							| 
									
										
										
										
											2025-02-14 21:41:36 +03:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2025-02-14 21:35:40 +03:00
										 |  |  |     auto e = w.make_entity(); | 
					
						
							| 
									
										
										
										
											2025-02-14 21:47:16 +03:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2025-02-14 21:35:40 +03:00
										 |  |  |     REQUIRE(w.is_alive(e)); | 
					
						
							| 
									
										
										
										
											2025-02-14 22:18:00 +03:00
										 |  |  |     REQUIRE(e.is_alive()); | 
					
						
							| 
									
										
										
										
											2025-02-14 21:01:46 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2025-02-14 21:41:36 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Destroy an entity and ensure it no longer exists in the world") | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     world w; | 
					
						
							| 
									
										
										
										
											2025-02-14 21:47:16 +03:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2025-02-14 21:41:36 +03:00
										 |  |  |     auto e = w.make_entity(); | 
					
						
							|  |  |  |     w.destroy_entity(e); | 
					
						
							| 
									
										
										
										
											2025-02-14 21:47:16 +03:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2025-02-14 21:41:36 +03:00
										 |  |  |     REQUIRE_FALSE(w.is_alive(e)); | 
					
						
							| 
									
										
										
										
											2025-02-14 22:18:00 +03:00
										 |  |  |     REQUIRE_FALSE(e.is_alive()); | 
					
						
							| 
									
										
										
										
											2025-02-14 21:41:36 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2025-02-14 21:47:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Entity #0 should be reserved and never used") | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     world w; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     auto e = w.make_entity(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(e != 0); | 
					
						
							| 
									
										
										
										
											2025-02-14 22:18:00 +03:00
										 |  |  |     REQUIRE(entity() == 0); | 
					
						
							|  |  |  |     REQUIRE_FALSE(entity().is_alive()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("World should throw on id overflow") | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     world w; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(int i = 0; i < MAX_ZECSY_ENTITIES; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-02-14 23:42:01 +03:00
										 |  |  |         w.make_entity(); | 
					
						
							| 
									
										
										
										
											2025-02-14 22:18:00 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE_THROWS(w.make_entity()); | 
					
						
							| 
									
										
										
										
											2025-02-14 21:47:16 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2025-02-14 23:42:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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)); | 
					
						
							|  |  |  |     REQUIRE_FALSE(e.has<ChoosenOne>()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Attempt of getting non-owned component should throw") | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     world w; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto e = w.make_entity(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE_THROWS(w.get<ChoosenOne>(e)); | 
					
						
							|  |  |  |     REQUIRE_THROWS(e.get<ChoosenOne>()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Attach a simple component to an entity and verify it is correctly associated") | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     world w; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto e1 = w.make_entity(); | 
					
						
							|  |  |  |     e1.set(ChoosenOne{}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(e1.has<ChoosenOne>()); | 
					
						
							|  |  |  |     REQUIRE(w.has<ChoosenOne>(e1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto e2 = w.make_entity(); | 
					
						
							|  |  |  |     w.set(e2, ChoosenOne{}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(e2.has<ChoosenOne>()); | 
					
						
							|  |  |  |     REQUIRE(w.has<ChoosenOne>(e2)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-02-14 23:56:01 +03:00
										 |  |  |   | 
					
						
							|  |  |  | 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(); | 
					
						
							|  |  |  |     e.set(Name{"zecsy!"}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(e.get<Name>().value == "zecsy!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     e.get<Name>().value = "super-zecsy!"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(e.get<Name>().value == "super-zecsy!"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-02-15 00:23:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Remove a component from an entity and verify it is no longer attached") | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     world w; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto e = w.make_entity(); | 
					
						
							|  |  |  |     e.set(ChoosenOne{}); | 
					
						
							|  |  |  |     REQUIRE_NOTHROW(e.remove<ChoosenOne>()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE_FALSE(e.has<ChoosenOne>()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     e.set(ChoosenOne{}); | 
					
						
							|  |  |  |     REQUIRE_NOTHROW(w.remove<ChoosenOne>(e)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE_FALSE(w.has<ChoosenOne>(e)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-02-15 00:36:15 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Addresses of removed components should be reused") | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     world w;  | 
					
						
							|  |  |  |     std::vector<entity> 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()); | 
					
						
							|  |  |  |             entities.back().set<ChoosenOne>(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if(addr.empty()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for(int j = 0; j < N; ++j) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 addr.emplace_back(&entities[j].get<ChoosenOne>()); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else  | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for(int j = 0; j < N; ++j) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 REQUIRE(&entities[j].get<ChoosenOne>() == addr[j]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for(auto e: entities) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             e.remove<ChoosenOne>(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         entities.clear(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-02-15 01:13:51 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Attach multiple components to an entity and verify all are correctly stored and retrievable") | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     world w; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto e = w.make_entity(); | 
					
						
							| 
									
										
										
										
											2025-02-15 01:47:12 +03:00
										 |  |  |     e.set(ChoosenOne{}, Name{"zecsy"}); | 
					
						
							| 
									
										
										
										
											2025-02-15 01:13:51 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(e.has<ChoosenOne, Name>()); | 
					
						
							|  |  |  |     REQUIRE(w.has<ChoosenOne, Name>(e)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-15 01:55:05 +03:00
										 |  |  |     e.remove<ChoosenOne, Name>(); | 
					
						
							| 
									
										
										
										
											2025-02-15 01:13:51 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE_FALSE(e.has<ChoosenOne, Name>()); | 
					
						
							|  |  |  |     REQUIRE_FALSE(w.has<ChoosenOne, Name>(e)); | 
					
						
							| 
									
										
										
										
											2025-02-15 01:55:05 +03:00
										 |  |  |     REQUIRE_FALSE(e.has<ChoosenOne>()); | 
					
						
							|  |  |  |     REQUIRE_FALSE(e.has<Name>()); | 
					
						
							| 
									
										
										
										
											2025-02-15 01:13:51 +03:00
										 |  |  | } |