From d750325fb2fdba28a11250a8f6354d9c9e7201ba Mon Sep 17 00:00:00 2001 From: "John Paul E. Balandan, CPA" Date: Tue, 27 May 2025 00:30:02 +0800 Subject: [PATCH] refactor: fix and micro-optimize code in `Format` --- system/Format/Exceptions/FormatException.php | 2 +- system/Format/Format.php | 13 +---- system/Format/FormatterInterface.php | 4 +- system/Format/JSONFormatter.php | 8 +-- system/Format/XMLFormatter.php | 7 +-- tests/system/Format/JSONFormatterTest.php | 54 +++++++------------ tests/system/Format/XMLFormatterTest.php | 6 +++ utils/phpstan-baseline/loader.neon | 2 +- .../missingType.iterableValue.neon | 32 +---------- 9 files changed, 40 insertions(+), 88 deletions(-) diff --git a/system/Format/Exceptions/FormatException.php b/system/Format/Exceptions/FormatException.php index 46daad558c50..cde333b1292c 100644 --- a/system/Format/Exceptions/FormatException.php +++ b/system/Format/Exceptions/FormatException.php @@ -37,7 +37,7 @@ public static function forInvalidFormatter(string $class) * Thrown in JSONFormatter when the json_encode produces * an error code other than JSON_ERROR_NONE and JSON_ERROR_RECURSION. * - * @param string $error The error message + * @param string|null $error The error message * * @return static */ diff --git a/system/Format/Format.php b/system/Format/Format.php index 4a9cb60981e6..6100b1a586a8 100644 --- a/system/Format/Format.php +++ b/system/Format/Format.php @@ -23,19 +23,8 @@ */ class Format { - /** - * Configuration instance - * - * @var FormatConfig - */ - protected $config; - - /** - * Constructor. - */ - public function __construct(FormatConfig $config) + public function __construct(protected FormatConfig $config) { - $this->config = $config; } /** diff --git a/system/Format/FormatterInterface.php b/system/Format/FormatterInterface.php index 0f005568c787..0c2492b90a77 100644 --- a/system/Format/FormatterInterface.php +++ b/system/Format/FormatterInterface.php @@ -21,9 +21,9 @@ interface FormatterInterface /** * Takes the given data and formats it. * - * @param array|object|string $data + * @param array|object|string $data * - * @return false|string + * @return false|non-empty-string */ public function format($data); } diff --git a/system/Format/JSONFormatter.php b/system/Format/JSONFormatter.php index 7d2ad5259ce3..a6ba87cd724a 100644 --- a/system/Format/JSONFormatter.php +++ b/system/Format/JSONFormatter.php @@ -26,9 +26,9 @@ class JSONFormatter implements FormatterInterface /** * Takes the given data and formats it. * - * @param array|bool|float|int|object|string|null $data + * @param array|object|string $data * - * @return false|string (JSON string | false) + * @return false|non-empty-string */ public function format($data) { @@ -37,7 +37,9 @@ public function format($data) $options = $config->formatterOptions['application/json'] ?? JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES; $options |= JSON_PARTIAL_OUTPUT_ON_ERROR; - $options = ENVIRONMENT === 'production' ? $options : $options | JSON_PRETTY_PRINT; + if (ENVIRONMENT !== 'production') { + $options |= JSON_PRETTY_PRINT; + } $result = json_encode($data, $options, 512); diff --git a/system/Format/XMLFormatter.php b/system/Format/XMLFormatter.php index c85eae5feffe..efef70cec2cb 100644 --- a/system/Format/XMLFormatter.php +++ b/system/Format/XMLFormatter.php @@ -27,9 +27,9 @@ class XMLFormatter implements FormatterInterface /** * Takes the given data and formats it. * - * @param array|bool|float|int|object|string|null $data + * @param array|object|string $data * - * @return false|string (XML string | false) + * @return false|non-empty-string */ public function format($data) { @@ -56,7 +56,8 @@ public function format($data) * * @see http://www.codexworld.com/convert-array-to-xml-in-php/ * - * @param SimpleXMLElement $output + * @param array $data + * @param SimpleXMLElement $output * * @return void */ diff --git a/tests/system/Format/JSONFormatterTest.php b/tests/system/Format/JSONFormatterTest.php index 7ac97091a4c7..027c618dc4f0 100644 --- a/tests/system/Format/JSONFormatterTest.php +++ b/tests/system/Format/JSONFormatterTest.php @@ -13,8 +13,9 @@ namespace CodeIgniter\Format; -use CodeIgniter\Exceptions\RuntimeException; +use CodeIgniter\Format\Exceptions\FormatException; use CodeIgniter\Test\CIUnitTestCase; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; /** @@ -31,51 +32,34 @@ protected function setUp(): void $this->jsonFormatter = new JSONFormatter(); } - public function testBasicJSON(): void + /** + * @param array $data + */ + #[DataProvider('provideFormattingToJson')] + public function testFormattingToJson(array $data, string $expected): void { - $data = [ - 'foo' => 'bar', - ]; - - $expected = '{ - "foo": "bar" -}'; - $this->assertSame($expected, $this->jsonFormatter->format($data)); } - public function testUnicodeOutput(): void + /** + * @return iterable, 1: string}> + */ + public static function provideFormattingToJson(): iterable { - $data = [ - 'foo' => 'База данни грешка', - ]; + yield 'empty array' => [[], '[]']; - $expected = '{ - "foo": "База данни грешка" -}'; + yield 'simple array' => [['foo' => 'bar'], "{\n \"foo\": \"bar\"\n}"]; - $this->assertSame($expected, $this->jsonFormatter->format($data)); - } + yield 'unicode array' => [['foo' => 'База данни грешка'], "{\n \"foo\": \"База данни грешка\"\n}"]; - public function testKeepsURLs(): void - { - $data = [ - 'foo' => 'https://www.example.com/foo/bar', - ]; - - $expected = '{ - "foo": "https://www.example.com/foo/bar" -}'; - - $this->assertSame($expected, $this->jsonFormatter->format($data)); + yield 'url array' => [['foo' => 'https://www.example.com/foo/bar'], "{\n \"foo\": \"https://www.example.com/foo/bar\"\n}"]; } - public function testJSONError(): void + public function testJSONFormatterThrowsError(): void { - $this->expectException(RuntimeException::class); + $this->expectException(FormatException::class); + $this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded'); - $data = ["\xB1\x31"]; - $expected = 'Boom'; - $this->assertSame($expected, $this->jsonFormatter->format($data)); + $this->assertSame('Boom', $this->jsonFormatter->format(["\xB1\x31"])); } } diff --git a/tests/system/Format/XMLFormatterTest.php b/tests/system/Format/XMLFormatterTest.php index 0615a1eafd91..107418a5d68c 100644 --- a/tests/system/Format/XMLFormatterTest.php +++ b/tests/system/Format/XMLFormatterTest.php @@ -104,6 +104,9 @@ public function testValidatingXmlTags(): void $this->assertSame($expected, $this->xmlFormatter->format($data)); } + /** + * @param array $input + */ #[DataProvider('provideValidatingInvalidTags')] public function testValidatingInvalidTags(string $expected, array $input): void { @@ -116,6 +119,9 @@ public function testValidatingInvalidTags(string $expected, array $input): void $this->assertSame($expectedXML, $this->xmlFormatter->format($input)); } + /** + * @return iterable}> + */ public static function provideValidatingInvalidTags(): iterable { return [ diff --git a/utils/phpstan-baseline/loader.neon b/utils/phpstan-baseline/loader.neon index 2102bc809eb3..4cb13113bbe1 100644 --- a/utils/phpstan-baseline/loader.neon +++ b/utils/phpstan-baseline/loader.neon @@ -1,4 +1,4 @@ -# total 3262 errors +# total 3256 errors includes: - argument.type.neon - assign.propertyType.neon diff --git a/utils/phpstan-baseline/missingType.iterableValue.neon b/utils/phpstan-baseline/missingType.iterableValue.neon index 80bfc79d9b97..be97474954ac 100644 --- a/utils/phpstan-baseline/missingType.iterableValue.neon +++ b/utils/phpstan-baseline/missingType.iterableValue.neon @@ -1,4 +1,4 @@ -# total 1571 errors +# total 1565 errors parameters: ignoreErrors: @@ -3052,26 +3052,6 @@ parameters: count: 1 path: ../../system/Filters/PerformanceMetrics.php - - - message: '#^Method CodeIgniter\\Format\\FormatterInterface\:\:format\(\) has parameter \$data with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Format/FormatterInterface.php - - - - message: '#^Method CodeIgniter\\Format\\JSONFormatter\:\:format\(\) has parameter \$data with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Format/JSONFormatter.php - - - - message: '#^Method CodeIgniter\\Format\\XMLFormatter\:\:arrayToXML\(\) has parameter \$data with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Format/XMLFormatter.php - - - - message: '#^Method CodeIgniter\\Format\\XMLFormatter\:\:format\(\) has parameter \$data with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Format/XMLFormatter.php - - message: '#^Method CodeIgniter\\HTTP\\CLIRequest\:\:getArgs\(\) return type has no value type specified in iterable type array\.$#' count: 1 @@ -6517,16 +6497,6 @@ parameters: count: 1 path: ../../tests/system/Filters/InvalidCharsTest.php - - - message: '#^Method CodeIgniter\\Format\\XMLFormatterTest\:\:provideValidatingInvalidTags\(\) return type has no value type specified in iterable type iterable\.$#' - count: 1 - path: ../../tests/system/Format/XMLFormatterTest.php - - - - message: '#^Method CodeIgniter\\Format\\XMLFormatterTest\:\:testValidatingInvalidTags\(\) has parameter \$input with no value type specified in iterable type array\.$#' - count: 1 - path: ../../tests/system/Format/XMLFormatterTest.php - - message: '#^Method CodeIgniter\\HTTP\\IncomingRequestTest\:\:provideCanGrabGetRawInputVar\(\) return type has no value type specified in iterable type iterable\.$#' count: 1