diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/api/report/LegacyPojoStackTraceWriterTest.java b/surefire-api/src/test/java/org/apache/maven/surefire/api/report/LegacyPojoStackTraceWriterTest.java index f2c8e85602..da8c07797b 100644 --- a/surefire-api/src/test/java/org/apache/maven/surefire/api/report/LegacyPojoStackTraceWriterTest.java +++ b/surefire-api/src/test/java/org/apache/maven/surefire/api/report/LegacyPojoStackTraceWriterTest.java @@ -34,6 +34,7 @@ public void testWriteTrimmedTraceToString() { String stackTrace = "junit.framework.AssertionFailedError: blah\n" + " at junit.framework.Assert.fail(Assert.java:47)\n" + + " at AnotherClass.execute(AnotherClass.java:60)\n" + " at TestSurefire3.testQuote(TestSurefire3.java:23)\n" + " at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" + " at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n" @@ -64,7 +65,10 @@ public void testWriteTrimmedTraceToString() MockThrowable t = new MockThrowable( stackTrace ); LegacyPojoStackTraceWriter w = new LegacyPojoStackTraceWriter( "TestSurefire3", "testQuote", t ); String out = w.writeTrimmedTraceToString(); - String expected = "junit.framework.AssertionFailedError: blah\n" + " at junit.framework.Assert.fail(Assert.java:47)\n" + " at TestSurefire3.testQuote(TestSurefire3.java:23)\n"; + String expected = "junit.framework.AssertionFailedError: blah\n" + + " at junit.framework.Assert.fail(Assert.java:47)\n" + + " at AnotherClass.execute(AnotherClass.java:60)\n" + + " at TestSurefire3.testQuote(TestSurefire3.java:23)\n"; assertEquals( expected, out ); } @@ -72,6 +76,7 @@ public void testWriteTrimmedTraceToString() public void testCausedBy() { String stackTrace = "java.lang.RuntimeException: blah\n" + + " at AnotherClass.execute(AnotherClass.java:60)\n" + " at TestSurefire3.testBlah(TestSurefire3.java:45)\n" + " at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" + " at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n" @@ -109,6 +114,7 @@ public void testCausedBy() LegacyPojoStackTraceWriter w = new LegacyPojoStackTraceWriter( "TestSurefire3", "testBlah", t ); String out = w.writeTrimmedTraceToString(); String expected = "java.lang.RuntimeException: blah\n" + + " at AnotherClass.execute(AnotherClass.java:60)\n" + " at TestSurefire3.testBlah(TestSurefire3.java:45)\n" + "Caused by: junit.framework.AssertionFailedError: \"\n" + " at junit.framework.Assert.fail(Assert.java:47)\n" diff --git a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java index d6d9703abd..7c4ff6b58c 100644 --- a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java +++ b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java @@ -83,7 +83,7 @@ public String smartTrimmedStackTrace() @Override public String writeTrimmedTraceToString() { - return t == null ? "" : SmartStackTraceParser.stackTraceWithFocusOnClassAsString( t, testClass ); + return t == null ? "" : new SmartStackTraceParser( testClass, t, testMethod ).getTrimmedStackTrace(); } @Override diff --git a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java index 3770f2bab4..329f80b7b6 100644 --- a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java +++ b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/SmartStackTraceParser.java @@ -212,6 +212,15 @@ static Throwable findTopmostWithClass( final Throwable t, StackTraceFilter filte return t; } + public String getTrimmedStackTrace( ) + { + StackTraceFilter filter = new ClassNameStackTraceFilter( testClassName ); + Throwable topmost = findTopmostWithClass( throwable.getTarget(), filter ); + List stackTraceElements = asList( topmost.getStackTrace() ); + String s = causeToString( topmost.getCause(), filter ); + return toTrimmedString( throwable.getTarget(), stackTraceElements, filter ) + s; + } + public static String stackTraceWithFocusOnClassAsString( Throwable t, String className ) { StackTraceFilter filter = new ClassNameStackTraceFilter( className ); @@ -258,6 +267,44 @@ private static String causeToString( Throwable cause, StackTraceFilter filter ) return resp.toString(); } + private static String toTrimmedString( Throwable t, Iterable elements, StackTraceFilter filter ) + { + StringBuilder result = new StringBuilder(); + if ( t != null ) + { + result.append( t.getClass().getName() ); + String msg = t.getMessage(); + if ( msg != null ) + { + result.append( ": " ); + if ( isMultiLine( msg ) ) + { + // SUREFIRE-986 + result.append( '\n' ); + } + result.append( msg ); + } + result.append( '\n' ); + } + + boolean matched = false; + for ( StackTraceElement element : elements ) + { + if ( filter.matches( element ) ) + { + matched = true; + } + + if ( filter.matches( element ) || !matched ) + { + result.append( "\tat " ) + .append( element ) + .append( '\n' ); + } + } + return result.toString(); + } + private static String toString( Throwable t, Iterable elements, StackTraceFilter filter ) { StringBuilder result = new StringBuilder(); diff --git a/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/PojoStackTraceWriterTest.java b/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/PojoStackTraceWriterTest.java index 69a3db06d7..e16e7a8c27 100644 --- a/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/PojoStackTraceWriterTest.java +++ b/surefire-providers/common-java5/src/test/java/org/apache/maven/surefire/report/PojoStackTraceWriterTest.java @@ -21,6 +21,8 @@ import junit.framework.TestCase; +import static org.assertj.core.api.Assertions.assertThat; + /** * */ @@ -56,6 +58,37 @@ public void testMultiLineMessage() } } + public void testTrimmedStackTrace( ) + { + Throwable throwable = new Exception( "" ); + + try + { + throwExceptionFromTestClass( ); + } + catch ( Throwable t ) + { + throwable = t; + } + PojoStackTraceWriter a = new PojoStackTraceWriter( + "org.apache.maven.surefire.report.PojoStackTraceWriterTest", null, throwable + ); + String result = a.writeTrimmedTraceToString(); + + assertThat( result ).contains( "org.apache.maven.surefire.report.PojoStackTraceWriterTest." + + "throwExceptionFromTestClass(PojoStackTraceWriterTest.java" ); + assertThat( result ).contains( "org.apache.maven.surefire.report.PojoStackTraceWriterTest." + + "testTrimmedStackTrace(PojoStackTraceWriterTest.java" ); + assertThat( result ).hasLineCount( 8 ); + assertThat( result ).contains( "Caused by: java.lang.Exception: Hey ho, hey ho, a throwable we throw!" ); + } + + public void throwExceptionFromTestClass() throws Exception + { + Object call = new RunnableTestClass1().call(); + throw new IllegalStateException( "illegal state", (Throwable) call ); + } + static class ATestClass { static class AnotherTestClass diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java index 76a3b61ff2..de04ad2213 100644 --- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java +++ b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java @@ -26,7 +26,6 @@ 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 @@ -99,11 +98,11 @@ public String writeTrimmedTraceToString() try { Throwable e = junitFailure.getException(); - return stackTraceWithFocusOnClassAsString( e, testClass ); + return new SmartStackTraceParser( testClass, e, null ).getTrimmedStackTrace(); } catch ( Throwable t ) { - return stackTraceWithFocusOnClassAsString( t, testClass ); + return new SmartStackTraceParser( testClass, t, null ).getTrimmedStackTrace(); } }