diff --git a/approot.inc.php b/approot.inc.php index 820ab0a6e..b4cbe59d6 100644 --- a/approot.inc.php +++ b/approot.inc.php @@ -25,4 +25,9 @@ define('ITOP_DESIGN_LATEST_VERSION', '3.1'); */ define('ITOP_CORE_VERSION', '3.1.0'); +/** + * @since 3.0.4 N°6274 Allow to test if PHPUnit is currently running. Starting with PHPUnit 9.5 we'll be able to replace it with $GLOBALS['phpunit_version'] + */ +define('ITOP_PHPUNIT_RUNNING_CONSTANT_NAME', 'ITOP_PHPUNIT_RUNNING'); + require_once APPROOT.'bootstrap.inc.php'; diff --git a/core/log.class.inc.php b/core/log.class.inc.php index a8ab6c41c..169bc72d9 100644 --- a/core/log.class.inc.php +++ b/core/log.class.inc.php @@ -1121,16 +1121,19 @@ class DeprecatedCallsLog extends LogAPI * @uses \set_error_handler() to catch deprecated notices * * @since 3.0.0 N°3002 logs deprecated notices in called code + * @since 3.0.4 N°6274 do not set handler when in PHPUnit context (otherwise PHP notices won't be caught) */ - public static function Enable($sTargetFile = null): void - { + public static function Enable($sTargetFile = null): void { if (empty($sTargetFile)) { $sTargetFile = APPROOT.'log/deprecated-calls.log'; } parent::Enable($sTargetFile); - if (static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD)) { - set_error_handler([static::class, 'DeprecatedNoticesErrorHandler']); + if ( + (false === defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) + && static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD) + ) { + set_error_handler([static::class, 'DeprecatedNoticesErrorHandler'], E_DEPRECATED | E_USER_DEPRECATED); } } diff --git a/tests/php-unit-tests/ItopTestCase.php b/tests/php-unit-tests/ItopTestCase.php index 0ac11233f..1a2b25db3 100644 --- a/tests/php-unit-tests/ItopTestCase.php +++ b/tests/php-unit-tests/ItopTestCase.php @@ -36,8 +36,7 @@ class ItopTestCase extends TestCase static $DEBUG_UNIT_TEST = false; /** @noinspection UsingInclusionOnceReturnValueInspection avoid errors for approot includes */ - protected function setUp(): void - { + protected function setUp(): void { $sAppRootRelPath = 'approot.inc.php'; $sDepthSeparator = '../'; for ($iDepth = 0; $iDepth < 8; $iDepth++) { @@ -52,6 +51,11 @@ class ItopTestCase extends TestCase static::$DEBUG_UNIT_TEST = getenv('DEBUG_UNIT_TEST'); $this->debug("\n----------\n---------- ".$this->getName()."\n----------\n"); + + if (false === defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME)) { + // setUp might be called multiple times, so protecting the define() call ! + define(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME, true); + } } /** diff --git a/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php b/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php new file mode 100644 index 000000000..906246ff4 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/Log/DeprecatedCallsLogTest.php @@ -0,0 +1,61 @@ +=')) { + $sUndefinedOffsetExceptionClass = Warning::class; + $sUndefinedOffsetExceptionMessage = 'Undefined array key "tutu"'; + } + else { + $sUndefinedOffsetExceptionClass = Notice::class; + $sUndefinedOffsetExceptionMessage = 'Undefined index: tutu'; + } + $this->expectException($sUndefinedOffsetExceptionClass); + $this->expectExceptionMessage($sUndefinedOffsetExceptionMessage); + } + + public function testPhpNoticeWithoutDeprecatedCallsLog(): void { + $this->SetUndefinedOffsetExceptionToExpect(); + + $aArray = []; + if ('toto' === $aArray['tutu']) { + //Do nothing, just raising a undefined offset warning + } + } + + /** + * The error handler set by DeprecatedCallsLog during startup was causing PHPUnit to miss PHP notices like "undefined offset" + * + * The error handler is now disabled when running PHPUnit + * + * @since 3.0.4 N°6274 + * @covers DeprecatedCallsLog::DeprecatedNoticesErrorHandler + */ + public function testPhpNoticeWithDeprecatedCallsLog(): void { + $this->RequireOnceItopFile('core/log.class.inc.php'); + DeprecatedCallsLog::Enable(); // will set error handler + $this->SetUndefinedOffsetExceptionToExpect(); + + $aArray = []; + if ('toto' === $aArray['tutu']) { + //Do nothing, just raising a undefined offset warning + } + } +}