RunTest.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <?php
  2. /**
  3. * Whoops - php errors for cool kids
  4. * @author Filipe Dobreira <http://github.com/filp>
  5. */
  6. namespace Whoops;
  7. use Whoops\TestCase;
  8. use Whoops\Run;
  9. use Whoops\Handler\Handler;
  10. use RuntimeException;
  11. use ArrayObject;
  12. use Mockery as m;
  13. class RunTest extends TestCase
  14. {
  15. /**
  16. * @param string $message
  17. * @return Exception
  18. */
  19. protected function getException($message = null)
  20. {
  21. return m::mock('Exception', array($message));
  22. }
  23. /**
  24. * @return Whoops\Handler\Handler
  25. */
  26. protected function getHandler()
  27. {
  28. return m::mock('Whoops\\Handler\\Handler')
  29. ->shouldReceive('setRun')
  30. ->andReturn(null)
  31. ->mock()
  32. ->shouldReceive('setInspector')
  33. ->andReturn(null)
  34. ->mock()
  35. ->shouldReceive('setException')
  36. ->andReturn(null)
  37. ->mock()
  38. ;
  39. }
  40. /**
  41. * @covers Whoops\Run::clearHandlers
  42. */
  43. public function testClearHandlers()
  44. {
  45. $run = $this->getRunInstance();
  46. $run->clearHandlers();
  47. $handlers = $run->getHandlers();
  48. $this->assertEmpty($handlers);
  49. }
  50. /**
  51. * @covers Whoops\Run::pushHandler
  52. */
  53. public function testPushHandler()
  54. {
  55. $run = $this->getRunInstance();
  56. $run->clearHandlers();
  57. $handlerOne = $this->getHandler();
  58. $handlerTwo = $this->getHandler();
  59. $run->pushHandler($handlerOne);
  60. $run->pushHandler($handlerTwo);
  61. $handlers = $run->getHandlers();
  62. $this->assertCount(2, $handlers);
  63. $this->assertContains($handlerOne, $handlers);
  64. $this->assertContains($handlerTwo, $handlers);
  65. }
  66. /**
  67. * @expectedException InvalidArgumentException
  68. * @covers Whoops\Run::pushHandler
  69. */
  70. public function testPushInvalidHandler()
  71. {
  72. $run = $this->getRunInstance();
  73. $run->pushHandler($banana = 'actually turnip');
  74. }
  75. /**
  76. * @covers Whoops\Run::pushHandler
  77. */
  78. public function testPushClosureBecomesHandler()
  79. {
  80. $run = $this->getRunInstance();
  81. $run->pushHandler(function() {});
  82. $this->assertInstanceOf('Whoops\\Handler\\CallbackHandler', $run->popHandler());
  83. }
  84. /**
  85. * @covers Whoops\Run::popHandler
  86. * @covers Whoops\Run::getHandlers
  87. */
  88. public function testPopHandler()
  89. {
  90. $run = $this->getRunInstance();
  91. $handlerOne = $this->getHandler();
  92. $handlerTwo = $this->getHandler();
  93. $handlerThree = $this->getHandler();
  94. $run->pushHandler($handlerOne);
  95. $run->pushHandler($handlerTwo);
  96. $run->pushHandler($handlerThree);
  97. $this->assertSame($handlerThree, $run->popHandler());
  98. $this->assertSame($handlerTwo, $run->popHandler());
  99. $this->assertSame($handlerOne, $run->popHandler());
  100. // Should return null if there's nothing else in
  101. // the stack
  102. $this->assertNull($run->popHandler());
  103. // Should be empty since we popped everything off
  104. // the stack:
  105. $this->assertEmpty($run->getHandlers());
  106. }
  107. /**
  108. * @covers Whoops\Run::register
  109. */
  110. public function testRegisterHandler()
  111. {
  112. $this->markTestSkipped("Need to test exception handler");
  113. $run = $this->getRunInstance();
  114. $run->register();
  115. $handler = $this->getHandler();
  116. $run->pushHandler($handler);
  117. throw $this->getException();
  118. $this->assertCount(2, $handler->exceptions);
  119. }
  120. /**
  121. * @covers Whoops\Run::unregister
  122. * @expectedException Exception
  123. */
  124. public function testUnregisterHandler()
  125. {
  126. $run = $this->getRunInstance();
  127. $run->register();
  128. $handler = $this->getHandler();
  129. $run->pushHandler($handler);
  130. $run->unregister();
  131. throw $this->getException("I'm not supposed to be caught!");
  132. }
  133. /**
  134. * @covers Whoops\Run::pushHandler
  135. * @covers Whoops\Run::getHandlers
  136. */
  137. public function testHandlerHoldsOrder()
  138. {
  139. $run = $this->getRunInstance();
  140. $handlerOne = $this->getHandler();
  141. $handlerTwo = $this->getHandler();
  142. $handlerThree = $this->getHandler();
  143. $handlerFour = $this->getHandler();
  144. $run->pushHandler($handlerOne);
  145. $run->pushHandler($handlerTwo);
  146. $run->pushHandler($handlerThree);
  147. $run->pushHandler($handlerFour);
  148. $handlers = $run->getHandlers();
  149. $this->assertSame($handlers[0], $handlerOne);
  150. $this->assertSame($handlers[1], $handlerTwo);
  151. $this->assertSame($handlers[2], $handlerThree);
  152. $this->assertSame($handlers[3], $handlerFour);
  153. }
  154. /**
  155. * @todo possibly split this up a bit and move
  156. * some of this test to Handler unit tests?
  157. * @covers Whoops\Run::handleException
  158. */
  159. public function testHandlersGonnaHandle()
  160. {
  161. $run = $this->getRunInstance();
  162. $exception = $this->getException();
  163. $order = new ArrayObject;
  164. $handlerOne = $this->getHandler();
  165. $handlerTwo = $this->getHandler();
  166. $handlerThree = $this->getHandler();
  167. $handlerOne->shouldReceive('handle')
  168. ->andReturnUsing(function() use($order) { $order[] = 1; });
  169. $handlerTwo->shouldReceive('handle')
  170. ->andReturnUsing(function() use($order) { $order[] = 2; });
  171. $handlerThree->shouldReceive('handle')
  172. ->andReturnUsing(function() use($order) { $order[] = 3; });
  173. $run->pushHandler($handlerOne);
  174. $run->pushHandler($handlerTwo);
  175. $run->pushHandler($handlerThree);
  176. // Get an exception to be handled, and verify that the handlers
  177. // are given the handler, and in the inverse order they were
  178. // registered.
  179. $run->handleException($exception);
  180. $this->assertEquals((array) $order, array(3, 2, 1));
  181. }
  182. /**
  183. * @covers Whoops\Run::handleException
  184. */
  185. public function testLastHandler()
  186. {
  187. $run = $this->getRunInstance();
  188. $handlerOne = $this->getHandler();
  189. $handlerTwo = $this->getHandler();
  190. $run->pushHandler($handlerOne);
  191. $run->pushHandler($handlerTwo);
  192. $test = $this;
  193. $handlerOne
  194. ->shouldReceive('handle')
  195. ->andReturnUsing(function () use($test) {
  196. $test->fail('$handlerOne should not be called');
  197. })
  198. ;
  199. $handlerTwo
  200. ->shouldReceive('handle')
  201. ->andReturn(Handler::LAST_HANDLER)
  202. ;
  203. $run->handleException($this->getException());
  204. }
  205. /**
  206. * Test error suppression using @ operator.
  207. */
  208. public function testErrorSuppression()
  209. {
  210. $run = $this->getRunInstance();
  211. $run->register();
  212. $handler = $this->getHandler();
  213. $run->pushHandler($handler);
  214. $test = $this;
  215. $handler
  216. ->shouldReceive('handle')
  217. ->andReturnUsing(function () use($test) {
  218. $test->fail('$handler should not be called, error not suppressed');
  219. })
  220. ;
  221. @trigger_error("Test error suppression");
  222. }
  223. /**
  224. * Test to make sure that error_reporting is respected.
  225. */
  226. public function testErrorReporting()
  227. {
  228. $run = $this->getRunInstance();
  229. $run->register();
  230. $handler = $this->getHandler();
  231. $run->pushHandler($handler);
  232. $test = $this;
  233. $handler
  234. ->shouldReceive('handle')
  235. ->andReturnUsing(function () use($test) {
  236. $test->fail('$handler should not be called, error_reporting not respected');
  237. })
  238. ;
  239. $oldLevel = error_reporting(E_ALL ^ E_USER_NOTICE);
  240. trigger_error("Test error reporting", E_USER_NOTICE);
  241. error_reporting($oldLevel);
  242. }
  243. /**
  244. * @covers Whoops\Run::handleException
  245. * @covers Whoops\Run::writeToOutput
  246. */
  247. public function testOutputIsSent()
  248. {
  249. $run = $this->getRunInstance();
  250. $run->pushHandler(function() {
  251. echo "hello there";
  252. });
  253. ob_start();
  254. $run->handleException(new RuntimeException);
  255. $this->assertEquals("hello there", ob_get_clean());
  256. }
  257. /**
  258. * @covers Whoops\Run::handleException
  259. * @covers Whoops\Run::writeToOutput
  260. */
  261. public function testOutputIsNotSent()
  262. {
  263. $run = $this->getRunInstance();
  264. $run->writeToOutput(false);
  265. $run->pushHandler(function() {
  266. echo "hello there";
  267. });
  268. ob_start();
  269. $this->assertEquals("hello there", $run->handleException(new RuntimeException));
  270. $this->assertEquals("", ob_get_clean());
  271. }
  272. }