8000 Add functional test for ServerDumpCommand · symfony/symfony@0573d8d · GitHub
[go: up one dir, main page]

Skip to content

Commit 0573d8d

Browse files
Add functional test for ServerDumpCommand
1 parent 272f021 commit 0573d8d

File tree

3 files changed

+73
-44
lines changed

3 files changed

+73
-44
lines changed

src/Symfony/Component/VarDumper/Command/ServerDumpCommand.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\Console\Output\OutputInterface;
2222
use Symfony\Component\Console\Style\SymfonyStyle;
2323
use Symfony\Component\VarDumper\Cloner\Data;
24+
use Symfony\Component\VarDumper\Cloner\Stub;
2425
use Symfony\Component\VarDumper\Command\Descriptor\CliDescriptor;
2526
use Symfony\Component\VarDumper\Command\Descriptor\DumpDescriptorInterface;
2627
use Symfony\Component\VarDumper\Command\Descriptor\HtmlDescriptor;
@@ -85,15 +86,25 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8586

8687
$errorIo = $io->getErrorStyle();
8788
$errorIo->title('Symfony Var Dumper Server');
88-
89-
$this->server->start();
90-
9189
$errorIo->success(sprintf('Server listening on %s', $this->server->getHost()));
9290
$errorIo->comment('Quit the server with CONTROL-C.');
93-
94-
$this->server->listen(function (Data $data, array $context, int $clientId) use ($descriptor, $io) {
95-
$descriptor->describe($io, $data, $context, $clientId);
96-
});
91+
$this->server->listen(
92+
function (int $clientId, string $message) use ($descriptor, $io) {
93+
$payload = @unserialize(base64_decode($message), ['allowed_classes' => [Data::class, Stub::class]]);
94+
95+
// Impossible to decode the message, give up.
96+
if (false === $payload) {
97+
return;
98+
}
99+
100+
if (!\is_array($payload) || \count($payload) < 2 || !$payload[0] instanceof Data || !\is_array($payload[1])) {
101+
return;
102+
}
103+
[$data, $context] = $payload;
104+
$descriptor->describe($io, $data, $context, $clientId);
105+
},
106+
$input,
107+
);
97108

98109
return 0;
99110
}

src/Symfony/Component/VarDumper/Server/DumpServer.php

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\VarDumper\Server;
1313

1414
use Psr\Log\LoggerInterface;
15+
use Symfony\Component\Console\Input\StreamableInputInterface;
1516
use Symfony\Component\VarDumper\Cloner\Data;
1617
use Symfony\Component\VarDumper\Cloner\Stub;
1718

@@ -32,6 +33,11 @@ class DumpServer
3233
*/
3334
private $socket;
3435

36+
/**
37+
* @var resource|null
38+
*/
39+
private $inputStream;
40+
3541
public function __construct(string $host, ?LoggerInterface $logger = null)
3642
{
3743
if (!str_contains($host, '://')) {
@@ -49,33 +55,18 @@ public function start(): void
4955
}
5056
}
5157

