/* * Copyright 2013 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.entitySystem; import com.google.common.collect.Lists; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.terasology.assets.AssetFactory; import org.terasology.assets.ResourceUrn; import org.terasology.assets.management.AssetManager; import org.terasology.assets.module.ModuleAwareAssetTypeManager; import org.terasology.context.Context; import org.terasology.context.internal.ContextImpl; import org.terasology.engine.bootstrap.EntitySystemSetupUtil; import org.terasology.engine.module.ModuleManager; import org.terasology.entitySystem.entity.EntityManager; import org.terasology.entitySystem.entity.EntityRef; import org.terasology.entitySystem.entity.internal.PojoEntityManager; import org.terasology.entitySystem.entity.lifecycleEvents.BeforeDeactivateComponent; import org.terasology.entitySystem.entity.lifecycleEvents.BeforeRemoveComponent; import org.terasology.entitySystem.entity.lifecycleEvents.OnActivatedComponent; import org.terasology.entitySystem.entity.lifecycleEvents.OnAddedComponent; import org.terasology.entitySystem.entity.lifecycleEvents.OnChangedComponent; import org.terasology.entitySystem.event.internal.EventSystem; import org.terasology.entitySystem.prefab.Prefab; import org.terasology.entitySystem.prefab.PrefabData; import org.terasology.entitySystem.prefab.internal.PojoPrefab; import org.terasology.entitySystem.stubs.EntityRefComponent; import org.terasology.entitySystem.stubs.IntegerComponent; import org.terasology.entitySystem.stubs.StringComponent; import org.terasology.network.NetworkSystem; import org.terasology.registry.CoreRegistry; import org.terasology.testUtil.ModuleManagerFactory; import org.terasology.utilities.Assets; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; /** */ public class PojoEntityManagerTest { private static Context context; private PojoEntityManager entityManager; private Prefab prefab; @BeforeClass public static void setupClass() throws Exception { context = new ContextImpl(); ModuleManager moduleManager = ModuleManagerFactory.create(); context.put(ModuleManager.class, moduleManager); ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManager(); assetTypeManager.registerCoreAssetType(Prefab.class, (AssetFactory<Prefab, PrefabData>) PojoPrefab::new, "prefabs"); assetTypeManager.switchEnvironment(moduleManager.getEnvironment()); context.put(AssetManager.class, assetTypeManager.getAssetManager()); CoreRegistry.setContext(context); } @Before public void setup() { context.put(NetworkSystem.class, mock(NetworkSystem.class)); EntitySystemSetupUtil.addReflectionBasedLibraries(context); EntitySystemSetupUtil.addEntityManagementRelatedClasses(context); entityManager = (PojoEntityManager) context.get(EntityManager.class); PrefabData protoPrefab = new PrefabData(); protoPrefab.addComponent(new StringComponent("Test")); prefab = Assets.generateAsset(new ResourceUrn("unittest:myprefab"), protoPrefab, Prefab.class); } @Test public void testCreateEntity() { EntityRef entity = entityManager.create(); assertNotNull(entity); } @Test public void testCreateEntityWithComponent() { StringComponent comp = new StringComponent("Test"); EntityRef entity = entityManager.create(comp); assertNotNull(entity); assertNotNull(entity.getComponent(StringComponent.class)); assertEquals(comp, entity.getComponent(StringComponent.class)); } @Test public void testAddAndRetrieveComponent() { EntityRef entity = entityManager.create(); assertNotNull(entity); StringComponent comp = new StringComponent(); entity.addComponent(comp); assertEquals(comp, entity.getComponent(StringComponent.class)); } @Test public void testRemoveComponent() { EntityRef entity = entityManager.create(); StringComponent comp = new StringComponent(); entity.addComponent(comp); entity.removeComponent(StringComponent.class); assertNull(entity.getComponent(StringComponent.class)); } @Test public void testReplaceComponent() { EntityRef entity = entityManager.create(); StringComponent comp = new StringComponent(); comp.value = "Hello"; StringComponent comp2 = new StringComponent(); comp2.value = "Goodbye"; entity.addComponent(comp); entity.addComponent(comp2); assertEquals(comp2, entity.getComponent(StringComponent.class)); } @Test public void testDestroyEntity() { EntityRef entity = entityManager.create(); entity.addComponent(new StringComponent()); entity.addComponent(new IntegerComponent()); entity.destroy(); assertNull(entity.getComponent(StringComponent.class)); assertNull(entity.getComponent(IntegerComponent.class)); } @Test public void testIterateComponents() { EntityRef entity = entityManager.create(); StringComponent comp = new StringComponent(); entity.addComponent(comp); for (Map.Entry<EntityRef, StringComponent> item : entityManager.listComponents(StringComponent.class)) { assertEquals(entity, item.getKey()); assertEquals(comp, item.getValue()); } } @Test public void testChangeComponentsDuringIterator() { EntityRef entity1 = entityManager.create(); entity1.addComponent(new StringComponent()); EntityRef entity2 = entityManager.create(); entity2.addComponent(new StringComponent()); Iterator<Map.Entry<EntityRef, StringComponent>> iterator = entityManager.listComponents(StringComponent.class).iterator(); iterator.next(); entity2.removeComponent(StringComponent.class); iterator.next(); } @Test public void testAddComponentEventSent() { EventSystem eventSystem = mock(EventSystem.class); entityManager.setEventSystem(eventSystem); EntityRef entity1 = entityManager.create(); StringComponent comp = entity1.addComponent(new StringComponent()); verify(eventSystem).send(entity1, OnAddedComponent.newInstance(), comp); verify(eventSystem).send(entity1, OnActivatedComponent.newInstance(), comp); } @Test public void testRemoveComponentEventSent() { EventSystem eventSystem = mock(EventSystem.class); EntityRef entity1 = entityManager.create(); StringComponent comp = entity1.addComponent(new StringComponent()); entityManager.setEventSystem(eventSystem); entity1.removeComponent(StringComponent.class); verify(eventSystem).send(entity1, BeforeDeactivateComponent.newInstance(), comp); verify(eventSystem).send(entity1, BeforeRemoveComponent.newInstance(), comp); } @Test public void testChangeComponentEventSentWhenSave() { EventSystem eventSystem = mock(EventSystem.class); EntityRef entity1 = entityManager.create(); StringComponent comp = entity1.addComponent(new StringComponent()); entityManager.setEventSystem(eventSystem); entity1.saveComponent(comp); verify(eventSystem).send(entity1, OnChangedComponent.newInstance(), comp); } @Test public void testChangeComponentEventSentWhenAddOverExisting() { EventSystem eventSystem = mock(EventSystem.class); EntityRef entity1 = entityManager.create(); entity1.addComponent(new StringComponent()); entityManager.setEventSystem(eventSystem); StringComponent comp2 = entity1.addComponent(new StringComponent()); verify(eventSystem).send(entity1, OnChangedComponent.newInstance(), comp2); } @Test public void testMassRemovedComponentEventSentOnDestroy() { EventSystem eventSystem = mock(EventSystem.class); EntityRef entity1 = entityManager.create(); entity1.addComponent(new StringComponent()); entityManager.setEventSystem(eventSystem); entity1.destroy(); verify(eventSystem).send(entity1, BeforeDeactivateComponent.newInstance()); verify(eventSystem).send(entity1, BeforeRemoveComponent.newInstance()); } @Test public void testIterateEntitiesFindsEntityWithSingleComponent() { EntityRef entity1 = entityManager.create(); entity1.addComponent(new StringComponent()); List<EntityRef> results = Lists.newArrayList(entityManager.getEntitiesWith(StringComponent.class)); assertEquals(Lists.newArrayList(entity1), results); } @Test public void testIterateEntitiesDoesNotFindEntityMissingAComponent() { EntityRef entity1 = entityManager.create(); entity1.addComponent(new StringComponent()); List<EntityRef> results = Lists.newArrayList(entityManager.getEntitiesWith(StringComponent.class, IntegerComponent.class)); assertEquals(Collections.<EntityRef>emptyList(), results); } @Test public void testIterateEntitiesFindsEntityWithTwoComponents() { EntityRef entity1 = entityManager.create(); entity1.addComponent(new StringComponent()); entity1.addComponent(new IntegerComponent()); List<EntityRef> results = Lists.newArrayList(entityManager.getEntitiesWith(StringComponent.class, IntegerComponent.class)); assertEquals(Lists.newArrayList(entity1), results); } @Test public void testIterateWithNoComponents() { List<EntityRef> results = Lists.newArrayList(entityManager.getEntitiesWith(StringComponent.class)); assertEquals(Collections.<EntityRef>emptyList(), results); } @Test public void testGetComponentCountWhenNoComponents() { assertEquals(0, entityManager.getCountOfEntitiesWith(StringComponent.class)); } @Test public void testGetComponentCount() { entityManager.create().addComponent(new StringComponent()); entityManager.create().addComponent(new StringComponent()); assertEquals(2, entityManager.getCountOfEntitiesWith(StringComponent.class)); } @Test public void testDestroyingEntityInvalidatesEntityRefs() { EntityRef main = entityManager.create(); main.addComponent(new StringComponent()); EntityRef reference = entityManager.create(); EntityRefComponent refComp = reference.addComponent(new EntityRefComponent()); refComp.entityRef = entityManager.getEntitiesWith(StringComponent.class).iterator().next(); assertTrue(main.exists()); entityManager.getEntitiesWith(StringComponent.class).iterator().next().destroy(); assertFalse(main.exists()); assertFalse(refComp.entityRef.exists()); } @Test public void testPrefabCopiedCorrectly() { EntityRef entity1 = entityManager.create(prefab); StringComponent comp = entity1.getComponent(StringComponent.class); assertEquals("Test", comp.value); comp.value = "One"; entity1.saveComponent(comp); assertEquals("Test", prefab.getComponent(StringComponent.class).value); EntityRef entity2 = entityManager.create(prefab); assertEquals("Test", prefab.getComponent(StringComponent.class).value); assertEquals("One", entity1.getComponent(StringComponent.class).value); assertEquals("Test", entity2.getComponent(StringComponent.class).value); } @Test public void testPrefabCopiedCorrectly2() { EntityRef test1 = entityManager.create("unittest:myprefab"); EntityRef test2 = entityManager.create("unittest:myprefab"); //This returns true because the Objectids are Identical. assertFalse(test1.getComponent(StringComponent.class) == (test2.getComponent(StringComponent.class))); } @Test public void testPrefabPersistedRetainedCorrectly() { PrefabData protoPrefab = new PrefabData(); protoPrefab.setPersisted(false); prefab = Assets.generateAsset(new ResourceUrn("unittest:nonpersistentPrefab"), protoPrefab, Prefab.class); EntityRef entity1 = entityManager.create(prefab); assertFalse(entity1.isPersistent()); } @Test public void testIsLoadedTrueOnCreate() { EntityRef entity = entityManager.create(); assertTrue(entity.isActive()); } @Test public void testIsLoadedFalseAfterDestroyed() { EntityRef entity = entityManager.create(); entity.destroy(); assertFalse(entity.isActive()); } @Test public void testIsLoadedFalseAfterPersist() { EntityRef entity = entityManager.create(); entityManager.deactivateForStorage(entity); assertFalse(entity.isActive()); } @Test public void testIsLoadedTrueAfterRestore() { entityManager.setNextId(3); EntityRef entity = entityManager.createEntityWithId(2, Collections.<Component>emptyList()); assertTrue(entity.isActive()); } @Test public void testLoadedStateClearedWhenEntityManagerCleared() { EntityRef entity = entityManager.create(); entityManager.clear(); assertFalse(entity.isActive()); } @Test public void testDestructionOfUnloadedEntitiesPrevented() { EntityRef entity = entityManager.create(); long id = entity.getId(); entityManager.deactivateForStorage(entity); assertTrue(entity.exists()); entity.destroy(); assertTrue(entity.exists()); } }