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