Make Junit3 class more consistent with JUnit

When calling suite() method or creating a TestCase check to see
if it fails with an InvocationTargetException and if it does
extract the cause and use that when reporting the failure.

When a suitable constructor for a TestCase (either no args or
one with that takes the name) then use the same message as JUnit
does.

Add an explicit check that a TestCase class is public and if it
is not then report the same message as JUnit does.

Bug: 27940141
Change-Id: I935b5894e3e12f4e23d82dcfa30e4177971e5bb8
diff --git a/src/vogar/target/junit/Junit3.java b/src/vogar/target/junit/Junit3.java
index bed6746..9b73981 100644
--- a/src/vogar/target/junit/Junit3.java
+++ b/src/vogar/target/junit/Junit3.java
@@ -157,6 +157,9 @@
             junit.framework.Test test;
             try {
                 test = (junit.framework.Test) suiteMethod.invoke(null);
+            } catch (InvocationTargetException e) {
+                out.add(new ConfigurationError(testClass.getName() + "#suite", e.getCause()));
+                return;
             } catch (Throwable e) {
                 out.add(new ConfigurationError(testClass.getName() + "#suite", e));
                 return;
@@ -242,7 +245,12 @@
         }
 
         public void run() throws Throwable {
-            TestCase testCase = getTestCase();
+            TestCase testCase;
+            try {
+                testCase = getTestCase();
+            } catch (InvocationTargetException t) {
+                throw t.getCause();
+            }
             Throwable failure = null;
             try {
                 setUp.invoke(testCase);
@@ -297,11 +305,18 @@
                         new Object[] { method.getName() });
             } catch (NoSuchMethodException ignored) {
             }
-            return new ConfigurationError(testClass.getName() + "#" + method.getName(),
-                    new Exception("Test cases must have a no-arg or string constructor."));
+            String testClassName = testClass.getName();
+            return new ConfigurationError(testClassName + "#" + method.getName(),
+                    new AssertionFailedError("Class " + testClassName
+                            + " has no public constructor TestCase(String name) or TestCase()"));
         }
 
         @Override protected TestCase getTestCase() throws Exception {
+
+            if (!Modifier.isPublic(constructor.getDeclaringClass().getModifiers())) {
+                throw new AssertionFailedError("Class " + testClass.getName() + " is not public");
+            }
+
             TestCase testCase = constructor.newInstance(constructorArgs);
             // If the test case used the no argument constructor then make sure to set its name
             // correctly.