diff --git a/VERSION b/VERSION index 83e07c1..1a757d2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2410.211811 +0.2410.630130 diff --git a/composer.json b/composer.json index 53212e3..93bd922 100644 --- a/composer.json +++ b/composer.json @@ -11,8 +11,8 @@ "twig/html-extra": "^3.13" }, "require-dev": { - "phpunit/phpunit": "^11.2", - "phpstan/phpstan": "^1.11" + "phpunit/phpunit": "^11.4", + "phpstan/phpstan": "^2.0" }, "suggest": { "ext-memcache": "Support for the Index\\Cache\\Memcached namespace (only if you can't use ext-memcached for some reason).", diff --git a/composer.lock b/composer.lock index c5ccd3a..17f8eab 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e79de830674f6cbf86bf7874b086c7e0", + "content-hash": "a08a0c9bbd0fcba5c7e578f098486b06", "packages": [ { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -55,7 +55,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -71,20 +71,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/mime", - "version": "v7.1.5", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff" + "reference": "cc84a4b81f62158c3846ac7ff10f696aae2b524d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/711d2e167e8ce65b05aea6b258c449671cdd38ff", - "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff", + "url": "https://api.github.com/repos/symfony/mime/zipball/cc84a4b81f62158c3846ac7ff10f696aae2b524d", + "reference": "cc84a4b81f62158c3846ac7ff10f696aae2b524d", "shasum": "" }, "require": { @@ -139,7 +139,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.5" + "source": "https://github.com/symfony/mime/tree/v7.2.0" }, "funding": [ { @@ -155,7 +155,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-11-23T09:19:39+00:00" }, { "name": "symfony/polyfill-ctype", @@ -558,16 +558,16 @@ }, { "name": "twig/html-extra", - "version": "v3.13.0", + "version": "v3.16.0", "source": { "type": "git", "url": "https://github.com/twigphp/html-extra.git", - "reference": "8229e750091171c1f11801a525927811c7ac5a7e" + "reference": "2086023d3ffc4bae2b1115f715d17f97fd013665" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/html-extra/zipball/8229e750091171c1f11801a525927811c7ac5a7e", - "reference": "8229e750091171c1f11801a525927811c7ac5a7e", + "url": "https://api.github.com/repos/twigphp/html-extra/zipball/2086023d3ffc4bae2b1115f715d17f97fd013665", + "reference": "2086023d3ffc4bae2b1115f715d17f97fd013665", "shasum": "" }, "require": { @@ -610,7 +610,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/html-extra/tree/v3.13.0" + "source": "https://github.com/twigphp/html-extra/tree/v3.16.0" }, "funding": [ { @@ -622,20 +622,20 @@ "type": "tidelift" } ], - "time": "2024-09-03T13:08:40+00:00" + "time": "2024-09-30T06:41:48+00:00" }, { "name": "twig/twig", - "version": "v3.14.0", + "version": "v3.16.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72" + "reference": "475ad2dc97d65d8631393e721e7e44fb544f0561" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/126b2c97818dbff0cdf3fbfc881aedb3d40aae72", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/475ad2dc97d65d8631393e721e7e44fb544f0561", + "reference": "475ad2dc97d65d8631393e721e7e44fb544f0561", "shasum": "" }, "require": { @@ -646,6 +646,7 @@ "symfony/polyfill-php81": "^1.29" }, "require-dev": { + "phpstan/phpstan": "^2.0", "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, @@ -689,7 +690,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.14.0" + "source": "https://github.com/twigphp/Twig/tree/v3.16.0" }, "funding": [ { @@ -701,22 +702,22 @@ "type": "tidelift" } ], - "time": "2024-09-09T17:55:12+00:00" + "time": "2024-11-29T08:27:05+00:00" } ], "packages-dev": [ { "name": "myclabs/deep-copy", - "version": "1.12.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -755,7 +756,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -763,7 +764,7 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "nikic/php-parser", @@ -943,20 +944,20 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.7", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0" + "reference": "46b4d3529b12178112d9008337beda0cc2a1a6b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", - "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/46b4d3529b12178112d9008337beda0cc2a1a6b4", + "reference": "46b4d3529b12178112d9008337beda0cc2a1a6b4", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -997,7 +998,7 @@ "type": "github" } ], - "time": "2024-10-18T11:12:07+00:00" + "time": "2024-11-28T22:19:37+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1324,16 +1325,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.4.2", + "version": "11.4.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1863643c3f04ad03dcb9c6996c294784cdda4805" + "reference": "f9ba7bd3c9f3ff54ec379d7a1c2e3f13fe0bbde4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1863643c3f04ad03dcb9c6996c294784cdda4805", - "reference": "1863643c3f04ad03dcb9c6996c294784cdda4805", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f9ba7bd3c9f3ff54ec379d7a1c2e3f13fe0bbde4", + "reference": "f9ba7bd3c9f3ff54ec379d7a1c2e3f13fe0bbde4", "shasum": "" }, "require": { @@ -1343,7 +1344,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", + "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.2", @@ -1354,7 +1355,7 @@ "phpunit/php-timer": "^7.0.1", "sebastian/cli-parser": "^3.0.2", "sebastian/code-unit": "^3.0.1", - "sebastian/comparator": "^6.1.1", + "sebastian/comparator": "^6.2.1", "sebastian/diff": "^6.0.2", "sebastian/environment": "^7.2.0", "sebastian/exporter": "^6.1.3", @@ -1404,7 +1405,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.2" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.4" }, "funding": [ { @@ -1420,7 +1421,7 @@ "type": "tidelift" } ], - "time": "2024-10-19T13:05:19+00:00" + "time": "2024-11-27T10:44:52+00:00" }, { "name": "sebastian/cli-parser", @@ -1594,16 +1595,16 @@ }, { "name": "sebastian/comparator", - "version": "6.1.1", + "version": "6.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5ef523a49ae7a302b87b2102b72b1eda8918d686" + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5ef523a49ae7a302b87b2102b72b1eda8918d686", - "reference": "5ef523a49ae7a302b87b2102b72b1eda8918d686", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739", "shasum": "" }, "require": { @@ -1614,12 +1615,12 @@ "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.3" + "phpunit/phpunit": "^11.4" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "6.2-dev" } }, "autoload": { @@ -1659,7 +1660,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.1.1" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.2.1" }, "funding": [ { @@ -1667,7 +1668,7 @@ "type": "github" } ], - "time": "2024-10-18T15:00:48+00:00" + "time": "2024-10-31T05:30:08+00:00" }, { "name": "sebastian/complexity", @@ -2398,13 +2399,13 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=8.3", "ext-mbstring": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/phpstan.neon b/phpstan.neon index 39c5d92..f334b99 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,5 +3,7 @@ parameters: checkUninitializedProperties: true checkImplicitMixed: true checkBenevolentUnionTypes: true + treatPhpDocTypesAsCertain: false paths: - src + - tests diff --git a/src/Cache/ArrayCache/ArrayCacheProvider.php b/src/Cache/ArrayCache/ArrayCacheProvider.php index 2e7f826..98eb825 100644 --- a/src/Cache/ArrayCache/ArrayCacheProvider.php +++ b/src/Cache/ArrayCache/ArrayCacheProvider.php @@ -1,7 +1,7 @@ <?php // ArrayCacheProvider.php // Created: 2024-04-10 -// Updated: 2024-10-19 +// Updated: 2024-12-02 namespace Index\Cache\ArrayCache; @@ -54,6 +54,8 @@ class ArrayCacheProvider implements CacheProvider { public function increment(string $key, int $amount = 1): int { $exists = array_key_exists($key, $this->items); $value = $exists ? unserialize($this->items[$key]['value']) : 0; + if(!is_int($value)) + $value = 0; $value += $amount; $serialised = serialize($value); @@ -65,9 +67,6 @@ class ArrayCacheProvider implements CacheProvider { 'ttl' => 0, ]; - if(is_float($value)) - $value = (int)$value; - return $value; } diff --git a/src/Cache/Memcached/MemcachedProviderLegacy.php b/src/Cache/Memcached/MemcachedProviderLegacy.php index ac66dde..7de461f 100644 --- a/src/Cache/Memcached/MemcachedProviderLegacy.php +++ b/src/Cache/Memcached/MemcachedProviderLegacy.php @@ -1,7 +1,7 @@ <?php // MemcachedProviderLegacy.php // Created: 2024-04-10 -// Updated: 2024-10-19 +// Updated: 2024-12-02 namespace Index\Cache\Memcached; @@ -72,7 +72,7 @@ class MemcachedProviderLegacy extends MemcachedProvider { public function increment(string $key, int $amount = 1): int { $key = $this->prefix . $key; $result = $this->memcache->increment($key, $amount); - if($result === false) { // @phpstan-ignore-line: PHP documentation states increment returns int|false + if($result === false) { $result = $amount; $this->memcache->set($key, serialize($result), 0); } @@ -83,7 +83,7 @@ class MemcachedProviderLegacy extends MemcachedProvider { public function decrement(string $key, int $amount = 1): int { $key = $this->prefix . $key; $result = $this->memcache->decrement($key, $amount); - if($result === false) { // @phpstan-ignore-line: PHP documentation states decrement returns int|false + if($result === false) { $result = $amount * -1; $this->memcache->set($key, serialize($result), 0); } diff --git a/src/Config/Config.php b/src/Config/Config.php index d6874eb..4ae9d15 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -1,7 +1,7 @@ <?php // Config.php // Created: 2023-10-20 -// Updated: 2024-10-04 +// Updated: 2024-12-02 namespace Index\Config; @@ -90,7 +90,7 @@ interface Config { * :f - float * :d - float * - * @param array<string|string[]> $specs Specification of what items to grab. + * @param array<string|array{0: string, 1?: mixed, 2?: string}> $specs Specification of what items to grab. * @throws InvalidArgumentException If $specs is malformed. * @return array<string, mixed> An associative array containing the retrieved values. */ diff --git a/src/Config/GetValuesTrait.php b/src/Config/GetValuesTrait.php index 23937dd..07575b4 100644 --- a/src/Config/GetValuesTrait.php +++ b/src/Config/GetValuesTrait.php @@ -1,7 +1,7 @@ <?php // GetValuesTrait.php // Created: 2023-10-20 -// Updated: 2024-10-04 +// Updated: 2024-12-02 namespace Index\Config; @@ -14,7 +14,7 @@ trait GetValuesTrait { /** * Format described in {@see Config::getValues}. * - * @param array<string|string[]> $specs + * @param array<string|array{0: string, 1?: mixed, 2?: string}> $specs Specification of what items to grab. * @throws InvalidArgumentException If $specs contains an invalid entry. * @return array<string, mixed> */ diff --git a/src/Db/MariaDb/MariaDbStatement.php b/src/Db/MariaDb/MariaDbStatement.php index 4b9d644..52c397b 100644 --- a/src/Db/MariaDb/MariaDbStatement.php +++ b/src/Db/MariaDb/MariaDbStatement.php @@ -1,7 +1,7 @@ <?php // MariaDbStatement.php // Created: 2021-05-02 -// Updated: 2024-10-19 +// Updated: 2024-12-02 namespace Index\Db\MariaDb; @@ -120,10 +120,11 @@ class MariaDbStatement implements DbStatement { } public function execute(): int|string { - $args = ['']; + $types = ''; + $args = [null]; foreach($this->params as $key => $param) { - $args[0] .= $param->getBindType(); + $types .= $param->getBindType(); $type = $param->getDbType(); $value = $param->getValue(); @@ -144,8 +145,10 @@ class MariaDbStatement implements DbStatement { $args[] = &${"value{$key}"}; } - if(!empty($args[0])) + if(!empty($types)) { + $args[0] = $types; call_user_func_array([$this->statement, 'bind_param'], $args); + } if(!$this->statement->execute()) throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode()); diff --git a/src/Db/Sqlite/SqliteMariaDbPolyfill.php b/src/Db/Sqlite/SqliteMariaDbPolyfill.php index d5e2cd5..c16dc4f 100644 --- a/src/Db/Sqlite/SqliteMariaDbPolyfill.php +++ b/src/Db/Sqlite/SqliteMariaDbPolyfill.php @@ -1,7 +1,7 @@ <?php // SqliteMariaDbPolyfill.php // Created: 2024-10-21 -// Updated: 2024-10-21 +// Updated: 2024-12-02 namespace Index\Db\Sqlite; @@ -210,13 +210,13 @@ final class SqliteMariaDbPolyfill { * * @see https://mariadb.com/kb/en/unhex/ * @param mixed $str Hex string. - * @return mixed Binary value. + * @return ?string Binary value. */ public static function mdbUnhex(mixed $str): ?string { if(!is_scalar($str)) return null; - $str = hex2bin($str); + $str = hex2bin((string)$str); if($str === false) return ''; diff --git a/src/Http/HttpMessageBuilder.php b/src/Http/HttpMessageBuilder.php index b3d0e75..85be622 100644 --- a/src/Http/HttpMessageBuilder.php +++ b/src/Http/HttpMessageBuilder.php @@ -1,7 +1,7 @@ <?php // HttpMessageBuilder.php // Created: 2022-02-08 -// Updated: 2024-10-02 +// Updated: 2024-12-02 namespace Index\Http; @@ -111,7 +111,6 @@ class HttpMessageBuilder { * Checks whether this HTTP message has body contents. * * @return bool true if it has body contents. - * @phpstan-impure */ public function hasContent(): bool { return $this->content !== null; diff --git a/src/MediaType.php b/src/MediaType.php index ecee030..b3e72e2 100644 --- a/src/MediaType.php +++ b/src/MediaType.php @@ -1,7 +1,7 @@ <?php // MediaType.php // Created: 2022-02-10 -// Updated: 2024-10-02 +// Updated: 2024-12-02 namespace Index; @@ -226,7 +226,8 @@ class MediaType implements Stringable, Comparable, Equatable { $string .= ';'; if(is_string($key)) $string .= $key . '='; - $string .= $value; + if(is_scalar($value)) + $string .= (string)$value; } return $string; diff --git a/src/UriBase64.php b/src/UriBase64.php index c9645c8..0860a26 100644 --- a/src/UriBase64.php +++ b/src/UriBase64.php @@ -1,7 +1,7 @@ <?php // UriBase64.php // Created: 2022-01-13 -// Updated: 2024-07-31 +// Updated: 2024-12-02 namespace Index; @@ -24,9 +24,9 @@ final class UriBase64 { * * @param string $string The encoded data. * @param bool $strict If the strict parameter is set to true then the base64_decode() function will return false if the input contains character from outside the base64 alphabet. Otherwise invalid characters will be silently discarded. - * @return string|false Returns the decoded data or false on failure. The returned data may be binary. + * @return string Returns the decoded data or false on failure. The returned data may be binary. */ - public static function decode(string $string, bool $strict = false): string|false { + public static function decode(string $string, bool $strict = false): string { return base64_decode(str_pad(strtr($string, '-_', '+/'), strlen($string) % 4, '=', STR_PAD_RIGHT)); } } diff --git a/tests/BencodeSerialisableTest.php b/tests/BencodeSerialisableTest.php index ee01992..86bd799 100644 --- a/tests/BencodeSerialisableTest.php +++ b/tests/BencodeSerialisableTest.php @@ -1,7 +1,7 @@ <?php // BencodeSerialisableTest.php // Created: 2024-09-29 -// Updated: 2024-10-02 +// Updated: 2024-12-02 declare(strict_types=1); @@ -54,7 +54,8 @@ final class BencodeSerialisableTest extends TestCase { public mixed $nullValPresent = null; #[BencodeProperty] - public array $scalarVals = [null, 0, 1234, 12.34, 'str', true, false]; + /** @var scalar[] */ + public array $scalarVals = [null, 0, 1234, 12.34, 'str', true, false]; // @phpstan-ignore-line: idgi?? #[BencodeProperty('stringVal_method')] public function getStringVal(): string { @@ -111,7 +112,8 @@ final class BencodeSerialisableTest extends TestCase { return null; } - #[BencodeProperty] + #[BencodeProperty] // @phpstan-ignore-line: idgi?? + /** @return scalar[] */ public function getScalarVals(): array { return [null, 0, 1234, 12.34, 'str', true, false]; } @@ -154,11 +156,11 @@ final class BencodeSerialisableTest extends TestCase { use BencodeSerializableTrait; #[BencodeProperty('test1')] - #[BencodeProperty('test2')] + #[BencodeProperty('test2')] // @phpstan-ignore-line: this is meant to test the dupe exception public string $stringVal = 'string value'; #[BencodeProperty('test3')] - #[BencodeProperty('test4')] + #[BencodeProperty('test4')] // @phpstan-ignore-line: this is meant to test the dupe exception public function getIntVal(): int { return 1234; } diff --git a/tests/BencodeTest.php b/tests/BencodeTest.php index ffe7baa..df47872 100644 --- a/tests/BencodeTest.php +++ b/tests/BencodeTest.php @@ -1,7 +1,7 @@ <?php // BencodeTest.php // Created: 2023-07-21 -// Updated: 2024-08-01 +// Updated: 2024-12-02 declare(strict_types=1); @@ -16,6 +16,7 @@ final class BencodeTest extends TestCase { public function testDecode(): void { $decoded = Bencode::decode(base64_decode(self::TORRENT)); + $this->assertIsArray($decoded); $this->assertEquals(5, count($decoded)); $this->assertArrayHasKey('announce', $decoded); @@ -26,15 +27,23 @@ final class BencodeTest extends TestCase { $this->assertArrayHasKey('info', $decoded); + $this->assertIsArray($decoded['info']); $this->assertArrayHasKey('private', $decoded['info']); $this->assertEquals(1, $decoded['info']['private']); $decoded = Bencode::decode(base64_decode(self::TORRENT), associative: false); - $this->assertEquals('https://tracker.flashii.net/announce.php/meow', $decoded->announce); - $this->assertEquals(1689973664, $decoded->{'creation date'}); - $this->assertEquals('this is the comments field', $decoded->comment); - $this->assertEquals(1, $decoded->info->private); + $this->assertIsObject($decoded); + $this->assertObjectHasProperty('announce', $decoded); + $this->assertEquals('https://tracker.flashii.net/announce.php/meow', $decoded->announce); // @phpstan-ignore-line: checked above + $this->assertObjectHasProperty('creation date', $decoded); + $this->assertEquals(1689973664, $decoded->{'creation date'}); // @phpstan-ignore-line: checked above + $this->assertObjectHasProperty('comment', $decoded); + $this->assertEquals('this is the comments field', $decoded->comment); // @phpstan-ignore-line: checked above + $this->assertObjectHasProperty('info', $decoded); + $this->assertIsObject($decoded->info); // @phpstan-ignore-line: checked above + $this->assertObjectHasProperty('private', $decoded->info); + $this->assertEquals(1, $decoded->info->private); // @phpstan-ignore-line: checked above } public function testEncode(): void { diff --git a/tests/DbConfigTest.php b/tests/DbConfigTest.php index 45d27d9..824bc11 100644 --- a/tests/DbConfigTest.php +++ b/tests/DbConfigTest.php @@ -1,13 +1,13 @@ <?php // DbConfigTest.php // Created: 2023-10-20 -// Updated: 2024-10-04 +// Updated: 2024-12-02 declare(strict_types=1); use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\CoversClass; -use Index\Config\{GetValueInfoTrait,GetValuesTrait,MutableConfigTrait}; +use Index\Config\{GetValueInfoTrait,GetValuesTrait,MutableConfigTrait,ScopedConfigValueInfo}; use Index\Config\Db\{DbConfig,DbConfigValueInfo}; use Index\Db\{DbBackends,DbConnection}; @@ -17,8 +17,8 @@ use Index\Db\{DbBackends,DbConnection}; #[CoversClass(GetValueInfoTrait::class)] #[CoversClass(GetValuesTrait::class)] final class DbConfigTest extends TestCase { - private DbConnection $dbConn; - private DbConfig $config; + private DbConnection $dbConn; // @phpstan-ignore-line: defined by PHPunit in setUp() + private DbConfig $config; // @phpstan-ignore-line: defined by PHPunit in setUp() private const VALUES = [ 'private.allow_password_reset' => 'b:1;', @@ -114,8 +114,10 @@ final class DbConfigTest extends TestCase { $expected = ['private.perm.cat' => 'user', 'private.perm.val' => 1]; $values = []; $valueInfos = $scoped->getValueInfos(['cat', 'val', 'poop']); - foreach($valueInfos as $valueInfo) + foreach($valueInfos as $valueInfo) { + $this->assertInstanceOf(ScopedConfigValueInfo::class, $valueInfo); $values[$valueInfo->getRealName()] = $valueInfo->getValue(); + } $this->assertEquals($expected, $values); diff --git a/tests/FsConfigTest.php b/tests/FsConfigTest.php index df1aa2a..ab08733 100644 --- a/tests/FsConfigTest.php +++ b/tests/FsConfigTest.php @@ -1,13 +1,13 @@ <?php // FsConfigTest.php // Created: 2023-10-20 -// Updated: 2024-10-04 +// Updated: 2024-12-02 declare(strict_types=1); use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\CoversClass; -use Index\Config\{GetValueInfoTrait,GetValuesTrait,ImmutableConfigTrait}; +use Index\Config\{GetValueInfoTrait,GetValuesTrait,ImmutableConfigTrait,ScopedConfigValueInfo}; use Index\Config\Fs\{FsConfig,FsConfigValueInfo}; #[CoversClass(FsConfig::class)] @@ -141,8 +141,10 @@ final class FsConfigTest extends TestCase { $expected = ['chat:channels:passwd:name' => 'Password', 'chat:channels:passwd:password' => 'meow']; $values = []; $valueInfos = $scoped->getValueInfos(['name', 'password', 'minRank']); - foreach($valueInfos as $valueInfo) + foreach($valueInfos as $valueInfo) { + $this->assertInstanceOf(ScopedConfigValueInfo::class, $valueInfo); $values[$valueInfo->getRealName()] = $valueInfo->getValue(); + } $this->assertEquals($expected, $values); diff --git a/tests/JsonSerializableTest.php b/tests/JsonSerializableTest.php index 8988151..5d65387 100644 --- a/tests/JsonSerializableTest.php +++ b/tests/JsonSerializableTest.php @@ -1,7 +1,7 @@ <?php // JsonSerializableTest.php // Created: 2024-09-29 -// Updated: 2024-09-30 +// Updated: 2024-12-02 declare(strict_types=1); @@ -52,7 +52,8 @@ final class JsonSerializableTest extends TestCase { public mixed $nullValPresent = null; #[JsonProperty] - public array $scalarVals = [null, 0, 1234, 12.34, 'str', true, false]; + /** @var scalar[] */ + public array $scalarVals = [null, 0, 1234, 12.34, 'str', true, false]; // @phpstan-ignore-line: idgi?? #[JsonProperty('stringVal_method')] public function getStringVal(): string { @@ -109,7 +110,8 @@ final class JsonSerializableTest extends TestCase { return null; } - #[JsonProperty] + #[JsonProperty] // @phpstan-ignore-line: idgi?? + /** @return scalar[] */ public function getScalarVals(): array { return [null, 0, 1234, 12.34, 'str', true, false]; } @@ -152,11 +154,11 @@ final class JsonSerializableTest extends TestCase { use JsonSerializableTrait; #[JsonProperty('test1')] - #[JsonProperty('test2')] + #[JsonProperty('test2')] // @phpstan-ignore-line: this is meant to test the dupe exception public string $stringVal = 'string value'; #[JsonProperty('test3')] - #[JsonProperty('test4')] + #[JsonProperty('test4')] // @phpstan-ignore-line: this is meant to test the dupe exception public function getIntVal(): int { return 1234; } diff --git a/tests/RouterTest.php b/tests/RouterTest.php index 64e4f9f..796c38b 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -1,7 +1,7 @@ <?php // RouterTest.php // Created: 2022-01-20 -// Updated: 2024-10-05 +// Updated: 2024-12-02 declare(strict_types=1); @@ -91,37 +91,37 @@ final class RouterTest extends TestCase { use RouteHandlerTrait; #[HttpGet('/')] - public function getIndex() { + public function getIndex(): string { return 'index'; } #[HttpPost('/avatar')] - public function postAvatar() { + public function postAvatar(): string { return 'avatar'; } #[HttpPut('/static')] - public static function putStatic() { + public static function putStatic(): string { return 'static'; } #[HttpGet('/meow')] #[HttpPost('/meow')] - public function multiple() { + public function multiple(): string { return 'meow'; } #[HttpMiddleware('/mw')] - public function useMw() { + public function useMw(): string { return 'this intercepts'; } #[HttpGet('/mw')] - public function getMw() { + public function getMw(): string { return 'this is intercepted'; } - public function hasNoAttr() { + public function hasNoAttr(): string { return 'not a route'; } }; diff --git a/tests/TemplatingTest.php b/tests/TemplatingTest.php index dc95f4b..2b24685 100644 --- a/tests/TemplatingTest.php +++ b/tests/TemplatingTest.php @@ -1,7 +1,7 @@ <?php // TemplatingTest.php // Created: 2024-08-04 -// Updated: 2024-10-04 +// Updated: 2024-12-02 declare(strict_types=1); @@ -34,9 +34,9 @@ final class TemplatingTest extends TestCase { 'twig_version' => TwigEnvironment::VERSION, ]); - $env->addFilter('test_filter', fn($text) => ('filter:' . $text)); - $env->addFunction('test_function', fn($text) => ('func:' . $text)); - $env->addTest('test_test', fn($text) => $text === 'test'); + $env->addFilter('test_filter', fn(string $text) => ('filter:' . $text)); + $env->addFunction('test_function', fn(string $text) => ('func:' . $text)); + $env->addTest('test_test', fn(string $text) => $text === 'test'); $rendered = $env->render('TemplatingTest-rendered', [ 'local_var' => 'this var is local', diff --git a/tests/XArrayTest.php b/tests/XArrayTest.php index 666ee0e..014a00b 100644 --- a/tests/XArrayTest.php +++ b/tests/XArrayTest.php @@ -1,7 +1,7 @@ <?php // XArrayTest.php // Created: 2021-04-26 -// Updated: 2024-07-31 +// Updated: 2024-12-02 declare(strict_types=1); @@ -31,14 +31,33 @@ final class XArrayTest extends TestCase { $array3 = [1 => 'a', 2 => 'b', 3 => 'c', 4 => 'd', 5 => 'e']; $array4 = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5]; - foreach(XArray::extractIterator($array1) as $key => $value) + foreach(XArray::extractIterator($array1) as $key => $value) { + $this->assertTrue(is_string($key) || is_int($key)); + $this->assertIsArray($array1); + $this->assertArrayHasKey($key, $array1); $this->assertEquals($value, $array1[$key]); - foreach(XArray::extractIterator($array2) as $key => $value) + } + + foreach(XArray::extractIterator($array2) as $key => $value) { + $this->assertTrue(is_string($key) || is_int($key)); + $this->assertIsArray($array2); + $this->assertArrayHasKey($key, $array2); $this->assertEquals($value, $array2[$key]); - foreach(XArray::extractIterator($array3) as $key => $value) + } + + foreach(XArray::extractIterator($array3) as $key => $value) { + $this->assertTrue(is_string($key) || is_int($key)); + $this->assertIsArray($array3); + $this->assertArrayHasKey($key, $array3); $this->assertEquals($value, $array3[$key]); - foreach(XArray::extractIterator($array4) as $key => $value) + } + + foreach(XArray::extractIterator($array4) as $key => $value) { + $this->assertTrue(is_string($key) || is_int($key)); + $this->assertIsArray($array4); + $this->assertArrayHasKey($key, $array4); $this->assertEquals($value, $array4[$key]); + } } public function testEquals(): void { @@ -109,13 +128,13 @@ final class XArrayTest extends TestCase { $array1 = ['Windows', 'Flashwave', 'Misaka Mikoto', 'Misuzu', 'Index', 'Kasane Teto', 'Some garbage']; $array2 = ['Misaka Mikoto', 'Kasane Teto', 'Some garbage']; - $this->assertTrue(XArray::sequenceEquals(XArray::where($array1, fn($value) => strpos($value, ' ') !== false), $array2)); + $this->assertTrue(XArray::sequenceEquals(XArray::where($array1, fn($value) => is_string($value) && strpos($value, ' ') !== false), $array2)); } public function testFirst(): void { $array = ['Windows', 'Flashwave', 'Misaka Mikoto', 'Misuzu', 'Index', 'Kasane Teto', 'Some garbage']; - $this->assertEquals(XArray::first($array, fn($value) => strpos($value, 't') !== false), 'Misaka Mikoto'); + $this->assertEquals(XArray::first($array, fn($value) => is_string($value) && strpos($value, 't') !== false), 'Misaka Mikoto'); } public function testSelect(): void {