aboutsummaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/src/main/java/org/osjava/jardiff/JarDiff.java19
-rw-r--r--api/src/test/java/org/semver/jardiff/ClassInheritanceTest.java96
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());
+ }
+
+}