Added StructureModifier tests for different packet types.

This commit is contained in:
Kristian S. Stangeland 2012-12-25 15:44:14 +01:00
parent 425c5fd682
commit 655fbf4799
2 changed files with 358 additions and 0 deletions

View File

@ -8,6 +8,7 @@
<properties> <properties>
<project.build.sourceEncoding>cp1252</project.build.sourceEncoding> <project.build.sourceEncoding>cp1252</project.build.sourceEncoding>
<powermock.version>1.5</powermock.version>
</properties> </properties>
<distributionManagement> <distributionManagement>
@ -211,5 +212,22 @@
<version>4.10</version> <version>4.10</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -0,0 +1,340 @@
package com.comphenix.protocol.events;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.List;
// Will have to be updated for every version though
import org.bukkit.craftbukkit.v1_4_6.inventory.CraftItemFactory;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.WorldType;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import com.comphenix.protocol.Packets;
import com.comphenix.protocol.reflect.FieldUtils;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.ChunkPosition;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
// Ensure that the CraftItemFactory is mockable
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PrepareForTest(CraftItemFactory.class)
public class PacketContainerTest {
@BeforeClass
public static void initializeBukkit() throws IllegalAccessException {
// Initialize reflection
MinecraftReflection.setMinecraftPackage("net.minecraft.server.v1_4_6", "org.bukkit.craftbukkit.v1_4_6");
// Mock the server object
Server mockedServer = mock(Server.class);
ItemFactory mockedFactory = mock(CraftItemFactory.class);
ItemMeta mockedMeta = mock(ItemMeta.class);
when(mockedServer.getItemFactory()).thenReturn(mockedFactory);
when(mockedFactory.getItemMeta(any(Material.class))).thenReturn(mockedMeta);
// Inject this fake server
FieldUtils.writeStaticField(Bukkit.class, "server", mockedServer, true);
// And the fake item factory
FieldUtils.writeStaticField(CraftItemFactory.class, "instance", mockedFactory, true);
}
private <T> void testPrimitive(StructureModifier<T> modifier, int index, T initialValue, T testValue) {
// Check initial value
assertEquals(initialValue, modifier.read(index));
// Test assignment
modifier.write(index, testValue);
assertEquals(testValue, modifier.read(0));
}
private <T> void testObjectArray(StructureModifier<T[]> modifier, int index, T[] initialValue, T[] testValue) {
// Check initial value
assertNull(modifier.read(index));
modifier.writeDefaults();
// Test initial
assertArrayEquals(initialValue, modifier.read(index));
// Test assignment
modifier.write(index, testValue);
assertArrayEquals(testValue, modifier.read(0));
}
@Test
public void testGetByteArrays() {
// Contains a byte array we will test
PacketContainer customPayload = new PacketContainer(Packets.Server.CUSTOM_PAYLOAD);
StructureModifier<byte[]> bytes = customPayload.getByteArrays();
byte[] testArray = new byte[] { 1, 2, 3 };
// It's NULL at first
assertArrayEquals(null, (byte[]) bytes.read(0));
customPayload.getModifier().writeDefaults();
// Then it should create an empty array
assertArrayEquals(new byte[0], (byte[]) bytes.read(0));
// Check and see if we can write to it
bytes.write(0, testArray);
assertArrayEquals(testArray, (byte[]) bytes.read(0));
}
@Test
public void testGetBytes() {
PacketContainer spawnMob = new PacketContainer(Packets.Server.MOB_SPAWN);
testPrimitive(spawnMob.getBytes(), 0, (byte)0, (byte)1);
}
@Test
public void testGetShorts() {
PacketContainer itemData = new PacketContainer(Packets.Server.ITEM_DATA);
testPrimitive(itemData.getShorts(), 0, (short)0, (short)1);
}
@Test
public void testGetIntegers() {
PacketContainer updateSign = new PacketContainer(Packets.Server.UPDATE_SIGN);
testPrimitive(updateSign.getIntegers(), 0, (int)0, (int)1);
}
@Test
public void testGetLongs() {
PacketContainer updateTime = new PacketContainer(Packets.Server.UPDATE_TIME);
testPrimitive(updateTime.getLongs(), 0, (long)0, (long)1);
}
@Test
public void testGetFloat() {
PacketContainer explosion = new PacketContainer(Packets.Server.EXPLOSION);
testPrimitive(explosion.getFloat(), 0, (float)0, (float)0.8);
}
@Test
public void testGetDoubles() {
PacketContainer explosion = new PacketContainer(Packets.Server.EXPLOSION);
testPrimitive(explosion.getDoubles(), 0, (double)0, (double)0.8);
}
@Test
public void testGetStrings() {
PacketContainer explosion = new PacketContainer(Packets.Server.CHAT);
testPrimitive(explosion.getStrings(), 0, null, "hello");
}
@Test
public void testGetStringArrays() {
PacketContainer explosion = new PacketContainer(Packets.Server.UPDATE_SIGN);
testObjectArray(explosion.getStringArrays(), 0, new String[0], new String[] { "hello", "world" });
}
@Test
public void testGetIntegerArrays() {
// Contains a byte array we will test
PacketContainer mapChunkBulk = new PacketContainer(Packets.Server.MAP_CHUNK_BULK);
StructureModifier<int[]> integers = mapChunkBulk.getIntegerArrays();
int[] testArray = new int[] { 1, 2, 3 };
// Pre and post conditions
assertArrayEquals(null, (int[]) integers.read(0));
mapChunkBulk.getModifier().writeDefaults();
assertArrayEquals(new int[0], (int[]) integers.read(0));
integers.write(0, testArray);
assertArrayEquals(testArray, (int[]) integers.read(0));
}
@Test
public void testGetItemModifier() {
PacketContainer windowClick = new PacketContainer(Packets.Client.WINDOW_CLICK);
StructureModifier<ItemStack> items = windowClick.getItemModifier();
ItemStack goldAxe = new ItemStack(Material.GOLD_AXE);
assertNull(items.read(0));
// Insert the goldaxe and check if it's there
items.write(0, goldAxe);
assertTrue(equivalentItem(goldAxe, items.read(0)));
}
@Test
public void testGetItemArrayModifier() {
PacketContainer windowItems = new PacketContainer(Packets.Server.WINDOW_ITEMS);
StructureModifier<ItemStack[]> itemAccess = windowItems.getItemArrayModifier();
ItemStack[] itemArray = new ItemStack[] {
new ItemStack(Material.GOLD_AXE),
new ItemStack(Material.DIAMOND_AXE)
};
assertNull(itemAccess.read(0));
// Insert and check that it was succesful
itemAccess.write(0, itemArray);
// Read back array
ItemStack[] comparision = itemAccess.read(0);
assertEquals(itemArray.length, comparision.length);
// Check that it is equivalent
for (int i = 0; i < itemArray.length; i++) {
assertTrue(String.format("Array element %s is not the same: %s != %s",
i, itemArray[i], comparision[i]), equivalentItem(itemArray[i], comparision[i]));
}
}
private boolean equivalentItem(ItemStack first, ItemStack second) {
if (first == null)
return second == null;
else if (second == null)
return false;
else
return first.getType().equals(second.getType());
}
private boolean equivalentPacket(PacketContainer first, PacketContainer second) {
if (first == null)
return second == null;
else if (second == null)
return false;
else
return first.getModifier().getValues().equals(second.getModifier().getValues());
}
@Test
public void testGetWorldTypeModifier() {
PacketContainer loginPacket = new PacketContainer(Packets.Server.LOGIN);
StructureModifier<WorldType> worldAccess = loginPacket.getWorldTypeModifier();
WorldType testValue = WorldType.LARGE_BIOMES;
assertNull(worldAccess.read(0));
// Insert and read back
worldAccess.write(0, testValue);
assertEquals(testValue, worldAccess.read(0));
}
@Test
public void testGetDataWatcherModifier() {
PacketContainer mobSpawnPacket = new PacketContainer(Packets.Server.MOB_SPAWN);
StructureModifier<WrappedDataWatcher> watcherAccessor = mobSpawnPacket.getDataWatcherModifier();
WrappedDataWatcher dataWatcher = new WrappedDataWatcher();
dataWatcher.setObject(1, 100);
dataWatcher.setObject(2, 125);
assertNull(watcherAccessor.read(0));
// Insert and read back
watcherAccessor.write(0, dataWatcher);
assertEquals(dataWatcher, watcherAccessor.read(0));
}
// Unfortunately, it might be too difficult to mock this one
//
// @Test
// public void testGetEntityModifier() { }
// No packet expose this type directly.
//
// @Test
// public void testGetPositionModifier() { }
@Test
public void testGetPositionCollectionModifier() {
PacketContainer explosionPacket = new PacketContainer(Packets.Server.EXPLOSION);
StructureModifier<List<ChunkPosition>> positionAccessor = explosionPacket.getPositionCollectionModifier();
assertNull(positionAccessor.read(0));
List<ChunkPosition> positions = Lists.newArrayList();
positions.add(new ChunkPosition(1, 2, 3));
positions.add(new ChunkPosition(3, 4, 5));
// Insert and read back
positionAccessor.write(0, positions);
assertEquals(positions, positionAccessor.read(0));
}
@Test
public void testGetWatchableCollectionModifier() {
PacketContainer entityMetadata = new PacketContainer(Packets.Server.ENTITY_METADATA);
StructureModifier<List<WrappedWatchableObject>> watchableAccessor =
entityMetadata.getWatchableCollectionModifier();
assertNull(watchableAccessor.read(0));
WrappedDataWatcher watcher = new WrappedDataWatcher();
watcher.setObject(1, 10);
watcher.setObject(8, 10);
List<WrappedWatchableObject> list = watcher.getWatchableObjects();
// Insert and read back
watchableAccessor.write(0, list);
assertEquals(list, watchableAccessor.read(0));
}
@Test
public void testDeepClone() {
// Try constructing all the packets
for (Integer id : Iterables.concat(
Packets.getClientRegistry().values(),
Packets.getServerRegistry().values() )) {
// Whether or not this packet has been registered
boolean registered = Packets.Server.isSupported(id) ||
Packets.Client.isSupported(id);
try {
PacketContainer constructed = new PacketContainer(id);
if (!registered) {
fail("Expected IllegalArgumentException(Packet " + id + " not registered");
}
// Make sure these packets contains fields as well
assertTrue("Constructed packet with no known fields (" + id + ")",
constructed.getModifier().size() > 0);
// Initialize default values
constructed.getModifier().writeDefaults();
// Clone the packet
PacketContainer cloned = constructed.deepClone();
// Make sure they're equivalent
assertTrue("Packet " + id + " could not be cloned.", equivalentPacket(constructed, cloned));
} catch (IllegalArgumentException e) {
if (!registered) {
// Check the same
assertEquals(e.getMessage(), "The packet ID " + id + " is not registered.");
} else {
// Something is very wrong
throw e;
}
}
}
}
}