diff --git a/.gitattributes b/.gitattributes index a353f44..e96ad9c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,3 +4,5 @@ /examples/ export-ignore /phpunit.xml.dist export-ignore /tests/ export-ignore + +*.php diff=php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 438fcc4..2a040a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,14 +11,9 @@ jobs: strategy: matrix: php: - - 7.3 - - 7.2 - - 7.1 - - 7.0 - - 5.6 - - 5.5 - - 5.4 - - 5.3 + - 8.1 + - 8.0 + - 7.4 steps: - uses: actions/checkout@v2 - uses: shivammathur/setup-php@v2 diff --git a/.gitignore b/.gitignore index c8153b5..1ea9e4c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ -/composer.lock -/vendor/ +.DS_Store +/vendor +composer.lock +/build +/.phpunit.cache +.phpunit.result.cache diff --git a/README.md b/README.md index 58eb26c..bb8b089 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ See the [examples](examples). The recommended way to install this library is [through composer](http://getcomposer.org). [New to composer?](http://getcomposer.org/doc/00-intro.md) -```JSON +```json { "require": { "clue/sse-react": "dev-master" @@ -28,14 +28,14 @@ The recommended way to install this library is [through composer](http://getcomp To run the test suite, you first need to clone this repo and then install all dependencies [through Composer](http://getcomposer.org): -```bash -$ composer install +```sh +composer install ``` To run the test suite, go to the project root and run: -```bash -$ php vendor/bin/phpunit +```sh +php vendor/bin/phpunit ``` ## License diff --git a/composer.json b/composer.json index 5da0c8d..1d646d7 100644 --- a/composer.json +++ b/composer.json @@ -1,26 +1,39 @@ { - "name": "clue/sse-react", + "name": "rodber/php-sse-react", "description": "Streaming, async HTML5 Server-Sent Events server (aka. SSE or EventSource)", - "keywords": ["Server-Sent Events", "SSE", "EventSource", "event-driven", "ReactPHP", "async"], - "homepage": "https://github.com/clue/php-sse-react", + "keywords": [ + "Server-Sent Events", + "SSE", + "EventSource", + "event-driven", + "ReactPHP", + "async" + ], + "homepage": "https://github.com/rodber/php-sse-react", "license": "MIT", "authors": [ { "name": "Christian Lück", "email": "christian@lueck.tv" + }, + { + "name": "Rodolfo Berrios", + "email": "rodolfo@chevere.org" } ], "autoload": { - "psr-4": { "Clue\\React\\Sse\\": "src/" } + "psr-4": { + "Clue\\React\\Sse\\": "src/" + } }, "require": { - "php": ">=5.3", - "react/event-loop": "^1.0", - "react/http": "^1.0", - "react/stream": "^1.0" + "php": ">=7.4", + "react/event-loop": "^1.2", + "react/http": "^1.5", + "react/stream": "^1.2" }, "require-dev": { - "clue/redis-react": "^2.4", - "phpunit/phpunit": "^5.0 || ^4.8" + "clue/redis-react": "^2.5", + "phpunit/phpunit": "^9.5" } } diff --git a/examples/01-simple-periodic.php b/examples/01-simple-periodic.php index fa8b7ef..2b87d5f 100644 --- a/examples/01-simple-periodic.php +++ b/examples/01-simple-periodic.php @@ -7,11 +7,11 @@ use React\Http\Message\Response; use React\Stream\ThroughStream; -$loop = React\EventLoop\Factory::create(); +$loop = React\EventLoop\Loop::get(); $channel = new BufferedChannel(); -$http = new React\Http\Server($loop, function (ServerRequestInterface $request) use ($channel, $loop) { +$http = new React\Http\HttpServer($loop, function (ServerRequestInterface $request) use ($channel, $loop) { if ($request->getUri()->getPath() === '/') { return new Response( 200, @@ -45,7 +45,7 @@ ); }); -$socket = new \React\Socket\Server(isset($argv[1]) ? '0.0.0.0:' . $argv[1] : '0.0.0.0:0', $loop); +$socket = new \React\Socket\SocketServer(isset($argv[1]) ? '0.0.0.0:' . $argv[1] : '0.0.0.0:0', [], $loop); $http->listen($socket); $loop->addPeriodicTimer(2.0, function () use ($channel) { diff --git a/examples/02-plaintext-chat.php b/examples/02-plaintext-chat.php index 896a565..fe7d619 100644 --- a/examples/02-plaintext-chat.php +++ b/examples/02-plaintext-chat.php @@ -8,11 +8,11 @@ use React\Socket\TcpConnector; use React\Stream\ThroughStream; -$loop = React\EventLoop\Factory::create(); +$loop = React\EventLoop\Loop::get(); $channel = new BufferedChannel(); -$http = new React\Http\Server($loop, function (ServerRequestInterface $request) use ($channel, $loop) { +$http = new React\Http\HttpServer($loop, function (ServerRequestInterface $request) use ($channel, $loop) { if ($request->getUri()->getPath() === '/') { return new Response( 200, @@ -61,7 +61,7 @@ }); }, 'printf'); -$socket = new \React\Socket\Server(isset($argv[1]) ? '0.0.0.0:' . $argv[1] : '0.0.0.0:0', $loop); +$socket = new \React\Socket\SocketServer(isset($argv[1]) ? '0.0.0.0:' . $argv[1] : '0.0.0.0:0', [], $loop); $http->listen($socket); echo 'Server now listening on ' . $socket->getAddress() . ' (port is first parameter)' . PHP_EOL; diff --git a/examples/03-redis-subscribe.php b/examples/03-redis-subscribe.php index f9ea908..c048857 100644 --- a/examples/03-redis-subscribe.php +++ b/examples/03-redis-subscribe.php @@ -8,11 +8,11 @@ use React\Http\Message\Response; use React\Stream\ThroughStream; -$loop = React\EventLoop\Factory::create(); +$loop = React\EventLoop\Loop::get(); $channel = new BufferedChannel(); -$http = new React\Http\Server($loop, function (ServerRequestInterface $request) use ($channel, $loop) { +$http = new React\Http\HttpServer($loop, function (ServerRequestInterface $request) use ($channel, $loop) { if ($request->getUri()->getPath() === '/') { return new Response( '200', @@ -57,7 +57,7 @@ echo 'ERROR: Unable to subscribe to Redis channel: ' . $e; }); -$socket = new \React\Socket\Server(isset($argv[1]) ? '0.0.0.0:' . $argv[1] : '0.0.0.0:0', $loop); +$socket = new \React\Socket\SocketServer(isset($argv[1]) ? '0.0.0.0:' . $argv[1] : '0.0.0.0:0', [], $loop); $http->listen($socket); echo 'Server now listening on ' . $socket->getAddress() . ' (port is first parameter)' . PHP_EOL; diff --git a/examples/11-chat.php b/examples/11-chat.php index c28da42..35311c7 100644 --- a/examples/11-chat.php +++ b/examples/11-chat.php @@ -7,11 +7,11 @@ use React\Http\Message\Response; use React\Stream\ThroughStream; -$loop = React\EventLoop\Factory::create(); +$loop = React\EventLoop\Loop::get(); $channel = new BufferedChannel(); -$http = new React\Http\Server($loop, function (ServerRequestInterface $request) use ($channel, $loop) { +$http = new React\Http\HttpServer($loop, function (ServerRequestInterface $request) use ($channel, $loop) { switch ($request->getUri()->getPath()) { case '/': return new Response( @@ -65,7 +65,7 @@ } }); -$socket = new \React\Socket\Server(isset($argv[1]) ? '0.0.0.0:' . $argv[1] : '0.0.0.0:0', $loop); +$socket = new \React\Socket\SocketServer(isset($argv[1]) ? '0.0.0.0:' . $argv[1] : '0.0.0.0:0', [], $loop); $http->listen($socket); echo 'Server now listening on ' . $socket->getAddress() . ' (port is first parameter)' . PHP_EOL; diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4633355..9d79e87 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,19 +1,31 @@ - + convertWarningsToExceptions="true"> - ./tests/ + tests/ - - - ./src/ - - + + + + + + src/ + + + + + + \ No newline at end of file diff --git a/tests/BufferedChannelTest.php b/tests/BufferedChannelTest.php index 2cd4cdb..ed862f5 100644 --- a/tests/BufferedChannelTest.php +++ b/tests/BufferedChannelTest.php @@ -1,41 +1,37 @@ getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - + $stream = $this + ->getMockBuilder('React\Stream\WritableStreamInterface') + ->getMock(); $called = 0; $stream->expects($this->any())->method('write')->will($this->returnCallback(function () use (&$called) { ++$called; })); - + /** @var $stream WritableStreamInterface */ $channel = new BufferedChannel(); - // initially nothing written $channel->connect($stream); $this->assertEquals(0, $called); - // writing does send $channel->writeMessage('first'); $this->assertEquals(1, $called); - // writing does send again $channel->writeMessage('second'); $this->assertEquals(2, $called); - // writing after disconnect does not send $channel->disconnect($stream); $channel->writeMessage('third'); $this->assertEquals(2, $called); - // connecting does not send $channel->connect($stream); $this->assertEquals(2, $called); - // connecting with offset will send remaining message $channel->disconnect($stream); $channel->connect($stream, 2); @@ -44,19 +40,17 @@ public function testNumberOfWritesToStream() public function testResultingStreamBuffer() { - $stream = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - + $stream = $this + ->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); $buffered = ''; $stream->expects($this->any())->method('write')->will($this->returnCallback(function ($data) use (&$buffered) { $buffered .= $data; })); - + /** @var $stream WritableStreamInterface */ $channel = new BufferedChannel(); - // initially nothing $channel->writeMessage('hello', 'world'); $this->assertEquals('', $buffered); - // connecting will send messages buffered in channel $channel->connect($stream, 0); $this->assertEquals("id: 0\nevent: world\ndata: hello\n\n", $buffered); diff --git a/tests/EncoderTest.php b/tests/EncoderTest.php index 17751c3..83945be 100644 --- a/tests/EncoderTest.php +++ b/tests/EncoderTest.php @@ -6,33 +6,37 @@ class EncoderTest extends TestCase { private $encoder; - public function setUp() + public function setUp(): void { $this->encoder = new Encoder(); } - public function testData() + public function testData(): void { - $this->assertEquals("data: test\n", $this->encoder->encodeData('test')); + $this->assertSame("data: test\n", $this->encoder->encodeData('test')); } - public function testDataMultiLine() + public function testDataMultiLine(): void { - $this->assertEquals("data: first\ndata: second\n", $this->encoder->encodeData("first\nsecond")); + $this->assertSame("data: first\ndata: second\n", $this->encoder->encodeData("first\nsecond")); } - public function testDataEmpty() + public function testDataEmpty(): void { - $this->assertEquals("data: \n", $this->encoder->encodeData("")); + $this->assertSame("data: \n", $this->encoder->encodeData("")); } - public function testComment() + public function testComment(): void { $this->assertEquals(":welcome!\n", $this->encoder->encodeComment('welcome!')); } - public function testMessage() + public function testMessage(): void { $this->assertEquals("id: 123\nevent: demo\ndata: test\n\n", $this->encoder->encodeMessage('test', 'demo', 123)); } + + public function testEncodeFieldEmpty(): void { + $this->assertEquals("string\n", $this->encoder->encodeFieldEmpty('string')); + } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 572fa88..1eb2c94 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,15 +1,14 @@ createCallableMock(); - $mock ->expects($this->once()) ->method('__invoke');