exceptions.php 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. /**
  3. * base include file for SimpleTest
  4. * @package SimpleTest
  5. * @subpackage UnitTester
  6. * @version $Id: exceptions.php 1769 2008-04-19 14:39:00Z pp11 $
  7. */
  8. /**#@+
  9. * Include required SimpleTest files
  10. */
  11. require_once dirname(__FILE__) . '/invoker.php';
  12. require_once dirname(__FILE__) . '/expectation.php';
  13. /**#@-*/
  14. /**
  15. * Extension that traps exceptions and turns them into
  16. * an error message. PHP5 only.
  17. * @package SimpleTest
  18. * @subpackage UnitTester
  19. */
  20. class SimpleExceptionTrappingInvoker extends SimpleInvokerDecorator {
  21. /**
  22. * Stores the invoker to be wrapped.
  23. * @param SimpleInvoker $invoker Test method runner.
  24. */
  25. function __construct($invoker) {
  26. parent::__construct($invoker);
  27. }
  28. /**
  29. * Invokes a test method whilst trapping expected
  30. * exceptions. Any left over unthrown exceptions
  31. * are then reported as failures.
  32. * @param string $method Test method to call.
  33. */
  34. function invoke($method) {
  35. $trap = SimpleTest::getContext()->get('SimpleExceptionTrap');
  36. $trap->clear();
  37. try {
  38. $has_thrown = false;
  39. parent::invoke($method);
  40. } catch (Exception $exception) {
  41. $has_thrown = true;
  42. if (! $trap->isExpected($this->getTestCase(), $exception)) {
  43. $this->getTestCase()->exception($exception);
  44. }
  45. $trap->clear();
  46. }
  47. if ($message = $trap->getOutstanding()) {
  48. $this->getTestCase()->fail($message);
  49. }
  50. if ($has_thrown) {
  51. try {
  52. parent::getTestCase()->tearDown();
  53. } catch (Exception $e) { }
  54. }
  55. }
  56. }
  57. /**
  58. * Tests exceptions either by type or the exact
  59. * exception. This could be improved to accept
  60. * a pattern expectation to test the error
  61. * message, but that will have to come later.
  62. * @package SimpleTest
  63. * @subpackage UnitTester
  64. */
  65. class ExceptionExpectation extends SimpleExpectation {
  66. private $expected;
  67. /**
  68. * Sets up the conditions to test against.
  69. * If the expected value is a string, then
  70. * it will act as a test of the class name.
  71. * An exception as the comparison will
  72. * trigger an identical match. Writing this
  73. * down now makes it look doubly dumb. I hope
  74. * come up with a better scheme later.
  75. * @param mixed $expected A class name or an actual
  76. * exception to compare with.
  77. * @param string $message Message to display.
  78. */
  79. function __construct($expected, $message = '%s') {
  80. $this->expected = $expected;
  81. parent::__construct($message);
  82. }
  83. /**
  84. * Carry out the test.
  85. * @param Exception $compare Value to check.
  86. * @return boolean True if matched.
  87. */
  88. function test($compare) {
  89. if (is_string($this->expected)) {
  90. return ($compare instanceof $this->expected);
  91. }
  92. if (get_class($compare) != get_class($this->expected)) {
  93. return false;
  94. }
  95. return $compare->getMessage() == $this->expected->getMessage();
  96. }
  97. /**
  98. * Create the message to display describing the test.
  99. * @param Exception $compare Exception to match.
  100. * @return string Final message.
  101. */
  102. function testMessage($compare) {
  103. if (is_string($this->expected)) {
  104. return "Exception [" . $this->describeException($compare) .
  105. "] should be type [" . $this->expected . "]";
  106. }
  107. return "Exception [" . $this->describeException($compare) .
  108. "] should match [" .
  109. $this->describeException($this->expected) . "]";
  110. }
  111. /**
  112. * Summary of an Exception object.
  113. * @param Exception $compare Exception to describe.
  114. * @return string Text description.
  115. */
  116. protected function describeException($exception) {
  117. return get_class($exception) . ": " . $exception->getMessage();
  118. }
  119. }
  120. /**
  121. * Stores expected exceptions for when they
  122. * get thrown. Saves the irritating try...catch
  123. * block.
  124. * @package SimpleTest
  125. * @subpackage UnitTester
  126. */
  127. class SimpleExceptionTrap {
  128. private $expected;
  129. private $message;
  130. /**
  131. * Clears down the queue ready for action.
  132. */
  133. function __construct() {
  134. $this->clear();
  135. }
  136. /**
  137. * Sets up an expectation of an exception.
  138. * This has the effect of intercepting an
  139. * exception that matches.
  140. * @param SimpleExpectation $expected Expected exception to match.
  141. * @param string $message Message to display.
  142. * @access public
  143. */
  144. function expectException($expected = false, $message = '%s') {
  145. if ($expected === false) {
  146. $expected = new AnythingExpectation();
  147. }
  148. if (! SimpleExpectation::isExpectation($expected)) {
  149. $expected = new ExceptionExpectation($expected);
  150. }
  151. $this->expected = $expected;
  152. $this->message = $message;
  153. }
  154. /**
  155. * Compares the expected exception with any
  156. * in the queue. Issues a pass or fail and
  157. * returns the state of the test.
  158. * @param SimpleTestCase $test Test case to send messages to.
  159. * @param Exception $exception Exception to compare.
  160. * @return boolean False on no match.
  161. */
  162. function isExpected($test, $exception) {
  163. if ($this->expected) {
  164. return $test->assert($this->expected, $exception, $this->message);
  165. }
  166. return false;
  167. }
  168. /**
  169. * Tests for any left over exception.
  170. * @return string/false The failure message or false if none.
  171. */
  172. function getOutstanding() {
  173. return sprintf($this->message, 'Failed to trap exception');
  174. }
  175. /**
  176. * Discards the contents of the error queue.
  177. */
  178. function clear() {
  179. $this->expected = false;
  180. $this->message = false;
  181. }
  182. }
  183. ?>