package openmods.serializable; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import java.io.IOException; import openmods.serializable.cls.ClassSerializersProvider; import openmods.serializable.cls.Serialize; import org.junit.Assert; import org.junit.Test; public class ClassSerializerTest { private static final int DUMMY_INT = -1; private static <T> void testSerializer(final IObjectSerializer<T> serializer, T source, T target) { try { ByteArrayDataOutput output = ByteStreams.newDataOutput(); serializer.writeToStream(source, output); ByteArrayDataInput input = ByteStreams.newDataInput(output.toByteArray()); serializer.readFromStream(target, input); assertFullyRead(input); } catch (IOException e) { throw new RuntimeException(e); } } private static void assertFullyRead(ByteArrayDataInput input) { Assert.assertEquals(0, input.skipBytes(256)); } public static class NonNullableClass { public int notSerialized = DUMMY_INT; @Serialize(nullable = false) public String stringField = "dummy"; @Serialize(nullable = false) public int intField = -2; } @Test public void testNonNullable() { IObjectSerializer<NonNullableClass> serializer = ClassSerializersProvider.instance.getSerializer(NonNullableClass.class); NonNullableClass source = new NonNullableClass(); source.intField = 4; source.stringField = "blarg"; source.notSerialized = 999; NonNullableClass target = new NonNullableClass(); testSerializer(serializer, source, target); Assert.assertEquals(source.stringField, target.stringField); Assert.assertEquals(source.intField, target.intField); Assert.assertEquals(DUMMY_INT, target.notSerialized); } @Test(expected = NullPointerException.class) public void testNonNullableFail() { IObjectSerializer<NonNullableClass> serializer = ClassSerializersProvider.instance.getSerializer(NonNullableClass.class); NonNullableClass source = new NonNullableClass(); source.stringField = null; NonNullableClass target = new NonNullableClass(); testSerializer(serializer, source, target); } public static class NullableClass { public int notSerialized = DUMMY_INT; @Serialize public String stringField = "dummy"; @Serialize public String nullField = "dummy2"; @Serialize public int intField = -2; } @Test public void testNullable() { IObjectSerializer<NullableClass> serializer = ClassSerializersProvider.instance.getSerializer(NullableClass.class); NullableClass source = new NullableClass(); source.intField = 4; source.stringField = "blarg"; source.nullField = null; source.notSerialized = 999; NullableClass target = new NullableClass(); testSerializer(serializer, source, target); Assert.assertEquals(source.stringField, target.stringField); Assert.assertEquals(source.intField, target.intField); Assert.assertEquals(source.nullField, target.nullField); Assert.assertEquals(DUMMY_INT, target.notSerialized); } public static class CompatibleSourceClass { @Serialize(rank = 1, nullable = false) public int field1 = 10; public boolean field2A = false; @Serialize(rank = 2) public boolean field2 = true; @Serialize(rank = 3) public String field3 = "hello"; @Serialize(rank = 4) public int field4 = 6210; } public static class CompatibleTargetClass { @Serialize(rank = 4) public int field0 = 6532; @Serialize(rank = 2) public boolean field1 = false; @Serialize(rank = 3) public String field2 = "zomg"; public String field2A = "fff"; @Serialize(rank = 1) public int field3 = 4424; } @Test public void testReorderedClasses() throws IOException { IObjectSerializer<CompatibleSourceClass> serializerA = ClassSerializersProvider.instance.getSerializer(CompatibleSourceClass.class); CompatibleSourceClass source = new CompatibleSourceClass(); ByteArrayDataOutput output = ByteStreams.newDataOutput(); serializerA.writeToStream(source, output); IObjectSerializer<CompatibleTargetClass> serializerB = ClassSerializersProvider.instance.getSerializer(CompatibleTargetClass.class); CompatibleTargetClass target = new CompatibleTargetClass(); ByteArrayDataInput input = ByteStreams.newDataInput(output.toByteArray()); serializerB.readFromStream(target, input); assertFullyRead(input); Assert.assertEquals(source.field1, target.field3); Assert.assertEquals(source.field2, target.field1); Assert.assertEquals(source.field3, target.field2); Assert.assertEquals(source.field4, target.field0); } public static class GenericBase1<A, B> { @Serialize public A fieldA; @Serialize public B fieldB; } public static class GenericBase2<A, B, C, D> extends GenericBase1<C, D> { @Serialize public A fieldC; @Serialize public B fieldD; } public static class GenericDerrived extends GenericBase2<Integer, String, Boolean, Float> { } @Test public void testClassWithGenericBase() { IObjectSerializer<GenericDerrived> serializer = ClassSerializersProvider.instance.getSerializer(GenericDerrived.class); GenericDerrived source = new GenericDerrived(); source.fieldA = false; source.fieldB = 3.5f; source.fieldC = 34; source.fieldD = "Hello"; GenericDerrived target = new GenericDerrived(); source.fieldA = true; source.fieldB = 99.2f; source.fieldC = 545; source.fieldD = "Bye"; testSerializer(serializer, source, target); } }