@Test
 public void testBlockEntityPrefabCorrectlyAddedOnChangeToBlockWithPrefab() {
   worldProvider.setBlock(Vector3i.zero(), plainBlock);
   EntityRef entity = worldProvider.getBlockEntityAt(Vector3i.zero());
   worldProvider.setBlock(Vector3i.zero(), blockWithString);
   assertEquals(blockWithString.getPrefab(), entity.getParentPrefab().getURI().toSimpleString());
 }
 @Test
 public void testBlockEntityPrefabCorrectlyRemovedOnChangeToBlockWithNoPrefab() {
   worldProvider.setBlock(Vector3i.zero(), blockWithString);
   EntityRef entity = worldProvider.getBlockEntityAt(Vector3i.zero());
   worldProvider.setBlock(Vector3i.zero(), plainBlock);
   assertEquals(null, entity.getParentPrefab());
 }
  @Override
  public byte getLeafSidesInNetwork(NetworkNode networkNode) {
    if (!hasLeafNode(networkNode))
      throw new IllegalArgumentException("Cannot test nodes not in network");

    if (networkingNodes.size() == 0) {
      // Degenerated network
      for (Side connectingOnSide : SideBitFlag.getSides(networkNode.connectionSides)) {
        Vector3i possibleLocation = networkNode.location.toVector3i();
        possibleLocation.add(connectingOnSide.getVector3i());
        for (NetworkNode node : leafNodes.get(new ImmutableBlockLocation(possibleLocation))) {
          if (SideBitFlag.hasSide(node.connectionSides, connectingOnSide.reverse())) {
            return SideBitFlag.getSide(connectingOnSide);
          }
        }
      }

      return 0;
    } else {
      byte result = 0;
      for (Side connectingOnSide : SideBitFlag.getSides(networkNode.connectionSides)) {
        Vector3i possibleLocation = networkNode.location.toVector3i();
        possibleLocation.add(connectingOnSide.getVector3i());
        for (NetworkNode node : networkingNodes.get(new ImmutableBlockLocation(possibleLocation))) {
          if (SideBitFlag.hasSide(node.connectionSides, connectingOnSide.reverse())) {
            result += SideBitFlag.getSide(connectingOnSide);
          }
        }
      }

      return result;
    }
  }
 @Test
 public void testEntityBecomesTemporaryWhenChangedFromAKeepActiveBlock() {
   worldProvider.setBlock(Vector3i.zero(), keepActiveBlock);
   EntityRef blockEntity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
   worldProvider.setBlock(Vector3i.zero(), BlockManager.getAir());
   worldProvider.update(1.0f);
   assertFalse(blockEntity.isActive());
 }
 @Test
 public void componentsAlteredIfBlockInSameFamilyWhenForced() {
   worldProvider.setBlock(Vector3i.zero(), blockInFamilyOne);
   EntityRef entity = worldProvider.getBlockEntityAt(Vector3i.zero());
   entity.addComponent(new IntegerComponent());
   worldProvider.setBlockForceUpdateEntity(Vector3i.zero(), blockInFamilyTwo);
   assertNull(entity.getComponent(IntegerComponent.class));
 }
 @Test
 public void threeDistanceOnlyIteration() {
   Iterator<Vector3i> iter = new Diamond3iIterator(Vector3i.zero(), 4, 3);
   while (iter.hasNext()) {
     Vector3i next = iter.next();
     assertEquals(3, Vector3i.zero().gridDistance(next));
   }
 }
 @Test
 public void componentUntouchedIfRetainRequested() {
   worldProvider.setBlock(Vector3i.zero(), blockInFamilyOne);
   EntityRef entity = worldProvider.getBlockEntityAt(Vector3i.zero());
   entity.addComponent(new IntegerComponent());
   worldProvider.setBlockRetainComponent(Vector3i.zero(), blockWithString, IntegerComponent.class);
   assertNotNull(entity.getComponent(IntegerComponent.class));
 }
 @Test
 public void testPrefabUpdatedWhenBlockChanged() {
   worldProvider.setBlock(Vector3i.zero(), blockWithString);
   assertEquals(
       blockWithString.getPrefab(),
       worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0)).getParentPrefab().getName());
   worldProvider.setBlock(Vector3i.zero(), blockWithDifferentString);
   assertEquals(
       blockWithDifferentString.getPrefab(),
       worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0)).getParentPrefab().getName());
 }
  @Test
  public void allComponentsNotMarkedAsRetainedRemovedOnBlockChange() {
    worldStub.setBlock(Vector3i.zero(), blockWithString);
    EntityRef entity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
    entity.addComponent(new ForceBlockActiveComponent());
    entity.addComponent(new RetainedOnBlockChangeComponent(2));

    worldProvider.setBlock(Vector3i.zero(), BlockManager.getAir());

    assertTrue(entity.hasComponent(RetainedOnBlockChangeComponent.class));
    assertFalse(entity.hasComponent(ForceBlockActiveComponent.class));
  }
  @Test
  public void testComponentsUpdatedWhenBlockChanged() {
    worldProvider.setBlock(Vector3i.zero(), blockWithString);

    LifecycleEventChecker checker =
        new LifecycleEventChecker(entityManager.getEventSystem(), StringComponent.class);

    worldProvider.setBlock(Vector3i.zero(), blockWithDifferentString);
    EntityRef blockEntity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
    assertTrue(blockEntity.exists());

    assertEquals(
        Lists.newArrayList(new EventInfo(OnChangedComponent.newInstance(), blockEntity)),
        checker.receivedEvents);
  }
 @Test
 public void twoDistanceIteration() {
   Iterator<Vector3i> iter = new Diamond3iIterator(Vector3i.zero(), 2);
   Set<Vector3i> expected =
       Sets.newHashSet(
           Vector3i.zero(),
           new Vector3i(1, 0, 0),
           new Vector3i(-1, 0, 0),
           new Vector3i(0, 1, 0),
           new Vector3i(0, -1, 0),
           new Vector3i(0, 0, 1),
           new Vector3i(0, 0, -1));
   while (iter.hasNext()) {
     Vector3i next = iter.next();
     assertTrue("Received Unexpected: " + next, expected.remove(next));
   }
   assertTrue("Missing: " + expected, expected.isEmpty());
 }
 @Test
 public void testEntityCeasesToBeTemporaryIfBlockChangedToKeepActive() {
   worldProvider.setBlock(Vector3i.zero(), keepActiveBlock);
   worldProvider.update(1.0f);
   LifecycleEventChecker checker =
       new LifecycleEventChecker(entityManager.getEventSystem(), StringComponent.class);
   worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
   assertTrue(checker.receivedEvents.isEmpty());
 }
  @Test
  public void retainedComponentsNotAltered() {
    EntityRef entity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
    entity.addComponent(new RetainedOnBlockChangeComponent(2));

    worldProvider.setBlock(Vector3i.zero(), blockWithRetainedComponent);

    assertEquals(2, entity.getComponent(RetainedOnBlockChangeComponent.class).value);
  }
  @Test
  public void testEntityExtraComponentsRemovedBeforeCleanUpForBlocksWithPrefabs() {
    worldStub.setBlock(Vector3i.zero(), blockWithString);
    EntityRef entity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
    entity.addComponent(new IntegerComponent(1));

    LifecycleEventChecker checker =
        new LifecycleEventChecker(entityManager.getEventSystem(), IntegerComponent.class);

    worldProvider.update(1.0f);
    assertEquals(
        Lists.newArrayList(
            new EventInfo(BeforeDeactivateComponent.newInstance(), entity),
            new EventInfo(BeforeRemoveComponent.newInstance(), entity)),
        checker.receivedEvents);
  }
  @Test
  public void testChangedComponentsRevertedBeforeCleanUp() {
    worldStub.setBlock(Vector3i.zero(), blockWithString);
    EntityRef entity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
    StringComponent comp = entity.getComponent(StringComponent.class);
    comp.value = "Moo";
    entity.saveComponent(comp);

    LifecycleEventChecker checker =
        new LifecycleEventChecker(entityManager.getEventSystem(), StringComponent.class);

    worldProvider.update(1.0f);
    assertEquals(
        Lists.newArrayList(new EventInfo(OnChangedComponent.newInstance(), entity)),
        checker.receivedEvents);
  }
  @Test
  public void testEntityMissingComponentsAddedBeforeCleanUp() {
    worldStub.setBlock(Vector3i.zero(), blockWithString);
    EntityRef entity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
    entity.removeComponent(StringComponent.class);

    LifecycleEventChecker checker =
        new LifecycleEventChecker(entityManager.getEventSystem(), StringComponent.class);

    worldProvider.update(1.0f);
    assertEquals(
        Lists.newArrayList(
            new EventInfo(OnAddedComponent.newInstance(), entity),
            new EventInfo(OnActivatedComponent.newInstance(), entity)),
        checker.receivedEvents);
  }
  @Test
  public void testActiveBlockNotCleanedUp() {
    Block testBlock = new Block();
    testBlock.setKeepActive(true);
    BlockFamily blockFamily = new SymmetricFamily(new BlockUri("test:keepActive"), testBlock);
    blockManager.addBlockFamily(blockFamily, true);
    worldStub.setBlock(Vector3i.zero(), testBlock);

    BlockEventChecker checker = new BlockEventChecker();
    entityManager.getEventSystem().registerEventHandler(checker);

    EntityRef blockEntity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0));
    worldProvider.update(1.0f);
    assertTrue(blockEntity.exists());
    assertTrue(blockEntity.isActive());
    assertTrue(checker.addedReceived);
    assertTrue(checker.activateReceived);
  }
 @Override
 public EntityRef getOrCreateBlockEntityAt(Vector3i blockPosition) {
   EntityRef blockEntity = getBlockEntityAt(blockPosition);
   if (!blockEntity.exists()) {
     Block block = getBlock(blockPosition.x, blockPosition.y, blockPosition.z);
     blockEntity = entityManager.create(block.getEntityPrefab());
     if (block.isEntityTemporary()) {
       tempBlocks.add(blockEntity);
     }
     blockEntity.addComponent(new LocationComponent(blockPosition.toVector3f()));
     blockEntity.addComponent(new BlockComponent(blockPosition, block.isEntityTemporary()));
     // TODO: Get regen and wait from block config?
     if (block.isDestructible()) {
       blockEntity.addComponent(new HealthComponent(block.getHardness(), 2.0f, 1.0f));
     }
   }
   return blockEntity;
 }
 @Test
 public void oneDistanceIteration() {
   Iterator<Vector3i> iter = new Diamond3iIterator(Vector3i.zero(), 1);
   assertEquals(Lists.newArrayList(Vector3i.zero()), Lists.newArrayList(iter));
 }
 @Test
 public void zeroDistanceIteration() {
   Iterator<Vector3i> iter = new Diamond3iIterator(Vector3i.zero(), 0);
   assertFalse(iter.hasNext());
 }