Skip to content

Commit

Permalink
Merge pull request #6469 from Codeception/error-handling-expectations
Browse files Browse the repository at this point in the history
Fix compatibility with PHPUnit error expectations
  • Loading branch information
Naktibalda committed Jun 16, 2022
2 parents 1316cdc + 8a365d2 commit 29df192
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/Codeception/Configuration.php
Expand Up @@ -133,6 +133,7 @@ class Configuration
'config' => [],
],
'error_level' => 'E_ALL & ~E_STRICT & ~E_DEPRECATED',
'convert_deprecations_to_exceptions' => false
];

protected static $params;
Expand Down
31 changes: 30 additions & 1 deletion src/Codeception/Subscriber/ErrorHandler.php
Expand Up @@ -4,6 +4,10 @@
use Codeception\Event\SuiteEvent;
use Codeception\Events;
use Codeception\Lib\Notification;
use PHPUnit\Framework\Error\Deprecated;
use PHPUnit\Framework\Error\Error;
use PHPUnit\Framework\Error\Notice;
use PHPUnit\Framework\Error\Warning;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ErrorHandler implements EventSubscriberInterface
Expand Down Expand Up @@ -35,6 +39,8 @@ class ErrorHandler implements EventSubscriberInterface
*/
private $errorLevel;

private $convertDeprecationsToExceptions = false;

public function __construct()
{
$this->errorLevel = E_ALL & ~E_STRICT & ~E_DEPRECATED;
Expand All @@ -53,6 +59,10 @@ public function handle(SuiteEvent $e)
}
error_reporting($this->errorLevel);

if ($settings['convert_deprecations_to_exceptions']) {
$this->convertDeprecationsToExceptions = true;
}

if ($this->initialized) {
return;
}
Expand All @@ -66,7 +76,7 @@ public function handle(SuiteEvent $e)

public function errorHandler($errno, $errstr, $errfile, $errline, $context = array())
{
if (E_USER_DEPRECATED === $errno) {
if ((E_USER_DEPRECATED === $errno || E_DEPRECATED === $errno) && !$this->convertDeprecationsToExceptions) {
$this->handleDeprecationError($errno, $errstr, $errfile, $errline, $context);
return;
}
Expand All @@ -80,6 +90,25 @@ public function errorHandler($errno, $errstr, $errfile, $errline, $context = arr
return false;
}

if (version_compare(\PHPUnit\Runner\Version::id(), '8.4.0', '>=')) {
switch ($errno) {
case E_DEPRECATED:
case E_USER_DEPRECATED:
// Renamed to Deprecation in PHPUnit 10
throw new Deprecated($errstr, $errno, $errfile, $errline);
case E_NOTICE:
case E_STRICT:
case E_USER_NOTICE:
throw new Notice($errstr, $errno, $errfile, $errline);
case E_WARNING:
case E_USER_WARNING:
throw new Warning($errstr, $errno, $errfile, $errline);
case E_USER_ERROR:
default:
throw new Error($errstr, $errno, $errfile, $errline);
}
}

$relativePath = codecept_relative_path($errfile);
throw new \PHPUnit\Framework\Exception("$errstr at $relativePath:$errline", $errno);
}
Expand Down
49 changes: 49 additions & 0 deletions tests/cli/ErrorExpectationsCest.php
@@ -0,0 +1,49 @@
<?php

class ErrorExpectationsCest
{

public function _before(\CliGuy $I)
{
$I->amInPath('tests/data/error_handling');
}

public function expectNoticeWorks(\CliGuy $I)
{
$this->skipIfOldPhpUnit($I);

$I->executeCommand('run tests/unit/ErrorExceptionTest.php:testNotice');
$I->seeInShellOutput("OK (");
}

public function expectWarningWorks(\CliGuy $I)
{
$this->skipIfOldPhpUnit($I);

$I->executeCommand('run tests/unit/ErrorExceptionTest.php:testWarning');
$I->seeInShellOutput('OK (');
}

public function expectErrorWorks(\CliGuy $I)
{
$this->skipIfOldPhpUnit($I);

$I->executeCommand('run tests/unit/ErrorExceptionTest.php:testError');
$I->seeInShellOutput('OK (');
}

public function expectDeprecationWorks(\CliGuy $I)
{
$this->skipIfOldPhpUnit($I);

$I->executeCommand('run tests/unit/ErrorExceptionTest.php:testDeprecation');
$I->seeInShellOutput('OK (');
}

private function skipIfOldPhpUnit(CliGuy $I)
{
if (version_compare(\PHPUnit\Runner\Version::id(), '8.4.0', '<')) {
$I->markTestSkipped('expectXXX is only available on PHPUnit 8.4+');
}
}
}
15 changes: 15 additions & 0 deletions tests/data/error_handling/codeception.yml
@@ -0,0 +1,15 @@
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
suites:
unit:
path: .
modules:
enabled:
- Asserts
settings:
convert_deprecations_to_exceptions: true
Empty file.
34 changes: 34 additions & 0 deletions tests/data/error_handling/tests/unit/ErrorExceptionTest.php
@@ -0,0 +1,34 @@
<?php

class ErrorExceptionTest extends \PHPUnit\Framework\TestCase
{

public function testNotice()
{
$this->expectNotice();
$this->expectNoticeMessage('foobar');
trigger_error('foobar', E_USER_NOTICE);
}

public function testWarning()
{
$this->expectWarning();
$this->expectWarningMessage('foobar');
trigger_error('foobar', E_USER_WARNING);
}

public function testError()
{
$this->expectError();
$this->expectErrorMessage('foobar');
trigger_error('foobar', E_USER_ERROR);
}

public function testDeprecation()
{
// This test fails.
$this->expectDeprecation();
$this->expectDeprecationMessage('foobar');
trigger_error('foobar', E_USER_DEPRECATED);
}
}
15 changes: 11 additions & 4 deletions tests/unit/Codeception/Subscriber/ErrorHandlerTest.php
Expand Up @@ -38,13 +38,20 @@ public function testDeprecationMessagesRespectErrorLevelSetting()

public function testShowsLocationOfWarning()
{
if (PHP_MAJOR_VERSION === 5) {
if (version_compare(\PHPUnit\Runner\Version::id(), '8.4.0', '>=')) {
$this->expectWarning();
} elseif (version_compare(\PHPUnit\Runner\Version::id(), '6.0.0', '>=')) {
$this->expectException(\PHPUnit\Framework\Exception::class);
} else {
$this->expectException(\PHPUnit_Framework_Exception::class);
}

if (version_compare(\PHPUnit\Runner\Version::id(), '8.4.0', '>=')) {
$this->expectWarningMessage('Undefined variable: file');
} else {
$this->expectException(\PHPUnit\Framework\Exception::class);
$SEP = DIRECTORY_SEPARATOR;
$this->expectExceptionMessage($expectedMessage = "Undefined variable: file at tests{$SEP}unit{$SEP}Codeception{$SEP}Subscriber{$SEP}ErrorHandlerTest.php:55");
}
$SEP = DIRECTORY_SEPARATOR;
$this->expectExceptionMessage("Undefined variable: file at tests{$SEP}unit{$SEP}Codeception{$SEP}Subscriber{$SEP}ErrorHandlerTest.php:48");
trigger_error('Undefined variable: file', E_USER_WARNING);
}
}

0 comments on commit 29df192

Please sign in to comment.