From dd687894add2bc82c6db6b903022329a3db07641 Mon Sep 17 00:00:00 2001 From: Paul Rock Date: Sat, 30 Jan 2021 17:29:35 +0300 Subject: [PATCH] Support of PHP 8.0 implemented, tests fixed, for #52 --- .travis.yml | 1 + composer.json | 9 +---- phpunit.local.xml | 37 ++++++++++++++++++ phpunit.xml | 7 ++-- src/Streams/ResourceStream.php | 27 ++++++------- tests/APIConnectorTest.php | 2 +- tests/ClientTest.php | 73 ++++++++++++++++++------------------ tests/ResponseIteratorTest.php | 2 +- tests/Streams/ResourceStreamTest.php | 23 ++++-------- 9 files changed, 104 insertions(+), 77 deletions(-) create mode 100644 phpunit.local.xml diff --git a/.travis.yml b/.travis.yml index 105c441..d934c76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ php: - '7.2' - '7.3' - '7.4' +- '8.0' before_script: - sudo apt-get update diff --git a/composer.json b/composer.json index a908f03..7affd51 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ } }, "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-sockets": "*", "divineomega/php-ssh-connection": "^2.2" }, @@ -49,12 +49,9 @@ "friendsofphp/php-cs-fixer": "^2.16", "limedeck/phpunit-detailed-printer": "^5.0", "orchestra/testbench": "^4.0|^5.0", - "phpstan/phpstan": "^0.12.32", - "phpstan/phpstan-strict-rules": "^0.12.2", "phpunit/phpunit": "^8.0", - "rector/rector": "^0.7.41", + "rector/rector": "^0.7|^0.8|^0.9", "roave/security-advisories": "dev-master", - "thecodingmachine/phpstan-strict-rules": "^0.12.0", "squizlabs/php_codesniffer": "^3.5", "larapack/dd": "^1.1" }, @@ -66,11 +63,9 @@ "lint": "rector process src && php-cs-fixer fix -v", "test:lint": "php-cs-fixer fix -v --dry-run", "test:rector": "rector process src --dry-run", - "test:types": "phpstan analyse --ansi --memory-limit=0", "test:unit": "phpunit --coverage-clover clover.xml", "test": [ "@test:lint", - "@test:types", "@test:unit" ] } diff --git a/phpunit.local.xml b/phpunit.local.xml new file mode 100644 index 0000000..b4bd85b --- /dev/null +++ b/phpunit.local.xml @@ -0,0 +1,37 @@ + + + + + ./src + + ./tests + + + + + + + + + ./tests/ + + + + + + + + + + + + diff --git a/phpunit.xml b/phpunit.xml index 809ef5f..4a090e5 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -26,11 +26,12 @@ - - - + + + + diff --git a/src/Streams/ResourceStream.php b/src/Streams/ResourceStream.php index 5139fc2..44e82e1 100644 --- a/src/Streams/ResourceStream.php +++ b/src/Streams/ResourceStream.php @@ -25,12 +25,7 @@ class ResourceStream implements StreamInterface public function __construct($stream) { if (!is_resource($stream)) { - throw new \InvalidArgumentException( - sprintf( - 'Argument must be a valid resource type. %s given.', - gettype($stream) - ) - ); + throw new \InvalidArgumentException(sprintf('Argument must be a valid resource type. %s given.', gettype($stream))); } // TODO: Should we verify the resource type? @@ -38,7 +33,7 @@ class ResourceStream implements StreamInterface } /** - * @inheritDoc + * {@inheritDoc} * * @throws \RouterOS\Exceptions\StreamException when length parameter is invalid * @throws \InvalidArgumentException when the stream have been totally read and read method is called again @@ -49,8 +44,11 @@ class ResourceStream implements StreamInterface throw new \InvalidArgumentException('Cannot read zero ot negative count of bytes from a stream'); } - // TODO: Ignore errors here, but why? - $result = @fread($this->stream, $length); + if (!is_resource($this->stream)) { + throw new StreamException('Stream is not writable'); + } + + $result = fread($this->stream, $length); if (false === $result) { throw new StreamException("Error reading $length bytes"); @@ -60,7 +58,7 @@ class ResourceStream implements StreamInterface } /** - * @inheritDoc + * {@inheritDoc} * * @throws \RouterOS\Exceptions\StreamException when not possible to write bytes */ @@ -70,8 +68,11 @@ class ResourceStream implements StreamInterface $length = strlen($string); } - // TODO: Ignore errors here, but why? - $result = @fwrite($this->stream, $string, $length); + if (!is_resource($this->stream)) { + throw new StreamException('Stream is not writable'); + } + + $result = fwrite($this->stream, $string, $length); if (false === $result) { throw new StreamException("Error writing $length bytes"); @@ -81,7 +82,7 @@ class ResourceStream implements StreamInterface } /** - * @inheritDoc + * {@inheritDoc} * * @throws \RouterOS\Exceptions\StreamException when not possible to close the stream */ diff --git a/tests/APIConnectorTest.php b/tests/APIConnectorTest.php index f0a5829..d74bc3c 100644 --- a/tests/APIConnectorTest.php +++ b/tests/APIConnectorTest.php @@ -38,7 +38,7 @@ class APIConnectorTest extends TestCase { return [ [new ResourceStream(fopen(__FILE__, 'rb'))], // Myself, sure I exists - [new ResourceStream(fsockopen('tcp://' . getenv('ROS_HOST'), getenv('ROS_PORT_MODERN')))], // Socket + [new ResourceStream(fsockopen('tcp://' . getenv('ROS_HOST_MODERN'), getenv('ROS_PORT_MODERN')))], // Socket [new ResourceStream(STDIN), false], // Try it, but do not close STDIN please !!! [new StringStream('Hello World !!!')], // Try it, but do not close STDIN please !!! [new StringStream('')], // Try it, but do not close STDIN please !!! diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 78dbb42..f8a391b 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -7,7 +7,6 @@ use PHPUnit\Framework\TestCase; use RouterOS\Client; use RouterOS\Exceptions\ConfigException; use RouterOS\Exceptions\QueryException; -use RouterOS\Query; use RouterOS\Config; use RouterOS\Exceptions\ClientException; use RouterOS\Exceptions\ConnectException; @@ -40,7 +39,7 @@ class ClientTest extends TestCase $this->config = [ 'user' => getenv('ROS_USER'), 'pass' => getenv('ROS_PASS'), - 'host' => getenv('ROS_HOST'), + 'host' => getenv('ROS_HOST_MODERN'), 'ssh_port' => (int) getenv('ROS_SSH_PORT'), ]; @@ -66,11 +65,11 @@ class ClientTest extends TestCase ->set('host', $this->config['host']); $obj = new Client($config); - $this->assertIsObject($obj); + self::assertIsObject($obj); $socket = $obj->getSocket(); - $this->assertIsResource($socket); + self::assertIsResource($socket); } catch (Exception $e) { - $this->assertStringContainsString('Must be initialized ', $e->getMessage()); + self::assertStringContainsString('Must be initialized ', $e->getMessage()); } } @@ -79,11 +78,11 @@ class ClientTest extends TestCase try { $config = new Config($this->config); $obj = new Client($config); - $this->assertIsObject($obj); + self::assertIsObject($obj); $socket = $obj->getSocket(); - $this->assertIsResource($socket); + self::assertIsResource($socket); } catch (Exception $e) { - $this->assertStringContainsString('Must be initialized ', $e->getMessage()); + self::assertStringContainsString('Must be initialized ', $e->getMessage()); } } @@ -91,11 +90,11 @@ class ClientTest extends TestCase { try { $obj = new Client($this->config); - $this->assertIsObject($obj); + self::assertIsObject($obj); $socket = $obj->getSocket(); - $this->assertIsResource($socket); + self::assertIsResource($socket); } catch (Exception $e) { - $this->assertStringContainsString('Must be initialized ', $e->getMessage()); + self::assertStringContainsString('Must be initialized ', $e->getMessage()); } } @@ -128,13 +127,13 @@ class ClientTest extends TestCase $obj = new Client([ 'user' => $this->config['user'], 'pass' => $this->config['pass'], - 'host' => $this->config['host'], + 'host' => getenv('ROS_HOST_LEGACY'), 'port' => $this->port_legacy, 'legacy' => true, ]); - $this->assertIsObject($obj); + self::assertIsObject($obj); } catch (Exception $e) { - $this->assertStringContainsString('Must be initialized ', $e->getMessage()); + self::assertStringContainsString('Must be initialized ', $e->getMessage()); } } @@ -153,9 +152,9 @@ class ClientTest extends TestCase 'port' => $this->port_legacy, 'legacy' => false, ]); - $this->assertIsObject($obj); + self::assertIsObject($obj); } catch (Exception $e) { - $this->assertStringContainsString('Must be initialized ', $e->getMessage()); + self::assertStringContainsString('Must be initialized ', $e->getMessage()); } } @@ -205,7 +204,7 @@ class ClientTest extends TestCase { $matches = []; $this->client->pregResponse($line, $matches); - $this->assertEquals($matches, $result); + self::assertEquals($matches, $result); } public function testQueryRead(): void @@ -215,22 +214,22 @@ class ClientTest extends TestCase */ $read = $this->client->query('/system/package/print', ['name'])->read(); - $this->assertNotEmpty($read); + self::assertNotEmpty($read); $read = $this->client->query('/system/package/print', ['.id', '*1'])->read(); - $this->assertCount(1, $read); + self::assertCount(1, $read); $read = $this->client->query('/system/package/print', ['.id', '=', '*1'])->read(); - $this->assertCount(1, $read); + self::assertCount(1, $read); $read = $this->client->query('/system/package/print', [['name']])->read(); - $this->assertNotEmpty($read); + self::assertNotEmpty($read); $read = $this->client->query('/system/package/print', [['.id', '*1']])->read(); - $this->assertCount(1, $read); + self::assertCount(1, $read); $read = $this->client->query('/system/package/print', [['.id', '=', '*1']])->read(); - $this->assertCount(1, $read); + self::assertCount(1, $read); /* * Build query with operations @@ -240,8 +239,8 @@ class ClientTest extends TestCase ['type', 'ether'], ['type', 'vlan'], ], '|')->read(); - $this->assertCount(1, $read); - $this->assertEquals('*1', $read[0]['.id']); + self::assertCount(1, $read); + self::assertEquals('*1', $read[0]['.id']); /* * Build query with tag @@ -249,34 +248,34 @@ class ClientTest extends TestCase $read = $this->client->query('/system/package/print', null, null, 'zzzz')->read(); - // $this->assertCount(13, $read); - $this->assertEquals('zzzz', $read[0]['tag']); + // self::assertCount(13, $read); + self::assertEquals('zzzz', $read[0]['tag']); /* * Build query with option count */ $read = $this->client->query('/interface/monitor-traffic')->read(true, ['count' => 3]); - $this->assertCount(3, $read); + self::assertCount(3, $read); } public function testReadAsIterator(): void { $result = $this->client->query('/system/package/print')->readAsIterator(); - $this->assertIsObject($result); + self::assertIsObject($result); } public function testWriteReadString(): void { $readTrap = $this->client->query('/interface')->read(false); - $this->assertCount(3, $readTrap); - $this->assertEquals('!trap', $readTrap[0]); + self::assertCount(3, $readTrap); + self::assertEquals('!trap', $readTrap[0]); } public function testFatal(): void { $readTrap = $this->client->query('/quit')->read(); - $this->assertCount(2, $readTrap); - $this->assertEquals('!fatal', $readTrap[0]); + self::assertCount(2, $readTrap); + self::assertEquals('!fatal', $readTrap[0]); } public function queryExceptionDataProvider(): array @@ -313,20 +312,20 @@ class ClientTest extends TestCase public function testExportMethod(): void { if (!in_array(gethostname(), ['pasha-lt', 'pasha-pc'])) { - $this->markTestSkipped('Travis does not allow to use SSH protocol on testing stage'); + self::markTestSkipped('Travis does not allow to use SSH protocol on testing stage'); } $result = $this->client->export(); - $this->assertNotEmpty($result); + self::assertNotEmpty($result); } public function testExportQuery(): void { if (!in_array(gethostname(), ['pasha-lt', 'pasha-pc'])) { - $this->markTestSkipped('Travis does not allow to use SSH protocol on testing stage'); + self::markTestSkipped('Travis does not allow to use SSH protocol on testing stage'); } $result = $this->client->query('/export'); - $this->assertNotEmpty($result); + self::assertNotEmpty($result); } } diff --git a/tests/ResponseIteratorTest.php b/tests/ResponseIteratorTest.php index ed205be..ef86a78 100644 --- a/tests/ResponseIteratorTest.php +++ b/tests/ResponseIteratorTest.php @@ -17,7 +17,7 @@ class ResponseIteratorTest extends TestCase $this->client = new Client([ 'user' => getenv('ROS_USER'), 'pass' => getenv('ROS_PASS'), - 'host' => getenv('ROS_HOST'), + 'host' => getenv('ROS_HOST_MODERN'), ]); } diff --git a/tests/Streams/ResourceStreamTest.php b/tests/Streams/ResourceStreamTest.php index 15d0e03..96e48dc 100644 --- a/tests/Streams/ResourceStreamTest.php +++ b/tests/Streams/ResourceStreamTest.php @@ -83,7 +83,7 @@ class ResourceStreamTest extends TestCase { return [ [fopen(__FILE__, 'rb')], // Myself, sure I exists - [fsockopen('tcp://' . getenv('ROS_HOST'), getenv('ROS_PORT_MODERN'))], // Socket + [fsockopen('tcp://' . getenv('ROS_HOST_MODERN'), getenv('ROS_PORT_MODERN'))], // Socket [STDIN, false], // Try it, but do not close STDIN please !!! // What else ? ]; @@ -150,26 +150,19 @@ class ResourceStreamTest extends TestCase * Test read to invalid resource * * @covers ::read - * @dataProvider readBadResourceProvider - * - * @param ResourceStream $stream Cannot typehint, PHP refuse it - * @param int $length + * @throws \RouterOS\Exceptions\StreamException */ - public function testReadBadResource(ResourceStream $stream, int $length): void + public function testReadBadResource(): void { $this->expectException(StreamException::class); - $stream->read($length); - } - public function readBadResourceProvider(): array - { - $resource = fopen(__FILE__, 'rb'); - $me = new ResourceStream($resource); + $resource = fopen(__DIR__, 'rb'); + $stream = new ResourceStream($resource); fclose($resource); - return [ - [$me, 1], - ]; + //dd($stream); + + $stream->read(1); } /**