109 lines
3.5 KiB
PHP
109 lines
3.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace NoccyLabs\React\Protocol\Json;
|
||
|
|
|
||
|
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||
|
|
use React\Stream\CompositeStream;
|
||
|
|
use React\Stream\ThroughStream;
|
||
|
|
|
||
|
|
#[CoversClass(JsonProtocol::class)]
|
||
|
|
class JsonProtocolTest extends \PHPUnit\Framework\TestCase
|
||
|
|
{
|
||
|
|
|
||
|
|
public function testFrameSeparators()
|
||
|
|
{
|
||
|
|
$proto = new JsonProtocol("\0");
|
||
|
|
$packed = $proto->packFrame(['foo' => 'bar']);
|
||
|
|
$this->assertEquals("{\"foo\":\"bar\"}\0", $packed);
|
||
|
|
|
||
|
|
$proto = new JsonProtocol("\n");
|
||
|
|
$packed = $proto->packFrame(['foo' => 'bar']);
|
||
|
|
$this->assertEquals("{\"foo\":\"bar\"}\n", $packed);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testFrameSizePrefixes()
|
||
|
|
{
|
||
|
|
$proto = new JsonProtocol(prependSizeBytes: 1);
|
||
|
|
$packed = $proto->packFrame(['foo' => 'bar']);
|
||
|
|
$this->assertEquals("\x0E{\"foo\":\"bar\"}\0", $packed);
|
||
|
|
|
||
|
|
$proto = new JsonProtocol(prependSizeBytes: 2, prependSizeEndian: 'l');
|
||
|
|
$packed = $proto->packFrame(['foo' => 'bar']);
|
||
|
|
$this->assertEquals("\x0E\x00{\"foo\":\"bar\"}\0", $packed);
|
||
|
|
|
||
|
|
$proto = new JsonProtocol(prependSizeBytes: 2, prependSizeEndian: 'b');
|
||
|
|
$packed = $proto->packFrame(['foo' => 'bar']);
|
||
|
|
$this->assertEquals("\x00\x0E{\"foo\":\"bar\"}\0", $packed);
|
||
|
|
|
||
|
|
$proto = new JsonProtocol(prependSizeBytes: 4, prependSizeEndian: 'l');
|
||
|
|
$packed = $proto->packFrame(['foo' => 'bar']);
|
||
|
|
$this->assertEquals("\x0E\x00\x00\x00{\"foo\":\"bar\"}\0", $packed);
|
||
|
|
|
||
|
|
$proto = new JsonProtocol(prependSizeBytes: 4, prependSizeEndian: 'b');
|
||
|
|
$packed = $proto->packFrame(['foo' => 'bar']);
|
||
|
|
$this->assertEquals("\x00\x00\x00\x0E{\"foo\":\"bar\"}\0", $packed);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testPackingCallbacks()
|
||
|
|
{
|
||
|
|
$proto = new JsonProtocol(
|
||
|
|
prependSizeBytes: 0,
|
||
|
|
beforePackCb: function (array $data) {
|
||
|
|
$data['a'] = true;
|
||
|
|
return $data;
|
||
|
|
},
|
||
|
|
afterPackCb: function (string $data) {
|
||
|
|
return $data."a";
|
||
|
|
},
|
||
|
|
);
|
||
|
|
$packed = $proto->packFrame(['foo' => 'bar']);
|
||
|
|
$this->assertEquals("{\"foo\":\"bar\",\"a\":true}\0a", $packed);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testUnpackingCallbacks()
|
||
|
|
{
|
||
|
|
$proto = new JsonProtocol(
|
||
|
|
prependSizeBytes: 0,
|
||
|
|
beforeUnpackCb: function (string $data) {
|
||
|
|
return strtolower($data);
|
||
|
|
},
|
||
|
|
afterUnpackCb: function (array $data) {
|
||
|
|
unset($data['a']);
|
||
|
|
return $data;
|
||
|
|
},
|
||
|
|
);
|
||
|
|
$unpacked = $proto->unpackFrame("{\"FOO\":\"bar\",\"a\":true}\0");
|
||
|
|
$expect = ['foo' => 'bar'];
|
||
|
|
$this->assertEquals($expect, $unpacked);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testConsumingFrames()
|
||
|
|
{
|
||
|
|
$proto = new JsonProtocol(
|
||
|
|
frameSeparator: "\n"
|
||
|
|
);
|
||
|
|
|
||
|
|
$buffer = '{"foo":true}'."\n".'{"bar":false}'."\n";
|
||
|
|
$msg1 = $proto->consumeFrame($buffer);
|
||
|
|
$msg2 = $proto->consumeFrame($buffer);
|
||
|
|
|
||
|
|
$this->assertEquals(['foo'=>true], $msg1);
|
||
|
|
$this->assertEquals(['bar'=>false], $msg2);
|
||
|
|
|
||
|
|
$proto = new JsonProtocol(
|
||
|
|
frameSeparator: "\n",
|
||
|
|
prependSizeBytes: 4,
|
||
|
|
prependSizeEndian: 'l',
|
||
|
|
);
|
||
|
|
|
||
|
|
$buffer = "\x0c\x00\x00\x00".'{"foo":true}'."\n"."\x0d\x00\x00\x00".'{"bar":false}'."\n";
|
||
|
|
$msg1 = $proto->consumeFrame($buffer);
|
||
|
|
$msg2 = $proto->consumeFrame($buffer);
|
||
|
|
|
||
|
|
$this->assertEquals(['foo'=>true], $msg1);
|
||
|
|
$this->assertEquals(['bar'=>false], $msg2);
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|