Author: gscokart
Date: Wed Feb 18 19:47:08 2009
New Revision: 745628

URL: http://svn.apache.org/viewvc?rev=745628&view=rev
Log:
handle more completely junit4 suites

Added:
    
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteRunnerTest.java
      - copied, changed from r744243, 
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteTest.java
Removed:
    
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitTestCaseRunner.java
    
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteTest.java
Modified:
    
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java
    
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java

Modified: 
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java
URL: 
http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java?rev=745628&r1=745627&r2=745628&view=diff
==============================================================================
--- 
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java
 (original)
+++ 
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit3/AntUnitSuite.java
 Wed Feb 18 19:47:08 2009
@@ -23,7 +23,6 @@
 import java.io.File;
 import java.io.PrintStream;
 import java.util.Collections;
-import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
 
@@ -32,6 +31,7 @@
 import junit.framework.TestResult;
 import junit.framework.TestSuite;
 
+import org.apache.ant.antunit.AntUnitExecutionNotifier;
 import org.apache.ant.antunit.AntUnitScriptRunner;
 import org.apache.ant.antunit.ProjectFactory;
 import org.apache.tools.ant.BuildException;
@@ -117,7 +117,9 @@
             initializationReportingTest.run(testResult);
         } else {
             List testTartgets = antScriptRunner.getTestTartgets();
-            runInContainer(testTartgets, testResult);
+            JUnitNotificationAdapter notifier = new JUnitNotificationAdapter(
+                    testResult, tests());
+            runInContainer(testTartgets, notifier);
         }
     }
 
@@ -142,7 +144,9 @@
         } else {
             String targetName = ((AntUnitTestCase) test).getTarget();
             List singleTargetList = Collections.singletonList(targetName);
-            runInContainer(singleTargetList, result);
+            JUnitNotificationAdapter notifier = new JUnitNotificationAdapter(
+                    result, tests());
+            runInContainer(singleTargetList, notifier);
         }
     }
 
@@ -150,18 +154,14 @@
      * Execute the test suite in a 'container' similar to the ant 'container'.
      * When ant executes a project it redirect the input and the output. In 
this
      * context we will only redirect output (unit test are not supposed to be
-     * interactive)
+     * interactive).<br/>
      * 
      * @param targetList
      *            The list of test target to execute
