From 77d346a183c2af75d237c669e3f9d66f66a875d7 Mon Sep 17 00:00:00 2001 From: Contributte AI Date: Sun, 8 Feb 2026 15:50:56 +0000 Subject: [PATCH 1/4] CI: use PHP 8.2 for QA, add PHP 8.4 and 8.5 tests, remove kodiak --- .github/.kodiak.toml | 10 ---------- .github/workflows/tests.yml | 20 +++++++++++++------- 2 files changed, 13 insertions(+), 17 deletions(-) delete mode 100644 .github/.kodiak.toml diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml deleted file mode 100644 index 60c34b6..0000000 --- a/.github/.kodiak.toml +++ /dev/null @@ -1,10 +0,0 @@ -version = 1 - -[merge] -automerge_label = "automerge" -blacklist_title_regex = "^WIP.*" -blacklist_labels = ["WIP"] -method = "rebase" -delete_branch_on_merge = true -notify_on_conflict = true -optimistic_updates = false diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a574bd1..0bdeea0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,27 +11,33 @@ on: - cron: "0 8 * * 1" jobs: - test83: + test85: name: "Nette Tester" uses: contributte/.github/.github/workflows/nette-tester.yml@master with: - php: "8.3" + php: "8.5" - test82: + test84: name: "Nette Tester" uses: contributte/.github/.github/workflows/nette-tester.yml@master with: - php: "8.2" + php: "8.4" - test81: + test83: name: "Nette Tester" uses: contributte/.github/.github/workflows/nette-tester.yml@master with: - php: "8.1" + php: "8.3" + + test82: + name: "Nette Tester" + uses: contributte/.github/.github/workflows/nette-tester.yml@master + with: + php: "8.2" testlower: name: "Nette Tester" uses: contributte/.github/.github/workflows/nette-tester.yml@master with: - php: "8.1" + php: "8.2" composer: "composer update --no-interaction --no-progress --prefer-dist --prefer-stable --prefer-lowest" From 157e0d54c8b3b12311678cc83815efdecd8c3c92 Mon Sep 17 00:00:00 2001 From: Contributte AI Date: Mon, 9 Feb 2026 13:03:28 +0000 Subject: [PATCH 2/4] Tests: add type hints, replace reference variables with objects --- tests/Cases/BulkConsumerTest.phpt | 51 +++++++++++++-------- tests/Cases/ConsumerTest.phpt | 75 ++++++++++++++++++------------- tests/Fixtures/ChannelMock.php | 24 +++++++++- tests/bootstrap.php | 1 - 4 files changed, 101 insertions(+), 50 deletions(-) diff --git a/tests/Cases/BulkConsumerTest.phpt b/tests/Cases/BulkConsumerTest.phpt index 9a9853f..d47449e 100644 --- a/tests/Cases/BulkConsumerTest.phpt +++ b/tests/Cases/BulkConsumerTest.phpt @@ -32,18 +32,18 @@ final class BulkConsumerTest extends TestCase ->shouldReceive('getConnection')->andReturn($connectionMock)->getMock() ->shouldReceive('getName')->andReturn('testQueue')->getMock(); - $countOfConsumerCallbackCalls = 0; - $callback = function ($messages) use (&$countOfConsumerCallbackCalls) { - $countOfConsumerCallbackCalls++; + $counter = (object) ['value' => 0]; + $callback = function (array $messages) use ($counter): array { + $counter->value++; - return array_map(fn ($message) => IConsumer::MESSAGE_ACK, $messages); + return array_map(fn (Message $message): int => IConsumer::MESSAGE_ACK, $messages); }; $instance = new BulkConsumer('bulkTest', $queueMock, $callback, null, null, 3, 2); $instance->consume(2); - Assert::same(2, $countOfConsumerCallbackCalls, 'Number of consumer callback calls'); + Assert::same(2, $counter->value, 'Number of consumer callback calls'); Assert::count(2, $channelMock->acks, 'Number of ACKs'); Assert::same([ 1 => [ @@ -72,9 +72,9 @@ final class BulkConsumerTest extends TestCase ->shouldReceive('getConnection')->andReturn($connectionMock)->getMock() ->shouldReceive('getName')->andReturn('testQueue')->getMock(); - $countOfConsumerCallbackCalls = 0; - $callback = function ($messages) use (&$countOfConsumerCallbackCalls): void { - $countOfConsumerCallbackCalls++; + $counter = (object) ['value' => 0]; + $callback = function (array $messages) use ($counter): void { + $counter->value++; throw new \Exception('test'); }; @@ -83,7 +83,7 @@ final class BulkConsumerTest extends TestCase $instance->consume(2); - Assert::same(2, $countOfConsumerCallbackCalls, 'Number of consumer callback calls'); + Assert::same(2, $counter->value, 'Number of consumer callback calls'); Assert::count(2, $channelMock->nacks, 'Number of NACKs'); Assert::same([ 1 => [ @@ -112,9 +112,9 @@ final class BulkConsumerTest extends TestCase ->shouldReceive('getConnection')->andReturn($connectionMock)->getMock() ->shouldReceive('getName')->andReturn('testQueue')->getMock(); - $countOfConsumerCallbackCalls = 0; - $callback = function ($messages) use (&$countOfConsumerCallbackCalls) { - $countOfConsumerCallbackCalls++; + $counter = (object) ['value' => 0]; + $callback = function (array $messages) use ($counter): bool { + $counter->value++; return true; }; @@ -123,7 +123,7 @@ final class BulkConsumerTest extends TestCase Assert::exception(fn () => $instance->consume(2), UnexpectedConsumerResultTypeException::class); - Assert::same(1, $countOfConsumerCallbackCalls, 'Number of consumer callback calls'); + Assert::same(1, $counter->value, 'Number of consumer callback calls'); Assert::count(1, $channelMock->nacks, 'Number of NACKs'); Assert::same([ 1 => [ @@ -144,31 +144,44 @@ final class BulkConsumerTest extends TestCase ['key' => '5', 'content' => '{"test":"5"}'], ]) extends Client { + /** @var array */ private array $dataToConsume; - private $callback; + /** @var callable|null */ + private mixed $callback = null; - private $channel; + private ?ChannelMock $channel = null; - public function __construct($dataToConsume) + /** + * @param array $dataToConsume + */ + public function __construct(array $dataToConsume) { $this->dataToConsume = $dataToConsume; } - public function setCallback($callback): void + public function setCallback(callable $callback): void { $this->callback = $callback; } - public function setChannel($channel): void + public function setChannel(ChannelMock $channel): void { $this->channel = $channel; } + /** + * @param int $replyCode + * @param string $replyText + */ public function disconnect($replyCode = 0, $replyText = ''): void { + // intentionally empty - mock } + /** + * @param float|null $maxSeconds + */ public function run($maxSeconds = null): void { $this->channel->ackPos++; @@ -186,10 +199,12 @@ final class BulkConsumerTest extends TestCase protected function feedReadBuffer(): void { + // intentionally empty - mock } protected function flushWriteBuffer(): void { + // intentionally empty - mock } }; diff --git a/tests/Cases/ConsumerTest.phpt b/tests/Cases/ConsumerTest.phpt index feb70fd..41dadfe 100644 --- a/tests/Cases/ConsumerTest.phpt +++ b/tests/Cases/ConsumerTest.phpt @@ -31,11 +31,11 @@ final class ConsumerTest extends TestCase ->shouldReceive('getConnection')->andReturn($connectionMock)->getMock() ->shouldReceive('getName')->andReturn('testQueue')->getMock(); - $countOfConsumerCallbackCalls = 0; - $callback = function (Message $message) use (&$countOfConsumerCallbackCalls) { - $countOfConsumerCallbackCalls++; - Assert::same('{"test":"' . $countOfConsumerCallbackCalls . '"}', $message->content, 'Consume message - content'); - Assert::same((string) $countOfConsumerCallbackCalls, $message->deliveryTag, 'Consume message - deliveryTag'); + $counter = (object) ['value' => 0]; + $callback = function (Message $message) use ($counter): int { + $counter->value++; + Assert::same('{"test":"' . $counter->value . '"}', $message->content, 'Consume message - content'); + Assert::same((string) $counter->value, $message->deliveryTag, 'Consume message - deliveryTag'); return IConsumer::MESSAGE_ACK; }; @@ -44,7 +44,7 @@ final class ConsumerTest extends TestCase $instance->consume(1); - Assert::same(2, $countOfConsumerCallbackCalls, 'Number of consumer callback calls'); + Assert::same(2, $counter->value, 'Number of consumer callback calls'); Assert::count(1, $channelMock->acks, 'Number of ACKs'); Assert::same([ 1 => [ @@ -68,11 +68,11 @@ final class ConsumerTest extends TestCase ->shouldReceive('getConnection')->andReturn($connectionMock)->getMock() ->shouldReceive('getName')->andReturn('testQueue')->getMock(); - $countOfConsumerCallbackCalls = 0; - $callback = function (Message $message) use (&$countOfConsumerCallbackCalls) { - $countOfConsumerCallbackCalls++; - Assert::same('{"test":"' . $countOfConsumerCallbackCalls . '"}', $message->content, 'Consume message - content'); - Assert::same((string) $countOfConsumerCallbackCalls, $message->deliveryTag, 'Consume message - deliveryTag'); + $counter = (object) ['value' => 0]; + $callback = function (Message $message) use ($counter): int { + $counter->value++; + Assert::same('{"test":"' . $counter->value . '"}', $message->content, 'Consume message - content'); + Assert::same((string) $counter->value, $message->deliveryTag, 'Consume message - deliveryTag'); return IConsumer::MESSAGE_ACK; }; @@ -80,7 +80,7 @@ final class ConsumerTest extends TestCase $instance = new Consumer('bulkTest', $queueMock, $callback, null, null); $instance->consume(null, 5); - Assert::same(5, $countOfConsumerCallbackCalls, 'Number of consumer callback calls'); + Assert::same(5, $counter->value, 'Number of consumer callback calls'); Assert::count(1, $channelMock->acks, 'Number of ACKs'); Assert::same([ 1 => [ @@ -107,9 +107,9 @@ final class ConsumerTest extends TestCase ->shouldReceive('getConnection')->andReturn($connectionMock)->getMock() ->shouldReceive('getName')->andReturn('testQueue')->getMock(); - $countOfConsumerCallbackCalls = 0; - $callback = function (Message $message) use (&$countOfConsumerCallbackCalls): void { - $countOfConsumerCallbackCalls++; + $counter = (object) ['value' => 0]; + $callback = function (Message $message) use ($counter): void { + $counter->value++; Assert::same('{"test":"1"}', $message->content, 'Consume message - content'); Assert::same('1', $message->deliveryTag, 'Consume message - deliveryTag'); @@ -120,7 +120,7 @@ final class ConsumerTest extends TestCase Assert::exception(fn () => $instance->consume(2), \Throwable::class, 'test-exc'); - Assert::same(1, $countOfConsumerCallbackCalls, 'Number of consumer callback calls'); + Assert::same(1, $counter->value, 'Number of consumer callback calls'); Assert::count(0, $channelMock->nacks, 'Number of NACKs'); Assert::same([], $channelMock->nacks, 'NACKs data'); } @@ -139,9 +139,9 @@ final class ConsumerTest extends TestCase ->shouldReceive('getConnection')->andReturn($connectionMock)->getMock() ->shouldReceive('getName')->andReturn('testQueue')->getMock(); - $countOfConsumerCallbackCalls = 0; - $callback = function (Message $message) use (&$countOfConsumerCallbackCalls) { - $countOfConsumerCallbackCalls++; + $counter = (object) ['value' => 0]; + $callback = function (Message $message) use ($counter): bool { + $counter->value++; Assert::same('{"test":"1"}', $message->content, 'Consume message - content'); Assert::same('1', $message->deliveryTag, 'Consume message - deliveryTag'); @@ -152,7 +152,7 @@ final class ConsumerTest extends TestCase Assert::exception(fn () => $instance->consume(1), \TypeError::class); - Assert::same(1, $countOfConsumerCallbackCalls, 'Number of consumer callback calls'); + Assert::same(1, $counter->value, 'Number of consumer callback calls'); Assert::count(0, $channelMock->nacks, 'Number of NACKs'); Assert::same([], $channelMock->nacks, 'NACKs data'); } @@ -171,9 +171,9 @@ final class ConsumerTest extends TestCase ->shouldReceive('getConnection')->andReturn($connectionMock)->getMock() ->shouldReceive('getName')->andReturn('testQueue')->getMock(); - $countOfConsumerCallbackCalls = 0; - $callback = function (Message $message) use (&$countOfConsumerCallbackCalls) { - $countOfConsumerCallbackCalls++; + $counter = (object) ['value' => 0]; + $callback = function (Message $message) use ($counter): int { + $counter->value++; Assert::same('{"test":"1"}', $message->content, 'Consume message - content'); Assert::same('1', $message->deliveryTag, 'Consume message - deliveryTag'); @@ -184,12 +184,12 @@ final class ConsumerTest extends TestCase Assert::exception(fn () => $instance->consume(1), \InvalidArgumentException::class); - Assert::same(1, $countOfConsumerCallbackCalls, 'Number of consumer callback calls'); + Assert::same(1, $counter->value, 'Number of consumer callback calls'); Assert::count(0, $channelMock->nacks, 'Number of NACKs'); Assert::same([], $channelMock->nacks, 'NACKs data'); } - protected function createClient(int $numberOfMessages = 2) + protected function createClient(int $numberOfMessages = 2): Client { $messages = []; for ($i = 1; $i <= $numberOfMessages; $i++) { @@ -198,31 +198,44 @@ final class ConsumerTest extends TestCase return new class($messages) extends Client { + /** @var array */ private array $dataToConsume; - private $callback; + /** @var callable|null */ + private mixed $callback = null; - private $channel; + private ?ChannelMock $channel = null; - public function __construct($dataToConsume) + /** + * @param array $dataToConsume + */ + public function __construct(array $dataToConsume) { $this->dataToConsume = $dataToConsume; } - public function setCallback($callback): void + public function setCallback(callable $callback): void { $this->callback = $callback; } - public function setChannel($channel): void + public function setChannel(ChannelMock $channel): void { $this->channel = $channel; } + /** + * @param int $replyCode + * @param string $replyText + */ public function disconnect($replyCode = 0, $replyText = ''): void { + // intentionally empty - mock } + /** + * @param float|null $maxSeconds + */ public function run($maxSeconds = null): void { $this->channel->ackPos++; @@ -240,10 +253,12 @@ final class ConsumerTest extends TestCase protected function feedReadBuffer(): void { + // intentionally empty - mock } protected function flushWriteBuffer(): void { + // intentionally empty - mock } }; diff --git a/tests/Fixtures/ChannelMock.php b/tests/Fixtures/ChannelMock.php index b341c8b..6ec0f4d 100644 --- a/tests/Fixtures/ChannelMock.php +++ b/tests/Fixtures/ChannelMock.php @@ -3,6 +3,7 @@ namespace Tests\Fixtures; use Bunny\Channel; +use Bunny\Client; use Bunny\Message; use Nette\Neon\Neon; use Tests\Fixtures\Helper\RabbitMQMessageHelper; @@ -30,7 +31,12 @@ public function __construct() } /** + * @param string $body * @param array $headers + * @param string $exchange + * @param string $routingKey + * @param bool $mandatory + * @param bool $immediate */ public function publish( $body, @@ -48,11 +54,23 @@ public function publish( } } + /** + * @param string $queue + * @param string $consumerTag + * @param bool $noLocal + * @param bool $noAck + * @param bool $exclusive + * @param bool $nowait + * @param array $arguments + */ public function consume(callable $callback, $queue = '', $consumerTag = '', $noLocal = false, $noAck = false, $exclusive = false, $nowait = false, $arguments = []): void { $this->client->setCallback($callback); } + /** + * @param bool $multiple + */ public function ack(Message $message, $multiple = false): void { if (!isset($this->acks[$this->ackPos])) { @@ -62,6 +80,10 @@ public function ack(Message $message, $multiple = false): void $this->acks[$this->ackPos][$message->deliveryTag] = $message->content; } + /** + * @param bool $multiple + * @param bool $requeue + */ public function nack(Message $message, $multiple = false, $requeue = false): void { if (!isset($this->nacks[$this->nackPos])) { @@ -71,7 +93,7 @@ public function nack(Message $message, $multiple = false, $requeue = false): voi $this->nacks[$this->nackPos][$message->deliveryTag] = $message->content; } - public function setClient($client): void + public function setClient(Client $client): void { $this->client = $client; $this->client->setChannel($this); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index f0a8948..86c92a0 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -8,4 +8,3 @@ } Environment::setup(__DIR__); -Environment::setupFinals(); From 72edd75dbc7990ad30adb80aa02958fe701a830d Mon Sep 17 00:00:00 2001 From: Contributte AI Date: Mon, 9 Feb 2026 13:03:37 +0000 Subject: [PATCH 3/4] Config: use PHP 8.2 base, update ruleset to 8.2 --- phpstan.neon | 4 +--- ruleset.xml | 9 +++++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 1a6d073..a8d2236 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,7 +3,7 @@ includes: parameters: level: 8 - phpVersion: 80100 + phpVersion: 80200 scanDirectories: - src @@ -14,5 +14,3 @@ parameters: paths: - src - .docs - - ignoreErrors: diff --git a/ruleset.xml b/ruleset.xml index 20ea697..efad834 100644 --- a/ruleset.xml +++ b/ruleset.xml @@ -1,7 +1,7 @@ - + @@ -17,6 +17,11 @@ + + + /tests + + - /tests + /tests/tmp From 682967d5c9357abc9be1c10c4fed6db8058e1cd9 Mon Sep 17 00:00:00 2001 From: Contributte AI Date: Mon, 9 Feb 2026 13:03:45 +0000 Subject: [PATCH 4/4] Composer: use PHP 8.2, full version format, sort packages --- composer.json | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 2e05e6f..2392f11 100644 --- a/composer.json +++ b/composer.json @@ -22,17 +22,17 @@ } ], "require": { - "php": ">=8.1", - "bunny/bunny": "^0.5", + "php": ">=8.2", + "bunny/bunny": "~0.5.0", "symfony/console": "^6.4.2 || ^7.0.2", "nette/di": "^3.0.7", "nette/utils": "^4.0.0" }, "require-dev": { + "contributte/phpstan": "~0.1.0", + "contributte/qa": "~0.4.0", + "contributte/tester": "~0.4.0", "mockery/mockery": "^1.6.6", - "contributte/qa": "^0.4", - "contributte/tester": "^0.4", - "contributte/phpstan": "^0.1", "nette/neon": "^3.2.1", "tracy/tracy": "^2.10.5" }, @@ -57,6 +57,7 @@ } }, "config": { + "sort-packages": true, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true }