1 package org.apache.maven.surefire.common.junit4;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.report.ReportEntry;
23 import org.apache.maven.surefire.report.RunListener;
24 import org.apache.maven.surefire.report.SimpleReportEntry;
25 import org.apache.maven.surefire.report.StackTraceWriter;
26 import org.apache.maven.surefire.testset.TestSetFailedException;
27 import org.junit.runner.Description;
28 import org.junit.runner.Result;
29 import org.junit.runner.notification.Failure;
30
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34 public class JUnit4RunListener
35 extends org.junit.runner.notification.RunListener
36 {
37 private static final Pattern PARENS = Pattern.compile( "^" + ".+"
38 + "\\(("
39
40 + "[^\\\\(\\\\)]+"
41 + ")\\)" + "$" );
42
43 protected final RunListener reporter;
44
45
46
47
48
49 private final ThreadLocal<Boolean> failureFlag = new InheritableThreadLocal<Boolean>();
50
51 private final JUnit4Reflector jUnit4Reflector = new JUnit4Reflector();
52
53
54
55
56
57
58 public JUnit4RunListener( RunListener reporter )
59 {
60 this.reporter = reporter;
61 }
62
63
64
65
66
67
68
69
70 public void testIgnored( Description description )
71 throws Exception
72 {
73 final String reason = jUnit4Reflector.getAnnotatedIgnoreValue( description );
74 final SimpleReportEntry report =
75 SimpleReportEntry.ignored( getClassName( description ), description.getDisplayName(), reason );
76 reporter.testSkipped( report );
77 }
78
79
80
81
82
83
84 public void testStarted( Description description )
85 throws Exception
86 {
87 reporter.testStarting( createReportEntry( description ) );
88 failureFlag.remove();
89 }
90
91
92
93
94
95
96 @SuppressWarnings( { "ThrowableResultOfMethodCallIgnored" } )
97 public void testFailure( Failure failure )
98 throws Exception
99 {
100 String testHeader = failure.getTestHeader();
101 if ( isInsaneJunitNullString( testHeader ) )
102 {
103 testHeader = "Failure when constructing test";
104 }
105 ReportEntry report = SimpleReportEntry.withException( getClassName( failure.getDescription() ), testHeader,
106 createStackTraceWriter( failure ) );
107
108 if ( failure.getException() instanceof AssertionError )
109 {
110 this.reporter.testFailed( report );
111 }
112 else
113 {
114 this.reporter.testError( report );
115 }
116 failureFlag.set( Boolean.TRUE );
117 }
118
119 protected StackTraceWriter createStackTraceWriter( Failure failure )
120 {
121 return new JUnit4StackTraceWriter( failure );
122 }
123
124 @SuppressWarnings( { "UnusedDeclaration" } )
125 public void testAssumptionFailure( Failure failure )
126 {
127 this.reporter.testAssumptionFailure( createReportEntry( failure.getDescription() ) );
128 failureFlag.set( Boolean.TRUE );
129 }
130
131
132
133
134
135
136
137 public void testFinished( Description description )
138 throws Exception
139 {
140 Boolean failure = failureFlag.get();
141 if ( failure == null )
142 {
143 reporter.testSucceeded( createReportEntry( description ) );
144 }
145 }
146
147 protected SimpleReportEntry createReportEntry( Description description )
148 {
149 return new SimpleReportEntry( getClassName( description ), description.getDisplayName() );
150 }
151
152 public String getClassName( Description description )
153 {
154 String name = extractClassName( description );
155 if ( name == null || isInsaneJunitNullString( name ) )
156 {
157
158 Description subDescription = description.getChildren().get( 0 );
159 if ( subDescription != null )
160 {
161 name = extractClassName( subDescription );
162 }
163 if ( name == null )
164 {
165 name = "Test Instantiation Error";
166 }
167 }
168 return name;
169 }
170
171 private boolean isInsaneJunitNullString( String value )
172 {
173 return "null".equals( value );
174 }
175
176 public static String extractClassName( Description description )
177 {
178 String displayName = description.getDisplayName();
179 Matcher m = PARENS.matcher( displayName );
180 if ( !m.find() )
181 {
182 return displayName;
183 }
184 return m.group( 1 );
185 }
186
187 public static String extractMethodName( Description description )
188 {
189 String displayName = description.getDisplayName();
190 int i = displayName.indexOf( "(" );
191 if (i >= 0 ) return displayName.substring( 0, i );
192 return displayName;
193 }
194
195
196 public static void rethrowAnyTestMechanismFailures( Result run )
197 throws TestSetFailedException
198 {
199 if ( run.getFailureCount() > 0 )
200 {
201 for ( Failure failure : run.getFailures() )
202 {
203 if ( isFailureInsideJUnitItself( failure ) )
204 {
205 final Throwable exception = failure.getException();
206 throw new TestSetFailedException( exception );
207 }
208 }
209 }
210 }
211
212 private static boolean isFailureInsideJUnitItself( Failure failure )
213 {
214 return failure.getDescription().getDisplayName().equals( "Test mechanism" );
215 }
216 }