1. package junit.framework;
  2. import java.util.Vector;
  3. import java.util.Enumeration;
  4. /**
  5. * A <code>TestResult</code> collects the results of executing
  6. * a test case. It is an instance of the Collecting Parameter pattern.
  7. * The test framework distinguishes between <i>failures</i> and <i>errors</i>.
  8. * A failure is anticipated and checked for with assertions. Errors are
  9. * unanticipated problems like an <code>ArrayIndexOutOfBoundsException</code>.
  10. *
  11. * @see Test
  12. */
  13. public class TestResult extends Object {
  14. protected Vector fFailures;
  15. protected Vector fErrors;
  16. protected Vector fListeners;
  17. protected int fRunTests;
  18. private boolean fStop;
  19. public TestResult() {
  20. fFailures= new Vector();
  21. fErrors= new Vector();
  22. fListeners= new Vector();
  23. fRunTests= 0;
  24. fStop= false;
  25. }
  26. /**
  27. * Adds an error to the list of errors. The passed in exception
  28. * caused the error.
  29. */
  30. public synchronized void addError(Test test, Throwable t) {
  31. fErrors.addElement(new TestFailure(test, t));
  32. for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
  33. ((TestListener)e.nextElement()).addError(test, t);
  34. }
  35. }
  36. /**
  37. * Adds a failure to the list of failures. The passed in exception
  38. * caused the failure.
  39. */
  40. public synchronized void addFailure(Test test, AssertionFailedError t) {
  41. fFailures.addElement(new TestFailure(test, t));
  42. for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
  43. ((TestListener)e.nextElement()).addFailure(test, t);
  44. }
  45. }
  46. /**
  47. * Registers a TestListener
  48. */
  49. public synchronized void addListener(TestListener listener) {
  50. fListeners.addElement(listener);
  51. }
  52. /**
  53. * Unregisters a TestListener
  54. */
  55. public synchronized void removeListener(TestListener listener) {
  56. fListeners.removeElement(listener);
  57. }
  58. /**
  59. * Returns a copy of the listeners.
  60. */
  61. private synchronized Vector cloneListeners() {
  62. return (Vector)fListeners.clone();
  63. }
  64. /**
  65. * Informs the result that a test was completed.
  66. */
  67. public void endTest(Test test) {
  68. for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
  69. ((TestListener)e.nextElement()).endTest(test);
  70. }
  71. }
  72. /**
  73. * Gets the number of detected errors.
  74. */
  75. public synchronized int errorCount() {
  76. return fErrors.size();
  77. }
  78. /**
  79. * Returns an Enumeration for the errors
  80. */
  81. public synchronized Enumeration errors() {
  82. return fErrors.elements();
  83. }
  84. /**
  85. * Gets the number of detected failures.
  86. */
  87. public synchronized int failureCount() {
  88. return fFailures.size();
  89. }
  90. /**
  91. * Returns an Enumeration for the failures
  92. */
  93. public synchronized Enumeration failures() {
  94. return fFailures.elements();
  95. }
  96. /**
  97. * Runs a TestCase.
  98. */
  99. protected void run(final TestCase test) {
  100. startTest(test);
  101. Protectable p= new Protectable() {
  102. public void protect() throws Throwable {
  103. test.runBare();
  104. }
  105. };
  106. runProtected(test, p);
  107. endTest(test);
  108. }
  109. /**
  110. * Gets the number of run tests.
  111. */
  112. public synchronized int runCount() {
  113. return fRunTests;
  114. }
  115. /**
  116. * Runs a TestCase.
  117. */
  118. public void runProtected(final Test test, Protectable p) {
  119. try {
  120. p.protect();
  121. }
  122. catch (AssertionFailedError e) {
  123. addFailure(test, e);
  124. }
  125. catch (ThreadDeath e) { // don't catch ThreadDeath by accident
  126. throw e;
  127. }
  128. catch (Throwable e) {
  129. addError(test, e);
  130. }
  131. }
  132. /**
  133. * Checks whether the test run should stop
  134. */
  135. public synchronized boolean shouldStop() {
  136. return fStop;
  137. }
  138. /**
  139. * Informs the result that a test will be started.
  140. */
  141. public void startTest(Test test) {
  142. final int count= test.countTestCases();
  143. synchronized(this) {
  144. fRunTests+= count;
  145. }
  146. for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
  147. ((TestListener)e.nextElement()).startTest(test);
  148. }
  149. }
  150. /**
  151. * Marks that the test run should stop.
  152. */
  153. public synchronized void stop() {
  154. fStop= true;
  155. }
  156. /**
  157. * Returns whether the entire test was successful or not.
  158. */
  159. public synchronized boolean wasSuccessful() {
  160. return failureCount() == 0 && errorCount() == 0;
  161. }
  162. }