You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ap...@apache.org on 2007/05/14 03:34:18 UTC

svn commit: r537691 [10/11] - in /maven/sandbox/branches/surefire/surefire-collab2: ./ maven-surefire-plugin/ maven-surefire-plugin/src/ maven-surefire-plugin/src/it/ maven-surefire-plugin/src/it/test1/ maven-surefire-plugin/src/it/test1/src/ maven-sur...

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/OutputConsumerProxyTest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/OutputConsumerProxyTest.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/OutputConsumerProxyTest.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/OutputConsumerProxyTest.java Sun May 13 18:33:45 2007
@@ -0,0 +1,117 @@
+package org.apache.maven.surefire.booter.output;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.jmock.Mock;
+import org.jmock.core.constraint.IsEqual;
+import org.jmock.core.matcher.InvokeOnceMatcher;
+
+/**
+ * Test for {@link OutputConsumerProxy}
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ * @version $Id: OutputConsumerProxyTest.java 513763 2007-03-02 13:51:08Z brett $
+ */
+public class OutputConsumerProxyTest
+    extends AbstractOutputConsumerTestCase
+{
+    private Mock outputConsumerMock;
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+        setOutputConsumerMock( new Mock( OutputConsumer.class ) );
+        setOutputConsumer( new OutputConsumerProxy( (OutputConsumer) getOutputConsumerMock().proxy() ) );
+    }
+
+    public void setOutputConsumerMock( Mock outputConsumerMock )
+    {
+        this.outputConsumerMock = outputConsumerMock;
+    }
+
+    public Mock getOutputConsumerMock()
+    {
+        return outputConsumerMock;
+    }
+
+    public void testConsumeFooterLine()
+    {
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetStarting" )
+            .with( new IsEqual( getReportEntry() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "consumeFooterLine" )
+            .with( new IsEqual( getLine() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetCompleted" );
+        super.testConsumeFooterLine();
+        getOutputConsumerMock().verify();
+    }
+
+    public void testConsumeHeaderLine()
+    {
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetStarting" )
+            .with( new IsEqual( getReportEntry() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "consumeHeaderLine" )
+            .with( new IsEqual( getLine() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetCompleted" );
+        super.testConsumeHeaderLine();
+        getOutputConsumerMock().verify();
+    }
+
+    public void testConsumeMessageLine()
+    {
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetStarting" )
+            .with( new IsEqual( getReportEntry() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "consumeMessageLine" )
+            .with( new IsEqual( getLine() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetCompleted" );
+        super.testConsumeMessageLine();
+        getOutputConsumerMock().verify();
+    }
+
+    public void testConsumeOutputLine()
+        throws Exception
+    {
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetStarting" )
+            .with( new IsEqual( getReportEntry() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "consumeOutputLine" )
+            .with( new IsEqual( getLine() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetCompleted" );
+        super.testConsumeOutputLine();
+        getOutputConsumerMock().verify();
+    }
+
+    public void testTestSetStarting()
+    {
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetStarting" )
+            .with( new IsEqual( getReportEntry() ) );
+        super.testTestSetStarting();
+        getOutputConsumerMock().verify();
+    }
+
+    public void testTestSetCompleted()
+    {
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetStarting" )
+            .with( new IsEqual( getReportEntry() ) );
+        getOutputConsumerMock().expects( new InvokeOnceMatcher() ).method( "testSetCompleted" );
+        super.testTestSetCompleted();
+        getOutputConsumerMock().verify();
+    }
+
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/PrintWriterOutputConsumerTest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/PrintWriterOutputConsumerTest.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/PrintWriterOutputConsumerTest.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/PrintWriterOutputConsumerTest.java Sun May 13 18:33:45 2007
@@ -0,0 +1,82 @@
+package org.apache.maven.surefire.booter.output;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import java.io.StringWriter;
+
+/**
+ * Test for {@link PrintWriterOutputConsumer}
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ * @version $Id: PrintWriterOutputConsumerTest.java 513763 2007-03-02 13:51:08Z brett $
+ */
+public class PrintWriterOutputConsumerTest
+    extends AbstractOutputConsumerTestCase
+{
+    private StringWriter writer;
+
+    private static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+        writer = new StringWriter();
+        setOutputConsumer( new PrintWriterOutputConsumer( writer ) );
+    }
+
+    public void testConsumeFooterLine()
+    {
+        super.testConsumeFooterLine();
+        assertEquals( this.getLine() + LINE_SEPARATOR, writer.toString() );
+    }
+
+    public void testConsumeHeaderLine()
+    {
+        super.testConsumeHeaderLine();
+        assertEquals( getLine() + LINE_SEPARATOR, writer.toString() );
+    }
+
+    public void testConsumeMessageLine()
+    {
+        super.testConsumeMessageLine();
+        assertEquals( getLine() + LINE_SEPARATOR, writer.toString() );
+    }
+
+    public void testConsumeOutputLine()
+        throws Exception
+    {
+        super.testConsumeOutputLine();
+        assertEquals( getLine() + LINE_SEPARATOR, writer.toString() );
+    }
+
+    public void testTestSetCompleted()
+    {
+        super.testTestSetCompleted();
+        assertEquals( "", writer.toString() );
+    }
+
+    public void testTestSetStarting()
+    {
+        super.testTestSetStarting();
+        assertEquals( "", writer.toString() );
+    }
+
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/StandardOutputConsumerTest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/StandardOutputConsumerTest.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/StandardOutputConsumerTest.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/StandardOutputConsumerTest.java Sun May 13 18:33:45 2007
@@ -0,0 +1,39 @@
+package org.apache.maven.surefire.booter.output;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * Test for {@link StandardOutputConsumer}
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ * @version $Id: StandardOutputConsumerTest.java 513763 2007-03-02 13:51:08Z brett $
+ */
+public class StandardOutputConsumerTest
+    extends AbstractOutputConsumerTestCase
+{
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+        setOutputConsumer( new StandardOutputConsumer() );
+    }
+
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/SupressFooterOutputConsumerProxyTest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/SupressFooterOutputConsumerProxyTest.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/SupressFooterOutputConsumerProxyTest.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/SupressFooterOutputConsumerProxyTest.java Sun May 13 18:33:45 2007
@@ -0,0 +1,45 @@
+package org.apache.maven.surefire.booter.output;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * Test for {@link SupressFooterOutputConsumerProxy}
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ * @version $Id: SupressFooterOutputConsumerProxyTest.java 510866 2007-02-23 08:13:49Z brett $
+ */
+public class SupressFooterOutputConsumerProxyTest
+    extends OutputConsumerProxyTest
+{
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+        setOutputConsumer( new SupressFooterOutputConsumerProxy( (OutputConsumer) getOutputConsumerMock().proxy() ) );
+    }
+
+    public void testConsumeFooterLine()
+    {
+        getOutputConsumer().consumeFooterLine( getLine() );
+        getOutputConsumerMock().verify();
+    }
+
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/SupressHeaderOutputConsumerProxyTest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/SupressHeaderOutputConsumerProxyTest.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/SupressHeaderOutputConsumerProxyTest.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-booter/src/test/java/org/apache/maven/surefire/booter/output/SupressHeaderOutputConsumerProxyTest.java Sun May 13 18:33:45 2007
@@ -0,0 +1,45 @@
+package org.apache.maven.surefire.booter.output;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * Test for {@link SupressHeaderOutputConsumerProxy}
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ * @version $Id: SupressHeaderOutputConsumerProxyTest.java 510866 2007-02-23 08:13:49Z brett $
+ */
+public class SupressHeaderOutputConsumerProxyTest
+    extends OutputConsumerProxyTest
+{
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+        setOutputConsumer( new SupressHeaderOutputConsumerProxy( (OutputConsumer) getOutputConsumerMock().proxy() ) );
+    }
+
+    public void testConsumeHeaderLine()
+    {
+        getOutputConsumer().consumeHeaderLine( getLine() );
+        getOutputConsumerMock().verify();
+    }
+
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/pom.xml?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/pom.xml (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/pom.xml Sun May 13 18:33:45 2007
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <artifactId>surefire</artifactId>
+    <groupId>org.apache.maven.surefire</groupId>
+    <version>2.4-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>surefire-providers</artifactId>
+  <packaging>pom</packaging>
+  <name>SureFire Providers</name>
+  <modules>
+    <module>surefire-junit</module>
+    <module>surefire-junit4</module>
+    <module>surefire-testng</module>
+  </modules>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven.surefire</groupId>
+      <artifactId>surefire-api</artifactId>
+    </dependency>
+  </dependencies>
+</project>
+

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/pom.xml?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/pom.xml (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/pom.xml Sun May 13 18:33:45 2007
@@ -0,0 +1,36 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.maven.surefire</groupId>
+    <artifactId>surefire-providers</artifactId>
+    <version>2.4-SNAPSHOT</version>
+  </parent>
+  <artifactId>surefire-junit</artifactId>
+  <name>SureFire JUnit Runner</name>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+    </dependency>
+  </dependencies>
+</project>

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitDirectoryTestSuite.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitDirectoryTestSuite.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitDirectoryTestSuite.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitDirectoryTestSuite.java Sun May 13 18:33:45 2007
@@ -0,0 +1,68 @@
+package org.apache.maven.surefire.junit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import junit.framework.Test;
+import org.apache.maven.surefire.suite.AbstractDirectoryTestSuite;
+import org.apache.maven.surefire.testset.PojoTestSet;
+import org.apache.maven.surefire.testset.SurefireTestSet;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
+import java.io.File;
+import java.util.ArrayList;
+
+/**
+ * Test suite for JUnit tests based on a directory of Java test classes.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class JUnitDirectoryTestSuite
+    extends AbstractDirectoryTestSuite
+{
+    public JUnitDirectoryTestSuite( File basedir, ArrayList includes, ArrayList excludes )
+    {
+        super( basedir, includes, excludes );
+    }
+
+    protected SurefireTestSet createTestSet( Class testClass, ClassLoader classLoader )
+        throws TestSetFailedException
+    {
+        Class junitClass = null;
+        try
+        {
+            junitClass = classLoader.loadClass( Test.class.getName() );
+        }
+        catch ( ClassNotFoundException e )
+        {
+            // ignore this
+        }
+
+        SurefireTestSet testSet;
+        if ( junitClass != null && junitClass.isAssignableFrom( testClass ) )
+        {
+            testSet = new JUnitTestSet( testClass );
+        }
+        else
+        {
+            testSet = new PojoTestSet( testClass );
+        }
+        return testSet;
+    }
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitStackTraceWriter.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitStackTraceWriter.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitStackTraceWriter.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitStackTraceWriter.java Sun May 13 18:33:45 2007
@@ -0,0 +1,36 @@
+package org.apache.maven.surefire.junit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.report.PojoStackTraceWriter;
+
+/**
+ * Stack trace writer for JUnit tests.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class JUnitStackTraceWriter
+    extends PojoStackTraceWriter
+{
+    public JUnitStackTraceWriter( String testClass, String testName, Throwable throwable )
+    {
+        super( testClass, testName, throwable );
+    }
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitTestSet.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitTestSet.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitTestSet.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/JUnitTestSet.java Sun May 13 18:33:45 2007
@@ -0,0 +1,293 @@
+package org.apache.maven.surefire.junit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.report.ReporterManager;
+import org.apache.maven.surefire.testset.AbstractTestSet;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+
+public final class JUnitTestSet
+    extends AbstractTestSet
+{
+    public static final String TEST_CASE = "junit.framework.Test";
+
+    public static final String TEST_RESULT = "junit.framework.TestResult";
+
+    public static final String TEST_LISTENER = "junit.framework.TestListener";
+
+    public static final String TEST = "junit.framework.Test";
+
+    public static final String ADD_LISTENER_METHOD = "addListener";
+
+    public static final String RUN_METHOD = "run";
+
+    public static final String COUNT_TEST_CASES_METHOD = "countTestCases";
+
+    public static final String SETUP_METHOD = "setUp";
+
+    public static final String TEARDOWN_METHOD = "tearDown";
+
+    private static final String TEST_SUITE = "junit.framework.TestSuite";
+
+    private Class[] interfacesImplementedByDynamicProxy;
+
+    private Class testResultClass;
+
+    private Method addListenerMethod;
+
+    private Method countTestCasesMethod;
+
+    private Method runMethod;
+
+    private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+
+    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+
+    public JUnitTestSet( Class testClass )
+        throws TestSetFailedException
+    {
+        super( testClass );
+
+        processTestClass();
+    }
+
+    private void processTestClass()
+        throws TestSetFailedException
+    {
+        try
+        {
+            Class testClass = getTestClass();
+            ClassLoader loader = testClass.getClassLoader();
+
+            testResultClass = loader.loadClass( TEST_RESULT );
+
+            Class testListenerInterface = loader.loadClass( TEST_LISTENER );
+
+            Class testInterface = loader.loadClass( TEST );
+
+            // ----------------------------------------------------------------------
+            // Strategy for executing JUnit tests
+            //
+            // o look for the suite method and if that is present execute that method
+            //   to get the test object.
+            //
+            // o look for test classes that are assignable from TestCase
+            //
+            // o look for test classes that only implement the Test interface
+            // ----------------------------------------------------------------------
+
+            interfacesImplementedByDynamicProxy = new Class[1];
+
+            interfacesImplementedByDynamicProxy[0] = testListenerInterface;
+
+            // The interface implemented by the dynamic proxy (TestListener), happens to be
+            // the same as the param types of TestResult.addTestListener
+            Class[] addListenerParamTypes = interfacesImplementedByDynamicProxy;
+
+            addListenerMethod = testResultClass.getMethod( ADD_LISTENER_METHOD, addListenerParamTypes );
+
+            if ( testInterface.isAssignableFrom( testClass ) )//testObject.getClass() ) )
+            {
+                countTestCasesMethod = testInterface.getMethod( COUNT_TEST_CASES_METHOD, EMPTY_CLASS_ARRAY );
+
+                runMethod = testInterface.getMethod( RUN_METHOD, new Class[]{testResultClass} );
+
+            }
+            else
+            {
+                countTestCasesMethod = testClass.getMethod( COUNT_TEST_CASES_METHOD, EMPTY_CLASS_ARRAY );
+
+                runMethod = testClass.getMethod( RUN_METHOD, new Class[]{testResultClass} );
+            }
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new TestSetFailedException( "JUnit classes not available", e );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            throw new TestSetFailedException( "Class is not a JUnit TestCase", e );
+        }
+    }
+
+    private static Object constructTestObject( Class testClass )
+        throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException,
+        ClassNotFoundException
+    {
+        Object testObject = createInstanceFromSuiteMethod( testClass );
+
+        if ( testObject == null && testClass.getClassLoader().loadClass( TEST_CASE ).isAssignableFrom( testClass ) )
+        {
+            Class[] constructorParamTypes = {Class.class};
+
+            Constructor constructor =
+                testClass.getClassLoader().loadClass( TEST_SUITE ).getConstructor( constructorParamTypes );
+
+            Object[] constructorParams = {testClass};
+
+            testObject = constructor.newInstance( constructorParams );
+        }
+
+        if ( testObject == null )
+        {
+            Constructor testConstructor = getTestConstructor( testClass );
+
+            if ( testConstructor.getParameterTypes().length == 0 )
+            {
+                testObject = testConstructor.newInstance( EMPTY_OBJECT_ARRAY );
+            }
+            else
+            {
+                testObject = testConstructor.newInstance( new Object[]{testClass.getName()} );
+            }
+        }
+        return testObject;
+    }
+
+    private static Object createInstanceFromSuiteMethod( Class testClass )
+        throws IllegalAccessException, InvocationTargetException
+    {
+        Object testObject = null;
+        try
+        {
+            Method suiteMethod = testClass.getMethod( "suite", EMPTY_CLASS_ARRAY );
+
+            if ( Modifier.isPublic( suiteMethod.getModifiers() ) && Modifier.isStatic( suiteMethod.getModifiers() ) )
+            {
+                testObject = suiteMethod.invoke( null, EMPTY_CLASS_ARRAY );
+            }
+        }
+        catch ( NoSuchMethodException e )
+        {
+            // No suite method
+        }
+        return testObject;
+    }
+
+    public void execute( ReporterManager reportManager, ClassLoader loader )
+        throws TestSetFailedException
+    {
+        Class testClass = getTestClass();
+
+        try
+        {
+            Object testObject = constructTestObject( testClass );
+
+            Object instanceOfTestResult = testResultClass.newInstance();
+
+            TestListenerInvocationHandler invocationHandler =
+                new TestListenerInvocationHandler( reportManager, instanceOfTestResult, loader );
+
+            Object testListener =
+                Proxy.newProxyInstance( loader, interfacesImplementedByDynamicProxy, invocationHandler );
+
+            Object[] addTestListenerParams = {testListener};
+
+            addListenerMethod.invoke( instanceOfTestResult, addTestListenerParams );
+
+            Object[] runParams = {instanceOfTestResult};
+
+            runMethod.invoke( testObject, runParams );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            throw new TestSetFailedException( testClass.getName(), e );
+        }
+        catch ( InstantiationException e )
+        {
+            throw new TestSetFailedException( testClass.getName(), e );
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new TestSetFailedException( testClass.getName(), e );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new TestSetFailedException( testClass.getName(), e.getTargetException() );
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new TestSetFailedException( "JUnit classes not available", e );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            throw new TestSetFailedException( "Class is not a JUnit TestCase", e );
+        }
+    }
+
+    public int getTestCount()
+        throws TestSetFailedException
+    {
+        Class testClass = getTestClass();
+        try
+        {
+            Object testObject = constructTestObject( testClass );
+
+            Integer integer = (Integer) countTestCasesMethod.invoke( testObject, EMPTY_CLASS_ARRAY );
+
+            return integer.intValue();
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new TestSetFailedException( testClass.getName(), e );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            throw new TestSetFailedException( testClass.getName(), e );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new TestSetFailedException( testClass.getName(), e.getTargetException() );
+        }
+        catch ( InstantiationException e )
+        {
+            throw new TestSetFailedException( testClass.getName(), e );
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new TestSetFailedException( "JUnit classes not available", e );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            throw new TestSetFailedException( "Class is not a JUnit TestCase", e );
+        }
+    }
+
+    private static Constructor getTestConstructor( Class testClass )
+        throws NoSuchMethodException
+    {
+        Constructor constructor;
+        try
+        {
+            constructor = testClass.getConstructor( new Class[]{String.class} );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            constructor = testClass.getConstructor( EMPTY_CLASS_ARRAY );
+        }
+        return constructor;
+    }
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/TestListenerInvocationHandler.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/TestListenerInvocationHandler.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/TestListenerInvocationHandler.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit/src/main/java/org/apache/maven/surefire/junit/TestListenerInvocationHandler.java Sun May 13 18:33:45 2007
@@ -0,0 +1,211 @@
+package org.apache.maven.surefire.junit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.report.ReportEntry;
+import org.apache.maven.surefire.report.ReporterManager;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+public class TestListenerInvocationHandler
+    implements InvocationHandler
+{
+    // The String names of the four methods in interface junit.framework.TestListener
+    private static final String START_TEST = "startTest";
+
+    private static final String ADD_FAILURE = "addFailure";
+
+    private static final String ADD_ERROR = "addError";
+
+    private static final String END_TEST = "endTest";
+
+    private Set failedTestsSet = new HashSet();
+
+    private ReporterManager reportManager;
+
+    private static final Class[] EMPTY_CLASS_ARRAY = new Class[]{};
+
+    private static final String[] EMPTY_STRING_ARRAY = new String[]{};
+
+    private static class FailedTest
+    {
+        private Object testThatFailed;
+
+        private Thread threadOnWhichTestFailed;
+
+        FailedTest( Object testThatFailed, Thread threadOnWhichTestFailed )
+        {
+            if ( testThatFailed == null )
+            {
+                throw new NullPointerException( "testThatFailed is null" );
+            }
+
+            if ( threadOnWhichTestFailed == null )
+            {
+                throw new NullPointerException( "threadOnWhichTestFailed is null" );
+            }
+
+            this.testThatFailed = testThatFailed;
+
+            this.threadOnWhichTestFailed = threadOnWhichTestFailed;
+        }
+
+        public boolean equals( Object obj )
+        {
+            boolean retVal = true;
+
+            if ( obj == null || getClass() != obj.getClass() )
+            {
+                retVal = false;
+            }
+            else
+            {
+                FailedTest ft = (FailedTest) obj;
+
+                if ( ft.testThatFailed != testThatFailed )
+                {
+                    retVal = false;
+                }
+                else if ( !ft.threadOnWhichTestFailed.equals( threadOnWhichTestFailed ) )
+                {
+                    retVal = false;
+                }
+            }
+
+            return retVal;
+        }
+
+        public int hashCode()
+        {
+            return threadOnWhichTestFailed.hashCode();
+        }
+    }
+
+    public TestListenerInvocationHandler( ReporterManager reportManager, Object instanceOfTestResult,
+                                          ClassLoader loader )
+    {
+        if ( reportManager == null )
+        {
+            throw new NullPointerException( "reportManager is null" );
+        }
+
+        if ( instanceOfTestResult == null )
+        {
+            throw new NullPointerException( "instanceOfTestResult is null" );
+        }
+
+        if ( loader == null )
+        {
+            throw new NullPointerException( "loader is null" );
+        }
+
+        this.reportManager = reportManager;
+    }
+
+    public Object invoke( Object proxy, Method method, Object[] args )
+        throws Throwable
+    {
+        String methodName = method.getName();
+
+        if ( methodName.equals( START_TEST ) )
+        {
+            handleStartTest( args );
+        }
+        else if ( methodName.equals( ADD_ERROR ) )
+        {
+            handleAddError( args );
+        }
+        else if ( methodName.equals( ADD_FAILURE ) )
+        {
+            handleAddFailure( args );
+        }
+        else if ( methodName.equals( END_TEST ) )
+        {
+            handleEndTest( args );
+        }
+
+        return null;
+    }
+
+    // Handler for TestListener.startTest(Test)
+    public void handleStartTest( Object[] args )
+    {
+        ReportEntry report = new ReportEntry( args[0], args[0].toString(), args[0].getClass().getName() );
+
+        reportManager.testStarting( report );
+    }
+
+    // Handler for TestListener.addFailure(Test, Throwable)
+    private void handleAddError( Object[] args )
+        throws IllegalAccessException, InvocationTargetException
+    {
+        ReportEntry report =
+            new ReportEntry( args[0], args[0].toString(), args[1].toString(), getStackTraceWriter( args ) );
+
+        reportManager.testError( report );
+
+        failedTestsSet.add( new FailedTest( args[0], Thread.currentThread() ) );
+    }
+
+    private JUnitStackTraceWriter getStackTraceWriter( Object[] args )
+        throws IllegalAccessException, InvocationTargetException
+    {
+        String testName;
+
+        try
+        {
+            Method m = args[0].getClass().getMethod( "getName", EMPTY_CLASS_ARRAY );
+            testName = (String) m.invoke( args[0], EMPTY_STRING_ARRAY );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            testName = "UNKNOWN";
+        }
+
+        return new JUnitStackTraceWriter( args[0].getClass().getName(), testName, (Throwable) args[1] );
+    }
+
+    private void handleAddFailure( Object[] args )
+        throws IllegalAccessException, InvocationTargetException
+    {
+        ReportEntry report =
+            new ReportEntry( args[0], args[0].toString(), args[1].toString(), getStackTraceWriter( args ) );
+
+        reportManager.testFailed( report );
+
+        failedTestsSet.add( new FailedTest( args[0], Thread.currentThread() ) );
+    }
+
+    private void handleEndTest( Object[] args )
+    {
+        boolean testHadFailed = failedTestsSet.remove( new FailedTest( args[0], Thread.currentThread() ) );
+
+        if ( !testHadFailed )
+        {
+            ReportEntry report = new ReportEntry( args[0], args[0].toString(), args[0].getClass().getName() );
+
+            reportManager.testSucceeded( report );
+        }
+    }
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/pom.xml?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/pom.xml (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/pom.xml Sun May 13 18:33:45 2007
@@ -0,0 +1,53 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.maven.surefire</groupId>
+    <artifactId>surefire-providers</artifactId>
+    <version>2.4-SNAPSHOT</version>
+  </parent>
+  <artifactId>surefire-junit4</artifactId>
+  <name>SureFire JUnit4 Runner</name>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.0</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <fork>false</fork>
+          <compilerVersion>1.4</compilerVersion>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <jvm>${java.home}/bin/java</jvm>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4DirectoryTestSuite.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4DirectoryTestSuite.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4DirectoryTestSuite.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4DirectoryTestSuite.java Sun May 13 18:33:45 2007
@@ -0,0 +1,59 @@
+package org.apache.maven.surefire.junit4;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.suite.AbstractDirectoryTestSuite;
+import org.apache.maven.surefire.testset.SurefireTestSet;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
+import java.io.File;
+import java.util.ArrayList;
+
+/**
+ * Test suite for JUnit4 based on a directory of Java test classes. This is
+ * capable of running both JUnit3 and JUnit4 test classes (I think).
+ *
+ * @author Karl M. Davis
+ */
+public class JUnit4DirectoryTestSuite
+    extends AbstractDirectoryTestSuite
+{
+    /**
+     * Constructor.
+     */
+    public JUnit4DirectoryTestSuite( File basedir, ArrayList includes, ArrayList excludes )
+    {
+        super( basedir, includes, excludes );
+    }
+
+    /**
+     * This method will be called for each class to be run as a test. It returns
+     * a surefire test set that will later be executed.
+     *
+     * @see org.apache.maven.surefire.suite.AbstractDirectoryTestSuite#createTestSet(java.lang.Class,
+     *java.lang.ClassLoader)
+     */
+    protected SurefireTestSet createTestSet( Class testClass, ClassLoader classLoader )
+        throws TestSetFailedException
+    {
+        return new JUnit4TestSet( testClass );
+    }
+
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4StackTraceWriter.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4StackTraceWriter.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4StackTraceWriter.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4StackTraceWriter.java Sun May 13 18:33:45 2007
@@ -0,0 +1,77 @@
+package org.apache.maven.surefire.junit4;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.report.StackTraceWriter;
+import org.junit.runner.notification.Failure;
+
+/**
+ * Writes out a specific {@link org.junit.runner.notification.Failure} for
+ * surefire as a stacktrace.
+ *
+ * @author Karl M. Davis
+ */
+public class JUnit4StackTraceWriter
+    implements StackTraceWriter
+{
+    // Member Variables
+    private Failure junitFailure;
+
+    /**
+     * Constructor.
+     *
+     * @param junitFailure the {@link Failure} that this will be operating on
+     */
+    public JUnit4StackTraceWriter( Failure junitFailure )
+    {
+        this.junitFailure = junitFailure;
+    }
+
+    /*
+      * (non-Javadoc)
+      *
+      * @see org.apache.maven.surefire.report.StackTraceWriter#writeTraceToString()
+      */
+    public String writeTraceToString()
+    {
+        return junitFailure.getTrace();
+    }
+
+    /**
+     * At the moment, returns the same as {@link #writeTraceToString()}.
+     *
+     * @see org.apache.maven.surefire.report.StackTraceWriter#writeTrimmedTraceToString()
+     */
+    public String writeTrimmedTraceToString()
+    {
+        return junitFailure.getTrace();
+    }
+
+    /**
+     * Returns the exception associated with this failure.
+     *
+     * @see org.apache.maven.surefire.report.StackTraceWriter#getThrowable()
+     */
+    public Throwable getThrowable()
+    {
+        return junitFailure.getException();
+    }
+
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4TestSet.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4TestSet.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4TestSet.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4TestSet.java Sun May 13 18:33:45 2007
@@ -0,0 +1,80 @@
+package org.apache.maven.surefire.junit4;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.report.ReporterManager;
+import org.apache.maven.surefire.testset.AbstractTestSet;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+
+public class JUnit4TestSet
+    extends AbstractTestSet
+{
+    // Member Variables
+    private Runner junitTestRunner;
+
+    /**
+     * Constructor.
+     *
+     * @param testClass the class to be run as a test
+     */
+    protected JUnit4TestSet( Class testClass )
+    {
+        super( testClass );
+
+        junitTestRunner = Request.aClass( testClass ).getRunner();
+    }
+
+    /**
+     * Actually runs the test and adds the tests results to the <code>reportManager</code>.
+     *
+     * @see org.apache.maven.surefire.testset.SurefireTestSet#execute(org.apache.maven.surefire.report.ReporterManager,java.lang.ClassLoader)
+     */
+    public void execute( ReporterManager reportManager, ClassLoader loader )
+        throws TestSetFailedException
+    {
+        RunNotifier fNotifier = new RunNotifier();
+        RunListener listener = new JUnit4TestSetReporter( this, reportManager );
+        fNotifier.addListener( listener );
+
+        try
+        {
+            junitTestRunner.run( fNotifier );
+        }
+        finally
+        {
+            fNotifier.removeListener( listener );
+        }
+    }
+
+    /**
+     * Returns the number of tests to be run in this class.
+     *
+     * @see org.apache.maven.surefire.testset.SurefireTestSet#getTestCount()
+     */
+    public int getTestCount()
+        throws TestSetFailedException
+    {
+        return junitTestRunner.testCount();
+    }
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4TestSetReporter.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4TestSetReporter.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4TestSetReporter.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4TestSetReporter.java Sun May 13 18:33:45 2007
@@ -0,0 +1,160 @@
+package org.apache.maven.surefire.junit4;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.Surefire;
+import org.apache.maven.surefire.report.ReportEntry;
+import org.apache.maven.surefire.report.ReporterManager;
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+import java.util.ResourceBundle;
+
+public class JUnit4TestSetReporter
+    extends RunListener
+{
+    // Constants
+    private static ResourceBundle bundle = ResourceBundle.getBundle( Surefire.SUREFIRE_BUNDLE_NAME );
+
+    // Member Variables
+    private JUnit4TestSet testSet;
+
+    private ReporterManager reportMgr;
+
+    /**
+     * This flag is set after a failure has occurred so that a <code>testSucceeded</code> event is not fired.  This is necessary because JUnit4 always fires a <code>testRunFinished</code> event-- even if there was a failure.
+     */
+    private boolean failureFlag;
+
+    /**
+     * Constructor.
+     *
+     * @param testSet       the specific test set that this will report on as it is
+     *                      executed
+     * @param reportManager the report manager to log testing events to
+     */
+    JUnit4TestSetReporter( JUnit4TestSet testSet, ReporterManager reportManager )
+    {
+        this.testSet = testSet;
+        this.reportMgr = reportManager;
+    }
+
+    /**
+     * Called right before any tests from a specific class are run.
+     *
+     * @see org.junit.runner.notification.RunListener#testRunStarted(org.junit.runner.Description)
+     */
+    public void testRunStarted( Description description )
+        throws Exception
+    {
+        String rawString = bundle.getString( "testSetStarting" );
+        ReportEntry report = new ReportEntry( testSet, testSet.getName(), rawString );
+
+        this.reportMgr.testSetStarting( report );
+    }
+
+    /**
+     * Called right after all tests from a specific class are run.
+     *
+     * @see org.junit.runner.notification.RunListener#testRunFinished(org.junit.runner.Result)
+     */
+    public void testRunFinished( Result result )
+        throws Exception
+    {
+        String rawString = bundle.getString( "testSetCompletedNormally" );
+        ReportEntry report = new ReportEntry( testSet, testSet.getName(), rawString );
+
+        this.reportMgr.testSetCompleted( report );
+        this.reportMgr.reset();
+    }
+
+    /**
+     * Called when a specific test has been skipped (for whatever reason).
+     *
+     * @see org.junit.runner.notification.RunListener#testIgnored(org.junit.runner.Description)
+     */
+    public void testIgnored( Description description )
+        throws Exception
+    {
+        String rawString = bundle.getString( "testSkipped" );
+        ReportEntry report = new ReportEntry( testSet, description.getDisplayName(), rawString );
+
+        this.reportMgr.testSkipped( report );
+    }
+
+    /**
+     * Called when a specific test has started.
+     *
+     * @see org.junit.runner.notification.RunListener#testStarted(org.junit.runner.Description)
+     */
+    public void testStarted( Description description )
+        throws Exception
+    {
+        String rawString = bundle.getString( "testStarting" );
+        ReportEntry report = new ReportEntry( testSet, description.getDisplayName(), rawString );
+
+        this.reportMgr.testStarting( report );
+
+        this.failureFlag = false;
+    }
+
+    /**
+     * Called when a specific test has failed.
+     *
+     * @see org.junit.runner.notification.RunListener#testFailure(org.junit.runner.notification.Failure)
+     */
+    public void testFailure( Failure failure )
+        throws Exception
+    {
+        String rawString = bundle.getString( "executeException" );
+        ReportEntry report =
+            new ReportEntry( testSet, failure.getTestHeader(), rawString, new JUnit4StackTraceWriter( failure ) );
+
+        if ( failure.getException() instanceof AssertionError )
+        {
+            this.reportMgr.testFailed( report );
+        }
+        else
+        {
+            this.reportMgr.testError( report );
+        }
+
+        failureFlag = true;
+    }
+
+    /**
+     * Called after a specific test has finished.
+     *
+     * @see org.junit.runner.notification.RunListener#testFinished(org.junit.runner.Description)
+     */
+    public void testFinished( Description description )
+        throws Exception
+    {
+        if ( failureFlag == false )
+        {
+            String rawString = bundle.getString( "testSuccessful" );
+            ReportEntry report = new ReportEntry( testSet, description.getDisplayName(), rawString );
+
+            this.reportMgr.testSucceeded( report );
+        }
+    }
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/pom.xml?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/pom.xml (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/pom.xml Sun May 13 18:33:45 2007
@@ -0,0 +1,83 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.maven.surefire</groupId>
+    <artifactId>surefire-providers</artifactId>
+    <version>2.4-SNAPSHOT</version>
+  </parent>
+  <artifactId>surefire-testng</artifactId>
+  <name>SureFire TestNG Runner</name>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact</artifactId>
+      <version>2.0</version>
+    </dependency>
+  </dependencies>
+  <profiles>
+    <profile>
+      <id>jdk14</id>
+      <activation>
+        <jdk>1.4</jdk>
+      </activation>
+      <dependencies>
+        <dependency>
+          <groupId>org.testng</groupId>
+          <artifactId>testng</artifactId>
+          <version>5.1</version>
+          <classifier>jdk14</classifier>
+        </dependency>
+      </dependencies>
+    </profile>
+    <profile>
+      <id>jdk15</id>
+      <activation>
+        <jdk>!1.4</jdk>
+      </activation>
+      <dependencies>
+        <dependency>
+          <groupId>org.testng</groupId>
+          <artifactId>testng</artifactId>
+          <version>5.1</version>
+          <classifier>jdk15</classifier>
+        </dependency>
+      </dependencies>
+    </profile>
+  </profiles>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <fork>false</fork>
+          <compilerVersion>1.4</compilerVersion>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <jvm>${java.home}/bin/java</jvm>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/ExecEnv.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/ExecEnv.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/ExecEnv.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/ExecEnv.java Sun May 13 18:33:45 2007
@@ -0,0 +1,34 @@
+package org.apache.maven.surefire.testng;
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.surefire.report.ReporterManager;
+import org.apache.maven.surefire.suite.SurefireTestSuite;
+
+/**
+ * A descriptor of the current execution environment.
+ * 
+ * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
+ */
+public class ExecEnv {
+	private SurefireTestSuite suite;
+	private ArtifactVersion version;
+	private ReporterManager reportManager;
+
+	public ExecEnv(SurefireTestSuite suite, ArtifactVersion version, ReporterManager reporter) {
+		this.suite = suite;
+		this.version = version;
+		this.reportManager = reporter;
+	}
+
+	public SurefireTestSuite getSuite() {
+		return suite;
+	}
+
+	public ArtifactVersion getVersion() {
+		return version;
+	}
+
+	public ReporterManager getReportManager() {
+		return reportManager;
+	}
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java Sun May 13 18:33:45 2007
@@ -0,0 +1,100 @@
+package org.apache.maven.surefire.testng;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.surefire.report.ReporterException;
+import org.apache.maven.surefire.report.ReporterManager;
+import org.apache.maven.surefire.suite.AbstractDirectoryTestSuite;
+import org.apache.maven.surefire.testset.SurefireTestSet;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
+/**
+ * Test suite for TestNG based on a directory of Java test classes. Can also execute JUnit tests.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
+ */
+public class TestNGDirectoryTestSuite
+    extends AbstractDirectoryTestSuite
+{
+	private ArtifactVersion version;
+	
+    private Map options;
+    
+    public TestNGDirectoryTestSuite( File basedir, List includes, List excludes, String testSourceDirectory,
+                                     ArtifactVersion artifactVersion, Map confOptions)
+    {
+        super( basedir, includes, excludes );
+
+        this.options = confOptions;
+        this.options.put(TestNGExecutor.SOURCE_DIRS_OPTION, testSourceDirectory);
+    }
+
+    protected SurefireTestSet createTestSet( Class testClass, ClassLoader classLoader )
+    {
+        return new TestNGTestSet( testClass );
+    }
+
+    // single class test
+    public void execute( String testSetName, ReporterManager reporterManager, ClassLoader classLoader )
+        throws ReporterException, TestSetFailedException
+    {
+        if ( testSets == null )
+        {
+            throw new IllegalStateException( "You must call locateTestSets before calling execute" );
+        }
+        SurefireTestSet testSet = (SurefireTestSet) testSets.get( testSetName );
+
+        if ( testSet == null )
+        {
+            throw new TestSetFailedException( "Unable to find test set '" + testSetName + "' in suite" );
+        }
+
+        // TODO: display a WARNING that you may see unexpected behavior
+        TestNGExecutor.run(new Class[] {testSet.getTestClass()}, this.options, 
+        		new ExecEnv(this, this.version, reporterManager));
+    }
+
+    public void execute( ReporterManager reporterManager, ClassLoader classLoader )
+        throws ReporterException, TestSetFailedException
+    {
+        if ( testSets == null )
+        {
+            throw new IllegalStateException( "You must call locateTestSets before calling execute" );
+        }
+
+        Class[] testClasses = new Class[testSets.size()];
+        int i = 0; 
+        for ( Iterator it = testSets.values().iterator(); it.hasNext(); )
+        {
+        	SurefireTestSet testSet = (SurefireTestSet) it.next();
+        	testClasses[i++] = testSet.getTestClass();
+        }
+
+        TestNGExecutor.run(testClasses, this.options, 
+        		new ExecEnv(this, this.version, reporterManager));
+    }
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java Sun May 13 18:33:45 2007
@@ -0,0 +1,88 @@
+package org.apache.maven.surefire.testng;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.testng.TestNG;
+
+/**
+ * Contains utility methods for executing TestNG.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
+ */
+public class TestNGExecutor
+{
+	public static final String SOURCE_DIRS_OPTION = "maven.testng.src.dir";
+	public static final String PARALLEL_MODE_OPTION = "parallel";
+	
+    private TestNGExecutor()
+    {
+    }
+	
+	public static void run(Class[] testClasses, Map options, ExecEnv execEnv) {
+		TestNG testng = initialize(execEnv, (String) options.remove(SOURCE_DIRS_OPTION));
+		IConfigurator configurator = getConfigurator(execEnv.getVersion());
+		configurator.configure(testng, options);
+		testng.setTestClasses(testClasses);
+		testng.run();
+	}
+
+	public static void run(List suiteFiles, Map options, ExecEnv execEnv) {
+		TestNG testng = initialize(execEnv, (String) options.remove(SOURCE_DIRS_OPTION));
+		IConfigurator configurator = getConfigurator(execEnv.getVersion());
+		configurator.configure(testng, options);
+		testng.setTestSuites(suiteFiles);
+		testng.run();
+	}
+	
+	private static interface IConfigurator {
+		void configure(TestNG testng, Map options);
+	}
+	
+	private static IConfigurator getConfigurator(ArtifactVersion version) {
+		return null;
+	}
+	
+	private static TestNG initialize(ExecEnv env, String sourcePath) {
+		TestNG testNG = new TestNG( false );
+		
+		// turn off all TestNG output
+		testNG.setVerbose( 0 );
+		
+        testNG.setListenerClasses( new ArrayList() );
+	
+        TestNGReporter reporter = new TestNGReporter( env.getReportManager(), env.getSuite() );
+        testNG.addListener( (Object) reporter );
+        if(sourcePath != null) {
+        	testNG.setSourcePath(sourcePath);
+        }
+        // workaround for SUREFIRE-49
+        // TestNG always creates an output directory, and if not set the name for the directory is "null"
+        testNG.setOutputDirectory( System.getProperty( "java.io.tmpdir" ) );
+        
+        return testNG;
+	}	
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGReporter.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGReporter.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGReporter.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGReporter.java Sun May 13 18:33:45 2007
@@ -0,0 +1,195 @@
+package org.apache.maven.surefire.testng;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.Surefire;
+import org.apache.maven.surefire.report.ReportEntry;
+import org.apache.maven.surefire.report.ReporterException;
+import org.apache.maven.surefire.report.ReporterManager;
+import org.apache.maven.surefire.suite.SurefireTestSuite;
+import org.testng.ISuite;
+import org.testng.ISuiteListener;
+import org.testng.ITestContext;
+import org.testng.ITestListener;
+import org.testng.ITestResult;
+import org.testng.TestNG;
+
+import java.util.ResourceBundle;
+
+/**
+ * Listens for and provides and adaptor layer so that
+ * TestNG tests can report their status to the current
+ * {@link org.apache.maven.surefire.report.ReporterManager}.
+ *
+ * @author jkuhnert
+ */
+public class TestNGReporter
+    implements ITestListener, ISuiteListener
+{
+    private ResourceBundle bundle = ResourceBundle.getBundle( Surefire.SUREFIRE_BUNDLE_NAME );
+
+    /**
+     * core Surefire reporting
+     */
+    protected ReporterManager reportManager;
+
+    private Object source;
+
+    /**
+     * Constructs a new instance that will listen to
+     * test updates from a {@link TestNG} class instance.
+     * <p/>
+     * <p/>It is assumed that the requisite {@link TestNG#addListener(ITestListener)}
+     * method call has already associated with this instance <i>before</i> the test
+     * suite is run.
+     *
+     * @param reportManager Instance to report suite status to
+     */
+    public TestNGReporter( ReporterManager reportManager, SurefireTestSuite source )
+    {
+        this.reportManager = reportManager;
+
+        if ( reportManager == null )
+        {
+            throw new IllegalArgumentException( "ReportManager passed in was null." );
+        }
+
+        this.source = source;
+    }
+
+    public void onTestStart( ITestResult result )
+    {
+        String rawString = bundle.getString( "testStarting" );
+        String group = groupString( result.getMethod().getGroups(), result.getTestClass().getName() );
+        ReportEntry report = new ReportEntry( source, getUserFriendlyTestName( result ), group, rawString );
+
+        reportManager.testStarting( report );
+    }
+
+    public void onTestSuccess( ITestResult result )
+    {
+        ReportEntry report =
+            new ReportEntry( source, getUserFriendlyTestName( result ), bundle.getString( "testSuccessful" ) );
+        reportManager.testSucceeded( report );
+    }
+
+    public void onTestFailure( ITestResult result )
+    {
+        String rawString = bundle.getString( "executeException" );
+
+        ReportEntry report = new ReportEntry( source, getUserFriendlyTestName( result ), rawString,
+                                              new TestNGStackTraceWriter( result ) );
+
+        reportManager.testFailed( report );
+    }
+
+    private static String getUserFriendlyTestName( ITestResult result )
+    {
+        // This is consistent with the JUnit output
+        return result.getName() + "(" + result.getTestClass().getName() + ")";
+    }
+
+    public void onTestSkipped( ITestResult result )
+    {
+        ReportEntry report =
+            new ReportEntry( source, getUserFriendlyTestName( result ), bundle.getString( "testSkipped" ) );
+
+        reportManager.testSkipped( report );
+    }
+
+    public void onTestFailedButWithinSuccessPercentage( ITestResult result )
+    {
+        String rawString = bundle.getString( "executeException" );
+
+        ReportEntry report = new ReportEntry( source, getUserFriendlyTestName( result ), rawString,
+                                              new TestNGStackTraceWriter( result ) );
+
+        reportManager.testError( report );
+    }
+
+    public void onStart( ITestContext context )
+    {
+        String rawString = bundle.getString( "testSetStarting" );
+
+        String group = groupString( context.getIncludedGroups(), context.getName() );
+
+        ReportEntry report = new ReportEntry( source, context.getName(), group, rawString );
+
+        try
+        {
+            reportManager.testSetStarting( report );
+        }
+        catch ( ReporterException e )
+        {
+            // TODO: remove this exception from the report manager
+        }
+    }
+
+    public void onFinish( ITestContext context )
+    {
+        String rawString = bundle.getString( "testSetCompletedNormally" );
+
+        ReportEntry report =
+            new ReportEntry( source, context.getName(), groupString( context.getIncludedGroups(), null ), rawString );
+
+        reportManager.testSetCompleted( report );
+
+        reportManager.reset();
+    }
+
+    public void onFinish( ISuite suite )
+    {
+    }
+
+    public void onStart( ISuite suite )
+    {
+    }
+
+    /**
+     * Creates a string out of the list of testng groups in the
+     * form of <pre>"group1,group2,group3"</pre>.
+     *
+     * @param groups
+     * @param defaultValue
+     */
+    private static String groupString( String[] groups, String defaultValue )
+    {
+        String retVal;
+        if ( groups != null && groups.length > 0 )
+        {
+            StringBuffer str = new StringBuffer();
+            for ( int i = 0; i < groups.length; i++ )
+            {
+                str.append( groups[i] );
+                if ( i + 1 < groups.length )
+                {
+                    str.append( "," );
+                }
+            }
+            retVal = str.toString();
+        }
+        else
+        {
+            retVal = defaultValue;
+        }
+        return retVal;
+    }
+
+}

Added: maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGStackTraceWriter.java
URL: http://svn.apache.org/viewvc/maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGStackTraceWriter.java?view=auto&rev=537691
==============================================================================
--- maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGStackTraceWriter.java (added)
+++ maven/sandbox/branches/surefire/surefire-collab2/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGStackTraceWriter.java Sun May 13 18:33:45 2007
@@ -0,0 +1,70 @@
+package org.apache.maven.surefire.testng;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.surefire.report.PojoStackTraceWriter;
+import org.codehaus.plexus.util.StringUtils;
+import org.testng.ITestResult;
+
+/**
+ * Write out stack traces for TestNG.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class TestNGStackTraceWriter
+    extends PojoStackTraceWriter
+{
+    public TestNGStackTraceWriter( ITestResult result )
+    {
+        super( result.getTestClass().getRealClass().getName(), result.getMethod().getMethodName(),
+               result.getThrowable() );
+    }
+
+    public String writeTrimmedTraceToString()
+    {
+        String text = writeTraceToString();
+
+        String marker = "at " + testClass + "." + testMethod;
+
+        String[] lines = StringUtils.split( text, "\n" );
+        int lastLine = lines.length - 1;
+        // skip first
+        for ( int i = 1; i < lines.length; i++ )
+        {
+            if ( lines[i].trim().startsWith( marker ) )
+            {
+                lastLine = i;
+            }
+        }
+
+        StringBuffer trace = new StringBuffer();
+        for ( int i = 0; i <= lastLine; i++ )
+        {
+            // if you call assertions from JUnit tests in TestNG, it ends up at the top of the trace
+            if ( !lines[i].trim().startsWith( "at junit.framework.Assert" ) )
+            {
+                trace.append( lines[i] );
+                trace.append( "\n" );
+            }
+        }
+
+        return trace.toString();
+    }
+}