diff --git a/.gitignore b/.gitignore index 5d13a24..f82edd4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ composer.lock vendor .idea +.php-cs-fixer.cache diff --git a/.travis.yml b/.travis.yml index ce14233..190c784 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,5 @@ script: matrix: fast_finish: true include: - - php: 7.0 - - php: 7.1 - - php: 7.2 - - php: 7.3 - - php: 7.4 - php: 8.0 + - php: 8.1 diff --git a/composer.json b/composer.json index e7652e3..9d04ca5 100644 --- a/composer.json +++ b/composer.json @@ -10,12 +10,14 @@ } ], "require": { - "php": ">=7.0", - "ext-mbstring": "*", + "php": ">=8.0", + "ext-zlib": "*", "predis/predis": "^1.1.1" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "phpunit/phpunit": "^9.5", + "friendsofphp/php-cs-fixer": "^3.8", + "phpstan/phpstan": "^1.5" }, "autoload": { "psr-4": { @@ -26,5 +28,10 @@ "psr-4": { "B1rdex\\PredisCompressible\\Tests\\": "tests/" } + }, + "scripts": { + "test": "vendor/bin/phpunit tests/", + "fix-cs": "vendor/bin/php-cs-fixer fix --rules=@PSR12:risky,@PHP80Migration:risky,@PHPUnit84Migration:risky --allow-risky=yes .", + "sca": "vendor/bin/phpstan --memory-limit=-1 analyse --level=max src/ tests/" } } diff --git a/src/Command/ArgumentsCompressibleCommandInterface.php b/src/Command/ArgumentsCompressibleCommandInterface.php index aa60b64..9088006 100644 --- a/src/Command/ArgumentsCompressibleCommandInterface.php +++ b/src/Command/ArgumentsCompressibleCommandInterface.php @@ -6,5 +6,10 @@ interface ArgumentsCompressibleCommandInterface extends CompressibleCommandInterface { + /** + * @param list $arguments + * + * @return list + */ public function compressArguments(array $arguments): array; } diff --git a/src/Command/CompressArgumentsHelperTrait.php b/src/Command/CompressArgumentsHelperTrait.php index 145643b..0b63a6c 100644 --- a/src/Command/CompressArgumentsHelperTrait.php +++ b/src/Command/CompressArgumentsHelperTrait.php @@ -5,15 +5,16 @@ namespace B1rdex\PredisCompressible\Command; use B1rdex\PredisCompressible\Compressor\CompressorException; +use B1rdex\PredisCompressible\Compressor\CompressorInterface; trait CompressArgumentsHelperTrait { - /** - * @var \B1rdex\PredisCompressible\Compressor\CompressorInterface - */ - protected $compressor; + protected CompressorInterface $compressor; - protected function compressArgument(array &$arguments, int $position) + /** + * @param list $arguments + */ + protected function compressArgument(array &$arguments, int $position): void { $content = $arguments[$position]; diff --git a/src/Command/CompressibleCommandInterface.php b/src/Command/CompressibleCommandInterface.php index ea38b3b..23325ef 100644 --- a/src/Command/CompressibleCommandInterface.php +++ b/src/Command/CompressibleCommandInterface.php @@ -8,5 +8,5 @@ interface CompressibleCommandInterface { - public function setCompressor(CompressorInterface $compressor); + public function setCompressor(CompressorInterface $compressor): void; } diff --git a/src/Command/CompressibleCommandTrait.php b/src/Command/CompressibleCommandTrait.php index 7c099c0..b9f0713 100644 --- a/src/Command/CompressibleCommandTrait.php +++ b/src/Command/CompressibleCommandTrait.php @@ -8,12 +8,9 @@ trait CompressibleCommandTrait { - /** - * @var \B1rdex\PredisCompressible\Compressor\CompressorInterface - */ - protected $compressor; + protected CompressorInterface $compressor; - public function setCompressor(CompressorInterface $compressor) + public function setCompressor(CompressorInterface $compressor): void { $this->compressor = $compressor; } diff --git a/src/Command/StringGetMultiple.php b/src/Command/StringGetMultiple.php index a9622e2..8625018 100644 --- a/src/Command/StringGetMultiple.php +++ b/src/Command/StringGetMultiple.php @@ -10,23 +10,25 @@ class StringGetMultiple extends BaseStringGetMultiple implements CompressibleCom { use CompressibleCommandTrait; + /** + * @param list|string $data + */ public function parseResponse($data) { if (is_array($data)) { - return array_map(function($item) { - return $this->decompress($item); - }, $data); + return array_map(fn($item) => $this->decompress($item), $data); } return $this->decompress($data); } - private function decompress(string $data = null) - { + private function decompress(?string $data): ?string + { if (!$this->compressor->isCompressed($data)) { return $data; } + /** @var string $data */ return $this->compressor->decompress($data); } } diff --git a/src/CompressProcessor.php b/src/CompressProcessor.php index e623d69..05325a8 100644 --- a/src/CompressProcessor.php +++ b/src/CompressProcessor.php @@ -12,14 +12,11 @@ class CompressProcessor implements ProcessorInterface { - private $compressor; - - public function __construct(CompressorInterface $compressor) + public function __construct(private CompressorInterface $compressor) { - $this->compressor = $compressor; } - public function process(CommandInterface $command) + public function process(CommandInterface $command): void { if ($command instanceof CompressibleCommandInterface) { $command->setCompressor($this->compressor); diff --git a/src/Compressor/CompressorException.php b/src/Compressor/CompressorException.php index d9de238..5678511 100644 --- a/src/Compressor/CompressorException.php +++ b/src/Compressor/CompressorException.php @@ -4,6 +4,6 @@ namespace B1rdex\PredisCompressible\Compressor; -interface CompressorException +interface CompressorException extends \Throwable { } diff --git a/src/Compressor/CompressorInterface.php b/src/Compressor/CompressorInterface.php index decff90..2a806c4 100644 --- a/src/Compressor/CompressorInterface.php +++ b/src/Compressor/CompressorInterface.php @@ -7,31 +7,21 @@ interface CompressorInterface { /** - * Returns compressed string or original string if its size is less than threshold + * Returns a compressed string or original data if its not compressible * - * @param mixed $data - * - * @return string|mixed Gzip string or original data + * @return string|mixed A compressed string or original data */ - public function compress($data); + public function compress(mixed $data): mixed; /** - * Checks if $data is gzipped string - * - * @param mixed $data - * - * @return bool + * Checks if $data is a compressed string */ - public function isCompressed($data): bool; + public function isCompressed(mixed $data): bool; /** * Returns original string from compressed $data * - * @param string $data - * - * @return string - * - * @throws \B1rdex\PredisCompressible\Compressor\CompressorException + * @throws CompressorException */ public function decompress(string $data): string; } diff --git a/src/Compressor/ConditionalCompressorWrapper.php b/src/Compressor/ConditionalCompressorWrapper.php index 2cac7ce..e42f3f0 100644 --- a/src/Compressor/ConditionalCompressorWrapper.php +++ b/src/Compressor/ConditionalCompressorWrapper.php @@ -6,25 +6,11 @@ class ConditionalCompressorWrapper implements CompressorInterface { - /** - * @var int - */ - private $bytesThreshold; - /** - * @var \B1rdex\PredisCompressible\Compressor\CompressorInterface - */ - private $compressor; - - public function __construct(int $bytesThreshold, CompressorInterface $compressor) + public function __construct(private int $bytesThreshold, private CompressorInterface $compressor) { - $this->bytesThreshold = $bytesThreshold; - $this->compressor = $compressor; - } + } - /** - * {@inheritdoc} - */ - public function compress($data) + public function compress(mixed $data): mixed { if ($this->shouldCompress($data)) { return $this->compressor->compress($data); @@ -33,26 +19,20 @@ public function compress($data) return $data; } - private function shouldCompress($data): bool + private function shouldCompress(mixed $data): bool { if (!\is_string($data)) { return false; } - return \mb_strlen($data, 'US-ASCII') > $this->bytesThreshold; + return strlen($data) > $this->bytesThreshold; } - /** - * {@inheritdoc} - */ - public function isCompressed($data): bool + public function isCompressed(mixed $data): bool { return $this->compressor->isCompressed($data); } - /** - * {@inheritdoc} - */ public function decompress(string $data): string { return $this->compressor->decompress($data); diff --git a/src/Compressor/GzipCompressor.php b/src/Compressor/GzipCompressor.php index a88bce1..556178e 100644 --- a/src/Compressor/GzipCompressor.php +++ b/src/Compressor/GzipCompressor.php @@ -8,12 +8,13 @@ class GzipCompressor implements CompressorInterface { - /** - * {@inheritdoc} - */ - public function compress($data) - { - $compressed = @\gzencode($data); + public function compress(mixed $data): mixed + { + if (!\is_string($data)) { + return $data; + } + + $compressed = @gzencode($data); if ($compressed === false) { throw new class('Compression failed') extends RuntimeException implements CompressorException {}; } @@ -21,21 +22,15 @@ public function compress($data) return $compressed; } - /** - * {@inheritdoc} - */ - public function isCompressed($data): bool + public function isCompressed(mixed $data): bool { if (!\is_string($data)) { return false; } - return 0 === \mb_strpos($data, "\x1f" . "\x8b" . "\x08", 0, 'US-ASCII'); + return str_starts_with($data, "\x1f" . "\x8b" . "\x08"); } - /** - * {@inheritdoc} - */ public function decompress(string $data): string { $decompressed = @\gzdecode($data); diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 5978f1d..11f32dd 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Sp\Tests\PredisCompress; +namespace B1rdex\PredisCompressible\Tests; use B1rdex\PredisCompressible\Command\StringGet; use B1rdex\PredisCompressible\Command\StringGetMultiple; @@ -24,7 +24,7 @@ class ClientTest extends TestCase /** * @test */ - public function it_should_work() + public function it_should_work(): void { $sut = $this->getCompressedClient(); @@ -74,9 +74,16 @@ private function getCompressedClient(): Client $sut->connect(); $this->assertTrue($sut->isConnected()); + // clear redis db before running the tests + $sut->flushdb(); + return $sut; } + /** + * @see \Predis\Client::createConnection() + * @return array + */ private function getConnectionParameters(): array { return []; @@ -90,7 +97,7 @@ private function getOriginalClient(): OriginalClient /** * @test */ - public function it_should_allow_setex() + public function it_should_allow_setex(): void { $sut = $this->getCompressedClient(); @@ -112,7 +119,7 @@ public function it_should_allow_setex() /** * @test */ - public function it_should_allow_setnx() + public function it_should_allow_setnx(): void { $sut = $this->getCompressedClient(); @@ -134,7 +141,7 @@ public function it_should_allow_setnx() /** * @test */ - public function it_should_not_throw_on_any_scalar_types() + public function it_should_not_throw_on_any_scalar_types(): void { $sut = $this->getCompressedClient(); @@ -149,7 +156,7 @@ public function it_should_not_throw_on_any_scalar_types() /** * @test */ - public function it_should_allow_mget() + public function it_should_allow_mget(): void { $sut = $this->getCompressedClient(); @@ -173,7 +180,7 @@ public function it_should_allow_mget() /** * @test */ - public function it_should_allow_mset() + public function it_should_allow_mset(): void { $sut = $this->getCompressedClient(); diff --git a/tests/ConditionalCompressorWrapperTest.php b/tests/ConditionalCompressorWrapperTest.php index 2a77591..d96f24b 100644 --- a/tests/ConditionalCompressorWrapperTest.php +++ b/tests/ConditionalCompressorWrapperTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Sp\Tests\PredisCompress; +namespace B1rdex\PredisCompressible; use B1rdex\PredisCompressible\Compressor\CompressorException; use B1rdex\PredisCompressible\Compressor\ConditionalCompressorWrapper; @@ -17,13 +17,14 @@ class ConditionalCompressorWrapperTest extends TestCase /** * @test */ - public function it_should_work() + public function it_should_work(): void { $sut = new ConditionalCompressorWrapper(5, new GzipCompressor()); $data = 'some text string'; $compressed = $sut->compress($data); + assert(is_string($compressed)); $this->assertStringStartsNotWith($data, $compressed); $decompressed = $sut->decompress($compressed);