-     * @param result
-     *            The JUnit3 TestResult receiving result notification
-     * @param tests
-     *            The JUnit3 Test classes instances to use in the notification.
-     */
-    private void runInContainer(List targetList, TestResult result) {
-        JUnitNotificationAdapter notifier = new JUnitNotificationAdapter(
-                result, tests());
+     * @param notifier
+     *            The AntUnit notifier that will receive execution 
notifications
+     */
+    public void runInContainer(List targetList, AntUnitExecutionNotifier 
notifier) {        
         PrintStream savedErr = System.err;
         PrintStream savedOut = System.out;
         try {

Modified: 
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java
URL: 
http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java?rev=745628&r1=745627&r2=745628&view=diff
==============================================================================
--- 
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java
 (original)
+++ 
ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/junit4/AntUnitSuiteRunner.java
 Wed Feb 18 19:47:08 2009
@@ -20,35 +20,62 @@
 
 package org.apache.ant.antunit.junit4;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
+import org.apache.ant.antunit.AntUnitExecutionNotifier;
+import org.apache.ant.antunit.AssertionFailedException;
 import org.apache.ant.antunit.junit3.AntUnitSuite;
 import org.apache.ant.antunit.junit3.AntUnitTestCase;
-import org.junit.internal.runners.CompositeRunner;
 import org.junit.internal.runners.InitializationError;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
 
 /**
  * JUnit4 Runner to put in a RunWith annotation of the AntUnitSuite when using 
a
  * JUnit4 runner. Using this runner is not mandatory because junit4 is able to
- * run junit3 test. However, the test will be faster (TODO make that true :-) )
- * with this Runner. Also, more features are available when this runner is used
- * (filtering & sorting) 
- * TODO Support filtering and sorting
+ * run junit3 test. However, the test may be faster with this Runner (with the
+ * default junit4 adapter, the suiteSetUp and suiteTearDown will be executed
+ * around every test target). Also, more features are available when this 
runner
+ * is used (filtering & sorting)
  */
-public class AntUnitSuiteRunner extends CompositeRunner {
+public class AntUnitSuiteRunner extends Runner implements Filterable, Sortable 
{
 
+    private final AntUnitSuite junit3Suite;
+    private final Map/*<String, Description>*/ targetDescriptions = new 
HashMap();
+    private final List/*<String>*/ targetsOrder = new LinkedList();
+    
     private AntUnitSuiteRunner(AntUnitSuite suite, Class junitTestClass) {
-        super(suite.getName());
+        junit3Suite = suite;
         Enumeration tests = suite.tests();
         while (tests.hasMoreElements()) {
             //TODO Handle the the case of FileNotFound. 
             //In that case the suite contains an error Test and we have
-            //a ClassCastException instead of a nice & clear error            
+            //a ClassCastException instead of a nice & clear error
+            //TODO Handle the possibility for the user to define suite of 
AntUnit scripts
             AntUnitTestCase tc = (AntUnitTestCase) tests.nextElement();
-            add(new AntUnitTestCaseRunner(tc, junitTestClass));
+            Description tc_desc = 
Description.createTestDescription(junitTestClass, tc.getName());
+            targetDescriptions.put(tc.getTarget(), tc_desc);
+            targetsOrder.add(tc.getTarget());
         }
     }
 
@@ -63,16 +90,93 @@
             if (!Modifier.isStatic(suiteMethod.getModifiers())) {
                 throw new InitializationError("suite method must be static");
             }
-            return (AntUnitSuite) suiteMethod.invoke(null, new Object[0]);
+            Object suite = suiteMethod.invoke(null, new Object[0]);
+            if (suite == null) {
+                throw new InitializationError("suite method can not return 
null");
+            }
+            if (!(suite instanceof AntUnitSuite)) {
+                throw new InitializationError("suite method must return an 
AntUnitSuite");
+            }
+            return (AntUnitSuite) suite;
         } catch (NoSuchMethodException e) {
             throw new InitializationError(new Throwable[] { e });
         } catch (IllegalAccessException e) {
             throw new InitializationError(new Throwable[] { e });
         } catch (InvocationTargetException e) {
             throw new InitializationError(new Throwable[] { e });
-        } catch (ClassCastException e) {
-            throw new InitializationError(new Throwable[] { e });
         }
     }
 
+    /**
+     * @Overwrite Filterable implementation
+     */
+    public void filter(Filter filter) throws NoTestsRemainException {
+        for (Iterator iter= targetDescriptions.entrySet().iterator(); 
iter.hasNext();) {
+            Map.Entry mapEntry = (Entry) iter.next(); 
+            if (!filter.shouldRun((Description) mapEntry.getValue()))
+                iter.remove();
+                targetsOrder.remove(mapEntry.getKey());
+        }
+    }
+
+    /**
+     * @Overwrite Sortable implementation
+     */
+    public void sort(final Sorter sorter) {
+        Collections.sort(targetsOrder, new Comparator/*<String>*/() {
+            public int compare(Object target1, Object target2) {
+                Description d2 = (Description)targetDescriptions.get(target2);
+                Description d1 = (Description)targetDescriptions.get(target1);
+                return sorter.compare(d1, d2);
+            }
+        });
+        /*for (Runner each : fRunners)
+            sorter.apply(each);
+        */
+    }
+
+    /**
+     * @Overwrite Runner implementation
+     */
+    public Description getDescription() {
+        Description r = Description.createSuiteDescription(
+                junit3Suite.getName(), new Annotation[0]);
+        
+        Collection childDesc = targetDescriptions.values();
+        for (Iterator iterator = childDesc.iterator(); iterator.hasNext();) {
+            Description desc = (Description) iterator.next();
+            r.addChild(desc);
+        }
+        return r;
+    }
+
+    /**
+     * @Overwrite Runner implementation
+     */
+    public void run(final RunNotifier junitNotifier) {
+        LinkedList targetList = new LinkedList(targetDescriptions.keySet());
+        
+        AntUnitExecutionNotifier antUnitNotifier = new 
AntUnitExecutionNotifier() {            
+            public void fireStartTest(String targetName) {
+                junitNotifier.fireTestStarted(getDescription(targetName));
+            }
+            public void fireEndTest(String targetName) {
+                junitNotifier.fireTestFinished(getDescription(targetName));    
            
+            }
+            public void fireError(String targetName, Throwable t) {
+                Failure failure = new Failure(getDescription(targetName), t);
+                junitNotifier.fireTestFailure(failure);
+            }
+            public void fireFail(String targetName, AssertionFailedException 
ae) {
+                Failure failure = new Failure(getDescription(targetName), ae);
+                junitNotifier.fireTestFailure(failure);
+            }            
+            private Description getDescription(String targetName) {
+                return (Description) targetDescriptions.get(targetName);
+            }
+        };
+        
+        junit3Suite.runInContainer(targetList, antUnitNotifier);
+    }
+
 }

Copied: 
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteRunnerTest.java
 (from r744243, 
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteTest.java)
URL: 
http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteRunnerTest.java?p2=ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteRunnerTest.java&p1=ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteTest.java&r1=744243&r2=745628&rev=745628&view=diff
==============================================================================
--- 
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteTest.java
 (original)
+++ 
ant/antlibs/antunit/trunk/src/tests/junit/org/apache/ant/antunit/junit4/AntUnitSuiteRunnerTest.java
 Wed Feb 18 19:47:08 2009
@@ -20,22 +20,45 @@
 package org.apache.ant.antunit.junit4;
 
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
 import java.util.ArrayList;
 
 import junit.framework.TestCase;
+import junit.framework.TestSuite;
 
 import org.apache.ant.antunit.junit3.AntUnitSuite;
-import org.junit.Ignore;
+import org.apache.tools.ant.util.FileUtils;
 import org.junit.internal.runners.InitializationError;
 import org.junit.runner.Description;
 import org.junit.runner.notification.RunNotifier;
 
-public class AntUnitSuiteTest extends TestCase {
+public class AntUnitSuiteRunnerTest extends TestCase {
 
     private boolean mockExecutionOK = false;
     private String mockExcutionError = "";
 
     /**
+     * Validates the execution sequence.
+     */
+    public void testRunFullSuite() throws FileNotFoundException, IOException,
+            InitializationError {
+        AntUnitSuiteRunner runner = new AntUnitSuiteRunner(
+                JUnit4AntUnitRunnable.class);
+
+        runner.run(new RunNotifier());
+        File outFile = new File("target/test_output/junit_out.xml");
+
+        String output = FileUtils.readFully(new FileReader(outFile));
+        String EXPECT1 = 
"suiteSetUp-setUp-test1-tearDown-setUp-test2-tearDown-suiteTearDown";
+        String EXPECT2 = 
"suiteSetUp-setUp-test2-tearDown-setUp-test1-tearDown-suiteTearDown";
+        assertTrue("unexted output : " + output, EXPECT1.equals(output)
+                || EXPECT2.equals(output));
+    }
+
+    
+    /**
      * When a test is executed, the description used in the notification must 
be
      * equals to the description declared, otherwise the runner is confused 
(for
      * example in eclipse you have all the tests listed twice, but reported 
only
@@ -108,6 +131,31 @@
         }
     }
 
+    public void testInvalidSuiteReturnTypeError() {
+        try {
+            AntUnitSuiteRunner runner = new AntUnitSuiteRunner(
+                    JUnit4AntUnitRunnableWithInvalidSuiteReturnType.class);
+            fail("InitializationError expected");
+        } catch (InitializationError e) {
+            String msg = e.getCauses().get(0).getMessage();
+            assertTrue("Unexpected error : " + msg, msg.contains("suite"));
+            assertTrue("Unexpected error : " + msg, 
msg.contains("AntUnitSuite"));
+        }
+    }
+
+    public void testInvalidSuiteReturnNull() {
+        try {
+            AntUnitSuiteRunner runner = new AntUnitSuiteRunner(
+                    JUnit4AntUnitRunnableWithInvalidSuiteReturningNull.class);
+            fail("InitializationError expected");
+        } catch (InitializationError e) {
+            String msg = e.getCauses().get(0).getMessage();
+            assertTrue("Unexpected error : " + msg, msg.contains("suite"));
+            assertTrue("Unexpected error : " + msg, msg.contains("null"));
+        }
+    }
+
+    
     public static class JUnit4AntUnitRunnable {
         public static AntUnitSuite suite() {
             File f = new File("src/etc/testcases/antunit/junit.xml");
@@ -126,4 +174,17 @@
     public static class JUnit4AntUnitRunnableWithoutSuiteMethod {
     }
 
+    public static class JUnit4AntUnitRunnableWithInvalidSuiteReturnType {
+        public static TestSuite suite() {
+            return new TestSuite("We don't support returning generic 
TestSuite." +
+                    "  The Runner can not handle that");
+        }
+    }
+    
+    public static class JUnit4AntUnitRunnableWithInvalidSuiteReturningNull {
+        public static TestSuite suite() {
+            return null;
+        }
+    }
+
 }


Reply via email to