52-
public function listen(callable $callback): void
58+
public function listen(callable $callback, ?StreamableInputInterface $streamInput): void
5359
{
54-
if (null === $this->socket) {
60+
if ($streamInput instanceof StreamableInputInterface && $stream = $streamInput->getStream()) {
61+
$this->inputStream = $stream;
62+
} elseif (null === $this->socket) {
5563
$this->start();
5664
}
5765

5866
foreach ($this->getMessages() as $clientId => $message) {
5967
$this->logger?->info('Received a payload from client {clientId}', ['clientId' => $clientId]);
6068

61-
$payload = @unserialize(base64_decode($message), ['allowed_classes' => [Data::class, Stub::class]]);
62-
63-
// Impossible to decode the message, give up.
64-
if (false === $payload) {
65-
$this->logger?->warning('Unable to decode a message from {clientId} client.', ['clientId' => $clientId]);
66-
67-
continue;
68-
}
69-
70-
if (!\is_array($payload) || \count($payload) < 2 || !$payload[0] instanceof Data || !\is_array($payload[1])) {
71-
$this->logger?->warning('Invalid payload from {clientId} client. Expected an array of two elements (Data $data, array $context)', ['clientId' => $clientId]);
72-
73-
continue;
74-
}
75-
76-
[$data, $context] = $payload;
77-
78-
$callback($data, $context, $clientId);
69+
$callback($clientId, $message);
7970
}
8071
}
8172

@@ -86,22 +77,29 @@ public function getHost(): string
8677

8778
private function getMessages(): iterable
8879
{
89-
$sockets = [(int) $this->socket => $this->socket];
90-
$write = [];
91-
92-
while (true) {
93-
$read = $sockets;
94-
stream_select($read, $write, $write, null);
95-
96-
foreach ($read as $stream) {
97-
if ($this->socket === $stream) {
98-
$stream = stream_socket_accept($this->socket);
99-
$sockets[(int) $stream] = $stream;
100-
} elseif (feof($stream)) {
101-
unset($sockets[(int) $stream]);
102-
fclose($stream);
103-
} else {
104-
yield (int) $stream => fgets($stream);
80+
if (null !== $inputStream = $this->inputStream) {
81+
F438 while (!feof($inputStream)) {
82+
$stream = fgets($inputStream);
83+
yield (int) $stream => $stream;
84+
}
85+
} else {
86+
$sockets = [(int) $this->socket => $this->socket];
87+
$write = [];
88+
89+
while (true) {
90+
$read = $sockets;
91+
stream_select($read, $write, $write, null);
92+
93+
foreach ($read as $stream) {
94+
if ($this->socket === $stream) {
95+
$stream = stream_socket_accept($this->socket);
96+
$sockets[(int) $stream] = $stream;
97+
} elseif (feof($stream)) {
98+
unset($sockets[(int) $stream]);
99+
fclose($stream);
100+
} else {
101+
yield (int) $stream => fgets($stream);
102+
}
105103
}
106104
}
107105
}

src/Symfony/Component/VarDumper/Tests/Command/ServerDumpCommandTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Console\Tester\CommandCompletionTester;
16+
use Symfony\Component\Console\Tester\CommandTester;
17+
use Symfony\Component\VarDumper\Cloner\Data;
1618
use Symfony\Component\VarDumper\Command\ServerDumpCommand;
1719
use Symfony\Component\VarDumper\Server\DumpServer;
1820

@@ -28,6 +30,24 @@ public function testComplete(array $input, array $expectedSuggestions)
2830
$this->assertSame($expectedSuggestions, $tester->complete($input));
2931
}
3032

D721 33+
public function testServerDumpSuccess()
34+
{
35+
$command = $this->createCommand();
36+
$commandTester = new CommandTester($command);
37+
38+
$data = new Data([['my dump']]);
39+
$input = base64_encode(serialize([$data, ['timestamp' => time(), 'source' => ['name' => 'sourceName', 'line' => 222, 'file' => 'myFile']]]))."\n";
40+
41+
$commandTester->setInputs([$input]);
42+
43+
$commandTester->execute(['--format' => 'html']);
44+
45+
$commandTester->assertCommandIsSuccessful();
46+
47+
$output = $commandTester->getDisplay();
48+
$this->assertStringContainsString('my dump', $output);
49+
}
50+
3151
public static function provideCompletionSuggestions()
3252
{
3353
yield 'option --format' => [
@@ -38,6 +58,6 @@ public static function provideCompletionSuggestions()
3858

3959
private function createCommand(): ServerDumpCommand
4060
{
41-
return new ServerDumpCommand($this->createMock(DumpServer::class));
61+
return new ServerDumpCommand(new DumpServer(''));
4262
}
4363
}

0 commit comments

Comments
 (0)
0