View Javadoc
1   package eu.simuline.testhelpers;
2   
3   import java.lang.reflect.InvocationTargetException;
4   
5   import javax.swing.SwingUtilities; // wrong place?
6   
7   import org.junit.runner.notification.Failure;
8   import org.junit.runner.Description;
9   import org.junit.runner.Result;
10  import org.junit.AssumptionViolatedException;
11  
12  /**
13   * An {@link ExtRunListener} which notifies the GUI {@link GUIRunner} 
14   * of the events occuring while running a testsuite 
15   * and which comprises a textual run listener. 
16   *
17   * Created: Sat Jun  3 17:17:23 2006
18   *
19   * @author <a href="mailto:ernst.reissner@simuline.eu">Ernst Reissner</a>
20   * @version 1.0
21   */
22  public final class GUIRunListener extends ExtRunListener {
23  
24  
25      /* -------------------------------------------------------------------- *
26       * fields.                                                              *
27       * -------------------------------------------------------------------- */
28  
29      private final GUIRunner guiRunner;
30  
31      private TestCase testCase;
32  
33  
34      /* -------------------------------------------------------------------- *
35       * constructor.                                                         *
36       * -------------------------------------------------------------------- */
37  
38      public GUIRunListener(GUIRunner guiRunner) {
39  	this.guiRunner = guiRunner;
40      }
41  
42      /* -------------------------------------------------------------------- *
43       * methods.                                                             *
44       * -------------------------------------------------------------------- */
45  
46  
47      /**
48       * Called before any tests have been run.
49       * Updates the enablement of the GUI-Actions 
50       * and then delegates to 
51       * {@link GUIRunner#testRunStarted(Description)}. 
52       * Updates the enablement of the GUI-Actions 
53       * and ***** OVERWRITTEN FOR ALL
54       *
55       * @param desc 
56       *    describes the tests to be run
57       */
58      public void testRunStarted(final Description desc) 
59  	throws Exception { //NOPMD
60  	assert !SwingUtilities.isEventDispatchThread();
61  	
62  	Runnable runnable = new Runnable() {
63  		public void run() {
64  		    GUIRunListener.this.guiRunner.testRunStarted(desc);
65  		}
66  	    };
67  	SwingUtilities.invokeAndWait(runnable);
68  System.out.println("..testRunStarted");
69       }
70  
71      /**
72       * Called when all tests have finished. 
73       * Prints a statistics on the result to the standard output, 
74       * a summary to the status bar of the GUI 
75       * and updates the enablement of the GUI-Actions. 
76       *
77       * @param result 
78       *    the summary of the test run, including all the tests that failed
79       */
80      // api-docs inherited from class RunListener
81      public void testRunFinished(final Result result) throws Exception { //NOPMD
82  	assert !SwingUtilities.isEventDispatchThread();
83  	// output text 
84  //	super.testRunFinished(result);
85  
86  	Runnable runnable = new Runnable() {
87  		public void run() {
88  		    GUIRunListener.this.guiRunner
89  			.testRunFinished(result.getRunTime());
90  		}
91  	    };
92  	SwingUtilities.invokeAndWait(runnable);
93   System.out.println("..testRunFinished");
94     }
95  
96      /**
97       * Called when a test suite is about to be started. 
98       * If this method is called for a given {@link Description}, 
99       * then {@link #testSuiteFinished(Description)} 
100      * will also be called for the same {@link Description}. 
101      * <p>
102      * Note that not all runners will call this method, so runners should 
103      * be prepared to handle {@link #testStarted(Description)} calls for tests 
104      * where there was no cooresponding {@link #testSuiteStarted(Description)} 
105      * call for the parent {@link Description}. 
106      *
107      * @param desc
108      *    the description of the test suite that is about to be run
109      *    (generally a class name)
110      * @since 4.13
111      */
112     // api-docs inherited from class RunListener
113     public void testSuiteStarted(Description desc) throws Exception { //NOPMD
114 	assert !SwingUtilities.isEventDispatchThread();
115 	// **** at the moment no actions on the GUI 
116     }
117 
118     /**
119      * Called when a test suite has finished, 
120      * whether the test suite succeeds or fails. 
121      * This method will not be called for a given {@link Description} 
122      * unless {@link #testSuiteStarted(Description)} was called 
123      * for the same {@link Description}. 
124      *
125      * @param desc 
126      *    the description of the test suite that just ran
127      * @since 4.13
128      */
129     public void testSuiteFinished(Description desc) throws Exception { //NOPMD
130 	assert !SwingUtilities.isEventDispatchThread();
131 	// output text 
132 	// **** at the moment no actions on the GUI 
133      }
134 
135     /**
136      * Called when an atomic test is about to be started. 
137      * An ignored test is never started. 
138      *
139      * @param desc 
140      *    the description of the test that is about to be started 
141      *    (generally a class and method name)
142      * @see #testIgnored(Description)
143      */
144     // api-docs inherited from class RunListener
145     public void testStarted(final Description desc) throws Exception { //NOPMD
146 	assert !SwingUtilities.isEventDispatchThread();
147 	
148 
149 	Runnable runnable = new Runnable() {
150 		public void run() {
151 		    GUIRunListener.this.testCase = 
152 			GUIRunListener.this.guiRunner
153 			.noteTestStartedI(Quality.Started);
154 		}
155 	    };
156 	SwingUtilities.invokeAndWait(runnable);
157 System.out.println("..testStarted");
158     }
159 
160     /**
161      * Called when an atomic test has finished, 
162      * whether the test succeeds or fails. 
163      * This method must be invoked after a test has been started 
164      * which was indicated by {@link #testStarted(Description)} before. 
165      * An ignored test is never finished. 
166      *
167      * @param desc
168      *    the description of the test that just ran
169      * @see #testIgnored(Description)
170      */
171     public void testFinished(final Description desc) throws Exception { //NOPMD
172 	assert !SwingUtilities.isEventDispatchThread();
173 
174 	Runnable runnable = new Runnable() {
175 		public void run() {
176 		    GUIRunListener.this.testCase.setFinished();
177 		    GUIRunListener.this.guiRunner
178 			.noteReportResult(GUIRunListener.this.testCase);
179 		}
180 	    };
181 
182 	SwingUtilities.invokeAndWait(runnable);
183 System.out.println("..testFinished");
184     }
185 
186     /**
187      * Called when an atomic test fails to execute properly 
188      * throwing a Throwable. 
189      * This method is invoked after {@link #testStarted(Description)} 
190      * and before {@link #testFinished(Description)}
191      * with the according description. 
192      * In case of a failed assumption, instead of this method 
193      * {@link #testAssumptionFailure(Failure)} is invoked 
194      * for the according test. 
195      *
196      * @param failure 
197      *    describes the test that failed and the exception that was thrown
198      */
199     public void testFailure(final Failure failure) throws Exception { //NOPMD
200 	assert !SwingUtilities.isEventDispatchThread();
201 	// GUI ignores failures in the test mechanism. 
202 	// **** this may be inappropriate. 
203 	if (failure.getDescription().equals(Description.TEST_MECHANISM)) {
204 	    return;
205 	}
206 	Runnable runnable = new Runnable() {
207 		public void run() {
208 		    GUIRunListener.this.testCase.setFailure(failure);
209 		    GUIRunListener.this.guiRunner.setStatus("testFailure: "
210 						 + failure.getException());
211 		}
212 	    };
213 	SwingUtilities.invokeAndWait(runnable);
214 System.out.println("..testFailure");
215     }
216 
217 
218     /**
219      * Called when an atomic test flags 
220      * that it assumes a condition that is false. 
221      * This is treated as ignored with the description of the failure. 
222      * This method is invoked after {@link #testStarted(Description)} 
223      * and before {@link #testFinished(Description)}
224      * with the according description. 
225      * A failed assertion does not count as a failure 
226      * and so {@link #testFailure(Failure)} is not invoked 
227      * for the according test. 
228      * <p>
229      * CAUTION: Although a failed assertion is like an ignored test, 
230      * {@link #testRunFinished(Result)} does not count this as ignored test 
231      * but rather than a passed test. 
232      *
233      * @param failure
234      *    describes the test that failed 
235      *    and the {@link AssumptionViolatedException} that was thrown. 
236      * @see #testIgnored(Description)
237      */
238     public void testAssumptionFailure(final Failure failure) {
239 	assert !SwingUtilities.isEventDispatchThread();
240 
241 	Runnable runnable = new Runnable() {
242 		public void run() {
243 		    GUIRunListener.this.testCase.setAssumptionFailure(failure);
244 		    GUIRunListener.this.guiRunner
245 			.setStatus("testAssumptionFailure: "
246 				   + failure.getException());
247 		}
248 	    };
249 
250 	try {
251 	    SwingUtilities.invokeAndWait(runnable);
252 	} catch (InterruptedException e) {
253 	    e.printStackTrace();
254 	} catch (InvocationTargetException e) {
255 	    e.printStackTrace();
256 	}
257 System.out.println("..testAssumptionFailure");
258     }
259 
260     /**
261      * Called when a test will not be run, 
262      * generally because a test method is annotated 
263      * with <code>@Ignored</code>. 
264      * This implies 
265      * that neither {@link #testStarted(Description)} 
266      * nor {@link #testFinished(Description)} are invoked 
267      * for the according test. 
268      * This in turn implies that neither {@link #testFailure(Failure)} 
269      * nor {@link #testAssumptionFailure(Failure)} are invoked. 
270      * are invoked. 
271      *
272      * @param desc 
273      *    describes the test that will not be run
274      */
275     public void testIgnored(final Description desc) throws Exception { //NOPMD
276 	assert !SwingUtilities.isEventDispatchThread();
277 
278 	Runnable runnable = new Runnable() {
279 		public void run() {
280 		    GUIRunListener.this.testCase = 
281 			GUIRunListener.this.guiRunner
282 			.noteTestStartedI(Quality.Ignored);
283 		    GUIRunListener.this.guiRunner
284 			.noteReportResult(GUIRunListener.this.testCase);
285 		}
286 	    };
287 	SwingUtilities.invokeAndWait(runnable);
288 System.out.println("...testIgnored");
289     }
290 
291     // homemade extension 
292     /**
293      * Invoked for stop and for break originated by the user. 
294      */
295     // not clear which test has been aborted. 
296     public void testRunAborted() {
297 	assert !SwingUtilities.isEventDispatchThread();
298 
299 	Runnable runnable = new Runnable() {
300 		public void run() {
301 		    GUIRunListener.this.guiRunner.testRunAborted();
302 		}
303 	    };
304 	try {
305 	    SwingUtilities.invokeAndWait(runnable);
306 	} catch (InterruptedException e) {
307 	    e.printStackTrace();
308 	} catch (InvocationTargetException e) {
309 	    e.printStackTrace();
310 	}
311 	System.out.println("..testRunAborted(");
312     }
313 
314     // homemade extension 
315     /**
316      * Invoked if a test class is loaded defining a testsuite 
317      * described by <code>desc</code>. 
318      */
319     public void testClassStructureLoaded(final Description desc) {
320 	Runnable runnable = new Runnable() {
321 		public void run() {
322 		    GUIRunListener.this.guiRunner
323 			.testClassStructureLoaded(desc);
324 		}
325 	    };
326 	try {
327 	    SwingUtilities.invokeAndWait(runnable);
328 	} catch (InterruptedException e) {
329 	    e.printStackTrace();
330 	} catch (InvocationTargetException e) {
331 	    e.printStackTrace();
332 	}
333 	System.out.println("..testClassStructureLoaded(");
334     }
335 }
336