diff options
Diffstat (limited to 'api')
-rw-r--r-- | api/src/main/java/org/osjava/jardiff/JarDiff.java | 19 | ||||
-rw-r--r-- | api/src/test/java/org/semver/jardiff/ClassInheritanceTest.java | 96 |
2 files changed, 108 insertions, 7 deletions
diff --git a/api/src/main/java/org/osjava/jardiff/JarDiff.java b/api/src/main/java/org/osjava/jardiff/JarDiff.java index 21eb333..6a55e87 100644 --- a/api/src/main/java/org/osjava/jardiff/JarDiff.java +++ b/api/src/main/java/org/osjava/jardiff/JarDiff.java @@ -46,10 +46,8 @@ import java.net.URL; import java.net.URLClassLoader; import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.Map; -import java.util.Set; import java.util.TreeSet; import java.util.TreeMap; import java.util.jar.JarEntry; @@ -187,8 +185,8 @@ public class JarDiff * @param reader the ClassReader * @return the ClassInfo */ - private synchronized ClassInfo loadClassInfo(ClassReader reader) - throws IOException + private synchronized ClassInfo loadClassInfo(ClassReader reader) + throws IOException { infoVisitor.reset(); reader.accept(infoVisitor, false); @@ -202,7 +200,7 @@ public class JarDiff * which contain classes in subdirectories or in the current directory. * * @param infoMap the map to store the ClassInfo in. - * @throws DiffException if there is an exception reading info about a + * @throws DiffException if there is an exception reading info about a * class. */ private void loadClasses(Map infoMap, URL path) throws DiffException { @@ -241,7 +239,7 @@ public class JarDiff * * @param infoMap the map to store the ClassInfo in. * @param file the jarfile to load classes from. - * @throws IOException if there is an IOException reading info about a + * @throws IOException if there is an IOException reading info about a * class. */ private void loadClasses(Map infoMap, File file) throws DiffException { @@ -313,7 +311,14 @@ public class JarDiff * writing to a file caused an IOException */ public void diff(DiffHandler handler, DiffCriteria criteria) - throws DiffException + throws DiffException + { + diff(handler, criteria, oldVersion, newVersion, oldClassInfo, newClassInfo); + } + + private void diff(DiffHandler handler, DiffCriteria criteria, + String oldVersion, String newVersion, + Map oldClassInfo, Map newClassInfo) throws DiffException { // TODO: Build the name from the MANIFEST rather than the filename handler.startDiff(oldVersion, newVersion); diff --git a/api/src/test/java/org/semver/jardiff/ClassInheritanceTest.java b/api/src/test/java/org/semver/jardiff/ClassInheritanceTest.java new file mode 100644 index 0000000..f399a8d --- /dev/null +++ b/api/src/test/java/org/semver/jardiff/ClassInheritanceTest.java @@ -0,0 +1,96 @@ +/** + * Copyright 2012 Julien Eluard and contributors. + * This project includes software developed by Julien Eluard: https://github.com/jeluard/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.semver.jardiff; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.Assert; + +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.osjava.jardiff.ClassInfo; +import org.osjava.jardiff.DiffCriteria; +import org.osjava.jardiff.DiffHandler; +import org.osjava.jardiff.JarDiff; +import org.osjava.jardiff.SimpleDiffCriteria; +import org.semver.Delta; +import org.semver.Delta.Change; + +public class ClassInheritanceTest { + + public static abstract class InheritanceRoot { + public abstract void aMethod(); + } + + public static class DirectDescendant extends InheritanceRoot { + @Override + public void aMethod() {} + } + + public static class ClassA extends InheritanceRoot { + @Override + public void aMethod() {} + } + + public static class ClassB extends DirectDescendant { + } + + public static class ClassC { + public void totallyDifferentMethod(int x) {}; + } + + @Test + public void shouldInheritedMethodMatchImplementedMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException { + /** + * The situation we are testing is as follows: + * Abstract class InheritanceRoot is initially implemented directly by ClassA. + * ClassA is later modified to extend another implementation of InheritanceRoot + * and the methods required by InheritanceRoot are now removed from ClassA directly, + * and instead inherited from the new parent, DirectDescendant. For the purposes of + * this test, this new ClassA is represented by ClassB (as we can't have the same + * class declared twice in a test -- in real life, this would both be ClassA's, + * in different jars). + */ + Map<String, ClassInfo> oldClassInfoMap = new HashMap<String, ClassInfo>(); + Map<String, ClassInfo> newClassInfoMap = new HashMap<String, ClassInfo>(); + JarDiff jd = new JarDiff(); + Method loadInfoMethod = JarDiff.class.getDeclaredMethod("loadClassInfo", ClassReader.class); + Method diffMethod = JarDiff.class.getDeclaredMethod("diff", DiffHandler.class, DiffCriteria.class, + String.class, String.class, + Map.class, Map.class); + diffMethod.setAccessible(true); + loadInfoMethod.setAccessible(true); + ClassInfo classInfoA = (ClassInfo) loadInfoMethod.invoke(jd, new ClassReader(ClassA.class.getName())); + oldClassInfoMap.put("ClassA", classInfoA); + ClassInfo classInfoB = (ClassInfo) loadInfoMethod.invoke(jd, new ClassReader(ClassB.class.getName())); + newClassInfoMap.put("ClassA", classInfoB); + DifferenceAccumulatingHandler handler = new DifferenceAccumulatingHandler(); + diffMethod.invoke(jd, handler, new SimpleDiffCriteria(), + "0.1.0", "0.2.0", oldClassInfoMap, newClassInfoMap); + + for (Delta.Difference d: handler.getDelta().getDifferences()) { + System.err.println(d.getClassName() + " : " + d.getClass().getName() + + " : " + d.getInfo().getName()); + if (d instanceof Change) { + System.err.println(" : " + ((Change) d).getModifiedInfo().getName()); + } + } + // We expect the class name change from ClassA to ClassB, and no other changes. + Assert.assertEquals("differences found", 1, handler.getDelta().getDifferences().size()); + } + +} |