2011-03-05 19:23:35 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
2011-03-06 11:40:06 +00:00
* ( c ) Fabien Potencier < fabien @ symfony . com >
2011-03-05 19:23:35 +00:00
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2013-03-20 17:09:46 +00:00
namespace Symfony\Component\Debug\Tests ;
2011-03-05 19:23:35 +00:00
2013-03-20 17:09:46 +00:00
use Symfony\Component\Debug\ErrorHandler ;
2013-11-05 20:12:21 +00:00
use Symfony\Component\Debug\ExceptionHandler ;
2011-03-05 19:23:35 +00:00
/**
* ErrorHandlerTest
*
* @ author Robert Schönthal < seroscho @ googlemail . com >
*/
class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
{
2013-11-05 20:12:21 +00:00
/**
* @ var int Error reporting level before running tests .
*/
protected $errorReporting ;
/**
* @ var string Display errors setting before running tests .
*/
protected $displayErrors ;
public function setUp () {
$this -> errorReporting = error_reporting ( E_ALL | E_STRICT );
$this -> displayErrors = ini_get ( 'display_errors' );
ini_set ( 'display_errors' , '1' );
}
public function tearDown () {
ini_set ( 'display_errors' , $this -> displayErrors );
error_reporting ( $this -> errorReporting );
}
2013-08-07 14:15:14 +01:00
public function testCompileTimeError ()
{
2013-11-05 20:12:21 +00:00
$exceptionHandler = $this -> getMock ( 'Symfony\Component\Debug\ExceptionHandler' , array ( 'handle' ));
set_exception_handler ( array ( $exceptionHandler , 'handle' ));
// the ContextErrorException must not be loaded to test the workaround
// for https://bugs.php.net/bug.php?id=65322.
2013-08-07 14:15:14 +01:00
if ( class_exists ( 'Symfony\Component\Debug\Exception\ContextErrorException' , false )) {
$this -> markTestSkipped ( 'The ContextErrorException class is already loaded.' );
}
2013-10-30 08:30:20 +00:00
2013-11-05 20:12:21 +00:00
$that = $this ;
$exceptionCheck = function ( $exception ) use ( $that ) {
$that -> assertInstanceOf ( 'Symfony\Component\Debug\Exception\ContextErrorException' , $exception );
$that -> assertEquals ( E_STRICT , $exception -> getSeverity ());
$that -> assertEquals ( 2 , $exception -> getLine ());
$that -> assertStringStartsWith ( 'Runtime Notice: Declaration of _CompileTimeError::foo() should be compatible with that of _BaseCompileTimeError::foo()' , $exception -> getMessage ());
$that -> assertArrayHasKey ( 'bar' , $exception -> getContext ());
};
2013-08-07 14:15:14 +01:00
2013-11-05 20:12:21 +00:00
$exceptionHandler -> expects ( $this -> once ())
-> method ( 'handle' )
-> will ( $this -> returnCallback ( $exceptionCheck ));
ErrorHandler :: register ();
// dummy variable to check for in error handler.
$bar = 123 ;
// trigger compile time error
eval ( <<< 'PHP'
2013-08-07 14:15:14 +01:00
class _BaseCompileTimeError { function foo () {} }
class _CompileTimeError extends _BaseCompileTimeError { function foo ( $invalid ) {} }
PHP
2013-11-05 20:12:21 +00:00
);
restore_error_handler ();
}
public function testNotice ()
{
$exceptionHandler = $this -> getMock ( 'Symfony\Component\Debug\ExceptionHandler' , array ( 'handle' ));
set_exception_handler ( array ( $exceptionHandler , 'handle' ));
$that = $this ;
$exceptionCheck = function ( $exception ) use ( $that ) {
$that -> assertInstanceOf ( 'Symfony\Component\Debug\Exception\ContextErrorException' , $exception );
$that -> assertEquals ( E_NOTICE , $exception -> getSeverity ());
$that -> assertEquals ( __LINE__ + 35 , $exception -> getLine ());
$that -> assertEquals ( __FILE__ , $exception -> getFile ());
$that -> assertRegexp ( '/^Notice: Undefined variable: (foo|bar)/' , $exception -> getMessage ());
$that -> assertArrayHasKey ( 'foobar' , $exception -> getContext ());
$trace = $exception -> getTrace ();
$that -> assertEquals ( __FILE__ , $trace [ 0 ][ 'file' ]);
$that -> assertEquals ( 'Symfony\Component\Debug\ErrorHandler' , $trace [ 0 ][ 'class' ]);
$that -> assertEquals ( 'handle' , $trace [ 0 ][ 'function' ]);
$that -> assertEquals ( '->' , $trace [ 0 ][ 'type' ]);
$that -> assertEquals ( __FILE__ , $trace [ 1 ][ 'file' ]);
$that -> assertEquals ( __CLASS__ , $trace [ 1 ][ 'class' ]);
$that -> assertEquals ( 'triggerNotice' , $trace [ 1 ][ 'function' ]);
$that -> assertEquals ( '::' , $trace [ 1 ][ 'type' ]);
$that -> assertEquals ( __CLASS__ , $trace [ 2 ][ 'class' ]);
$that -> assertEquals ( 'testNotice' , $trace [ 2 ][ 'function' ]);
$that -> assertEquals ( '->' , $trace [ 2 ][ 'type' ]);
};
$exceptionHandler -> expects ( $this -> exactly ( 3 ))
-> method ( 'handle' )
-> will ( $this -> returnCallback ( $exceptionCheck ));
ErrorHandler :: register ();
self :: triggerNotice ( $this );
2013-08-07 14:15:14 +01:00
restore_error_handler ();
}
2011-04-15 20:12:02 +01:00
2013-11-05 20:12:21 +00:00
// dummy function to test trace in error handler.
private static function triggerNotice ( $that ) {
// dummy variable to check for in error handler.
$foobar = 123 ;
$that -> assertSame ( '' , $foo . $foo . $bar );
}
2011-03-05 19:23:35 +00:00
public function testConstruct ()
{
2011-05-05 07:46:20 +01:00
$handler = ErrorHandler :: register ( 3 );
2011-04-15 20:12:02 +01:00
2011-05-05 07:46:20 +01:00
$level = new \ReflectionProperty ( $handler , 'level' );
2011-03-05 19:23:35 +00:00
$level -> setAccessible ( true );
2011-04-15 20:12:02 +01:00
2011-05-05 07:46:20 +01:00
$this -> assertEquals ( 3 , $level -> getValue ( $handler ));
2011-04-15 20:12:02 +01:00
2011-05-05 07:46:20 +01:00
restore_error_handler ();
2011-03-05 19:23:35 +00:00
}
public function testHandle ()
{
2011-05-05 07:46:20 +01:00
$handler = ErrorHandler :: register ( 0 );
$this -> assertFalse ( $handler -> handle ( 0 , 'foo' , 'foo.php' , 12 , 'foo' ));
restore_error_handler ();
$handler = ErrorHandler :: register ( 3 );
$this -> assertFalse ( $handler -> handle ( 4 , 'foo' , 'foo.php' , 12 , 'foo' ));
2011-04-15 20:12:02 +01:00
2011-05-05 07:46:20 +01:00
restore_error_handler ();
2011-04-15 20:12:02 +01:00
2011-05-05 07:46:20 +01:00
$handler = ErrorHandler :: register ( 3 );
try {
2012-10-07 20:03:04 +01:00
$handler -> handle ( 111 , 'foo' , 'foo.php' , 12 , 'foo' );
2011-05-05 07:46:20 +01:00
} catch ( \ErrorException $e ) {
2012-10-07 20:03:04 +01:00
$this -> assertSame ( '111: foo in foo.php line 12' , $e -> getMessage ());
$this -> assertSame ( 111 , $e -> getSeverity ());
2012-06-25 21:04:54 +01:00
$this -> assertSame ( 'foo.php' , $e -> getFile ());
$this -> assertSame ( 12 , $e -> getLine ());
2011-03-05 19:23:35 +00:00
}
2011-05-05 07:46:20 +01:00
restore_error_handler ();
2012-12-01 11:25:00 +00:00
$handler = ErrorHandler :: register ( E_USER_DEPRECATED );
$this -> assertTrue ( $handler -> handle ( E_USER_DEPRECATED , 'foo' , 'foo.php' , 12 , 'foo' ));
restore_error_handler ();
$handler = ErrorHandler :: register ( E_DEPRECATED );
$this -> assertTrue ( $handler -> handle ( E_DEPRECATED , 'foo' , 'foo.php' , 12 , 'foo' ));
restore_error_handler ();
2013-11-05 20:12:21 +00:00
$logger = $this -> getMock ( 'Psr\Log\LoggerInterface' , array ( 'warning' ));
2012-12-07 11:47:14 +00:00
$that = $this ;
$warnArgCheck = function ( $message , $context ) use ( $that ) {
$that -> assertEquals ( 'foo' , $message );
$that -> assertArrayHasKey ( 'type' , $context );
$that -> assertEquals ( $context [ 'type' ], ErrorHandler :: TYPE_DEPRECATION );
$that -> assertArrayHasKey ( 'stack' , $context );
$that -> assertInternalType ( 'array' , $context [ 'stack' ]);
};
$logger
-> expects ( $this -> once ())
2013-01-09 09:41:17 +00:00
-> method ( 'warning' )
2012-12-07 11:47:14 +00:00
-> will ( $this -> returnCallback ( $warnArgCheck ))
;
2012-12-01 11:25:00 +00:00
$handler = ErrorHandler :: register ( E_USER_DEPRECATED );
$handler -> setLogger ( $logger );
$handler -> handle ( E_USER_DEPRECATED , 'foo' , 'foo.php' , 12 , 'foo' );
restore_error_handler ();
2011-05-05 07:46:20 +01:00
}
2011-03-05 19:23:35 +00:00
}