createDatabaseInterface(); $this->object = new ErrorHandler(); $_SESSION['errors'] = []; $config = Config::getInstance(); $config->settings['environment'] = 'production'; $config->settings['SendErrorReports'] = 'always'; } /** * Tears down the fixture, for example, closes a network connection. * This method is called after a test is executed. */ protected function tearDown(): void { parent::tearDown(); unset($this->object); } public function testUniqueness(): void { ErrorHandler::$instance = null; $instanceOne = ErrorHandler::getInstance(); $instanceTwo = ErrorHandler::getInstance(); self::assertSame($instanceOne, $instanceTwo); } /** @return array */ public static function providerForTestHandleError(): array { return [ [E_RECOVERABLE_ERROR, 'Compile Error', 'error.txt', 12, 'never', ''], [E_RECOVERABLE_ERROR, 'Compile Error', 'error.txt', 12, 'always', 'Compile Error'], [E_RECOVERABLE_ERROR, 'Compile Error', 'error.txt', 12, 'ask', 'Compile Error'], [E_USER_NOTICE, 'User notice', 'error.txt', 12, 'never', 'User notice'], [E_USER_NOTICE, 'User notice', 'error.txt', 12, 'always', 'User notice'], [E_USER_NOTICE, 'User notice', 'error.txt', 12, 'ask', 'User notice'], ]; } #[DataProvider('providerForTestHandleError')] public function testGetDisplayErrors( int $errorNumber, string $errorMessage, string $errorFile, int $errorLine, string $reportErrorConfig, string $expected, ): void { $config = new Config(); $config->settings['environment'] = 'production'; $config->settings['SendErrorReports'] = $reportErrorConfig; Config::$instance = $config; $error = new Error($errorNumber, $errorMessage, $errorFile, $errorLine); $_SESSION['errors'] = [$error->getHash() => $error]; $handler = new ErrorHandler(); if ($expected === '') { self::assertSame('', $handler->getDispErrors()); } else { self::assertStringContainsString($expected, $handler->getDispErrors()); } } /** * Test for checkSavedErrors */ public function testCheckSavedErrors(): void { $this->callFunction( $this->object, ErrorHandler::class, 'checkSavedErrors', [], ); self::assertArrayNotHasKey('errors', $_SESSION); } /** * Test for countErrors */ #[Group('medium')] public function testCountErrors(): void { $this->object->addError('Compile Error', E_WARNING, 'error.txt', 15); self::assertEquals( 1, $this->object->countErrors(), ); } /** * Test for sliceErrors */ #[Group('medium')] public function testSliceErrors(): void { $this->object->addError('Compile Error', E_WARNING, 'error.txt', 15); $this->object->addError('Compile Error', E_WARNING, 'error.txt', 16); self::assertEquals( 2, $this->object->countErrors(), ); self::assertEquals( [], $this->object->sliceErrors(2), ); self::assertEquals( 2, $this->object->countErrors(), ); self::assertCount( 1, $this->object->sliceErrors(1), ); self::assertEquals( 1, $this->object->countErrors(), ); } /** * Test for sliceErrors with 10 elements as an example */ #[Group('medium')] public function testSliceErrorsOtherExample(): void { for ($i = 0; $i < 10; $i++) { $this->object->addError('Compile Error', E_WARNING, 'error.txt', $i); } // 10 initial items self::assertEquals(10, $this->object->countErrors()); self::assertEquals(10, count($this->object->getCurrentErrors())); // slice 9 elements, returns one 10 - 9 $elements = $this->object->sliceErrors(9); $firstKey = array_keys($elements)[0]; // Gives the last element self::assertEquals( [$firstKey => $elements[$firstKey]], $elements, ); self::assertEquals(9, count($this->object->getCurrentErrors())); self::assertEquals(9, $this->object->countErrors()); // Slice as much as there is (9), does nothing $elements = $this->object->sliceErrors(9); self::assertEquals([], $elements); self::assertEquals(9, count($this->object->getCurrentErrors())); self::assertEquals(9, $this->object->countErrors()); // Slice 0, removes everything $elements = $this->object->sliceErrors(0); self::assertEquals(9, count($elements)); self::assertEquals(0, count($this->object->getCurrentErrors())); self::assertEquals(0, $this->object->countErrors()); } /** * Test for countUserErrors */ public function testCountUserErrors(): void { $this->object->addError('Compile Error', E_WARNING, 'error.txt', 15); self::assertEquals( 0, $this->object->countUserErrors(), ); $this->object->addError('Compile Error', E_USER_WARNING, 'error.txt', 15); self::assertEquals( 1, $this->object->countUserErrors(), ); } /** * Test for hasUserErrors */ public function testHasUserErrors(): void { self::assertFalse($this->object->hasUserErrors()); } /** * Test for hasErrors */ public function testHasErrors(): void { self::assertFalse($this->object->hasErrors()); } /** * Test for countDisplayErrors */ public function testCountDisplayErrorsForDisplayTrue(): void { self::assertEquals( 0, $this->object->countDisplayErrors(), ); } /** * Test for countDisplayErrors */ public function testCountDisplayErrorsForDisplayFalse(): void { self::assertEquals( 0, $this->object->countDisplayErrors(), ); } /** * Test for hasDisplayErrors */ public function testHasDisplayErrors(): void { self::assertFalse($this->object->hasDisplayErrors()); } public function testHandleExceptionForDevEnv(): void { $GLOBALS['lang'] = 'en'; Config::getInstance()->set('environment', 'development'); $errorHandler = new ErrorHandler(); self::assertSame([], $errorHandler->getCurrentErrors()); try { $errorHandler->handleException(new Exception('Exception message.')); } catch (Throwable $throwable) { } self::assertInstanceOf(ExitException::class, $throwable ?? null); $output = $this->getActualOutputForAssertion(); $errors = $errorHandler->getCurrentErrors(); self::assertCount(1, $errors); $error = array_pop($errors); self::assertInstanceOf(Error::class, $error); self::assertSame('Exception: Exception message.', $error->getOnlyMessage()); self::assertStringContainsString($error->getDisplay(), $output); self::assertStringContainsString('Internal error', $output); self::assertStringContainsString('ErrorHandlerTest.php#' . $error->getLine(), $output); self::assertStringContainsString('Exception: Exception message.', $output); } public function testHandleExceptionForProdEnv(): void { $GLOBALS['lang'] = 'en'; Config::getInstance()->set('environment', 'production'); $errorHandler = new ErrorHandler(); self::assertSame([], $errorHandler->getCurrentErrors()); try { $errorHandler->handleException(new Exception('Exception message.')); } catch (Throwable $throwable) { } self::assertInstanceOf(ExitException::class, $throwable ?? null); $output = $this->getActualOutputForAssertion(); $errors = $errorHandler->getCurrentErrors(); self::assertCount(1, $errors); $error = array_pop($errors); self::assertInstanceOf(Error::class, $error); self::assertSame('Exception: Exception message.', $error->getOnlyMessage()); self::assertStringContainsString($error->getDisplay(), $output); self::assertStringContainsString('Exception: Exception message.', $output); self::assertStringNotContainsString('ErrorHandlerTest.php#' . $error->getLine(), $output); } public function testAddErrorWithFatalError(): void { $GLOBALS['lang'] = 'en'; Config::getInstance()->set('environment', 'production'); $errorHandler = new ErrorHandler(); try { $errorHandler->addError('Fatal error message!', E_ERROR, './file/name', 1); } catch (Throwable $exception) { } self::assertInstanceOf(ExitException::class, $exception ?? null); // phpcs:disable Generic.Files.LineLength.TooLong $expectedStart = <<<'HTML' Error: Fatal error message! ' . "\n\n" . '' . "\n" . '', $output); } }