PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php

http://github.com/symfony/symfony
PHP | 239 lines | 183 code | 38 blank | 18 comment | 9 complexity | e90bd249706c03d733f833456c3e43f9 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpKernel\Tests\EventListener;
  11. use PHPUnit\Framework\TestCase;
  12. use Psr\Log\LoggerInterface;
  13. use Psr\Log\LogLevel;
  14. use Symfony\Component\Console\Application;
  15. use Symfony\Component\Console\Command\Command;
  16. use Symfony\Component\Console\ConsoleEvents;
  17. use Symfony\Component\Console\Event\ConsoleEvent;
  18. use Symfony\Component\Console\Helper\HelperSet;
  19. use Symfony\Component\Console\Input\ArgvInput;
  20. use Symfony\Component\Console\Output\ConsoleOutput;
  21. use Symfony\Component\ErrorHandler\ErrorHandler;
  22. use Symfony\Component\EventDispatcher\EventDispatcher;
  23. use Symfony\Component\HttpFoundation\Request;
  24. use Symfony\Component\HttpKernel\Event\KernelEvent;
  25. use Symfony\Component\HttpKernel\EventListener\DebugHandlersListener;
  26. use Symfony\Component\HttpKernel\HttpKernelInterface;
  27. use Symfony\Component\HttpKernel\KernelEvents;
  28. /**
  29. * @author Nicolas Grekas <p@tchwork.com>
  30. */
  31. class DebugHandlersListenerTest extends TestCase
  32. {
  33. public function testConfigure()
  34. {
  35. $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
  36. $userHandler = function () {};
  37. $listener = new DebugHandlersListener($userHandler, $logger);
  38. $eHandler = new ErrorHandler();
  39. $exception = null;
  40. set_error_handler([$eHandler, 'handleError']);
  41. set_exception_handler([$eHandler, 'handleException']);
  42. try {
  43. $listener->configure();
  44. } catch (\Exception $exception) {
  45. }
  46. restore_exception_handler();
  47. restore_error_handler();
  48. if (null !== $exception) {
  49. throw $exception;
  50. }
  51. $this->assertSame($userHandler, $eHandler->setExceptionHandler('var_dump'));
  52. $loggers = $eHandler->setLoggers([]);
  53. $this->assertArrayHasKey(E_DEPRECATED, $loggers);
  54. $this->assertSame([$logger, LogLevel::INFO], $loggers[E_DEPRECATED]);
  55. }
  56. public function testConfigureForHttpKernelWithNoTerminateWithException()
  57. {
  58. $listener = new DebugHandlersListener(null);
  59. $eHandler = new ErrorHandler();
  60. $event = new KernelEvent(
  61. $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(),
  62. Request::create('/'),
  63. HttpKernelInterface::MASTER_REQUEST
  64. );
  65. $exception = null;
  66. $h = set_exception_handler([$eHandler, 'handleException']);
  67. try {
  68. $listener->configure($event);
  69. } catch (\Exception $exception) {
  70. }
  71. restore_exception_handler();
  72. if (null !== $exception) {
  73. throw $exception;
  74. }
  75. $this->assertNull($h);
  76. }
  77. public function testConsoleEvent()
  78. {
  79. $dispatcher = new EventDispatcher();
  80. $listener = new DebugHandlersListener(null);
  81. $app = $this->getMockBuilder('Symfony\Component\Console\Application')->getMock();
  82. $app->expects($this->once())->method('getHelperSet')->willReturn(new HelperSet());
  83. $command = new Command(__FUNCTION__);
  84. $command->setApplication($app);
  85. $event = new ConsoleEvent($command, new ArgvInput(), new ConsoleOutput());
  86. $dispatcher->addSubscriber($listener);
  87. $xListeners = [
  88. KernelEvents::REQUEST => [[$listener, 'configure']],
  89. ConsoleEvents::COMMAND => [[$listener, 'configure']],
  90. ];
  91. $this->assertSame($xListeners, $dispatcher->getListeners());
  92. $exception = null;
  93. $eHandler = new ErrorHandler();
  94. set_error_handler([$eHandler, 'handleError']);
  95. set_exception_handler([$eHandler, 'handleException']);
  96. try {
  97. $dispatcher->dispatch($event, ConsoleEvents::COMMAND);
  98. } catch (\Exception $exception) {
  99. }
  100. restore_exception_handler();
  101. restore_error_handler();
  102. if (null !== $exception) {
  103. throw $exception;
  104. }
  105. $xHandler = $eHandler->setExceptionHandler('var_dump');
  106. $this->assertInstanceOf('Closure', $xHandler);
  107. $app->expects($this->once())
  108. ->method(method_exists(Application::class, 'renderThrowable') ? 'renderThrowable' : 'renderException');
  109. $xHandler(new \Exception());
  110. }
  111. public function testReplaceExistingExceptionHandler()
  112. {
  113. $userHandler = function () {};
  114. $listener = new DebugHandlersListener($userHandler);
  115. $eHandler = new ErrorHandler();
  116. $eHandler->setExceptionHandler('var_dump');
  117. $exception = null;
  118. set_exception_handler([$eHandler, 'handleException']);
  119. try {
  120. $listener->configure();
  121. } catch (\Exception $exception) {
  122. }
  123. restore_exception_handler();
  124. if (null !== $exception) {
  125. throw $exception;
  126. }
  127. $this->assertSame($userHandler, $eHandler->setExceptionHandler('var_dump'));
  128. }
  129. public function provideLevelsAssignedToLoggers(): array
  130. {
  131. return [
  132. [false, false, '0', null, null],
  133. [false, false, E_ALL, null, null],
  134. [false, false, [], null, null],
  135. [false, false, [E_WARNING => LogLevel::WARNING, E_USER_DEPRECATED => LogLevel::NOTICE], null, null],
  136. [true, false, E_ALL, E_ALL, null],
  137. [true, false, E_DEPRECATED, E_DEPRECATED, null],
  138. [true, false, [], null, null],
  139. [true, false, [E_WARNING => LogLevel::WARNING, E_DEPRECATED => LogLevel::NOTICE], [E_WARNING => LogLevel::WARNING, E_DEPRECATED => LogLevel::NOTICE], null],
  140. [false, true, '0', null, null],
  141. [false, true, E_ALL, null, E_DEPRECATED | E_USER_DEPRECATED],
  142. [false, true, E_ERROR, null, null],
  143. [false, true, [], null, null],
  144. [false, true, [E_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::DEBUG], null, [E_DEPRECATED => LogLevel::DEBUG]],
  145. [true, true, '0', null, null],
  146. [true, true, E_ALL, E_ALL & ~(E_DEPRECATED | E_USER_DEPRECATED), E_DEPRECATED | E_USER_DEPRECATED],
  147. [true, true, E_ERROR, E_ERROR, null],
  148. [true, true, E_USER_DEPRECATED, null, E_USER_DEPRECATED],
  149. [true, true, [E_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::DEBUG], [E_ERROR => LogLevel::ERROR], [E_DEPRECATED => LogLevel::DEBUG]],
  150. [true, true, [E_ERROR => LogLevel::ALERT], [E_ERROR => LogLevel::ALERT], null],
  151. [true, true, [E_USER_DEPRECATED => LogLevel::NOTICE], null, [E_USER_DEPRECATED => LogLevel::NOTICE]],
  152. ];
  153. }
  154. /**
  155. * @dataProvider provideLevelsAssignedToLoggers
  156. *
  157. * @param array|string $levels
  158. * @param array|string|null $expectedLoggerLevels
  159. * @param array|string|null $expectedDeprecationLoggerLevels
  160. */
  161. public function testLevelsAssignedToLoggers(bool $hasLogger, bool $hasDeprecationLogger, $levels, $expectedLoggerLevels, $expectedDeprecationLoggerLevels)
  162. {
  163. if (!class_exists(ErrorHandler::class)) {
  164. $this->markTestSkipped('ErrorHandler component is required to run this test.');
  165. }
  166. $handler = $this->createMock(ErrorHandler::class);
  167. $expectedCalls = [];
  168. $logger = null;
  169. $deprecationLogger = null;
  170. if ($hasDeprecationLogger) {
  171. $deprecationLogger = $this->createMock(LoggerInterface::class);
  172. if (null !== $expectedDeprecationLoggerLevels) {
  173. $expectedCalls[] = [$deprecationLogger, $expectedDeprecationLoggerLevels];
  174. }
  175. }
  176. if ($hasLogger) {
  177. $logger = $this->createMock(LoggerInterface::class);
  178. if (null !== $expectedLoggerLevels) {
  179. $expectedCalls[] = [$logger, $expectedLoggerLevels];
  180. }
  181. }
  182. $handler
  183. ->expects($this->exactly(\count($expectedCalls)))
  184. ->method('setDefaultLogger')
  185. ->withConsecutive(...$expectedCalls);
  186. $sut = new DebugHandlersListener(null, $logger, $levels, null, true, null, true, $deprecationLogger);
  187. $prevHander = set_exception_handler([$handler, 'handleError']);
  188. try {
  189. $handler
  190. ->method('handleError')
  191. ->willReturnCallback(function () use ($prevHander) {
  192. $prevHander(...\func_get_args());
  193. });
  194. $sut->configure();
  195. set_exception_handler($prevHander);
  196. } catch (\Exception $e) {
  197. set_exception_handler($prevHander);
  198. throw $e;
  199. }
  200. }
  201. }