package org.apache.maven.surefire.common.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 java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.maven.surefire.testset.TestSetFailedException;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.createRequest;
import static org.apache.maven.surefire.util.internal.StringUtils.isBlank;
import static org.junit.runner.Description.TEST_MECHANISM;
/**
*
* Utility method used among all JUnit4 providers
*
* @author Qingzhou Luo
*
*/
public final class JUnit4ProviderUtil
{
private JUnit4ProviderUtil()
{
throw new IllegalStateException( "Cannot instantiate." );
}
/**
* Organize all the failures in previous run into a map between test classes and corresponding failing test methods
*
* @param allFailures all the failures in previous run
* @param testClassLoader ClassLoader used for test classes
* @return a map between failing test classes and their corresponding failing test methods
*/
public static Map<Class<?>, Set<String>> generateFailingTests( List<Failure> allFailures,
ClassLoader testClassLoader )
throws TestSetFailedException
{
Map<Class<?>, Set<String>> testClassMethods = new HashMap<Class<?>, Set<String>>();
Set<ClassMethod> failingTests = generateFailingTests( allFailures );
for ( ClassMethod classMethod: failingTests )
{
try
{
Class testClassObj = Class.forName( classMethod.getClazz(), false, testClassLoader );
Set<String> failingMethods = testClassMethods.get( testClassObj );
if ( failingMethods == null )
{
failingMethods = new HashSet<String>();
testClassMethods.put( testClassObj, failingMethods );
}
failingMethods.add( classMethod.getMethod() );
}
catch ( ClassNotFoundException e )
{
throw new TestSetFailedException( "Unable to create test class '" + classMethod.getClazz() + "'", e );
}
}
return testClassMethods;
}
/**
* Get all test methods from a list of Failures
*
* @param allFailures the list of failures for a given test class
* @return the list of test methods
*/
public static Set<ClassMethod> generateFailingTests( List<Failure> allFailures )
{
Set<ClassMethod> failingMethods = new HashSet<ClassMethod>();
for ( Failure failure : allFailures )
{
Description description = failure.getDescription();
if ( description.isTest() && !isFailureInsideJUnitItself( description ) )
{
ClassMethod classMethod = cutTestClassAndMethod( description );
if ( classMethod.isValid() )
{
failingMethods.add( classMethod );
}
}
}
return failingMethods;
}
public static Description createSuiteDescription( Collection<Class<?>> classes )
{
return createRequest( classes.toArray( new Class[classes.size()] ) ).getRunner().getDescription();
}
public static boolean isFailureInsideJUnitItself( Description failure )
{
return TEST_MECHANISM.equals( failure );
}
/**
* Java Patterns of regex is slower than cutting a substring.
* @param description method(class) or method[#](class) or method[#whatever-literals](class)
* @return method JUnit test method
*/
public static ClassMethod cutTestClassAndMethod( Description description )
{
String name = description.getDisplayName();
String clazz = null;
String method = null;
if ( name != null )
{
// The order is : 1.method and then 2.class
// method(class)
name = name.trim();
if ( name.endsWith( ")" ) )
{
int classBracket = name.lastIndexOf( '(' );
if ( classBracket != -1 )
{
clazz = tryBlank( name.substring( classBracket + 1, name.length() - 1 ) );
method = tryBlank( name.substring( 0, classBracket ) );
}
}
}
return new ClassMethod( clazz, method );
}
private static String tryBlank( String s )
{
s = s.trim();
return isBlank( s ) ? null : s;
}
}