blob: 76a3b61ff2aea88785d746245409dbfdc7fe11f1 [file] [log] [blame]
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 org.apache.maven.surefire.api.report.SafeThrowable;
import org.apache.maven.surefire.report.SmartStackTraceParser;
import org.apache.maven.surefire.api.report.StackTraceWriter;
import org.apache.maven.surefire.api.util.internal.ClassMethod;
import org.junit.runner.notification.Failure;
import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod;
import static org.apache.maven.surefire.report.SmartStackTraceParser.stackTraceWithFocusOnClassAsString;
/**
* Writes out a specific {@link org.junit.runner.notification.Failure} for
* surefire as a stacktrace.
*
* @author Karl M. Davis
*/
public class JUnit4StackTraceWriter
implements StackTraceWriter
{
private final 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()
*/
@Override
public String writeTraceToString()
{
Throwable t = junitFailure.getException();
if ( t != null )
{
String originalTrace = junitFailure.getTrace();
if ( isMultiLineExceptionMessage( t ) )
{
// SUREFIRE-986
StringBuilder builder = new StringBuilder( originalTrace );
String exc = t.getClass().getName() + ": ";
if ( originalTrace.startsWith( exc ) )
{
builder.insert( exc.length(), '\n' );
}
return builder.toString();
}
return originalTrace;
}
return "";
}
@Override
public String smartTrimmedStackTrace()
{
Throwable exception = junitFailure.getException();
ClassMethod classMethod = toClassMethod( junitFailure.getDescription() );
return exception == null
? junitFailure.getMessage()
: new SmartStackTraceParser( classMethod.getClazz(), exception, classMethod.getMethod() ).getString();
}
/**
* At the moment, returns the same as {@link #writeTraceToString()}.
*
* @see StackTraceWriter#writeTrimmedTraceToString()
*/
@Override
public String writeTrimmedTraceToString()
{
String testClass = toClassMethod( junitFailure.getDescription() ).getClazz();
try
{
Throwable e = junitFailure.getException();
return stackTraceWithFocusOnClassAsString( e, testClass );
}
catch ( Throwable t )
{
return stackTraceWithFocusOnClassAsString( t, testClass );
}
}
/**
* Returns the exception associated with this failure.
*
* @see StackTraceWriter#getThrowable()
*/
@Override
public SafeThrowable getThrowable()
{
return new SafeThrowable( junitFailure.getException() );
}
private static boolean isMultiLineExceptionMessage( Throwable t )
{
String msg = t.getLocalizedMessage();
if ( msg != null )
{
int countNewLines = 0;
for ( int i = 0, length = msg.length(); i < length; i++ )
{
if ( msg.charAt( i ) == '\n' )
{
if ( ++countNewLines == 2 )
{
break;
}
}
}
return countNewLines > 1 || countNewLines == 1 && !msg.trim().endsWith( "\n" );
}
return false;
}
}