1 package org.apache.maven.surefire.junit;
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.ReporterManager;
24
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.util.HashSet;
29 import java.util.Set;
30
31 public class TestListenerInvocationHandler
32 implements InvocationHandler
33 {
34
35 private static final String START_TEST = "startTest";
36
37 private static final String ADD_FAILURE = "addFailure";
38
39 private static final String ADD_ERROR = "addError";
40
41 private static final String END_TEST = "endTest";
42
43 private Set failedTestsSet = new HashSet();
44
45 private ReporterManager reportManager;
46
47 private static final Class[] EMPTY_CLASS_ARRAY = new Class[]{};
48
49 private static final String[] EMPTY_STRING_ARRAY = new String[]{};
50
51 private static class FailedTest
52 {
53 private Object testThatFailed;
54
55 private Thread threadOnWhichTestFailed;
56
57 FailedTest( Object testThatFailed, Thread threadOnWhichTestFailed )
58 {
59 if ( testThatFailed == null )
60 {
61 throw new NullPointerException( "testThatFailed is null" );
62 }
63
64 if ( threadOnWhichTestFailed == null )
65 {
66 throw new NullPointerException( "threadOnWhichTestFailed is null" );
67 }
68
69 this.testThatFailed = testThatFailed;
70
71 this.threadOnWhichTestFailed = threadOnWhichTestFailed;
72 }
73
74 public boolean equals( Object obj )
75 {
76 boolean retVal = true;
77
78 if ( obj == null || getClass() != obj.getClass() )
79 {
80 retVal = false;
81 }
82 else
83 {
84 FailedTest ft = (FailedTest) obj;
85
86 if ( ft.testThatFailed != testThatFailed )
87 {
88 retVal = false;
89 }
90 else if ( !ft.threadOnWhichTestFailed.equals( threadOnWhichTestFailed ) )
91 {
92 retVal = false;
93 }
94 }
95
96 return retVal;
97 }
98
99 public int hashCode()
100 {
101 return threadOnWhichTestFailed.hashCode();
102 }
103 }
104
105 public TestListenerInvocationHandler( ReporterManager reportManager, Object instanceOfTestResult,
106 ClassLoader loader )
107 {
108 if ( reportManager == null )
109 {
110 throw new NullPointerException( "reportManager is null" );
111 }
112
113 if ( instanceOfTestResult == null )
114 {
115 throw new NullPointerException( "instanceOfTestResult is null" );
116 }
117
118 if ( loader == null )
119 {
120 throw new NullPointerException( "loader is null" );
121 }
122
123 this.reportManager = reportManager;
124 }
125
126 public Object invoke( Object proxy, Method method, Object[] args )
127 throws Throwable
128 {
129 String methodName = method.getName();
130
131 if ( methodName.equals( START_TEST ) )
132 {
133 handleStartTest( args );
134 }
135 else if ( methodName.equals( ADD_ERROR ) )
136 {
137 handleAddError( args );
138 }
139 else if ( methodName.equals( ADD_FAILURE ) )
140 {
141 handleAddFailure( args );
142 }
143 else if ( methodName.equals( END_TEST ) )
144 {
145 handleEndTest( args );
146 }
147
148 return null;
149 }
150
151
152 public void handleStartTest( Object[] args )
153 {
154 ReportEntry report = new ReportEntry( args[0].getClass().getName(), args[0].toString(), args[0].getClass().getName() );
155
156 reportManager.testStarting( report );
157 }
158
159
160 private void handleAddError( Object[] args )
161 throws IllegalAccessException, InvocationTargetException
162 {
163 ReportEntry report =
164 new ReportEntry( args[0].getClass().getName(), args[0].toString(), args[1].toString(), getStackTraceWriter( args ) );
165
166 reportManager.testError( report );
167
168 failedTestsSet.add( new FailedTest( args[0], Thread.currentThread() ) );
169 }
170
171 private JUnitStackTraceWriter getStackTraceWriter( Object[] args )
172 throws IllegalAccessException, InvocationTargetException
173 {
174 String testName;
175
176 try
177 {
178 Method m = args[0].getClass().getMethod( "getName", EMPTY_CLASS_ARRAY );
179 testName = (String) m.invoke( args[0], EMPTY_STRING_ARRAY );
180 }
181 catch ( NoSuchMethodException e )
182 {
183 testName = "UNKNOWN";
184 }
185
186 return new JUnitStackTraceWriter( args[0].getClass().getName(), testName, (Throwable) args[1] );
187 }
188
189 private void handleAddFailure( Object[] args )
190 throws IllegalAccessException, InvocationTargetException
191 {
192 ReportEntry report =
193 new ReportEntry( args[0].getClass().getName(), args[0].toString(), args[1].toString(), getStackTraceWriter( args ) );
194
195 reportManager.testFailed( report );
196
197 failedTestsSet.add( new FailedTest( args[0], Thread.currentThread() ) );
198 }
199
200 private void handleEndTest( Object[] args )
201 {
202 boolean testHadFailed = failedTestsSet.remove( new FailedTest( args[0], Thread.currentThread() ) );
203
204 if ( !testHadFailed )
205 {
206 ReportEntry report = new ReportEntry( args[0].getClass().getName(), args[0].toString(), args[0].getClass().getName() );
207
208 reportManager.testSucceeded( report );
209 }
210 }
211 }