package coffee.liz.ecs.model; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import lombok.RequiredArgsConstructor; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.Collection; import java.util.List; import java.util.stream.Stream; final class EntityTest { @ParameterizedTest @MethodSource("componentCombinationProvider") public void hasAllReportsPresenceForComponentSets(final Collection> query, final boolean expected) { final Entity entity = Entity.builder().id(7).build(); entity.add(new AlphaComponent("first")); entity.add(new BetaComponent(3)); entity.add(new GammaKeyedComponent()); assertEquals(expected, entity.hasAll(query)); } private static Stream componentCombinationProvider() { return Stream .of(Arguments.of(List.of(AlphaComponent.class), true), Arguments.of(List.of(BetaComponent.class), true), Arguments.of(List.of(AlphaComponent.class, BetaComponent.class, GammaComponent.class), true), Arguments.of(List.of(AlphaComponent.class, BetaComponent.class, GammaKeyedComponent.class), false), Arguments.of(List.of(GammaComponent.class), true), Arguments.of(List.of(GammaKeyedComponent.class), false)); } @Test public void getThrowsForMissingComponentsWithHelpfulMessage() { final Entity entity = Entity.builder().id(99).build(); final IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> entity.get(AlphaComponent.class)); assertTrue(thrown.getMessage().contains("AlphaComponent")); assertTrue(thrown.getMessage().contains("99")); } @Test public void addReplacesExistingComponentInstance() { final Entity entity = Entity.builder().id(17).build(); final AlphaComponent initial = new AlphaComponent("initial"); entity.add(initial); final AlphaComponent replacement = new AlphaComponent("replacement"); entity.add(replacement); assertSame(replacement, entity.get(AlphaComponent.class)); } @Test public void removeClearsComponentPresence() { final Entity entity = Entity.builder().id(45).build(); entity.add(new BetaComponent(2)); assertTrue(entity.has(BetaComponent.class)); entity.remove(BetaComponent.class); assertFalse(entity.has(BetaComponent.class)); assertTrue(entity.componentTypes().isEmpty()); } private record AlphaComponent(String name) implements Component { } private record BetaComponent(int level) implements Component { } @RequiredArgsConstructor private class GammaComponent implements Component { @Override public Class getKey() { return GammaComponent.class; } } private class GammaKeyedComponent extends GammaComponent { } private record ContextualComponent(int ownerId) implements Component { } }