Skip to content

Commit a1b7171

Browse files
Improve test coverage (#241)
* Improve test coverage * Apply fixes from StyleCI * Apply Rector changes (CI) --------- Co-authored-by: StyleCI Bot <[email protected]> Co-authored-by: viktorprogger <[email protected]>
1 parent 4561dde commit a1b7171

File tree

8 files changed

+293
-51
lines changed

8 files changed

+293
-51
lines changed

src/Exception/InvalidStatusException.php

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/Message/EnvelopeTrait.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ abstract public static function fromMessage(MessageInterface $message): self;
1515

1616
public static function fromData(string $handlerName, mixed $data, array $metadata = []): MessageInterface
1717
{
18-
return self::fromMessage(Message::fromData($handlerName, $data, $metadata));
18+
return static::fromMessage(Message::fromData($handlerName, $data, $metadata));
1919
}
2020

2121
public function getMessage(): MessageInterface
@@ -46,8 +46,8 @@ public function getMetadata(): array
4646
return array_merge(
4747
$this->message->getMetadata(),
4848
[
49-
self::ENVELOPE_STACK_KEY => array_merge(
50-
$this->message->getMetadata()[self::ENVELOPE_STACK_KEY] ?? [],
49+
EnvelopeInterface::ENVELOPE_STACK_KEY => array_merge(
50+
$this->message->getMetadata()[EnvelopeInterface::ENVELOPE_STACK_KEY] ?? [],
5151
[self::class],
5252
),
5353
],

tests/App/DummyEnvelope.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Queue\Tests\App;
6+
7+
use Yiisoft\Queue\Message\EnvelopeInterface;
8+
use Yiisoft\Queue\Message\EnvelopeTrait;
9+
use Yiisoft\Queue\Message\MessageInterface;
10+
11+
final class DummyEnvelope implements EnvelopeInterface
12+
{
13+
use EnvelopeTrait;
14+
15+
public static function fromMessage(MessageInterface $message): self
16+
{
17+
$instance = new self();
18+
$instance->message = $message;
19+
20+
return $instance;
21+
}
22+
}

tests/App/StaticMessageHandler.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Queue\Tests\App;
6+
7+
class StaticMessageHandler
8+
{
9+
public static bool $wasHandled = false;
10+
11+
public static function handle(): void
12+
{
13+
self::$wasHandled = true;
14+
}
15+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Queue\Tests\Unit\Command;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Yiisoft\Queue\Cli\SoftLimitTrait;
9+
10+
final class SoftLimitTraitTest extends TestCase
11+
{
12+
public function testMemoryLimitNotReachedWhenLimitIsZero(): void
13+
{
14+
$instance = new class () {
15+
use SoftLimitTrait {
16+
memoryLimitReached as public;
17+
}
18+
19+
protected function getMemoryLimit(): int
20+
{
21+
return 0;
22+
}
23+
};
24+
25+
$this->assertFalse($instance->memoryLimitReached());
26+
}
27+
28+
public function testMemoryLimitNotReachedWhenUsageIsLower(): void
29+
{
30+
$currentMemoryUsage = memory_get_usage(true);
31+
$instance = new class ($currentMemoryUsage + 1024 * 1024) { // 1MB higher than current usage
32+
use SoftLimitTrait {
33+
memoryLimitReached as public;
34+
}
35+
36+
public function __construct(private int $limit)
37+
{
38+
}
39+
40+
protected function getMemoryLimit(): int
41+
{
42+
return $this->limit;
43+
}
44+
};
45+
46+
$this->assertFalse($instance->memoryLimitReached());
47+
}
48+
49+
public function testMemoryLimitReachedWhenUsageIsHigher(): void
50+
{
51+
$currentMemoryUsage = memory_get_usage(true);
52+
$instance = new class ($currentMemoryUsage - 1024) { // 1KB lower than current usage
53+
use SoftLimitTrait {
54+
memoryLimitReached as public;
55+
}
56+
57+
public function __construct(private int $limit)
58+
{
59+
}
60+
61+
protected function getMemoryLimit(): int
62+
{
63+
return $this->limit;
64+
}
65+
};
66+
67+
$this->assertTrue($instance->memoryLimitReached());
68+
}
69+
70+
public function testMemoryLimitExceededWhenUsageIncreases(): void
71+
{
72+
$currentMemoryUsage = memory_get_usage(true);
73+
$instance = new class ($currentMemoryUsage + 5 * 1024 * 1024) { // Set limit 5MB higher than current usage
74+
use SoftLimitTrait {
75+
memoryLimitReached as public;
76+
}
77+
78+
public function __construct(private int $limit)
79+
{
80+
}
81+
82+
protected function getMemoryLimit(): int
83+
{
84+
return $this->limit;
85+
}
86+
};
87+
88+
// Initially memory limit is not reached
89+
$this->assertFalse($instance->memoryLimitReached());
90+
91+
// Create a large string to increase memory usage
92+
$largeString = str_repeat('x', 5 * 1024 * 1024 + 1); // 5MB and 1 byte string
93+
94+
// Now memory limit should be exceeded
95+
$this->assertTrue($instance->memoryLimitReached());
96+
97+
// Clean up to free memory
98+
unset($largeString);
99+
}
100+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Queue\Tests\Unit\Message;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Yiisoft\Queue\Message\Message;
9+
use Yiisoft\Queue\Tests\App\DummyEnvelope;
10+
11+
final class EnvelopeTraitTest extends TestCase
12+
{
13+
private function createTestEnvelope(): DummyEnvelope
14+
{
15+
return new DummyEnvelope();
16+
}
17+
18+
public function testFromData(): void
19+
{
20+
$handlerName = 'test-handler';
21+
$data = ['key' => 'value'];
22+
$metadata = ['meta' => 'data'];
23+
24+
$envelope = DummyEnvelope::fromData($handlerName, $data, $metadata);
25+
26+
$this->assertInstanceOf(DummyEnvelope::class, $envelope);
27+
$this->assertSame($handlerName, $envelope->getHandlerName());
28+
$this->assertSame($data, $envelope->getData());
29+
$this->assertArrayHasKey('meta', $envelope->getMetadata());
30+
$this->assertSame('data', $envelope->getMetadata()['meta']);
31+
}
32+
33+
public function testWithMessage(): void
34+
{
35+
$originalMessage = new Message('original-handler', 'original-data');
36+
$newMessage = new Message('new-handler', 'new-data');
37+
38+
$envelope = $this->createTestEnvelope();
39+
$envelope = $envelope->withMessage($originalMessage);
40+
41+
$this->assertSame($originalMessage, $envelope->getMessage());
42+
43+
$newEnvelope = $envelope->withMessage($newMessage);
44+
45+
$this->assertNotSame($envelope, $newEnvelope);
46+
$this->assertSame($newMessage, $newEnvelope->getMessage());
47+
$this->assertSame($originalMessage, $envelope->getMessage());
48+
}
49+
}

tests/Unit/Message/JsonMessageSerializerTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Yiisoft\Queue\Tests\Unit\Message;
66

77
use InvalidArgumentException;
8+
use PHPUnit\Framework\Attributes\DataProvider;
89
use PHPUnit\Framework\TestCase;
910
use Yiisoft\Queue\Message\EnvelopeInterface;
1011
use Yiisoft\Queue\Message\IdEnvelope;
@@ -18,6 +19,55 @@
1819
*/
1920
final class JsonMessageSerializerTest extends TestCase
2021
{
22+
/**
23+
* @dataProvider dataUnsupportedHandlerNameFormat
24+
*/
25+
#[DataProvider('dataUnsupportedHandlerNameFormat')]
26+
public function testHandlerNameFormat(mixed $name): void
27+
{
28+
$payload = ['name' => $name, 'data' => 'test'];
29+
$serializer = $this->createSerializer();
30+
31+
$this->expectExceptionMessage(sprintf('Handler name must be a string. Got %s.', get_debug_type($name)));
32+
$this->expectException(InvalidArgumentException::class);
33+
$serializer->unserialize(json_encode($payload));
34+
}
35+
36+
public static function dataUnsupportedHandlerNameFormat(): iterable
37+
{
38+
yield 'number' => [1];
39+
yield 'boolean' => [true];
40+
yield 'null' => [null];
41+
yield 'array' => [[]];
42+
}
43+
44+
public function testDefaultMessageClassFallbackWrongClass(): void
45+
{
46+
$serializer = $this->createSerializer();
47+
$payload = [
48+
'name' => 'handler',
49+
'data' => 'test',
50+
'meta' => [
51+
'message-class' => 'NonExistentClass',
52+
],
53+
];
54+
55+
$message = $serializer->unserialize(json_encode($payload));
56+
$this->assertInstanceOf(Message::class, $message);
57+
}
58+
59+
public function testDefaultMessageClassFallbackClassNotSet(): void
60+
{
61+
$serializer = $this->createSerializer();
62+
$payload = [
63+
'name' => 'handler',
64+
'data' => 'test',
65+
'meta' => [],
66+
];
67+
$message = $serializer->unserialize(json_encode($payload));
68+
$this->assertInstanceOf(Message::class, $message);
69+
}
70+
2171
/**
2272
* @dataProvider dataUnsupportedPayloadFormat
2373
*/

tests/Unit/WorkerTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFactoryFailureInterface;
1919
use Yiisoft\Queue\QueueInterface;
2020
use Yiisoft\Queue\Tests\App\FakeHandler;
21+
use Yiisoft\Queue\Tests\App\StaticMessageHandler;
2122
use Yiisoft\Queue\Tests\TestCase;
2223
use Yiisoft\Queue\Worker\Worker;
2324

@@ -199,4 +200,57 @@ private function createWorkerByParams(
199200
new FailureMiddlewareDispatcher($this->createMock(MiddlewareFactoryFailureInterface::class), []),
200201
);
201202
}
203+
204+
public function testHandlerNotFoundInContainer(): void
205+
{
206+
$message = new Message('nonexistent', ['test-data']);
207+
$logger = new SimpleLogger();
208+
$container = new SimpleContainer();
209+
$handlers = [];
210+
211+
$queue = $this->createMock(QueueInterface::class);
212+
$worker = $this->createWorkerByParams($handlers, $logger, $container);
213+
214+
$this->expectException(\RuntimeException::class);
215+
$this->expectExceptionMessage('Queue handler with name "nonexistent" does not exist');
216+
$worker->process($message, $queue);
217+
}
218+
219+
public function testHandlerInContainerNotImplementingInterface(): void
220+
{
221+
$message = new Message('invalid', ['test-data']);
222+
$logger = new SimpleLogger();
223+
$container = new SimpleContainer([
224+
'invalid' => new class () {
225+
public function handle(): void
226+
{
227+
}
228+
},
229+
]);
230+
$handlers = [];
231+
232+
$queue = $this->createMock(QueueInterface::class);
233+
$worker = $this->createWorkerByParams($handlers, $logger, $container);
234+
235+
$this->expectException(\RuntimeException::class);
236+
$this->expectExceptionMessage('Queue handler with name "invalid" does not exist');
237+
$worker->process($message, $queue);
238+
}
239+
240+
public function testStaticMethodHandler(): void
241+
{
242+
$message = new Message('static-handler', ['test-data']);
243+
$logger = new SimpleLogger();
244+
$container = new SimpleContainer();
245+
$handlers = [
246+
'static-handler' => StaticMessageHandler::handle(...),
247+
];
248+
249+
$queue = $this->createMock(QueueInterface::class);
250+
$worker = $this->createWorkerByParams($handlers, $logger, $container);
251+
252+
StaticMessageHandler::$wasHandled = false;
253+
$worker->process($message, $queue);
254+
$this->assertTrue(StaticMessageHandler::$wasHandled);
255+
}
202256
}

0 commit comments

Comments
 (0)