package japicmp.compat;
import japicmp.cmp.ClassesHelper;
import japicmp.cmp.JarArchiveComparatorOptions;
import japicmp.model.*;
import japicmp.util.CtClassBuilder;
import japicmp.util.CtFieldBuilder;
import japicmp.util.CtMethodBuilder;
import javassist.ClassPool;
import javassist.CtClass;
import org.junit.Test;
import java.io.Serializable;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static japicmp.util.Helper.getJApiClass;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public class SerializationChangesTest {
@Test
public void testEnumUnchanged() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().enumModifier().name("japicmp.Test").withSuperclass(classPool.get(Enum.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(ctClass).staticAccess().finalAccess().name("OPTION1").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().enumModifier().name("japicmp.Test").withSuperclass(classPool.get(Enum.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(ctClass).staticAccess().finalAccess().name("OPTION1").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getClassType().getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getClassType().getNewTypeOptional().get(), is(JApiClassType.ClassType.ENUM));
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getSerialVersionUid().isSerializableOld(), is(true));
assertThat(jApiClass.getSerialVersionUid().isSerializableNew(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible().isIncompatible(), is(false));
}
@Test
public void testEnumElementAdded() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().enumModifier().name("japicmp.Test").withSuperclass(classPool.get(Enum.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(ctClass).staticAccess().finalAccess().name("OPTION1").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().enumModifier().name("japicmp.Test").withSuperclass(classPool.get(Enum.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(ctClass).staticAccess().finalAccess().name("OPTION1").addToClass(ctClass);
CtFieldBuilder.create().type(ctClass).staticAccess().finalAccess().name("OPTION2").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getClassType().getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getClassType().getNewTypeOptional().get(), is(JApiClassType.ClassType.ENUM));
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.MODIFIED));
assertThat(jApiClass.getSerialVersionUid().isSerializableOld(), is(true));
assertThat(jApiClass.getSerialVersionUid().isSerializableNew(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible().isIncompatible(), is(false));
}
@Test
public void testEnumElementRemoved() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().enumModifier().name("japicmp.Test").withSuperclass(classPool.get(Enum.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(ctClass).staticAccess().finalAccess().name("OPTION1").addToClass(ctClass);
CtFieldBuilder.create().type(ctClass).staticAccess().finalAccess().name("OPTION2").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().enumModifier().name("japicmp.Test").withSuperclass(classPool.get(Enum.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(ctClass).staticAccess().finalAccess().name("OPTION1").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getClassType().getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getClassType().getNewTypeOptional().get(), is(JApiClassType.ClassType.ENUM));
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.MODIFIED));
assertThat(jApiClass.getSerialVersionUid().isSerializableOld(), is(true));
assertThat(jApiClass.getSerialVersionUid().isSerializableNew(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible().isIncompatible(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible(), is(JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus.SERIALIZABLE_INCOMPATIBLE_FIELD_REMOVED));
}
@Test
public void testClassCompatible() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").implementsInterface(classPool.get(Serializable.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).staticAccess().finalAccess().name("CONST").addToClass(ctClass);
CtMethodBuilder.create().returnType(CtClass.intType).name("method").body("return 42;").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").implementsInterface(classPool.get(Serializable.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).staticAccess().finalAccess().name("CONST").addToClass(ctClass);
CtMethodBuilder.create().returnType(CtClass.intType).name("method").body("return 42;").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getClassType().getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getClassType().getNewTypeOptional().get(), is(JApiClassType.ClassType.CLASS));
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getSerialVersionUid().isSerializableOld(), is(true));
assertThat(jApiClass.getSerialVersionUid().isSerializableNew(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible().isIncompatible(), is(false));
assertThat(jApiClass.getJavaObjectSerializationCompatible(), is(JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus.SERIALIZABLE_COMPATIBLE));
}
@Test
public void testClassCompatibleWithSerialVersionUid() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").implementsInterface(classPool.get(Serializable.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).staticAccess().finalAccess().name("CONST").addToClass(ctClass);
CtFieldBuilder.create().type(CtClass.longType).staticAccess().finalAccess().name("serialVersionUID").withConstantValue(1L).addToClass(ctClass);
CtMethodBuilder.create().returnType(CtClass.intType).name("method").body("return 42;").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").implementsInterface(classPool.get(Serializable.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).staticAccess().finalAccess().name("CONST").addToClass(ctClass);
CtFieldBuilder.create().type(CtClass.longType).staticAccess().finalAccess().name("serialVersionUID").withConstantValue(1L).addToClass(ctClass);
CtMethodBuilder.create().returnType(CtClass.intType).name("method").body("return 42;").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getClassType().getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getClassType().getNewTypeOptional().get(), is(JApiClassType.ClassType.CLASS));
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getSerialVersionUid().isSerializableOld(), is(true));
assertThat(jApiClass.getSerialVersionUid().isSerializableNew(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible().isIncompatible(), is(false));
assertThat(jApiClass.getJavaObjectSerializationCompatible(), is(JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus.SERIALIZABLE_COMPATIBLE));
}
@Test
public void testClassSerialVersionUidChanged() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").implementsInterface(classPool.get(Serializable.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).staticAccess().finalAccess().name("CONST").addToClass(ctClass);
CtFieldBuilder.create().type(CtClass.longType).staticAccess().finalAccess().name("serialVersionUID").withConstantValue(1L).addToClass(ctClass);
CtMethodBuilder.create().returnType(CtClass.intType).name("method").body("return 42;").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").implementsInterface(classPool.get(Serializable.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).staticAccess().finalAccess().name("CONST").addToClass(ctClass);
CtFieldBuilder.create().type(CtClass.longType).staticAccess().finalAccess().name("serialVersionUID").withConstantValue(2L).addToClass(ctClass);
CtMethodBuilder.create().returnType(CtClass.intType).name("method").body("return 42;").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getClassType().getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getClassType().getNewTypeOptional().get(), is(JApiClassType.ClassType.CLASS));
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getSerialVersionUid().isSerializableOld(), is(true));
assertThat(jApiClass.getSerialVersionUid().isSerializableNew(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible().isIncompatible(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible(), is(JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus.SERIALIZABLE_INCOMPATIBLE_SERIALVERSIONUID_MODIFIED));
}
@Test
public void testClassSerialVersionUidRemovedAndNotMatchesNewDefault() throws Exception {
JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
options.setIncludeSynthetic(true);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(options, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").implementsInterface(classPool.get(Serializable.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).staticAccess().finalAccess().name("CONST").addToClass(ctClass);
CtFieldBuilder.create().type(CtClass.longType).staticAccess().finalAccess().name("serialVersionUID").withConstantValue(1L).addToClass(ctClass);
CtMethodBuilder.create().returnType(CtClass.intType).name("method").body("return 42;").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").implementsInterface(classPool.get(Serializable.class.getName())).addToClassPool(classPool);
CtFieldBuilder.create().type(CtClass.intType).staticAccess().finalAccess().name("CONST").addToClass(ctClass);
CtMethodBuilder.create().returnType(CtClass.intType).name("method").body("return 42;").addToClass(ctClass);
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getClassType().getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(jApiClass.getClassType().getNewTypeOptional().get(), is(JApiClassType.ClassType.CLASS));
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.MODIFIED));
assertThat(jApiClass.getSerialVersionUid().isSerializableOld(), is(true));
assertThat(jApiClass.getSerialVersionUid().isSerializableNew(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible().isIncompatible(), is(true));
assertThat(jApiClass.getJavaObjectSerializationCompatible(), is(JApiJavaObjectSerializationCompatibility.JApiJavaObjectSerializationChangeStatus.SERIALIZABLE_INCOMPATIBLE_SERIALVERSIONUID_REMOVED_AND_NOT_MACHTES_NEW_DEFAULT));
}
}