From c78bccc56df2f714f6f0d71cbabace92fc181f16 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Tue, 9 May 2023 12:46:52 -0400 Subject: [PATCH] Style and tool updates --- CHANGELOG.md | 5 +- justfile | 6 +- src/Ion/Attribute/Controller.php | 9 +- src/Ion/Attribute/DefaultController.php | 4 +- src/Ion/Attribute/Route.php | 7 +- src/Ion/Di/Container.php | 4 +- src/Ion/Type/ArrayType.php | 4 +- src/Ion/Type/Stringy.php | 384 ++++++++++-------- src/Ion/View/HttpView.php | 3 +- .../Transformer/AnimeListTransformerTest.php | 16 +- tests/AnimeClient/DispatcherTest.php | 137 +++---- .../AnimeClient/Helper/PictureHelperTest.php | 12 +- tests/AnimeClient/KitsuTest.php | 32 +- tests/AnimeClient/RoutingBaseTest.php | 38 +- tests/AnimeClient/UrlGeneratorTest.php | 11 +- tests/AnimeClient/UtilTest.php | 57 ++- tests/Ion/ConfigTest.php | 10 +- tests/Ion/Di/ContainerTest.php | 11 +- tests/Ion/EnumTest.php | 28 +- tests/Ion/JsonTest.php | 28 +- .../Transformer/AbstractTransformerTest.php | 62 ++- tests/Ion/Type/ArrayTypeTest.php | 24 +- tests/Ion/Type/StringTypeTest.php | 7 +- tools/composer.json | 2 +- tools/header_comment.txt | 6 +- tools/offline-db-update.php | 0 tools/rector.php | 76 ++-- tools/update_header_comments.php | 6 +- 28 files changed, 514 insertions(+), 475 deletions(-) create mode 100644 tools/offline-db-update.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 12ceddbc..da8195a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ # Changelog ## Version 5.2 -* Updated PHP requirement to 8 -* Updated to support PHP 8.1 +* Updated PHP requirement to 8.1 +* Updated to support PHP 8.2 +* Improve Anilist <-> Kitsu mappings to be more reliable ## Version 5.1 * Added session check, so when coming back to a page, if the session is expired, the page will refresh. diff --git a/justfile b/justfile index b154948d..9954e4b9 100644 --- a/justfile +++ b/justfile @@ -4,11 +4,11 @@ default: # Runs rector, showing what changes will be make rector-dry-run: - tools/vendor/bin/rector process --config=tools/rector.php --dry-run src + tools/vendor/bin/rector process --config=tools/rector.php --dry-run src tests -# Runs rector, and updates the files +# Runs rector, and updates the source files rector: - tools/vendor/bin/rector process --config=tools/rector.php src + tools/vendor/bin/rector process --config=tools/rector.php src tests # Check code formatting check-fmt: diff --git a/src/Ion/Attribute/Controller.php b/src/Ion/Attribute/Controller.php index c060323a..0adba4df 100644 --- a/src/Ion/Attribute/Controller.php +++ b/src/Ion/Attribute/Controller.php @@ -17,6 +17,9 @@ namespace Aviat\Ion\Attribute; use Attribute; #[Attribute(Attribute::TARGET_CLASS)] -class Controller { - public function __construct(public string $prefix = '') {} -} \ No newline at end of file +class Controller +{ + public function __construct(public string $prefix = '') + { + } +} diff --git a/src/Ion/Attribute/DefaultController.php b/src/Ion/Attribute/DefaultController.php index 830a79d1..4aea3e41 100644 --- a/src/Ion/Attribute/DefaultController.php +++ b/src/Ion/Attribute/DefaultController.php @@ -17,4 +17,6 @@ namespace Aviat\Ion\Attribute; use Attribute; #[Attribute(Attribute::TARGET_CLASS)] -class DefaultController {} \ No newline at end of file +class DefaultController +{ +} diff --git a/src/Ion/Attribute/Route.php b/src/Ion/Attribute/Route.php index 21e771a2..a6cfbd58 100644 --- a/src/Ion/Attribute/Route.php +++ b/src/Ion/Attribute/Route.php @@ -17,7 +17,8 @@ namespace Aviat\Ion\Attribute; use Attribute; #[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] -class Route { +class Route +{ public const GET = 'get'; public const POST = 'post'; @@ -25,8 +26,6 @@ class Route { public string $name, public string $path, public string $verb = self::GET, - ) - { - + ) { } } diff --git a/src/Ion/Di/Container.php b/src/Ion/Di/Container.php index cf79e0d7..12f5a3d3 100644 --- a/src/Ion/Di/Container.php +++ b/src/Ion/Di/Container.php @@ -39,8 +39,8 @@ class Container implements ContainerInterface */ public function __construct( /** - * Array of container Generator functions - */ + * Array of container Generator functions + */ protected array $container = [] ) { $this->loggers = []; diff --git a/src/Ion/Type/ArrayType.php b/src/Ion/Type/ArrayType.php index 01529049..4766c48f 100644 --- a/src/Ion/Type/ArrayType.php +++ b/src/Ion/Type/ArrayType.php @@ -156,7 +156,7 @@ class ArrayType /** * Find an array key by its associated value */ - public function search(mixed $value, bool $strict = TRUE): int|string|FALSE|null + public function search(mixed $value, bool $strict = TRUE): int|string|false|null { return array_search($value, $this->arr, $strict); } @@ -172,7 +172,7 @@ class ArrayType /** * Return the array, or a key */ - public function &get(string|int|NULL $key = NULL): mixed + public function &get(string|int|null $key = NULL): mixed { $value = NULL; if ($key === NULL) diff --git a/src/Ion/Type/Stringy.php b/src/Ion/Type/Stringy.php index 1305d6ba..2aab130a 100644 --- a/src/Ion/Type/Stringy.php +++ b/src/Ion/Type/Stringy.php @@ -21,7 +21,22 @@ use Exception; use InvalidArgumentException; use IteratorAggregate; use OutOfBoundsException; +use RuntimeException; use Traversable; +use function mb_convert_case; +use function mb_ereg_match; +use function mb_ereg_replace; +use function mb_internal_encoding; +use function mb_regex_encoding; +use function mb_split; +use function mb_stripos; +use function mb_strlen; +use function mb_strrpos; +use function mb_strtolower; +use function mb_strtoupper; +use function mb_substr; +use function mb_substr_count; +use const MB_CASE_TITLE; /** * Vendored, slightly modernized version of Stringy @@ -29,16 +44,12 @@ use Traversable; abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { /** * An instance's string. - * - * @var string */ protected string $str; /** * The string's encoding, which should be one of the mbstring module's * supported encodings. - * - * @var string */ protected string $encoding; @@ -51,8 +62,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param mixed $str Value to modify, after being cast to string * @param string|null $encoding The character encoding - * @throws \InvalidArgumentException if an array or object without a - * __toString method is passed as the first argument + * @throws InvalidArgumentException if an array or object without a + * __toString method is passed as the first argument */ public function __construct(mixed $str = '', ?string $encoding = NULL) { @@ -61,7 +72,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { throw new InvalidArgumentException( 'Passed value cannot be an array' ); - } elseif (is_object($str) && ! method_exists($str, '__toString')) + } + if (is_object($str) && ! method_exists($str, '__toString')) { throw new InvalidArgumentException( 'Passed object must have a __toString method' @@ -69,7 +81,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { } $this->str = (string)$str; - $this->encoding = $encoding ?: \mb_internal_encoding(); + $this->encoding = $encoding ?: mb_internal_encoding(); } /** @@ -82,8 +94,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * @param mixed $str Value to modify, after being cast to string * @param string|null $encoding The character encoding * @return static A Stringy object - * @throws \InvalidArgumentException if an array or object without a - * __toString method is passed as the first argument + * @throws InvalidArgumentException if an array or object without a + * __toString method is passed as the first argument */ public static function create(mixed $str = '', ?string $encoding = NULL): self { @@ -140,7 +152,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return static::create('', $this->encoding); } - $substrIndex = $startIndex + \mb_strlen($start, $this->encoding); + $substrIndex = $startIndex + mb_strlen($start, $this->encoding); $endIndex = $this->indexOf($end, $substrIndex); if ($endIndex === FALSE) { @@ -165,10 +177,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/[-_\s]+(.)?/u', - function ($match) use ($encoding) { + static function ($match) use ($encoding): string { if (isset($match[1])) { - return \mb_strtoupper($match[1], $encoding); + return mb_strtoupper($match[1], $encoding); } return ''; @@ -178,9 +190,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/[\d]+(.)?/u', - function ($match) use ($encoding) { - return \mb_strtoupper($match[0], $encoding); - }, + static fn($match) => mb_strtoupper($match[0], $encoding), $stringy->str ); @@ -195,6 +205,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function chars(): array { $chars = []; + for ($i = 0, $l = $this->length(); $i < $l; $i++) { $chars[] = $this->at($i)->str; @@ -222,7 +233,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $needle Substring to look for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return bool Whether or not $str contains $needle + * @return bool Whether or not $str contains $needle */ public function contains(string $needle, bool $caseSensitive = TRUE): bool { @@ -230,10 +241,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($caseSensitive) { - return (\mb_strpos($this->str, $needle, 0, $encoding) !== FALSE); + return \mb_strpos($this->str, $needle, 0, $encoding) !== FALSE; } - return (\mb_stripos($this->str, $needle, 0, $encoding) !== FALSE); + return mb_stripos($this->str, $needle, 0, $encoding) !== FALSE; } /** @@ -243,7 +254,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string[] $needles Substrings to look for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return bool Whether or not $str contains $needle + * @return bool Whether or not $str contains $needle */ public function containsAll(array $needles, bool $caseSensitive = TRUE): bool { @@ -270,7 +281,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string[] $needles Substrings to look for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return bool Whether or not $str contains $needle + * @return bool Whether or not $str contains $needle */ public function containsAny(array $needles, bool $caseSensitive = TRUE): bool { @@ -307,19 +318,19 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $substring The substring to search for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return int The number of $substring occurrences + * @return int The number of $substring occurrences */ public function countSubstr(string $substring, bool $caseSensitive = TRUE): int { if ($caseSensitive) { - return \mb_substr_count($this->str, $substring, $this->encoding); + return mb_substr_count($this->str, $substring, $this->encoding); } - $str = \mb_strtoupper($this->str, $this->encoding); - $substring = \mb_strtoupper($substring, $this->encoding); + $str = mb_strtoupper($this->str, $this->encoding); + $substring = mb_strtoupper($substring, $this->encoding); - return \mb_substr_count($str, $substring, $this->encoding); + return mb_substr_count($str, $substring, $this->encoding); } /** @@ -349,7 +360,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $this->regexEncoding($this->encoding); $str = $this->eregReplace('\B([A-Z])', '-\1', $this->trim()->__toString()); - $str = \mb_strtolower($str, $this->encoding); + $str = mb_strtolower($str, $this->encoding); $str = $this->eregReplace('[-_\s]+', $delimiter, $str); $this->regexEncoding($regexEncoding); @@ -364,20 +375,24 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $substring The substring to look for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return bool Whether or not $str ends with $substring + * @return bool Whether or not $str ends with $substring */ public function endsWith(string $substring, bool $caseSensitive = TRUE): bool { - $substringLength = \mb_strlen($substring, $this->encoding); + $substringLength = mb_strlen($substring, $this->encoding); $strLength = $this->length(); - $endOfStr = \mb_substr($this->str, $strLength - $substringLength, - $substringLength, $this->encoding); + $endOfStr = mb_substr( + $this->str, + $strLength - $substringLength, + $substringLength, + $this->encoding + ); if ( ! $caseSensitive) { - $substring = \mb_strtolower($substring, $this->encoding); - $endOfStr = \mb_strtolower($endOfStr, $this->encoding); + $substring = mb_strtolower($substring, $this->encoding); + $endOfStr = mb_strtolower($endOfStr, $this->encoding); } return (string)$substring === $endOfStr; @@ -390,8 +405,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string[] $substrings Substrings to look for * @param bool $caseSensitive Whether or not to enforce - * case-sensitivity - * @return bool Whether or not $str ends with $substring + * case-sensitivity + * @return bool Whether or not $str ends with $substring */ public function endsWithAny(array $substrings, bool $caseSensitive = TRUE): bool { @@ -462,6 +477,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($n < 0) { $stringy->str = ''; + return $stringy; } @@ -513,14 +529,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $this->matchesPattern('.*[[:upper:]]'); } - /** * Convert all HTML entities to their applicable characters. An alias of * html_entity_decode. For a list of flags, refer to * http://php.net/manual/en/function.html-entity-decode.php * * @param int|null $flags Optional flags - * @return static Object with the resulting $str after being html decoded. + * @return static Object with the resulting $str after being html decoded. */ public function htmlDecode(?int $flags = ENT_COMPAT): self { @@ -535,7 +550,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * for a list of flags. * * @param int|null $flags Optional flags - * @return static Object with the resulting $str after being html encoded. + * @return static Object with the resulting $str after being html encoded. */ public function htmlEncode(?int $flags = ENT_COMPAT): self { @@ -564,12 +579,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $needle Substring to look for * @param int $offset Offset from which to search - * @return int|bool The occurrence's index if found, otherwise false + * @return bool|int The occurrence's index if found, otherwise false */ public function indexOf(string $needle, int $offset = 0): int|false { - return \mb_strpos($this->str, (string)$needle, - (int)$offset, $this->encoding); + return \mb_strpos( + $this->str, + (string)$needle, + (int)$offset, + $this->encoding + ); } /** @@ -580,12 +599,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $needle Substring to look for * @param int $offset Offset from which to search - * @return int|bool The last occurrence's index if found, otherwise false + * @return bool|int The last occurrence's index if found, otherwise false */ public function indexOfLast(string $needle, int $offset = 0): int|false { - return \mb_strrpos($this->str, (string)$needle, - (int)$offset, $this->encoding); + return mb_strrpos( + $this->str, + (string)$needle, + (int)$offset, + $this->encoding + ); } /** @@ -603,9 +626,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $stringy; } - $start = \mb_substr($stringy->str, 0, $index, $stringy->encoding); - $end = \mb_substr($stringy->str, $index, $stringy->length(), - $stringy->encoding); + $start = mb_substr($stringy->str, 0, $index, $stringy->encoding); + $end = mb_substr( + $stringy->str, + $index, + $stringy->length(), + $stringy->encoding + ); $stringy->str = $start . $substring . $end; @@ -672,7 +699,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { json_decode($this->str); - return (json_last_error() === JSON_ERROR_NONE); + return json_last_error() === JSON_ERROR_NONE; } /** @@ -696,7 +723,6 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $this->str === 'b:0;' || @unserialize($this->str) !== FALSE; } - /** * Returns true if the string is base64 encoded, false otherwise. * @@ -704,7 +730,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function isBase64(): bool { - return (base64_encode(base64_decode($this->str, TRUE)) === $this->str); + return base64_encode(base64_decode($this->str, TRUE)) === $this->str; } /** @@ -731,6 +757,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($n <= 0) { $stringy->str = ''; + return $stringy; } @@ -744,7 +771,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function length(): int { - return \mb_strlen($this->str, $this->encoding); + return mb_strlen($this->str, $this->encoding); } /** @@ -756,7 +783,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function lines(): array { $array = $this->split('[\r\n]{1,2}', $this->str); - for ($i = 0; $i < count($array); $i++) + $arrayCount = count($array); + + for ($i = 0; $i < $arrayCount; $i++) { $array[$i] = static::create($array[$i], $this->encoding); } @@ -773,14 +802,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function longestCommonPrefix(string $otherStr): self { $encoding = $this->encoding; - $maxLength = min($this->length(), \mb_strlen($otherStr, $encoding)); + $maxLength = min($this->length(), mb_strlen($otherStr, $encoding)); $longestCommonPrefix = ''; + for ($i = 0; $i < $maxLength; $i++) { - $char = \mb_substr($this->str, $i, 1, $encoding); + $char = mb_substr($this->str, $i, 1, $encoding); - if ($char == \mb_substr($otherStr, $i, 1, $encoding)) + if ($char === mb_substr($otherStr, $i, 1, $encoding)) { $longestCommonPrefix .= $char; } else @@ -801,14 +831,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function longestCommonSuffix(string $otherStr): self { $encoding = $this->encoding; - $maxLength = min($this->length(), \mb_strlen($otherStr, $encoding)); + $maxLength = min($this->length(), mb_strlen($otherStr, $encoding)); $longestCommonSuffix = ''; + for ($i = 1; $i <= $maxLength; $i++) { - $char = \mb_substr($this->str, -$i, 1, $encoding); + $char = mb_substr($this->str, -$i, 1, $encoding); - if ($char == \mb_substr($otherStr, -$i, 1, $encoding)) + if ($char === mb_substr($otherStr, -$i, 1, $encoding)) { $longestCommonSuffix = $char . $longestCommonSuffix; } else @@ -834,28 +865,32 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $encoding = $this->encoding; $stringy = static::create($this->str, $encoding); $strLength = $stringy->length(); - $otherLength = \mb_strlen($otherStr, $encoding); + $otherLength = mb_strlen($otherStr, $encoding); // Return if either string is empty - if ($strLength == 0 || $otherLength == 0) + if ($strLength === 0 || $otherLength === 0) { $stringy->str = ''; + return $stringy; } $len = 0; $end = 0; - $table = array_fill(0, $strLength + 1, - array_fill(0, $otherLength + 1, 0)); + $table = array_fill( + 0, + $strLength + 1, + array_fill(0, $otherLength + 1, 0) + ); for ($i = 1; $i <= $strLength; $i++) { for ($j = 1; $j <= $otherLength; $j++) { - $strChar = \mb_substr($stringy->str, $i - 1, 1, $encoding); - $otherChar = \mb_substr($otherStr, $j - 1, 1, $encoding); + $strChar = mb_substr($stringy->str, $i - 1, 1, $encoding); + $otherChar = mb_substr($otherStr, $j - 1, 1, $encoding); - if ($strChar == $otherChar) + if ($strChar === $otherChar) { $table[$i][$j] = $table[$i - 1][$j - 1] + 1; if ($table[$i][$j] > $len) @@ -870,7 +905,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { } } - $stringy->str = \mb_substr($stringy->str, $end - $len, $len, $encoding); + $stringy->str = mb_substr($stringy->str, $end - $len, $len, $encoding); return $stringy; } @@ -882,11 +917,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function lowerCaseFirst(): self { - $first = \mb_substr($this->str, 0, 1, $this->encoding); - $rest = \mb_substr($this->str, 1, $this->length() - 1, - $this->encoding); + $first = mb_substr($this->str, 0, 1, $this->encoding); + $rest = mb_substr( + $this->str, + 1, + $this->length() - 1, + $this->encoding + ); - $str = \mb_strtolower($first, $this->encoding) . $rest; + $str = mb_strtolower($first, $this->encoding) . $rest; return static::create($str, $this->encoding); } @@ -897,7 +936,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * part of the ArrayAccess interface. * * @param mixed $offset The index to check - * @return boolean Whether or not the index exists + * @return bool Whether or not the index exists */ public function offsetExists(mixed $offset): bool { @@ -906,10 +945,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($offset >= 0) { - return ($length > $offset); + return $length > $offset; } - return ($length >= abs($offset)); + return $length >= abs($offset); } /** @@ -919,9 +958,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * does not exist. * * @param mixed $offset The index from which to retrieve the char - * @return string The character at the specified index - * @throws \OutOfBoundsException If the positive or negative offset does - * not exist + * @return string The character at the specified index + * @throws OutOfBoundsException If the positive or negative offset does + * not exist */ public function offsetGet(mixed $offset): string { @@ -933,7 +972,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { throw new OutOfBoundsException('No character exists at the index'); } - return \mb_substr($this->str, $offset, 1, $this->encoding); + return mb_substr($this->str, $offset, 1, $this->encoding); } /** @@ -942,7 +981,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param mixed $offset The index of the character * @param mixed $value Value to set - * @throws \Exception When called + * @throws Exception When called */ public function offsetSet(mixed $offset, mixed $value): void { @@ -955,7 +994,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * when called. This maintains the immutability of Stringy objects. * * @param mixed $offset The index of the character - * @throws \Exception When called + * @throws Exception When called */ public function offsetUnset(mixed $offset): void { @@ -979,7 +1018,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self { - if ( ! in_array($padType, ['left', 'right', 'both'])) + if ( ! in_array($padType, ['left', 'right', 'both'], TRUE)) { throw new InvalidArgumentException('Pad expects $padType ' . "to be one of 'left', 'right' or 'both'"); @@ -989,8 +1028,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { case 'left': return $this->padLeft($length, $padStr); + case 'right': return $this->padRight($length, $padStr); + default: return $this->padBoth($length, $padStr); } @@ -1008,8 +1049,11 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { $padding = $length - $this->length(); - return $this->applyPadding(floor($padding / 2), ceil($padding / 2), - $padStr); + return $this->applyPadding( + floor($padding / 2), + ceil($padding / 2), + $padStr + ); } /** @@ -1084,7 +1128,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($stringy->startsWith($substring)) { - $substringLength = \mb_strlen($substring, $stringy->encoding); + $substringLength = mb_strlen($substring, $stringy->encoding); + return $stringy->substr($substringLength); } @@ -1103,7 +1148,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($stringy->endsWith($substring)) { - $substringLength = \mb_strlen($substring, $stringy->encoding); + $substringLength = mb_strlen($substring, $stringy->encoding); + return $stringy->substr(0, $stringy->length() - $substringLength); } @@ -1148,7 +1194,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { // Loop from last index of string to first for ($i = $strLength - 1; $i >= 0; $i--) { - $reversed .= \mb_substr($this->str, $i, 1, $this->encoding); + $reversed .= mb_substr($this->str, $i, 1, $this->encoding); } return static::create($reversed, $this->encoding); @@ -1174,19 +1220,19 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { // Need to further trim the string so we can append the substring $encoding = $stringy->encoding; - $substringLength = \mb_strlen($substring, $encoding); + $substringLength = mb_strlen($substring, $encoding); $length = $length - $substringLength; - $truncated = \mb_substr($stringy->str, 0, $length, $encoding); + $truncated = mb_substr($stringy->str, 0, $length, $encoding); // If the last word was truncated - if (mb_strpos($stringy->str, ' ', $length - 1, $encoding) != $length) + if (mb_strpos($stringy->str, ' ', $length - 1, $encoding) !== $length) { // Find pos of the last occurrence of a space, get up to that - $lastPos = \mb_strrpos($truncated, ' ', 0, $encoding); + $lastPos = mb_strrpos($truncated, ' ', 0, $encoding); if ($lastPos !== FALSE) { - $truncated = \mb_substr($truncated, 0, $lastPos, $encoding); + $truncated = mb_substr($truncated, 0, $lastPos, $encoding); } } @@ -1195,7 +1241,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $stringy; } - /* + /** * A multibyte str_shuffle() function. It returns a string with its * characters in random order. * @@ -1207,9 +1253,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { shuffle($indexes); $shuffledStr = ''; + foreach ($indexes as $i) { - $shuffledStr .= \mb_substr($this->str, $i, 1, $this->encoding); + $shuffledStr .= mb_substr($this->str, $i, 1, $this->encoding); } return static::create($shuffledStr, $this->encoding); @@ -1233,7 +1280,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = str_replace('@', $replacement, $stringy); $quotedReplacement = preg_quote($replacement); - $pattern = "/[^a-zA-Z\d\s-_$quotedReplacement]/u"; + $pattern = "/[^a-zA-Z\\d\\s-_{$quotedReplacement}]/u"; $stringy->str = preg_replace($pattern, '', $stringy); return $stringy->toLowerCase()->delimit($replacement) @@ -1247,19 +1294,23 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $substring The substring to look for * @param bool $caseSensitive Whether or not to enforce - * case-sensitivity - * @return bool Whether or not $str starts with $substring + * case-sensitivity + * @return bool Whether or not $str starts with $substring */ public function startsWith(string $substring, bool $caseSensitive = TRUE): bool { - $substringLength = \mb_strlen($substring, $this->encoding); - $startOfStr = \mb_substr($this->str, 0, $substringLength, - $this->encoding); + $substringLength = mb_strlen($substring, $this->encoding); + $startOfStr = mb_substr( + $this->str, + 0, + $substringLength, + $this->encoding + ); if ( ! $caseSensitive) { - $substring = \mb_strtolower($substring, $this->encoding); - $startOfStr = \mb_strtolower($startOfStr, $this->encoding); + $substring = mb_strtolower($substring, $this->encoding); + $startOfStr = mb_strtolower($startOfStr, $this->encoding); } return (string)$substring === $startOfStr; @@ -1272,8 +1323,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string[] $substrings Substrings to look for * @param bool $caseSensitive Whether or not to enforce - * case-sensitivity - * @return bool Whether or not $str starts with $substring + * case-sensitivity + * @return bool Whether or not $str starts with $substring */ public function startsWithAny(array $substrings, bool $caseSensitive = TRUE): bool { @@ -1303,7 +1354,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * @param int $end Optional index at which to end extraction * @return static Object with its $str being the extracted substring */ - public function slice(int $start, int $end = NULL): self + public function slice(int $start, ?int $end = NULL): self { if ($end === NULL) { @@ -1331,7 +1382,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * @param int $limit Optional maximum number of results to return * @return static[] An array of Stringy objects */ - public function split(string $pattern, int $limit = NULL): array + public function split(string $pattern, ?int $limit = NULL): array { if ($limit === 0) { @@ -1350,7 +1401,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { // mb_split returns the remaining unsplit string in the last index when // supplying a limit - $limit = ($limit > 0) ? $limit += 1 : -1; + $limit = ($limit > 0) ? ++$limit : -1; static $functionExists; if ($functionExists === NULL) @@ -1360,10 +1411,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($functionExists) { - $array = \mb_split($pattern, $this->str, $limit); - } else if ($this->supportsEncoding()) + $array = mb_split($pattern, $this->str, $limit); + } elseif ($this->supportsEncoding()) { - $array = \preg_split("/$pattern/", $this->str, $limit); + $array = \preg_split("/{$pattern}/", $this->str, $limit); } $this->regexEncoding($regexEncoding); @@ -1372,8 +1423,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { array_pop($array); } + $arrayCount = count($array); - for ($i = 0; $i < count($array); $i++) + for ($i = 0; $i < $arrayCount; $i++) { $array[$i] = static::create($array[$i], $this->encoding); } @@ -1405,7 +1457,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function substr(int $start, ?int $length = NULL): self { $length = $length === NULL ? $this->length() : $length; - $str = \mb_substr($this->str, $start, $length, $this->encoding); + $str = mb_substr($this->str, $start, $length, $this->encoding); return static::create($str, $this->encoding); } @@ -1415,7 +1467,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $substring The substring to add to both sides * @return static Object whose $str had the substring both prepended and - * appended + * appended */ public function surround(string $substring): self { @@ -1436,13 +1488,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/[\S]/u', - function ($match) use ($encoding) { - if ($match[0] == \mb_strtoupper($match[0], $encoding)) + static function ($match) use ($encoding): string { + if ($match[0] === mb_strtoupper($match[0], $encoding)) { - return \mb_strtolower($match[0], $encoding); + return mb_strtolower($match[0], $encoding); } - return \mb_strtoupper($match[0], $encoding); + return mb_strtoupper($match[0], $encoding); }, $stringy->str ); @@ -1489,8 +1541,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/([\S]+)/u', - function ($match) use ($encoding, $ignore) { - if ($ignore && in_array($match[0], $ignore)) + static function ($match) use ($encoding, $ignore): string { + if ($ignore && in_array($match[0], $ignore, TRUE)) { return $match[0]; } @@ -1515,7 +1567,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $language Language of the source string * @param bool $removeUnsupported Whether or not to remove the - * unsupported characters + * unsupported characters * @return static Object whose $str contains only ASCII characters */ public function toAscii(string $language = 'en', bool $removeUnsupported = TRUE): self @@ -1563,15 +1615,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { 'false' => FALSE, '0' => FALSE, 'off' => FALSE, - 'no' => FALSE + 'no' => FALSE, ]; if (array_key_exists($key, $map)) { return $map[$key]; - } elseif (is_numeric($this->str)) + } + if (is_numeric($this->str)) { - return (intval($this->str) > 0); + return (int)($this->str) > 0; } return (bool)$this->regexReplace('[[:space:]]', '')->str; @@ -1585,7 +1638,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function toLowerCase(): self { - $str = \mb_strtolower($this->str, $this->encoding); + $str = mb_strtolower($this->str, $this->encoding); return static::create($str, $this->encoding); } @@ -1628,7 +1681,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function toTitleCase(): self { - $str = \mb_convert_case($this->str, \MB_CASE_TITLE, $this->encoding); + $str = mb_convert_case($this->str, MB_CASE_TITLE, $this->encoding); return static::create($str, $this->encoding); } @@ -1641,7 +1694,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function toUpperCase(): self { - $str = \mb_strtoupper($this->str, $this->encoding); + $str = mb_strtoupper($this->str, $this->encoding); return static::create($str, $this->encoding); } @@ -1658,7 +1711,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { $chars = ($chars) ? preg_quote($chars) : '[:space:]'; - return $this->regexReplace("^[$chars]+|[$chars]+\$", ''); + return $this->regexReplace("^[{$chars}]+|[{$chars}]+\$", ''); } /** @@ -1673,7 +1726,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { $chars = ($chars) ? preg_quote($chars) : '[:space:]'; - return $this->regexReplace("^[$chars]+", ''); + return $this->regexReplace("^[{$chars}]+", ''); } /** @@ -1688,7 +1741,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { $chars = ($chars) ? preg_quote($chars) : '[:space:]'; - return $this->regexReplace("[$chars]+\$", ''); + return $this->regexReplace("[{$chars}]+\$", ''); } /** @@ -1709,10 +1762,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { } // Need to further trim the string so we can append the substring - $substringLength = \mb_strlen($substring, $stringy->encoding); + $substringLength = mb_strlen($substring, $stringy->encoding); $length = $length - $substringLength; - $truncated = \mb_substr($stringy->str, 0, $length, $stringy->encoding); + $truncated = mb_substr($stringy->str, 0, $length, $stringy->encoding); $stringy->str = $truncated . $substring; return $stringy; @@ -1750,11 +1803,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function upperCaseFirst(): self { - $first = \mb_substr($this->str, 0, 1, $this->encoding); - $rest = \mb_substr($this->str, 1, $this->length() - 1, - $this->encoding); + $first = mb_substr($this->str, 0, 1, $this->encoding); + $rest = mb_substr( + $this->str, + 1, + $this->length() - 1, + $this->encoding + ); - $str = \mb_strtoupper($first, $this->encoding) . $rest; + $str = mb_strtoupper($first, $this->encoding) . $rest; return static::create($str, $this->encoding); } @@ -1767,7 +1824,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { protected function charsArray(): array { static $charsArray; - if (isset($charsArray)) return $charsArray; + if (isset($charsArray)) + { + return $charsArray; + } return $charsArray = [ '0' => ['°', '₀', '۰', '0'], @@ -1940,7 +2000,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * will simply return 'a'. * * @param string $language Language of the source string - * @return array An array of replacements. + * @return array An array of replacements. */ protected static function langSpecificCharsArray(string $language = 'en'): array { @@ -1960,17 +2020,11 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { ], 'bg' => [ ['х', 'Х', 'щ', 'Щ', 'ъ', 'Ъ', 'ь', 'Ь'], - ['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y'] - ] + ['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y'], + ], ]; - if (isset($languageSpecific[$language])) - { - $charsArray[$language] = $languageSpecific[$language]; - } else - { - $charsArray[$language] = []; - } + $charsArray[$language] = isset($languageSpecific[$language]) ? $languageSpecific[$language] : []; return $charsArray[$language]; } @@ -1987,7 +2041,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { protected function applyPadding(int $left = 0, int $right = 0, string $padStr = ' '): self { $stringy = static::create($this->str, $this->encoding); - $length = \mb_strlen($padStr, $stringy->encoding); + $length = mb_strlen($padStr, $stringy->encoding); $strLength = $stringy->length(); $paddedLength = $strLength + $left + $right; @@ -1997,10 +2051,18 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $stringy; } - $leftPadding = \mb_substr(str_repeat($padStr, ceil($left / $length)), 0, - $left, $stringy->encoding); - $rightPadding = \mb_substr(str_repeat($padStr, ceil($right / $length)), - 0, $right, $stringy->encoding); + $leftPadding = mb_substr( + str_repeat($padStr, ceil($left / $length)), + 0, + $left, + $stringy->encoding + ); + $rightPadding = mb_substr( + str_repeat($padStr, ceil($right / $length)), + 0, + $right, + $stringy->encoding + ); $stringy->str = $leftPadding . $stringy->str . $rightPadding; @@ -2011,14 +2073,14 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * Returns true if $str matches the supplied pattern, false otherwise. * * @param string $pattern Regex pattern to match against - * @return bool Whether or not $str matches the pattern + * @return bool Whether or not $str matches the pattern */ protected function matchesPattern(string $pattern): bool { $regexEncoding = $this->regexEncoding(); $this->regexEncoding($this->encoding); - $match = \mb_ereg_match($pattern, $this->str); + $match = mb_ereg_match($pattern, $this->str); $this->regexEncoding($regexEncoding); return $match; @@ -2038,11 +2100,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($functionExists) { - return \mb_ereg_replace($pattern, $replacement, $string, $option); - } else if ($this->supportsEncoding()) + return mb_ereg_replace($pattern, $replacement, $string, $option); + } + if ($this->supportsEncoding()) { $option = str_replace('r', '', (string)$option); - return \preg_replace("/$pattern/u$option", $replacement, $string); + + return \preg_replace("/{$pattern}/u{$option}", $replacement, $string); } } @@ -2062,7 +2126,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($functionExists) { $args = func_get_args(); - return call_user_func_array('\mb_regex_encoding', $args); + + return mb_regex_encoding(...$args); } } @@ -2073,11 +2138,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if (isset($supported[$this->encoding])) { return TRUE; - } else - { - throw new \RuntimeException('Stringy method requires the ' . - 'mbstring module for encodings other than ASCII and UTF-8. ' . - 'Encoding used: ' . $this->encoding); } + + throw new RuntimeException('Stringy method requires the ' . + 'mbstring module for encodings other than ASCII and UTF-8. ' . + 'Encoding used: ' . $this->encoding); } } diff --git a/src/Ion/View/HttpView.php b/src/Ion/View/HttpView.php index 36f57653..f02076eb 100644 --- a/src/Ion/View/HttpView.php +++ b/src/Ion/View/HttpView.php @@ -20,6 +20,7 @@ use InvalidArgumentException; use Laminas\Diactoros\Response; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; +use PHPUnit\Framework\Attributes\CodeCoverageIgnore; use Psr\Http\Message\ResponseInterface; use Stringable; @@ -168,10 +169,10 @@ class HttpView implements HttpViewInterface, Stringable /** * Send the appropriate response * - * @codeCoverageIgnore * @throws DoubleRenderException * @throws InvalidArgumentException */ + #[CodeCoverageIgnore] protected function output(): void { if ($this->hasRendered) diff --git a/tests/AnimeClient/API/Kitsu/Transformer/AnimeListTransformerTest.php b/tests/AnimeClient/API/Kitsu/Transformer/AnimeListTransformerTest.php index b54673b4..4b5e45e1 100644 --- a/tests/AnimeClient/API/Kitsu/Transformer/AnimeListTransformerTest.php +++ b/tests/AnimeClient/API/Kitsu/Transformer/AnimeListTransformerTest.php @@ -46,7 +46,7 @@ final class AnimeListTransformerTest extends AnimeClientTestCase $this->assertMatchesSnapshot($actual); } - public function dataUntransform(): array + public static function dataUntransform(): array { return [[ 'input' => [ @@ -87,12 +87,10 @@ final class AnimeListTransformerTest extends AnimeClientTestCase ]]; } - /** - * @dataProvider dataUntransform - */ - public function testUntransform(array $input): void - { - $actual = $this->transformer->untransform($input); - $this->assertMatchesSnapshot($actual); - } + #[\PHPUnit\Framework\Attributes\DataProvider('dataUntransform')] + public function testUntransform(array $input): void + { + $actual = $this->transformer->untransform($input); + $this->assertMatchesSnapshot($actual); + } } diff --git a/tests/AnimeClient/DispatcherTest.php b/tests/AnimeClient/DispatcherTest.php index cb5e9839..d3a02428 100644 --- a/tests/AnimeClient/DispatcherTest.php +++ b/tests/AnimeClient/DispatcherTest.php @@ -71,7 +71,7 @@ final class DispatcherTest extends AnimeClientTestCase $this->assertIsObject($this->router); } - public function dataRoute(): array + public static function dataRoute(): array { $defaultConfig = [ 'routes' => [ @@ -141,35 +141,32 @@ final class DispatcherTest extends AnimeClientTestCase return $data; } - /** - * @dataProvider dataRoute - * @param mixed $config - * @param mixed $controller - * @param mixed $host - * @param mixed $uri - */ - public function testRoute($config, $controller, $host, $uri): void - { - $this->doSetUp($config, $uri, $host); + /** + * @param mixed $config + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataRoute')] + public function testRoute($config, mixed $controller, mixed $host, mixed $uri): void + { + $this->doSetUp($config, $uri, $host); - $request = $this->container->get('request'); + $request = $this->container->get('request'); - // Check route setup - $this->assertSame($config['routes'], $this->config->get('routes'), 'Incorrect route path'); - $this->assertIsArray($this->router->getOutputRoutes()); + // Check route setup + $this->assertSame($config['routes'], $this->config->get('routes'), 'Incorrect route path'); + $this->assertIsArray($this->router->getOutputRoutes()); - // Check environment variables - $this->assertSame($uri, $request->getServerParams()['REQUEST_URI']); - $this->assertSame($host, $request->getServerParams()['HTTP_HOST']); + // Check environment variables + $this->assertSame($uri, $request->getServerParams()['REQUEST_URI']); + $this->assertSame($host, $request->getServerParams()['HTTP_HOST']); - // Make sure the route is an anime type - //$this->assertTrue($matcher->count() > 0, '0 routes'); - $this->assertSame($controller, $this->router->getController(), 'Incorrect Route type'); + // Make sure the route is an anime type + //$this->assertTrue($matcher->count() > 0, '0 routes'); + $this->assertSame($controller, $this->router->getController(), 'Incorrect Route type'); - // Make sure the route matches, by checking that it is actually an object - $route = $this->router->getRoute(); - $this->assertInstanceOf(Route::class, $route, 'Route is invalid, not matched'); - } + // Make sure the route matches, by checking that it is actually an object + $route = $this->router->getRoute(); + $this->assertInstanceOf(Route::class, $route, 'Route is invalid, not matched'); + } public function testDefaultRoute(): void { @@ -209,53 +206,51 @@ final class DispatcherTest extends AnimeClientTestCase } #[ArrayShape(['controller_list_sanity_check' => 'array', 'empty_controller_list' => 'array'])] - public function dataGetControllerList(): array - { - $expectedList = [ - 'anime' => Controller\Anime::class, - 'anime-collection' => Controller\AnimeCollection::class, - 'character' => Controller\Character::class, - 'misc' => Controller\Misc::class, - 'manga' => Controller\Manga::class, - 'people' => Controller\People::class, - 'settings' => Controller\Settings::class, - 'user' => Controller\User::class, - 'images' => Controller\Images::class, - 'history' => Controller\History::class, - ]; +public static function dataGetControllerList(): array +{ + $expectedList = [ + 'anime' => Controller\Anime::class, + 'anime-collection' => Controller\AnimeCollection::class, + 'character' => Controller\Character::class, + 'misc' => Controller\Misc::class, + 'manga' => Controller\Manga::class, + 'people' => Controller\People::class, + 'settings' => Controller\Settings::class, + 'user' => Controller\User::class, + 'images' => Controller\Images::class, + 'history' => Controller\History::class, + ]; - return [ - 'controller_list_sanity_check' => [ - 'config' => [ - 'anime_path' => 'anime', - 'manga_path' => 'manga', - 'default_anime_list_path' => 'watching', - 'default_manga_list_path' => 'all', - 'default_list' => 'manga', - 'routes' => [], - ], - 'expected' => $expectedList, + return [ + 'controller_list_sanity_check' => [ + 'config' => [ + 'anime_path' => 'anime', + 'manga_path' => 'manga', + 'default_anime_list_path' => 'watching', + 'default_manga_list_path' => 'all', + 'default_list' => 'manga', + 'routes' => [], ], - 'empty_controller_list' => [ - 'config' => [ - 'anime_path' => 'anime', - 'manga_path' => 'manga', - 'default_anime_path' => '/anime/watching', - 'default_manga_path' => '/manga/all', - 'default_list' => 'manga', - 'routes' => [], - ], - 'expected' => $expectedList, + 'expected' => $expectedList, + ], + 'empty_controller_list' => [ + 'config' => [ + 'anime_path' => 'anime', + 'manga_path' => 'manga', + 'default_anime_path' => '/anime/watching', + 'default_manga_path' => '/manga/all', + 'default_list' => 'manga', + 'routes' => [], ], - ]; - } - - /** - * @dataProvider dataGetControllerList - */ - public function testGetControllerList(array $config, array $expected): void - { - $this->doSetUp($config, '/', 'localhost'); - $this->assertEquals($expected, $this->router->getControllerList()); - } + 'expected' => $expectedList, + ], + ]; +} + + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetControllerList')] + public function testGetControllerList(array $config, array $expected): void + { + $this->doSetUp($config, '/', 'localhost'); + $this->assertEquals($expected, $this->router->getControllerList()); + } } diff --git a/tests/AnimeClient/Helper/PictureHelperTest.php b/tests/AnimeClient/Helper/PictureHelperTest.php index 39f5a427..e8f2ed24 100644 --- a/tests/AnimeClient/Helper/PictureHelperTest.php +++ b/tests/AnimeClient/Helper/PictureHelperTest.php @@ -22,9 +22,7 @@ use Aviat\AnimeClient\Tests\AnimeClientTestCase; */ final class PictureHelperTest extends AnimeClientTestCase { - /** - * @dataProvider dataPictureCase - */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataPictureCase')] public function testPictureHelper(array $params): void { $helper = new PictureHelper(); @@ -35,9 +33,7 @@ final class PictureHelperTest extends AnimeClientTestCase $this->assertMatchesSnapshot($actual); } - /** - * @dataProvider dataSimpleImageCase - */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataSimpleImageCase')] public function testSimpleImage(string $ext, bool $isSimple, string $fallbackExt = 'jpg'): void { $helper = new PictureHelper(); @@ -61,7 +57,7 @@ final class PictureHelperTest extends AnimeClientTestCase $this->assertTrue( ! str_contains($actual, ' [ @@ -119,7 +115,7 @@ final class PictureHelperTest extends AnimeClientTestCase ]; } - public function dataSimpleImageCase(): array + public static function dataSimpleImageCase(): array { return [ 'avif' => [ diff --git a/tests/AnimeClient/KitsuTest.php b/tests/AnimeClient/KitsuTest.php index ccc216c4..2cd88eeb 100644 --- a/tests/AnimeClient/KitsuTest.php +++ b/tests/AnimeClient/KitsuTest.php @@ -77,7 +77,7 @@ final class KitsuTest extends TestCase $this->assertSame(AnimeAiringStatus::AIRING, Kitsu::getAiringStatus('yesterday')); } - public function getPublishingStatus(): array + public static function getPublishingStatus(): array { return [ 'current' => [ @@ -91,16 +91,14 @@ final class KitsuTest extends TestCase ]; } - /** - * @dataProvider getPublishingStatus - */ - public function testGetPublishingStatus(string $kitsuStatus, string $expected): void - { - $actual = Kitsu::getPublishingStatus($kitsuStatus); - $this->assertSame($expected, $actual); - } + #[\PHPUnit\Framework\Attributes\DataProvider('getPublishingStatus')] + public function testGetPublishingStatus(string $kitsuStatus, string $expected): void + { + $actual = Kitsu::getPublishingStatus($kitsuStatus); + $this->assertSame($expected, $actual); + } - public function getFriendlyTime(): array + public static function getFriendlyTime(): array { $SECONDS_IN_DAY = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_DAY; $SECONDS_IN_HOUR = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_HOUR; @@ -121,15 +119,13 @@ final class KitsuTest extends TestCase ]]; } - /** - * @dataProvider getFriendlyTime - */ - public function testGetFriendlyTime(int $seconds, string $expected): void - { - $actual = Kitsu::friendlyTime($seconds); + #[\PHPUnit\Framework\Attributes\DataProvider('getFriendlyTime')] + public function testGetFriendlyTime(int $seconds, string $expected): void + { + $actual = Kitsu::friendlyTime($seconds); - $this->assertSame($expected, $actual); - } + $this->assertSame($expected, $actual); + } public function testFilterLocalizedTitles(): void { diff --git a/tests/AnimeClient/RoutingBaseTest.php b/tests/AnimeClient/RoutingBaseTest.php index 0cabf77a..2669330d 100644 --- a/tests/AnimeClient/RoutingBaseTest.php +++ b/tests/AnimeClient/RoutingBaseTest.php @@ -23,7 +23,7 @@ use JetBrains\PhpStorm\ArrayShape; final class RoutingBaseTest extends AnimeClientTestCase { #[ArrayShape(['empty_segment' => 'array', 'three_segments' => 'array'])] - public function dataSegments() + public static function dataSegments() { return [ 'empty_segment' => [ @@ -41,26 +41,24 @@ final class RoutingBaseTest extends AnimeClientTestCase ]; } - /** - * @dataProvider dataSegments - */ - public function testSegments(string $requestUri, string $path, array $segments, ?string $lastSegment): void - { - $this->setSuperGlobals([ - '_SERVER' => [ - 'REQUEST_URI' => $requestUri, - ], - ]); + #[\PHPUnit\Framework\Attributes\DataProvider('dataSegments')] + public function testSegments(string $requestUri, string $path, array $segments, ?string $lastSegment): void + { + $this->setSuperGlobals([ + '_SERVER' => [ + 'REQUEST_URI' => $requestUri, + ], + ]); - $routingBase = new RoutingBase($this->container); + $routingBase = new RoutingBase($this->container); - $this->assertSame($path, $routingBase->path(), 'Path is invalid'); - $this->assertSame($segments, $routingBase->segments(), 'Segments array is invalid'); - $this->assertEquals($lastSegment, $routingBase->lastSegment(), 'Last segment is invalid'); + $this->assertSame($path, $routingBase->path(), 'Path is invalid'); + $this->assertSame($segments, $routingBase->segments(), 'Segments array is invalid'); + $this->assertEquals($lastSegment, $routingBase->lastSegment(), 'Last segment is invalid'); - foreach ($segments as $i => $value) - { - $this->assertEquals($value, $routingBase->getSegment($i), "Segment {$i} is invalid"); - } - } + foreach ($segments as $i => $value) + { + $this->assertEquals($value, $routingBase->getSegment($i), "Segment {$i} is invalid"); + } + } } diff --git a/tests/AnimeClient/UrlGeneratorTest.php b/tests/AnimeClient/UrlGeneratorTest.php index 6e3d9fe2..715b2e7a 100644 --- a/tests/AnimeClient/UrlGeneratorTest.php +++ b/tests/AnimeClient/UrlGeneratorTest.php @@ -16,13 +16,14 @@ namespace Aviat\AnimeClient\Tests; use Aviat\AnimeClient\UrlGenerator; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; /** * @internal */ final class UrlGeneratorTest extends AnimeClientTestCase { - public function assetUrlProvider() + public static function assetUrlProvider(): array { return [ 'single argument' => [ @@ -40,12 +41,8 @@ final class UrlGeneratorTest extends AnimeClientTestCase ]; } - /** - * @dataProvider assetUrlProvider - * @param mixed $args - * @param mixed $expected - */ - public function testAssetUrl($args, $expected) + #[DataProvider('assetUrlProvider')] + public function testAssetUrl(mixed $args, string $expected): void { $urlGenerator = new UrlGenerator($this->container); diff --git a/tests/AnimeClient/UtilTest.php b/tests/AnimeClient/UtilTest.php index 8aca3700..8b4c1658 100644 --- a/tests/AnimeClient/UtilTest.php +++ b/tests/AnimeClient/UtilTest.php @@ -47,7 +47,7 @@ final class UtilTest extends AnimeClientTestCase $this->assertSame('', Util::isNotSelected('foo', 'foo')); } - public function dataIsViewPage() + public static function dataIsViewPage() { return [ [ @@ -69,35 +69,34 @@ final class UtilTest extends AnimeClientTestCase ]; } - /** - * @dataProvider dataIsViewPage - * @param mixed $uri - * @param mixed $expected - */ - public function testIsViewPage($uri, $expected) - { - $this->setSuperGlobals([ - '_SERVER' => [ - 'REQUEST_URI' => $uri, - ], - ]); - $this->assertSame($expected, $this->util->isViewPage()); - } + /** + * @param mixed $uri + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataIsViewPage')] + public function testIsViewPage($uri, mixed $expected) + { + $this->setSuperGlobals([ + '_SERVER' => [ + 'REQUEST_URI' => $uri, + ], + ]); + $this->assertSame($expected, $this->util->isViewPage()); + } - /** - * @dataProvider dataIsViewPage - * @param mixed $uri - * @param mixed $expected - */ - public function testIsFormPage($uri, $expected) - { - $this->setSuperGlobals([ - '_SERVER' => [ - 'REQUEST_URI' => $uri, - ], - ]); - $this->assertSame( ! $expected, $this->util->isFormPage()); - } + /** + * @param mixed $uri + * @param mixed $expected + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataIsViewPage')] + public function testIsFormPage($uri, $expected) + { + $this->setSuperGlobals([ + '_SERVER' => [ + 'REQUEST_URI' => $uri, + ], + ]); + $this->assertSame( ! $expected, $this->util->isFormPage()); + } public function testAriaCurrent(): void { diff --git a/tests/Ion/ConfigTest.php b/tests/Ion/ConfigTest.php index 203bb1b1..6bc26181 100644 --- a/tests/Ion/ConfigTest.php +++ b/tests/Ion/ConfigTest.php @@ -15,6 +15,7 @@ namespace Aviat\Ion\Tests; use Aviat\Ion\Config; +use PHPUnit\Framework\Attributes\DataProvider; /** * @internal @@ -67,7 +68,7 @@ final class ConfigTest extends IonTestCase $this->assertSame('great', $this->config->get(['apple', 'sauce', 'is']), 'Array argument get for config failed.'); } - public function dataConfigDelete(): array + public static function dataConfigDelete(): array { return [ 'top level delete' => [ @@ -124,11 +125,8 @@ final class ConfigTest extends IonTestCase ]; } - /** - * @dataProvider dataConfigDelete - * @param mixed $key - */ - public function testConfigDelete($key, array $assertKeys): void + #[DataProvider('dataConfigDelete')] + public function testConfigDelete(string|array $key, array $assertKeys): void { $config = new Config([]); $config->set(['apple', 'sauce', 'is'], 'great'); diff --git a/tests/Ion/Di/ContainerTest.php b/tests/Ion/Di/ContainerTest.php index d90d1aaf..2ae8130e 100644 --- a/tests/Ion/Di/ContainerTest.php +++ b/tests/Ion/Di/ContainerTest.php @@ -20,6 +20,7 @@ use Aviat\Ion\Di\{Container, ContainerAware}; use Aviat\Ion\Tests\IonTestCase; use Monolog\Handler\{NullHandler, TestHandler}; use Monolog\Logger; +use PHPUnit\Framework\Attributes\DataProvider; use Throwable; use TypeError; @@ -51,7 +52,7 @@ final class ContainerTest extends IonTestCase $this->container = new Container(); } - public function dataGetWithException(): array + public static function dataGetWithException(): array { return [ 'Bad index type: number' => [ @@ -71,9 +72,9 @@ final class ContainerTest extends IonTestCase } /** - * @dataProvider dataGetWithException * @param mixed $exception */ + #[DataProvider('dataGetWithException')] public function testGetWithException(mixed $id, $exception, ?string $message = NULL): void { try @@ -92,9 +93,9 @@ final class ContainerTest extends IonTestCase } /** - * @dataProvider dataGetWithException * @param mixed $exception */ + #[DataProvider('dataGetWithException')] public function testGetNewWithException(mixed $id, $exception, ?string $message = NULL): void { $this->expectException($exception); @@ -106,7 +107,7 @@ final class ContainerTest extends IonTestCase $this->container->getNew($id); } - public function dataSetInstanceWithException(): array + public static function dataSetInstanceWithException(): array { return [ 'Non-existent id' => [ @@ -123,11 +124,11 @@ final class ContainerTest extends IonTestCase } /** - * @dataProvider dataSetInstanceWithException * @param mixed $id * @param mixed $exception * @param mixed $message */ + #[DataProvider('dataSetInstanceWithException')] public function testSetInstanceWithException($id, $exception, $message): void { try diff --git a/tests/Ion/EnumTest.php b/tests/Ion/EnumTest.php index 382bd820..f5d9a5bf 100644 --- a/tests/Ion/EnumTest.php +++ b/tests/Ion/EnumTest.php @@ -19,6 +19,7 @@ namespace Aviat\Ion\Tests; */ final class EnumTest extends IonTestCase { + public $enum; protected $expectedConstList = [ 'FOO' => 'bar', 'BAR' => 'foo', @@ -43,7 +44,7 @@ final class EnumTest extends IonTestCase $this->assertSame($this->expectedConstList, $actual); } - public function dataIsValid() + public static function dataIsValid() { return [ 'Valid' => [ @@ -69,18 +70,17 @@ final class EnumTest extends IonTestCase ]; } - /** - * @dataProvider dataIsValid - * @param mixed $value - * @param mixed $expected - * @param mixed $static - */ - public function testIsValid($value, $expected, $static) - { - $actual = ($static) - ? TestEnum::isValid($value) - : $this->enum->isValid($value); + /** + * @param mixed $value + * @param mixed $static + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataIsValid')] + public function testIsValid($value, mixed $expected, $static) + { + $actual = ($static) + ? TestEnum::isValid($value) + : $this->enum->isValid($value); - $this->assertSame($expected, $actual); - } + $this->assertSame($expected, $actual); + } } diff --git a/tests/Ion/JsonTest.php b/tests/Ion/JsonTest.php index 48a14037..d58e24a8 100644 --- a/tests/Ion/JsonTest.php +++ b/tests/Ion/JsonTest.php @@ -32,7 +32,7 @@ final class JsonTest extends IonTestCase $this->assertSame($expected, Json::encode($data)); } - public function dataEncodeDecode(): array + public static function dataEncodeDecode(): array { return [ 'set1' => [ @@ -47,24 +47,22 @@ final class JsonTest extends IonTestCase ]; } - /** - * @dataProvider dataEncodeDecode - */ - public function testEncodeDecodeFile(array $data, int $expected_size, string $expected_json): void - { - $target_file = _dir(self::TEST_DATA_DIR, 'json_write.json'); + #[\PHPUnit\Framework\Attributes\DataProvider('dataEncodeDecode')] + public function testEncodeDecodeFile(array $data, int $expected_size, string $expected_json): void + { + $target_file = _dir(self::TEST_DATA_DIR, 'json_write.json'); - $actual_size = Json::encodeFile($target_file, $data); - $actual_json = file_get_contents($target_file); + $actual_size = Json::encodeFile($target_file, $data); + $actual_json = file_get_contents($target_file); - $this->assertTrue(Json::isJson($actual_json)); - $this->assertSame($expected_size, $actual_size); - $this->assertSame($expected_json, $actual_json); + $this->assertTrue(Json::isJson($actual_json)); + $this->assertSame($expected_size, $actual_size); + $this->assertSame($expected_json, $actual_json); - $this->assertEquals($data, Json::decodeFile($target_file)); + $this->assertEquals($data, Json::decodeFile($target_file)); - unlink($target_file); - } + unlink($target_file); + } public function testDecode() { diff --git a/tests/Ion/Transformer/AbstractTransformerTest.php b/tests/Ion/Transformer/AbstractTransformerTest.php index bb185151..bca18325 100644 --- a/tests/Ion/Transformer/AbstractTransformerTest.php +++ b/tests/Ion/Transformer/AbstractTransformerTest.php @@ -32,7 +32,7 @@ final class AbstractTransformerTest extends IonTestCase $this->untransformer = new TestTransformerUntransform(); } - public function dataTransformCollection() + public static function dataTransformCollection() { return [ 'object' => [ @@ -90,7 +90,7 @@ final class AbstractTransformerTest extends IonTestCase ]; } - public function dataUnTransformCollection() + public static function dataUnTransformCollection() { return [ 'object' => [ @@ -130,36 +130,34 @@ final class AbstractTransformerTest extends IonTestCase $this->assertSame($expected, $actual); } - /** - * @dataProvider dataTransformCollection - * @param mixed $original - * @param mixed $expected - */ - public function testTransformCollection($original, $expected) - { - $actual = $this->transformer->transformCollection($original); - $this->assertSame($expected, $actual); - } + /** + * @param mixed $original + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataTransformCollection')] + public function testTransformCollection($original, mixed $expected) + { + $actual = $this->transformer->transformCollection($original); + $this->assertSame($expected, $actual); + } - /** - * @dataProvider dataUnTransformCollection - * @param mixed $original - * @param mixed $expected - */ - public function testUntransformCollection($original, $expected) - { - $actual = $this->untransformer->untransformCollection($original); - $this->assertSame($expected, $actual); - } + /** + * @param mixed $original + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataUnTransformCollection')] + public function testUntransformCollection($original, mixed $expected) + { + $actual = $this->untransformer->untransformCollection($original); + $this->assertSame($expected, $actual); + } - /** - * @dataProvider dataUnTransformCollection - * @param mixed $original - * @param mixed $expected - */ - public function testUntransformCollectionWithException($original, $expected) - { - $this->expectException(BadMethodCallException::class); - $this->transformer->untransformCollection($original); - } + /** + * @param mixed $original + * @param mixed $expected + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataUnTransformCollection')] + public function testUntransformCollectionWithException($original, $expected) + { + $this->expectException(BadMethodCallException::class); + $this->transformer->untransformCollection($original); + } } diff --git a/tests/Ion/Type/ArrayTypeTest.php b/tests/Ion/Type/ArrayTypeTest.php index b67a8667..027eb711 100644 --- a/tests/Ion/Type/ArrayTypeTest.php +++ b/tests/Ion/Type/ArrayTypeTest.php @@ -22,7 +22,7 @@ use Aviat\Ion\Type\ArrayType; */ final class ArrayTypeTest extends IonTestCase { - public function dataCall() + public static function dataCall() { $method_map = [ 'chunk' => 'array_chunk', @@ -80,18 +80,16 @@ final class ArrayTypeTest extends IonTestCase ]; } - /** - * Test the array methods defined for the __Call method - * - * @dataProvider dataCall - * @param $expected - */ - public function testCall(string $method, array $array, array $args, $expected): void - { - $obj = ArrayType::from($array); - $actual = $obj->__call($method, $args); - $this->assertSame($expected, $actual); - } + /** + * Test the array methods defined for the __Call method + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataCall')] + public function testCall(string $method, array $array, array $args, mixed $expected): void + { + $obj = ArrayType::from($array); + $actual = $obj->__call($method, $args); + $this->assertSame($expected, $actual); + } public function testSet(): void { diff --git a/tests/Ion/Type/StringTypeTest.php b/tests/Ion/Type/StringTypeTest.php index 869bca1f..8535e342 100644 --- a/tests/Ion/Type/StringTypeTest.php +++ b/tests/Ion/Type/StringTypeTest.php @@ -16,13 +16,14 @@ namespace Aviat\Ion\Tests\Type; use Aviat\Ion\Tests\IonTestCase; use Aviat\Ion\Type\StringType; +use PHPUnit\Framework\Attributes\DataProvider; /** * @internal */ final class StringTypeTest extends IonTestCase { - public function dataFuzzyCaseMatch(): array + public static function dataFuzzyCaseMatch(): array { return [ 'space separated' => [ @@ -53,9 +54,7 @@ final class StringTypeTest extends IonTestCase ]; } - /** - * @dataProvider dataFuzzyCaseMatch - */ + #[DataProvider('dataFuzzyCaseMatch')] public function testFuzzyCaseMatch(string $str1, string $str2, bool $expected): void { $actual = StringType::from($str1)->fuzzyCaseMatch($str2); diff --git a/tools/composer.json b/tools/composer.json index 3e6d249f..d1d3c047 100644 --- a/tools/composer.json +++ b/tools/composer.json @@ -1,6 +1,6 @@ { "require": { "friendsofphp/php-cs-fixer": "^3.6", - "rector/rector": "^0.12.16" + "rector/rector": "^0.15.21" } } diff --git a/tools/header_comment.txt b/tools/header_comment.txt index b6560506..5e445e2b 100644 --- a/tools/header_comment.txt +++ b/tools/header_comment.txt @@ -3,11 +3,11 @@ * * An API client for Kitsu to manage anime and manga watch lists * - * PHP version 8 + * PHP version 8.1 * - * @copyright 2015 - 2022 Timothy J. Warren + * @copyright 2015 - 2023 Timothy J. Warren * @license http://www.opensource.org/licenses/mit-license.html MIT License * @version 5.2 - * @link https://git.timshome.page/timw4mail/HummingBirdAnimeClient + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient */ diff --git a/tools/offline-db-update.php b/tools/offline-db-update.php new file mode 100644 index 00000000..e69de29b diff --git a/tools/rector.php b/tools/rector.php index 23483ee0..e7bf177b 100644 --- a/tools/rector.php +++ b/tools/rector.php @@ -1,65 +1,54 @@ importNames(); + $config->importShortClasses(false); -return static function (ContainerConfigurator $config): void { - $parameters = $config->parameters(); - $parameters->set(Option::AUTO_IMPORT_NAMES, FALSE); - $parameters->set(Option::IMPORT_SHORT_CLASSES, FALSE); - $parameters->set(Option::SKIP, [ - ReadOnlyPropertyRector::class, - RestoreDefaultNullToNullableTypePropertyRector::class, + $config->sets([ + LevelSetList::UP_TO_PHP_81, + PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES, + PHPUnitSetList::PHPUNIT_100, ]); - walk_array([$config, 'import'], [ - LevelSetList::UP_TO_PHP_80, - ]); - - $services = $config->services(); - walk_array([$services, 'set'], [ + $config->rules([ AddArrayDefaultToArrayPropertyRector::class, - AddArrayParamDocTypeRector::class, - AddArrayReturnDocTypeRector::class, AddClosureReturnTypeRector::class, AddMethodCallBasedStrictParamTypeRector::class, CallUserFuncArrayToVariadicRector::class, CallUserFuncToMethodCallRector::class, + CountArrayToEmptyArrayComparisonRector::class, ChangeIfElseValueAssignToEarlyReturnRector::class, ChangeNestedForeachIfsToEarlyContinueRector::class, CompleteDynamicPropertiesRector::class, @@ -67,7 +56,6 @@ return static function (ContainerConfigurator $config): void { CountArrayToEmptyArrayComparisonRector::class, ForRepeatedCountToOwnVariableRector::class, ForToForeachRector::class, - // MakeTypedPropertyNullableIfCheckedRector::class, // NewlineAfterStatementRector::class, NewlineBeforeNewAssignSetRector::class, ParamTypeByMethodCallTypeRector::class, @@ -79,13 +67,23 @@ return static function (ContainerConfigurator $config): void { RemoveUselessParamTagRector::class, RemoveUselessReturnTagRector::class, RemoveUselessVarTagRector::class, - // SimplifyDeMorganBinaryRector::class, - SimplifyDuplicatedTernaryRector::class, SimplifyIfElseToTernaryRector::class, SimplifyIfReturnBoolRector::class, SimplifyTautologyTernaryRector::class, + SymplifyQuoteEscapeRector::class, + StaticArrowFunctionRector::class, SwitchNegatedTernaryRector::class, TypedPropertyFromAssignsRector::class, + VersionCompareFuncCallToConstantRector::class, WrapEncapsedVariableInCurlyBracesRector::class, ]); + + $config->ruleWithConfiguration(OrderAttributesRector::class, [ + 'alphabetically', + ]); + + $config->skip([ + ReadOnlyPropertyRector::class, + RestoreDefaultNullToNullableTypePropertyRector::class, + ]); }; diff --git a/tools/update_header_comments.php b/tools/update_header_comments.php index 4850413c..72f5ca6b 100644 --- a/tools/update_header_comments.php +++ b/tools/update_header_comments.php @@ -39,7 +39,7 @@ function get_text_to_replace(array $tokens): string // [0] => token type constant // [1] => raw syntax parsed to that token // [2] => line number - foreach($tokens as $token) + foreach ($tokens as $token) { // Since we only care about opening docblocks, // bail out when we get to the namespace token @@ -81,9 +81,9 @@ function replace_file(string $file, string $template): void $files = array_filter( glob_recursive('*.php'), - fn (string $file) => ! (str_contains($file, '/vendor/') || str_contains($file, '/tmp/')) + static fn (string $file) => ! (str_contains($file, '/vendor/') || str_contains($file, '/tmp/')) ); -array_walk($files, fn (string $file) => replace_file($file, '/header_comment.txt')); +array_walk($files, static fn (string $file) => replace_file($file, '/header_comment.txt')); echo json_encode(array_values($files), JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . "\n"; printf("Successfully updated header comments in %d files\n", count($files));