diff --git a/src/functionalTest/java/codechicken/multipart/test/ControlKeyModiferFunctionalTest.java b/src/functionalTest/java/codechicken/multipart/test/ControlKeyModiferFunctionalTest.java new file mode 100644 index 0000000..bd9d795 --- /dev/null +++ b/src/functionalTest/java/codechicken/multipart/test/ControlKeyModiferFunctionalTest.java @@ -0,0 +1,76 @@ +package codechicken.multipart.test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.WorldServer; +import net.minecraftforge.common.util.FakePlayerFactory; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import codechicken.multipart.ControlKeyModifer; + +/** + * isControlDown needs a player with a world to pick its branch. On a dedicated server the world is never remote, so + * these cover the server half: the map the client keeps in sync through packet 1. The client half reads + * isClientPressing instead and no test harness has a client. + */ +class ControlKeyModiferFunctionalTest { + + @BeforeEach + @AfterEach + void clearRecordedPlayers() { + clearAll(); + } + + @Test + void aPlayerTheServerHasNotHeardFromIsNotHoldingTheKey() { + assertFalse(ControlKeyModifer.isControlDown(player())); + } + + @Test + void reflectsWhatTheServerLastRecordedForThePlayer() { + EntityPlayer player = player(); + + record(player, true); + assertTrue(ControlKeyModifer.isControlDown(player)); + + record(player, false); + assertFalse(ControlKeyModifer.isControlDown(player)); + } + + /** Server stop clears the map, so a player must not carry a held key into the next run. */ + @Test + void clearingResetsThePlayerToNotHolding() { + EntityPlayer player = player(); + record(player, true); + + clearAll(); + + assertFalse(ControlKeyModifer.isControlDown(player)); + } + + // The two adapters below are the only places the map's collection type is named. + + private static void record(EntityPlayer player, boolean pressed) { + ControlKeyModifer.map().put(player, pressed); + } + + private static void clearAll() { + ControlKeyModifer.map().clear(); + } + + private static EntityPlayer player() { + WorldServer world = MinecraftServer.getServer().worldServers[0]; + assertNotNull(world); + EntityPlayer player = FakePlayerFactory.getMinecraft(world); + assertNotNull(player); + assertFalse(player.worldObj.isRemote, "A dedicated server world is never remote"); + return player; + } +} diff --git a/src/test/java/codechicken/multipart/ControlKeyModiferCharacterizationTest.java b/src/test/java/codechicken/multipart/ControlKeyModiferCharacterizationTest.java new file mode 100644 index 0000000..4da0461 --- /dev/null +++ b/src/test/java/codechicken/multipart/ControlKeyModiferCharacterizationTest.java @@ -0,0 +1,35 @@ +package codechicken.multipart; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import net.minecraft.entity.player.EntityPlayer; + +import org.junit.jupiter.api.Test; + +/** + * Every branch of isControlDown needs a player with a world, so the behavior is covered by the Forge server suite + * against a FakePlayer. What is pinned here is the Java-facing entry point, which the reference scaladoc calls out as + * existing for Java callers rather than for the Scala implicit. + */ +class ControlKeyModiferCharacterizationTest { + + /** The class name carries a typo in the reference. It is the published name, so the port keeps it. */ + @Test + void theTypoInTheClassNameIsPreserved() { + assertEquals("codechicken.multipart.ControlKeyModifer", ControlKeyModifer.class.getName()); + } + + @Test + void theJavaFacingQueryIsAPublicStaticTakingAPlayer() throws Exception { + Method isControlDown = ControlKeyModifer.class.getDeclaredMethod("isControlDown", EntityPlayer.class); + + assertSame(boolean.class, isControlDown.getReturnType()); + assertTrue(Modifier.isPublic(isControlDown.getModifiers())); + assertTrue(Modifier.isStatic(isControlDown.getModifiers())); + } +}