From 3b3cf812d4bf0c8c44ba5ba0e97b62342cdbbf1d Mon Sep 17 00:00:00 2001 From: Dustin Wilson Date: Sun, 27 Nov 2022 21:44:41 -0600 Subject: [PATCH] Started testing ThrowableController --- lib/Catcher/ThrowableController.php | 18 ++-- run | 2 +- tests/cases/TestThrowableController.php | 113 ++++++++++++++++++++++++ tests/phpunit.dist.xml | 1 + 4 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 tests/cases/TestThrowableController.php diff --git a/lib/Catcher/ThrowableController.php b/lib/Catcher/ThrowableController.php index fbbe780..8822b3f 100644 --- a/lib/Catcher/ThrowableController.php +++ b/lib/Catcher/ThrowableController.php @@ -102,7 +102,7 @@ class ThrowableController { ) { $frames = $this->throwable->getTrace(); } else { - $frames = array_diff_key(array_reverse(xdebug_get_function_stack()), debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS)); + $frames = array_values(array_diff_key(xdebug_get_function_stack(), debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS))); } // PHP for some stupid reason thinks it's okay not to provide line numbers and file @@ -133,11 +133,17 @@ class ThrowableController { } // Delete everything that has anything to do with userland error handling - for ($frameCount = count($frames), $i = $frameCount - 1; $i >= 0; $i--) { - $frame = $frames[$i]; - if ($frame['file'] === $this->throwable->getFile() && $frame['line'] === $this->throwable->getLine()) { - array_splice($frames, 0, $i); - break; + $frameCount = count($frames); + if ($frameCount > 0) { + $tFile = $this->throwable->getFile(); + $tLine = $this->throwable->getLine(); + + for ($i = $frameCount - 1; $i >= 0; $i--) { + $frame = $frames[$i]; + if ($tFile === $frame['file'] && $tLine === $frame['line']) { + array_splice($frames, 0, $i); + break; + } } } diff --git a/run b/run index 97eebba..1d926ef 100755 --- a/run +++ b/run @@ -92,7 +92,7 @@ if (!extension_loaded('xdebug')) { error('Xdebug is not installed on your system; aborting'); } } -$cmd[] = '-d xdebug.mode=coverage,trace'; +$cmd[] = '-d xdebug.mode=coverage,develop,trace'; $cmd = implode(' ', $cmd); $process = proc_open("$cmd $phpunitPath -c $confPath $opts", [ diff --git a/tests/cases/TestThrowableController.php b/tests/cases/TestThrowableController.php new file mode 100644 index 0000000..2180c76 --- /dev/null +++ b/tests/cases/TestThrowableController.php @@ -0,0 +1,113 @@ + false ])); + ob_start(); + trigger_error('Ook!', \E_USER_DEPRECATED); + ob_end_clean(); + $this->assertEquals(\E_USER_DEPRECATED, $c->getLastThrowable()->getCode()); + $c->unregister(); + + $c = new Catcher(new PlainTextHandler([ 'outputToStderr' => false ])); + ob_start(); + trigger_error('Ook!', \E_USER_WARNING); + ob_end_clean(); + $this->assertEquals(\E_USER_WARNING, $c->getLastThrowable()->getCode()); + $c->unregister(); + + // These others will be tested by invoking the method directly + $c = new ThrowableController(new Error('Ook!', \E_ERROR)); + $this->assertEquals('PHP Fatal Error', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_WARNING)); + $this->assertEquals('PHP Warning', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_PARSE)); + $this->assertEquals('PHP Parsing Error', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_NOTICE)); + $this->assertEquals('PHP Notice', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_DEPRECATED)); + $this->assertEquals('Deprecated', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_CORE_ERROR)); + $this->assertEquals('PHP Core Error', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_CORE_WARNING)); + $this->assertEquals('PHP Core Warning', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_COMPILE_ERROR)); + $this->assertEquals('Compile Error', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_COMPILE_WARNING)); + $this->assertEquals('Compile Warning', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_STRICT)); + $this->assertEquals('Runtime Notice', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!', \E_RECOVERABLE_ERROR)); + $this->assertEquals('Recoverable Error', $c->getErrorType()); + $c = new ThrowableController(new Error('Ook!')); + $this->assertNull($c->getErrorType()); + $c = new ThrowableController(new \Exception('Ook!')); + $this->assertNull($c->getErrorType()); + } + + /** + * @covers \MensBeam\Foundation\Catcher\ThrowableController::getFrames + * + */ + public function testMethod_getFrames(): void { + $f = false; + try { + throw new \Exception('Ook!'); + } catch (\Throwable $t) { + $c = new ThrowableController($t); + $f = $c->getFrames(); + } finally { + $this->assertEquals('Exception', $f[0]['class']); + } + + $f = false; + try { + throw new Error('Ook!', \E_ERROR); + } catch (\Throwable $t) { + $c = new ThrowableController($t); + $f = $c->getFrames(); + } finally { + $this->assertEquals(Error::class, $f[0]['class']); + } + } +} \ No newline at end of file diff --git a/tests/phpunit.dist.xml b/tests/phpunit.dist.xml index 43acf33..3b4fc0a 100644 --- a/tests/phpunit.dist.xml +++ b/tests/phpunit.dist.xml @@ -19,6 +19,7 @@ cases/TestCatcher.php cases/TestHandler.php + cases/TestThrowableController.php \ No newline at end of file