Skip to content

Commit 5e9818c

Browse files
authored
Replace StubAdapter to InMemoryAdapter + Add stubs to CS Fixer config (#285)
1 parent c529da1 commit 5e9818c

9 files changed

Lines changed: 197 additions & 79 deletions

File tree

.php-cs-fixer.dist.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
$finder = (new Finder())->in([
1010
__DIR__ . '/config',
1111
__DIR__ . '/src',
12+
__DIR__ . '/stubs',
1213
__DIR__ . '/tests',
1314
]);
1415

psalm.xml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,8 @@
1212
<projectFiles>
1313
<directory name="src" />
1414
<directory name="stubs" />
15-
<directory name="tests" />
1615
<ignoreFiles>
1716
<directory name="vendor" />
1817
</ignoreFiles>
1918
</projectFiles>
20-
<issueHandlers>
21-
<PropertyNotSetInConstructor>
22-
<errorLevel type="suppress">
23-
<directory name="tests" />
24-
</errorLevel>
25-
</PropertyNotSetInConstructor>
26-
</issueHandlers>
2719
</psalm>
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Yiisoft\Queue\Tests\App;
5+
namespace Yiisoft\Queue\Stubs;
66

77
use Yiisoft\Queue\Adapter\AdapterInterface;
88
use Yiisoft\Queue\Message\IdEnvelope;
@@ -11,9 +11,21 @@
1111

1212
use function count;
1313

14-
final class MemoryAdapter implements AdapterInterface
14+
/**
15+
* In-memory implementation of {@see AdapterInterface} for testing and development purposes.
16+
*
17+
* This adapter stores messages in a local array and processes them sequentially within the same process without any
18+
* external queue backend. Messages are assigned incremental integer identifiers and are handled in FIFO order.
19+
*
20+
* Note: This implementation is not persistent and should not be used in production, as all data is lost when the
21+
* process ends.
22+
*/
23+
final class InMemoryAdapter implements AdapterInterface
1524
{
16-
/** @var array<int, MessageInterface> */
25+
/**
26+
* @var MessageInterface[]
27+
* @psalm-var array<int, MessageInterface>
28+
*/
1729
private array $messages = [];
1830
private int $current = 0;
1931

stubs/StubAdapter.php

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

stubs/StubLoop.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ final class StubLoop implements LoopInterface
1313
{
1414
public function __construct(
1515
private readonly bool $canContinue = true,
16-
) {
17-
}
16+
) {}
1817

1918
public function canContinue(): bool
2019
{

tests/Unit/Provider/QueueFactoryProviderTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use Yiisoft\Queue\Provider\QueueFactoryProvider;
1212
use Yiisoft\Queue\Provider\QueueNotFoundException;
1313
use Yiisoft\Queue\QueueInterface;
14-
use Yiisoft\Queue\Stubs\StubAdapter;
14+
use Yiisoft\Queue\Stubs\InMemoryAdapter;
1515
use Yiisoft\Queue\Stubs\StubLoop;
1616
use Yiisoft\Queue\Stubs\StubQueue;
1717
use Yiisoft\Queue\Tests\Unit\Support\StringEnum;
@@ -116,9 +116,8 @@ public function testGetHasByStringEnum(): void
116116

117117
public function testWithContainer(): void
118118
{
119-
$adapter = new StubAdapter();
120119
$container = new SimpleContainer([
121-
AdapterInterface::class => $adapter,
120+
AdapterInterface::class => new InMemoryAdapter(),
122121
]);
123122

124123
$provider = new QueueFactoryProvider(

tests/Unit/QueueTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
use Yiisoft\Queue\Message\IdEnvelope;
99
use Yiisoft\Queue\Message\Message;
1010
use Yiisoft\Queue\MessageStatus;
11+
use Yiisoft\Queue\Stubs\InMemoryAdapter;
1112
use Yiisoft\Queue\Tests\App\FakeAdapter;
12-
use Yiisoft\Queue\Tests\App\MemoryAdapter;
1313
use Yiisoft\Queue\Tests\TestCase;
1414

1515
use function extension_loaded;
@@ -73,7 +73,7 @@ public function testStatusReturnsNotFoundWithoutAdapter(): void
7373

7474
public function testRunWithAdapter(): void
7575
{
76-
$queue = $this->createQueue(new MemoryAdapter());
76+
$queue = $this->createQueue(new InMemoryAdapter());
7777
$message = new Message('simple', null);
7878
$queue->push($message);
7979
$queue->push(clone $message);
@@ -84,7 +84,7 @@ public function testRunWithAdapter(): void
8484

8585
public function testRunPartlyWithAdapter(): void
8686
{
87-
$queue = $this->createQueue(new MemoryAdapter());
87+
$queue = $this->createQueue(new InMemoryAdapter());
8888
$message = new Message('simple', null);
8989
$queue->push($message);
9090
$queue->push(clone $message);
@@ -95,7 +95,7 @@ public function testRunPartlyWithAdapter(): void
9595

9696
public function testListenWithAdapter(): void
9797
{
98-
$queue = $this->createQueue(new MemoryAdapter());
98+
$queue = $this->createQueue(new InMemoryAdapter());
9999
$message = new Message('simple', null);
100100
$queue->push($message);
101101
$queue->push(clone $message);
@@ -107,7 +107,7 @@ public function testListenWithAdapter(): void
107107

108108
public function testStatusWithAdapter(): void
109109
{
110-
$queue = $this->createQueue(new MemoryAdapter());
110+
$queue = $this->createQueue(new InMemoryAdapter());
111111
$envelope = $queue->push(new Message('simple', null));
112112

113113
self::assertArrayHasKey(IdEnvelope::MESSAGE_ID_KEY, $envelope->getMetadata());
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Queue\Tests\Unit\Stubs;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Yiisoft\Queue\Message\IdEnvelope;
9+
use Yiisoft\Queue\Message\Message;
10+
use Yiisoft\Queue\Message\MessageInterface;
11+
use Yiisoft\Queue\MessageStatus;
12+
use Yiisoft\Queue\Stubs\InMemoryAdapter;
13+
14+
final class InMemoryAdapterTest extends TestCase
15+
{
16+
public function testPush(): void
17+
{
18+
$adapter = new InMemoryAdapter();
19+
20+
$envelope1 = $adapter->push(new Message('test', 'a'));
21+
$envelope2 = $adapter->push(new Message('test', 'b'));
22+
$envelope3 = $adapter->push(new Message('test', 'c'));
23+
24+
$this->assertInstanceOf(IdEnvelope::class, $envelope1);
25+
$this->assertInstanceOf(IdEnvelope::class, $envelope2);
26+
$this->assertInstanceOf(IdEnvelope::class, $envelope3);
27+
28+
$this->assertSame(0, $envelope1->getId());
29+
$this->assertSame('a', $envelope1->getMessage()->getData());
30+
$this->assertSame(1, $envelope2->getId());
31+
$this->assertSame('b', $envelope2->getMessage()->getData());
32+
$this->assertSame(2, $envelope3->getId());
33+
$this->assertSame('c', $envelope3->getMessage()->getData());
34+
}
35+
36+
public function testStatusWaitingForPushedMessage(): void
37+
{
38+
$adapter = new InMemoryAdapter();
39+
$envelope = $adapter->push(new Message('test', null));
40+
41+
$this->assertInstanceOf(IdEnvelope::class, $envelope);
42+
$this->assertSame(MessageStatus::WAITING, $adapter->status($envelope->getId()));
43+
}
44+
45+
public function testStatusDoneAfterProcessing(): void
46+
{
47+
$adapter = new InMemoryAdapter();
48+
$envelope = $adapter->push(new Message('test', null));
49+
50+
$adapter->runExisting(static fn() => true);
51+
52+
$this->assertInstanceOf(IdEnvelope::class, $envelope);
53+
$this->assertSame(MessageStatus::DONE, $adapter->status($envelope->getId()));
54+
}
55+
56+
public function testStatusNotFoundForNonExistentId(): void
57+
{
58+
$adapter = new InMemoryAdapter();
59+
60+
$this->assertSame(MessageStatus::NOT_FOUND, $adapter->status(99));
61+
}
62+
63+
public function testStatusNotFoundForNegativeId(): void
64+
{
65+
$adapter = new InMemoryAdapter();
66+
67+
$this->assertSame(MessageStatus::NOT_FOUND, $adapter->status(-1));
68+
}
69+
70+
public function testStatusAcceptsStringId(): void
71+
{
72+
$adapter = new InMemoryAdapter();
73+
$envelope = $adapter->push(new Message('test', null));
74+
75+
$this->assertInstanceOf(IdEnvelope::class, $envelope);
76+
$this->assertSame(MessageStatus::WAITING, $adapter->status((string) $envelope->getId()));
77+
}
78+
79+
public function testRunExistingProcessesAllMessages(): void
80+
{
81+
$adapter = new InMemoryAdapter();
82+
$adapter->push(new Message('test', 'a'));
83+
$adapter->push(new Message('test', 'b'));
84+
$adapter->push(new Message('test', 'c'));
85+
86+
$processed = [];
87+
$adapter->runExisting(
88+
static function (MessageInterface $message) use (&$processed): bool {
89+
$processed[] = $message->getData();
90+
return true;
91+
},
92+
);
93+
94+
$this->assertSame(['a', 'b', 'c'], $processed);
95+
}
96+
97+
public function testRunExistingStopsWhenHandlerReturnsFalse(): void
98+
{
99+
$adapter = new InMemoryAdapter();
100+
$adapter->push(new Message('test', 'a'));
101+
$adapter->push(new Message('test', 'b'));
102+
$adapter->push(new Message('test', 'c'));
103+
104+
$processed = [];
105+
$adapter->runExisting(
106+
static function (MessageInterface $message) use (&$processed): bool {
107+
$processed[] = $message->getData();
108+
return false;
109+
},
110+
);
111+
112+
$this->assertSame(['a'], $processed);
113+
}
114+
115+
public function testRunExistingOnEmptyQueue(): void
116+
{
117+
$adapter = new InMemoryAdapter();
118+
119+
$called = false;
120+
$adapter->runExisting(static function () use (&$called): bool {
121+
$called = true;
122+
return true;
123+
});
124+
125+
$this->assertFalse($called);
126+
}
127+
128+
public function testRunExistingDoesNotReprocessMessages(): void
129+
{
130+
$adapter = new InMemoryAdapter();
131+
$adapter->push(new Message('test', 'x'));
132+
133+
$count = 0;
134+
$handler = static function () use (&$count): bool {
135+
$count++;
136+
return true;
137+
};
138+
$adapter->runExisting($handler);
139+
$adapter->runExisting($handler);
140+
141+
$this->assertSame(1, $count);
142+
}
143+
144+
public function testIdContinuesAfterProcessing(): void
145+
{
146+
$adapter = new InMemoryAdapter();
147+
$adapter->push(new Message('test', null));
148+
$adapter->runExisting(static fn() => true);
149+
150+
$envelope = $adapter->push(new Message('test', null));
151+
152+
$this->assertInstanceOf(IdEnvelope::class, $envelope);
153+
$this->assertSame(1, $envelope->getId());
154+
$this->assertSame(MessageStatus::WAITING, $adapter->status($envelope->getId()));
155+
}
156+
157+
public function testSubscribeProcessesExistingMessages(): void
158+
{
159+
$adapter = new InMemoryAdapter();
160+
$adapter->push(new Message('test', 'a'));
161+
$adapter->push(new Message('test', 'b'));
162+
163+
$processed = [];
164+
$adapter->subscribe(
165+
static function (MessageInterface $message) use (&$processed): bool {
166+
$processed[] = $message->getData();
167+
return true;
168+
},
169+
);
170+
171+
$this->assertSame(['a', 'b'], $processed);
172+
}
173+
}

tests/Unit/Stubs/StubAdapterTest.php

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

0 commit comments

Comments
 (0)