package japicmp.cmp;
import japicmp.model.AccessModifier;
import japicmp.model.JApiChangeStatus;
import japicmp.model.JApiClass;
import japicmp.model.JApiCompatibilityChange;
import japicmp.util.CtClassBuilder;
import japicmp.util.CtInterfaceBuilder;
import javassist.ClassPool;
import javassist.CtClass;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static japicmp.util.Helper.getJApiClass;
import static japicmp.util.Helper.getJApiImplementedInterface;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
public class SuperclassTest {
@Test
public void testClassHasNoSuperclass() 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 = classPool.get("java.lang.Object");
return Collections.singletonList(ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = classPool.get("java.lang.Object");
return Collections.singletonList(ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "java.lang.Object");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
}
@Test
public void testNewClass() 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 {
return Collections.EMPTY_LIST;
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClass = CtClassBuilder.create().name("japicmp.Test").addToClassPool(classPool);
CtClass ctClassSuper = CtClassBuilder.create().name("japicmp.Super").addToClassPool(classPool);
ctClass.setSuperclass(ctClassSuper);
return Arrays.asList(ctClass, ctClassSuper);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.NEW));
assertThat(jApiClass.getSuperclass().getChangeStatus(), is(JApiChangeStatus.NEW));
assertThat(jApiClass.getSuperclass().getOldSuperclass().isPresent(), is(false));
assertThat(jApiClass.getSuperclass().getNewSuperclass().isPresent(), is(true));
assertThat(jApiClass.getSuperclass().getNewSuperclass().get().getName(), is("japicmp.Super"));
}
@Test
public void testRemovedClass() 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").addToClassPool(classPool);
CtClass ctClassSuper = CtClassBuilder.create().name("japicmp.Super").addToClassPool(classPool);
ctClass.setSuperclass(ctClassSuper);
return Arrays.asList(ctClass, ctClassSuper);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
return Collections.EMPTY_LIST;
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "japicmp.Test");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.REMOVED));
assertThat(jApiClass.getSuperclass().getChangeStatus(), is(JApiChangeStatus.REMOVED));
assertThat(jApiClass.getSuperclass().getOldSuperclass().isPresent(), is(true));
assertThat(jApiClass.getSuperclass().getNewSuperclass().isPresent(), is(false));
assertThat(jApiClass.getSuperclass().getOldSuperclass().get().getName(), is("japicmp.Super"));
}
@Test
public void testClassHierarchyHasOneMoreLevel() throws Exception {
JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions();
jarArchiveComparatorOptions.setAccessModifier(AccessModifier.PRIVATE);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClassBase = CtInterfaceBuilder.create().name("Base").addToClassPool(classPool);
CtClass ctClass = CtClassBuilder.create().name("Test").withSuperclass(ctClassBase).addToClassPool(classPool);
return Arrays.asList(ctClassBase, ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClassBase = CtClassBuilder.create().name("Base").addToClassPool(classPool);
CtClass ctClassIntermediate = CtClassBuilder.create().name("Intermediate").withSuperclass(ctClassBase).addToClassPool(classPool);
CtClass ctClass = CtClassBuilder.create().name("Test").withSuperclass(ctClassIntermediate).addToClassPool(classPool);
return Arrays.asList(ctClassBase, ctClassIntermediate, ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "Test");
assertThat(jApiClass.isBinaryCompatible(), is(true));
assertThat(jApiClass.isSourceCompatible(), is(true));
assertThat(jApiClass.getCompatibilityChanges(), not(hasItem(JApiCompatibilityChange.SUPERCLASS_REMOVED)));
assertThat(jApiClass.getSuperclass().getChangeStatus(), is(JApiChangeStatus.MODIFIED));
jApiClass = getJApiClass(jApiClasses, "Intermediate");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.NEW));
}
@Test
public void testClassHierarchyHasOneMoreLevelWithExistingClasses() throws Exception {
JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions();
jarArchiveComparatorOptions.setAccessModifier(AccessModifier.PRIVATE);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClassBase = CtInterfaceBuilder.create().name("Base").addToClassPool(classPool);
CtClass ctClassIntermediate = CtClassBuilder.create().name("Intermediate").withSuperclass(ctClassBase).addToClassPool(classPool);
CtClass ctClass = CtClassBuilder.create().name("Test").withSuperclass(ctClassBase).addToClassPool(classPool);
return Arrays.asList(ctClassBase, ctClassIntermediate, ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClassBase = CtClassBuilder.create().name("Base").addToClassPool(classPool);
CtClass ctClassIntermediate = CtClassBuilder.create().name("Intermediate").withSuperclass(ctClassBase).addToClassPool(classPool);
CtClass ctClass = CtClassBuilder.create().name("Test").withSuperclass(ctClassIntermediate).addToClassPool(classPool);
return Arrays.asList(ctClassBase, ctClassIntermediate, ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "Test");
assertThat(jApiClass.isBinaryCompatible(), is(true));
assertThat(jApiClass.isSourceCompatible(), is(true));
assertThat(jApiClass.getSuperclass().getChangeStatus(), is(JApiChangeStatus.MODIFIED));
jApiClass = getJApiClass(jApiClasses, "Intermediate");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
}
@Test
public void testClassHierarchyHasOneLessLevel() throws Exception {
JarArchiveComparatorOptions jarArchiveComparatorOptions = new JarArchiveComparatorOptions();
jarArchiveComparatorOptions.setAccessModifier(AccessModifier.PRIVATE);
List<JApiClass> jApiClasses = ClassesHelper.compareClasses(jarArchiveComparatorOptions, new ClassesHelper.ClassesGenerator() {
@Override
public List<CtClass> createOldClasses(ClassPool classPool) throws Exception {
CtClass ctClassBase = CtClassBuilder.create().name("Base").addToClassPool(classPool);
CtClass ctClassIntermediate = CtClassBuilder.create().name("Intermediate").withSuperclass(ctClassBase).addToClassPool(classPool);
CtClass ctClass = CtClassBuilder.create().name("Test").withSuperclass(ctClassIntermediate).addToClassPool(classPool);
return Arrays.asList(ctClassBase, ctClassIntermediate, ctClass);
}
@Override
public List<CtClass> createNewClasses(ClassPool classPool) throws Exception {
CtClass ctClassBase = CtInterfaceBuilder.create().name("Base").addToClassPool(classPool);
CtClass ctClass = CtClassBuilder.create().name("Test").withSuperclass(ctClassBase).addToClassPool(classPool);
return Arrays.asList(ctClassBase, ctClass);
}
});
JApiClass jApiClass = getJApiClass(jApiClasses, "Test");
assertThat(jApiClass.isBinaryCompatible(), is(false));
assertThat(jApiClass.isSourceCompatible(), is(false));
assertThat(jApiClass.getSuperclass().getCompatibilityChanges(), hasItem(JApiCompatibilityChange.SUPERCLASS_REMOVED));
assertThat(jApiClass.getSuperclass().getChangeStatus(), is(JApiChangeStatus.MODIFIED));
jApiClass = getJApiClass(jApiClasses, "Intermediate");
assertThat(jApiClass.getChangeStatus(), is(JApiChangeStatus.REMOVED));
}
}