From ab208cde4276e58334f92f7607b31e77dde8a52d Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Fri, 14 May 2021 08:16:29 -0700 Subject: Remove jdiff --- testing-util/pom.xml | 6 - .../java/org/aspectj/testing/util/TestUtil.java | 369 +++++++-------------- .../java/org/aspectj/testingutil/TestUtilTest.java | 11 +- 3 files changed, 134 insertions(+), 252 deletions(-) (limited to 'testing-util') diff --git a/testing-util/pom.xml b/testing-util/pom.xml index 0acc00a08..cd62ba319 100644 --- a/testing-util/pom.xml +++ b/testing-util/pom.xml @@ -33,12 +33,6 @@ compile - - - jdiff - jdiff - 1.3 - diff --git a/testing-util/src/main/java/org/aspectj/testing/util/TestUtil.java b/testing-util/src/main/java/org/aspectj/testing/util/TestUtil.java index 79ae9a776..51c940277 100644 --- a/testing-util/src/main/java/org/aspectj/testing/util/TestUtil.java +++ b/testing-util/src/main/java/org/aspectj/testing/util/TestUtil.java @@ -14,33 +14,38 @@ package org.aspectj.testing.util; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringReader; -import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.StringTokenizer; import org.aspectj.bridge.IMessageHandler; import org.aspectj.bridge.MessageUtil; import org.aspectj.util.FileUtil; import org.aspectj.util.LangUtil; import org.aspectj.util.Reflection; - -import jdiff.text.FileLine; -import jdiff.util.Diff; -import jdiff.util.DiffNormalOutput; import org.junit.Assert; + import junit.framework.AssertionFailedError; import junit.framework.Test; import junit.framework.TestCase; @@ -48,8 +53,7 @@ import junit.framework.TestResult; import junit.framework.TestSuite; /** - * Things that junit should perhaps have, but doesn't. Note the file-comparison methods require JDiff to run, but JDiff types are - * not required to resolve this class. Also, the bytecode weaver is required to compare class files, but not to compare other files. + * Things that junit should perhaps have, but doesn't. Also, the bytecode weaver is required to compare class files, but not to compare other files. */ public final class TestUtil { private static final String SANDBOX_NAME = "ajcSandbox"; @@ -208,9 +212,9 @@ public final class TestUtil { return path.toString(); } - public static String aspectjrtClasspath() { - return TestUtil.aspectjrtPath().getPath(); - } + public static String aspectjrtClasspath() { + return TestUtil.aspectjrtPath().getPath(); + } /** * @param input the String to parse for [on|off|true|false] @@ -536,76 +540,115 @@ public final class TestUtil { File expectedFile = new File(expectedBaseDir, path); return doSameFile(handler, expectedBaseDir, actualBaseDir, expectedFile, actualFile); } + + public static String disassembleClass(File basedir, File file) { + String basedirPath = FileUtil.normalizedPath(basedir); + String name = FileUtil.fileToClassName(basedir, file); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + String utf8 = StandardCharsets.UTF_8.name(); + try (PrintStream out = new PrintStream(baos, true, utf8)) { + Class c = Class.forName("org.aspectj.weaver.bcel.LazyClassGen"); + Method m = c.getMethod("disassemble", new Class[] { String.class, String.class, PrintStream.class }); + m.invoke(null, new Object[] { basedirPath, name, out }); + return baos.toString(utf8); + } catch (Throwable t) { + throw new IllegalStateException(t); + } + } + + public static List toLines(String inputString) { + List lines = new ArrayList<>(); + try (BufferedReader br = new BufferedReader(new StringReader(inputString))) { + String line = null; + while ((line= br.readLine()) != null) { + lines.add(line); + } + } catch (IOException ioe) { + throw new IllegalStateException("Unable to create lines from string "+inputString,ioe); + } + return lines; + } + + public static String toString(List lines) { + return String.join("\n", lines); + } + + private static int longestLine(List lines) { + int longest = -1; + for (String line: lines) { + if (line.length()>longest) { + longest = line.length(); + } + } + return longest; + } - /** - * This does the work, selecting a lineator subclass and converting public API's to JDiff APIs for comparison. Currently, all - * jdiff interfaces are method-local, so this class will load without it; if we do use it, we can avoid the duplication. - */ private static boolean doSameFile(IMessageHandler handler, File expectedBaseDir, File actualBaseDir, File expectedFile, File actualFile) { String path = expectedFile.getPath(); - // XXX permit user to specify lineator - ILineator lineator = Lineator.TEXT; + List expectedLines = null; + List actualLines = null; + List errorContext = new ArrayList<>(); if (path.endsWith(".class")) { - if (ClassLineator.haveDisassembler()) { - lineator = Lineator.CLASS; - } else { - MessageUtil.abort(handler, "skipping - dissassembler not available"); - return false; - } - } - CanonicalLine[] actualLines = null; - CanonicalLine[] expectedLines = null; - try { - actualLines = lineator.getLines(handler, actualFile, actualBaseDir); - expectedLines = lineator.getLines(handler, expectedFile, expectedBaseDir); - } catch (IOException e) { - MessageUtil.fail(handler, "rendering lines ", e); + expectedLines = toLines(disassembleClass(expectedBaseDir, expectedFile)); + actualLines = toLines(disassembleClass(actualBaseDir, actualFile)); + } else { + expectedLines = FileUtil.readAsLines(expectedFile); + actualLines = FileUtil.readAsLines(actualFile); + } + // TODO replace this section with assertMultiLineStringEquals ? + int longestLine = longestLine(expectedLines); + int actualLongestLine = longestLine(actualLines); + String padding = null; + if (actualLongestLine>longestLine) { + longestLine = actualLongestLine; + } + StringBuilder s = new StringBuilder(); + for (int i=0;iexpectedLines.size()) { + StringBuilder extra = new StringBuilder(); + for (int l=expectedLines.size();l tests = source.tests(); while (tests.hasMoreElements()) { - sink.addTest((Test) tests.nextElement()); + sink.addTest(tests.nextElement()); } } @@ -772,168 +815,6 @@ public final class TestUtil { } } - /** component that reduces file to CanonicalLine[] */ - public interface ILineator { - /** Lineator suitable for text files */ - ILineator TEXT = new TextLineator(); - - /** Lineator suitable for class files (disassembles first) */ - ILineator CLASS = new ClassLineator(); - - /** - * Reduce file to CanonicalLine[]. - * - * @param handler the IMessageHandler for errors (may be null) - * @param file the File to render - * @param basedir the File for the base directory (may be null) - * @return CanonicalLine[] of lines - not null, but perhaps empty - */ - CanonicalLine[] getLines(IMessageHandler handler, File file, File basedir) throws IOException; - } - - /** alias for jdiff FileLine to avoid client binding */ - public static class CanonicalLine { - public static final CanonicalLine[] NO_LINES = new CanonicalLine[0]; - - /** canonical variant of line for comparison */ - public final String canonical; - - /** actual line, for logging */ - public final String line; - - public CanonicalLine(String canonical, String line) { - this.canonical = canonical; - this.line = line; - } - - public String toString() { - return line; - } - } - - private abstract static class Lineator implements ILineator { - /** - * Reduce file to CanonicalLine[]. - * - * @param handler the IMessageHandler for errors (may be null) - * @param file the File to render - * @param basedir the File for the base directory (may be null) - */ - public CanonicalLine[] getLines(IMessageHandler handler, File file, File basedir) throws IOException { - - if (!file.canRead() || !file.isFile()) { - MessageUtil.error(handler, "not readable file: " + basedir + " - " + file); - return null; - } - // capture file as FileLine[] - InputStream in = null; - /* String path = */FileUtil.normalizedPath(file, basedir); - LineStream capture = new LineStream(); - try { - lineate(capture, handler, basedir, file); - } catch (IOException e) { - MessageUtil.fail(handler, "NormalizedCompareFiles IOException reading " + file, e); - return null; - } finally { - if (null != in) { - try { - in.close(); - } catch (IOException e) { - } // ignore - } - capture.flush(); - capture.close(); - } - String missed = capture.getMissed(); - if (!LangUtil.isEmpty(missed)) { - MessageUtil.warn(handler, "NormalizedCompareFiles missed input: " + missed); - return null; - } else { - String[] lines = capture.getLines(); - CanonicalLine[] result = new CanonicalLine[lines.length]; - for (int i = 0; i < lines.length; i++) { - result[i] = new CanonicalLine(lines[i], lines[i]); - } - return result; - } - } - - protected abstract void lineate(PrintStream sink, IMessageHandler handler, File basedir, File file) throws IOException; - } - - private static class TextLineator extends Lineator { - - protected void lineate(PrintStream sink, IMessageHandler handler, File basedir, File file) throws IOException { - InputStream in = null; - try { - in = new FileInputStream(file); - FileUtil.copyStream(new DataInputStream(in), sink); - } finally { - try { - in.close(); - } catch (IOException e) { - } // ignore - } - } - } - - public static class ClassLineator extends Lineator { - - protected void lineate(PrintStream sink, IMessageHandler handler, File basedir, File file) throws IOException { - String name = FileUtil.fileToClassName(basedir, file); - // XXX re-enable preflight? - // if ((null != basedir) && (path.length()-6 != name.length())) { - // MessageUtil.error(handler, "unexpected class name \"" - // + name + "\" for path " + path); - // return null; - // } - disassemble(handler, basedir, name, sink); - } - - public static boolean haveDisassembler() { - try { - return (null != Class.forName("org.aspectj.weaver.bcel.LazyClassGen")); - } catch (ClassNotFoundException e) { - // XXX fix - // System.err.println(e.getMessage()); - // e.printStackTrace(System.err); - return false; - } - } - - /** XXX dependency on bcweaver/bcel */ - private static void disassemble(IMessageHandler handler, File basedir, String name, PrintStream out) throws IOException { - // LazyClassGen.disassemble(FileUtil.normalizedPath(basedir), name, - // capture); - - Throwable thrown = null; - String basedirPath = FileUtil.normalizedPath(basedir); - // XXX use reflection utilities to invoke dissassembler? - try { - // XXX need test to detect when this is refactored - Class c = Class.forName("org.aspectj.weaver.bcel.LazyClassGen"); - Method m = c.getMethod("disassemble", new Class[] { String.class, String.class, PrintStream.class }); - m.invoke(null, new Object[] { basedirPath, name, out }); - } catch (ClassNotFoundException e) { - thrown = e; - } catch (NoSuchMethodException e) { - thrown = e; - } catch (IllegalAccessException e) { - thrown = e; - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - if (t instanceof IOException) { - throw (IOException) t; - } - thrown = t; - } - if (null != thrown) { - MessageUtil.fail(handler, "disassembling " + name + " path: " + basedirPath, thrown); - } - } - } - - public static File createEmptySandbox() { File sandbox; @@ -944,9 +825,9 @@ public final class TestUtil { if (os.startsWith("Windows")) { tempDir = new File("N:\\temp"); if (!tempDir.exists()) { - tempDir = new File("C:\\temp"); - if (!tempDir.exists()) { - tempDir.mkdir(); + tempDir = new File("C:\\temp"); + if (!tempDir.exists()) { + tempDir.mkdir(); } } } else { @@ -1059,4 +940,12 @@ public final class TestUtil { } } + public static boolean haveDisassembler() { + try { + return (Class.forName("org.aspectj.weaver.bcel.LazyClassGen") != null); + } catch (ClassNotFoundException e) { + return false; + } + } + } diff --git a/testing-util/src/test/java/org/aspectj/testingutil/TestUtilTest.java b/testing-util/src/test/java/org/aspectj/testingutil/TestUtilTest.java index 1427ccc8a..6b791da43 100644 --- a/testing-util/src/test/java/org/aspectj/testingutil/TestUtilTest.java +++ b/testing-util/src/test/java/org/aspectj/testingutil/TestUtilTest.java @@ -81,16 +81,14 @@ public class TestUtilTest extends TestCase { public void testFileCompareNonClassStaticNegative() throws IOException { MessageHandler holder = new MessageHandler(); - File basedir = new File("testdata/testCompareTextFiles/differentFile"); + File basedir = new File(UtilTests.TESTING_UTIL_PATH + "/testdata/testCompareTextFiles/differentFile"); File expectedBaseDir = new File(basedir, "expected"); File actualBaseDir = new File(basedir, "actual"); String filename = "TestUtilTest.java"; File expected = new File(expectedBaseDir, filename); File actual = new File(actualBaseDir, filename); - - assertTrue(!TestUtil.sameFiles(holder, expected, actual)); - - assertTrue(!TestUtil.sameFiles(holder, expectedBaseDir, actualBaseDir, filename)); + assertTrue(!TestUtil.sameFiles(holder, expected, actual)); + assertTrue(!TestUtil.sameFiles(holder, expectedBaseDir, actualBaseDir, filename)); } public void testParseBoolean() { @@ -127,8 +125,9 @@ public class TestUtilTest extends TestCase { } } + public void testFileCompareClass() throws IOException { - if (!TestUtil.ClassLineator.haveDisassembler()) { + if (!TestUtil.haveDisassembler()) { System.err.println("skipping testFileCompareClass - no disassembler on classpath"); return; } -- cgit v1.2.3