From efd9e831798d5fad674b7ff99762bf9ca43319b7 Mon Sep 17 00:00:00 2001 From: Paul Rock Date: Sat, 23 Mar 2019 19:47:38 +0300 Subject: [PATCH] code style finetyne --- src/APIConnector.php | 25 +++--- src/APILengthCoDec.php | 130 ++++++++++++++-------------- src/Client.php | 40 ++------- src/Helpers/BinaryStringHelper.php | 39 +++++---- src/Interfaces/StreamInterface.php | 23 +++-- src/SocketTrait.php | 21 +++++ src/Streams/ResourceStream.php | 70 ++++++++++----- src/Streams/StringStream.php | 48 ++++++----- tests/APIConnectorTest.php | 78 +++++++++-------- tests/APILengthCoDecTest.php | 4 +- tests/Streams/ResourceStreamTest.php | 159 +++++++++++++++++++---------------- tests/Streams/StringStreamTest.php | 80 +++++++++++------- 12 files changed, 403 insertions(+), 314 deletions(-) diff --git a/src/APIConnector.php b/src/APIConnector.php index cee50ed..f85c013 100644 --- a/src/APIConnector.php +++ b/src/APIConnector.php @@ -1,17 +1,17 @@ stream); - if ($length>0) { - return $this->stream->read($length); - } - return ''; + return ($length > 0) ? $this->stream->read($length) : ''; } - public function writeWord(string $word) + /** + * Write word to stream + * + * @param string $word + * @return int return number of written bytes + */ + public function writeWord(string $word): int { $encodedLength = APILengthCoDec::encodeLength(strlen($word)); - return $this->stream->write($encodedLength.$word); + return $this->stream->write($encodedLength . $word); } } diff --git a/src/APILengthCoDec.php b/src/APILengthCoDec.php index b3a59d2..b37c15a 100644 --- a/src/APILengthCoDec.php +++ b/src/APILengthCoDec.php @@ -7,16 +7,15 @@ use RouterOS\Helpers\BinaryStringHelper; /** * class APILengthCoDec - * + * * Coder / Decoder for length field in mikrotik API communication protocol * * @package RouterOS * @since 0.9 */ - class APILengthCoDec { - public static function encodeLength(int $length) + public static function encodeLength(int $length): string { // Encode the length : // - if length <= 0x7F (binary : 01111111 => 7 bits set to 1) @@ -26,63 +25,63 @@ class APILengthCoDec // - length <= 0x3FFF (binary : 00111111 11111111 => 14 bits set to 1) // - encode length with two bytes // - set length value to 0x8000 (=> 10000000 00000000) - // - add length : as length maximumal value is 14 bits to 1, this does not modify the 2 most significants bits (10) + // - add length : as length maximumal value is 14 bits to 1, this does not modify the 2 most significance bits (10) // - end // => minimal encoded value is 10000000 10000000 // - length <= 0x1FFFFF (binary : 00011111 11111111 11111111 => 21 bits set to 1) // - encode length with three bytes // - set length value to 0xC00000 (binary : 11000000 00000000 00000000) - // - add length : as length maximal vlaue is 21 bits to 1, this does not modify the 3 most significants bits (110) + // - add length : as length maximal vlaue is 21 bits to 1, this does not modify the 3 most significance bits (110) // - end // => minimal encoded value is 11000000 01000000 00000000 // - length <= 0x0FFFFFFF (binary : 00001111 11111111 11111111 11111111 => 28 bits set to 1) // - encode length with four bytes // - set length value to 0xE0000000 (binary : 11100000 00000000 00000000 00000000) - // - add length : as length maximal vlaue is 28 bits to 1, this does not modify the 4 most significants bits (1110) + // - add length : as length maximal vlaue is 28 bits to 1, this does not modify the 4 most significance bits (1110) // - end // => minimal encoded value is 11100000 00100000 00000000 00000000 // - length <= 0x7FFFFFFFFF (binary : 00000111 11111111 11111111 11111111 11111111 => 35 bits set to 1) // - encode length with five bytes // - set length value to 0xF000000000 (binary : 11110000 00000000 00000000 00000000 00000000) - // - add length : as length maximal vlaue is 35 bits to 1, this does not modify the 5 most significants bits (11110) + // - add length : as length maximal vlaue is 35 bits to 1, this does not modify the 5 most significance bits (11110) // - end // - length > 0x7FFFFFFFFF : not supported - - if ($length<0) - { - throw new \DomainException(sprintf("Length of word can not be negative (%d)", $length)); + if ($length < 0) { + throw new \DomainException("Length of word can not be negative ($length)"); } - - if ($length<=0x7F) { + + if ($length <= 0x7F) { return BinaryStringHelper::IntegerToNBOBinaryString($length); } - else if ($length<=0x3FFF) { - return BinaryStringHelper::IntegerToNBOBinaryString(0x8000+$length); + + if ($length <= 0x3FFF) { + return BinaryStringHelper::IntegerToNBOBinaryString(0x8000 + $length); } - else if ($length<=0x1FFFFF) { - return BinaryStringHelper::IntegerToNBOBinaryString(0xC00000+$length); + + if ($length <= 0x1FFFFF) { + return BinaryStringHelper::IntegerToNBOBinaryString(0xC00000 + $length); } - else if ($length<=0x0FFFFFFF){ - return BinaryStringHelper::IntegerToNBOBinaryString(0xE0000000+$length); + + if ($length <= 0x0FFFFFFF) { + return BinaryStringHelper::IntegerToNBOBinaryString(0xE0000000 + $length); + } // cannot compare with 0x7FFFFFFFFF on 32 bits systems + + if (PHP_INT_SIZE < 8) { + // Cannot be done on 32 bits systems + // PHP5 windows versions of php, even on 64 bits systems was impacted + // see : https://stackoverflow.com/questions/27865340/php-int-size-returns-4-but-my-operating-system-is-64-bit + + // @codeCoverageIgnoreStart + throw new \OverflowException("Your system is using 32 bits integers, cannot encode length of $length bytes on this system"); + // @codeCoverageIgnoreEnd } - // cannot compare with 0x7FFFFFFFFF on 32 bits systems - else { - if (PHP_INT_SIZE<8) { - // Cannot be done on 32 bits systems - // PHP5 windows versions of php, even on 64 bits systems was impacted - // see : https://stackoverflow.com/questions/27865340/php-int-size-returns-4-but-my-operating-system-is-64-bit - - // @codeCoverageIgnoreStart - throw new \OverflowException(sprintf("Your system is using 32 bits integers, cannot encode length of %d bytes on this system", $length)); - // @codeCoverageIgnoreEnd - } - if ($length<=0x7FFFFFFFFF) - { - return BinaryStringHelper::IntegerToNBOBinaryString(0xF000000000+$length); - } + + if ($length <= 0x7FFFFFFFFF) { + return BinaryStringHelper::IntegerToNBOBinaryString(0xF000000000 + $length); } - throw new \DomainException(sprintf('Length of word too huge (%x)', $length)); + + throw new \DomainException("Length of word too huge ($length)"); } // Decode length of data when reading : @@ -107,7 +106,7 @@ class APILengthCoDec // After receiving unknown control byte API client cannot proceed, because it cannot know how to interpret following bytes // Currently control bytes are not used - public static function decodeLength(StreamInterface $stream) + public static function decodeLength(StreamInterface $stream): int { // if (false === is_resource($stream)) { // throw new \InvalidArgumentException( @@ -122,76 +121,81 @@ class APILengthCoDec $firstByte = ord($stream->read(1)); // If first byte is not set, length is the value of the byte - if (0==($firstByte&0x80)) { + if (0 === ($firstByte & 0x80)) { return $firstByte; } // if 10xxxxxx, length is 2 bytes encoded - if (0x80==($firstByte&0xC0)) - { - // Set 2 most significants bits to 0 + if (0x80 === ($firstByte & 0xC0)) { + // Set 2 most significands bits to 0 $result = $firstByte & 0x3F; + // shift left 8 bits to have 2 bytes - $result = $result << 8; - // read next byte and use it as least significant + $result <<= 8; + + // read next byte and use it as least significant $result |= ord($stream->read(1)); return $result; } // if 110xxxxx, length is 3 bytes encoded - if (0xC0 == ($firstByte & 0xE0)) - { - // Set 3 most significants bits to 0 + if (0xC0 === ($firstByte & 0xE0)) { + // Set 3 most significands bits to 0 $result = $firstByte & 0x1F; + // shift left 16 bits to have 3 bytes - $result = $result << 16; + $result <<= 16; + // read next 2 bytes as value and use it as least significant position $result |= (ord($stream->read(1)) << 8); $result |= ord($stream->read(1)); - return $result; + return $result; } // if 1110xxxx, length is 4 bytes encoded - if (0xE0 == ($firstByte & 0xF0)) - { - // Set 4 most significants bits to 0 + if (0xE0 === ($firstByte & 0xF0)) { + // Set 4 most significance bits to 0 $result = $firstByte & 0x0F; + // shift left 24 bits to have 4 bytes - $result = $result << 24; + $result <<= 24; + // read next 3 bytes as value and use it as least significant position $result |= (ord($stream->read(1)) << 16); $result |= (ord($stream->read(1)) << 8); $result |= ord($stream->read(1)); - return $result; + return $result; } // if 11110xxx, length is 5 bytes encoded - if (0xF0 == ($firstByte & 0xF8)) - { - // Not possibe on 32 bits systems - if (PHP_INT_SIZE<8) { + if (0xF0 === ($firstByte & 0xF8)) { + // Not possible on 32 bits systems + if (PHP_INT_SIZE < 8) { // Cannot be done on 32 bits systems // PHP5 windows versions of php, even on 64 bits systems was impacted // see : https://stackoverflow.com/questions/27865340/php-int-size-returns-4-but-my-operating-system-is-64-bit // How can we test it ? // @codeCoverageIgnoreStart - throw new \OverflowException(sprintf("Your system is using 32 bits integers, cannot decode this value (%x) on this system", $firstByte)); + throw new \OverflowException("Your system is using 32 bits integers, cannot decode this value ($firstByte) on this system"); // @codeCoverageIgnoreEnd } - // Set 5 most significants bits to 0 + + // Set 5 most significance bits to 0 $result = $firstByte & 0x07; + // shift left 232 bits to have 5 bytes - $result = $result << 32; + $result <<= 32; + // read next 4 bytes as value and use it as least significant position $result |= (ord($stream->read(1)) << 24); $result |= (ord($stream->read(1)) << 16); $result |= (ord($stream->read(1)) << 8); $result |= ord($stream->read(1)); - return $result; + return $result; } - // Now the only solution is 5 most significants bits are set to 1 (11111xxx) + // Now the only solution is 5 most significance bits are set to 1 (11111xxx) // This is a control word, not implemented by Mikrotik for the moment - throw new \UnexpectedValueException("Control Word found\n"); + throw new \UnexpectedValueException('Control Word found'); } -} \ No newline at end of file +} diff --git a/src/Client.php b/src/Client.php index e9f7553..d43cf16 100644 --- a/src/Client.php +++ b/src/Client.php @@ -18,27 +18,6 @@ class Client implements Interfaces\ClientInterface use SocketTrait; /** - * Socket resource - * - * @var resource|null - */ - private $_socket; - - /** - * Code of error - * - * @var int - */ - private $_socket_err_num; - - /** - * Description of socket error - * - * @var string - */ - private $_socket_err_str; - - /** * Configuration of connection * * @var \RouterOS\Config @@ -48,10 +27,10 @@ class Client implements Interfaces\ClientInterface /** * API communication object * - * @var APIConnector + * @var \RouterOS\APIConnector */ - private $connector; + private $_connector; /** * Client constructor. @@ -121,7 +100,6 @@ class Client implements Interfaces\ClientInterface * * @param string|array|\RouterOS\Query $query * @return \RouterOS\Client - * @throws \RouterOS\Exceptions\ClientException * @throws \RouterOS\Exceptions\QueryException */ public function write($query): Client @@ -139,11 +117,11 @@ class Client implements Interfaces\ClientInterface // Send commands via loop to router foreach ($query->getQuery() as $command) { - $this->connector->writeWord(trim($command)); + $this->_connector->writeWord(trim($command)); } // Write zero-terminator (empty string) - $this->connector->writeWord(''); + $this->_connector->writeWord(''); return $this; } @@ -156,7 +134,7 @@ class Client implements Interfaces\ClientInterface * Each block end with an zero byte (empty line) * Reply ends with a complete !done or !fatal block (ended with 'empty line') * A !fatal block precedes TCP connexion close - * + * * @param bool $parse * @return array */ @@ -169,9 +147,9 @@ class Client implements Interfaces\ClientInterface // Read answer from socket in loop while (true) { - $word = $this->connector->readWord(); + $word = $this->_connector->readWord(); - if (''===$word) { + if ('' === $word) { if ($lastReply) { // We received a !done or !fatal message in a precedent loop // response is complete @@ -202,7 +180,6 @@ class Client implements Interfaces\ClientInterface * * @param string|array|\RouterOS\Query $query * @return \RouterOS\Client - * @throws \RouterOS\Exceptions\ClientException * @throws \RouterOS\Exceptions\QueryException */ public function w($query): Client @@ -373,7 +350,7 @@ class Client implements Interfaces\ClientInterface // If socket is active if (null !== $this->getSocket()) { - $this->connector = new APIConnector(new Streams\ResourceStream($this->getSocket())); + $this->_connector = new APIConnector(new Streams\ResourceStream($this->getSocket())); // If we logged in then exit from loop if (true === $this->login()) { $connected = true; @@ -382,7 +359,6 @@ class Client implements Interfaces\ClientInterface // Else close socket and start from begin $this->closeSocket(); - $this->stream = null; } // Sleep some time between tries diff --git a/src/Helpers/BinaryStringHelper.php b/src/Helpers/BinaryStringHelper.php index aeb5a0f..a5e7e70 100644 --- a/src/Helpers/BinaryStringHelper.php +++ b/src/Helpers/BinaryStringHelper.php @@ -1,60 +1,65 @@ chr(0x0F).chr(0xF7) * 0x12345678 => chr(0x12).chr(0x34).chr(0x56).chr(0x76) * Compatible with 8, 16, 32, 64 etc.. bits systems * * @see https://en.wikipedia.org/wiki/Endianness - * @param int $value the integer value to be converted - * @return string the binary string - */ - public static function IntegerToNBOBinaryString(int $value) + * @param int $value the integer value to be converted + * @return string the binary string + */ + public static function IntegerToNBOBinaryString(int $value): string { // Initialize an empty string $buffer = ''; + // Lets start from the most significant byte - for ($i=(PHP_INT_SIZE-1); $i>=0; $i--) { + for ($i = (PHP_INT_SIZE - 1); $i >= 0; $i--) { // Prepare a mask to keep only the most significant byte of $value - $mask = 0xFF << ($i*8); + $mask = 0xFF << ($i * 8); + // If the most significant byte is not 0, the final string must contain it // If we have already started to construct the string (i.e. there are more signficant digits) // we must set the byte, even if it is a 0. // 0xFF00FF, for example, require to set the second byte byte with a 0 value - if (($value & $mask) || strlen($buffer)!=0) { - // Get the curent byte by shifting it to least significant position and add it to the string + if (($value & $mask) || $buffer !== '') { + // Get the current byte by shifting it to least significant position and add it to the string // 0xFF12345678 => 0xFF - $byte = $value>>(8*$i); + $byte = $value >> (8 * $i); $buffer .= chr($byte); + // Set the most significant byte to 0 so we can restart the process being shure // that the value is left padded with 0 // 0xFF12345678 => 0x12345678 // -1 = 0xFFFFF.... (number of F depend of PHP_INT_SIZE ) - $mask = -1 >> ((PHP_INT_SIZE-$i)*8); + $mask = -1 >> ((PHP_INT_SIZE - $i) * 8); $value &= $mask; } } + // Special case, 0 will not fill the buffer, have to construct it manualy - if (0==$value) { + if (0 === $value) { $buffer = chr(0); } + return $buffer; } -} \ No newline at end of file +} diff --git a/src/Interfaces/StreamInterface.php b/src/Interfaces/StreamInterface.php index 2832a37..4131992 100644 --- a/src/Interfaces/StreamInterface.php +++ b/src/Interfaces/StreamInterface.php @@ -1,4 +1,5 @@ stream = $stream; } /** - * {@inheritDoc} - * @throws \InvalidArgumentException + * @param int $length + * @return string + * @throws \RouterOS\Exceptions\StreamException + * @throws \InvalidArgumentException */ - public function read(int $length) : string + public function read(int $length): string { - if ($length<=0) { - throw new \InvalidArgumentException("Cannot read zero ot negative count of bytes from a stream"); + if ($length <= 0) { + 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 (false === $result) { - throw new StreamException(sprintf("Error reading %d bytes", $length)); + throw new StreamException("Error reading $length bytes"); } return $result; } /** - * {@inheritDoc} + * Writes a string to a stream + * + * Write $length bytes of string, if not mentioned, write all the string + * Must be binary safe (as fread). + * if $length is greater than string length, write all string and return number of writen bytes + * if $length os smaller than string length, remaining bytes are losts. + * + * @param string $string + * @param int|null $length the numer of bytes to read + * @return int the number of written bytes + * @throws \RouterOS\Exceptions\StreamException */ - public function write(string $string, $length=null) : int + public function write(string $string, int $length = null): int { - if (is_null($length)) { + if (null === $length) { $length = strlen($string); } + + // TODO: Ignore errors here, but why? $result = @fwrite($this->stream, $string, $length); + if (false === $result) { - throw new StreamException(sprintf("Error writing %d bytes", $length)); + throw new StreamException("Error writing $length bytes"); } + return $result; } + /** + * Close stream connection + * + * @return void + * @throws \RouterOS\Exceptions\StreamException + */ public function close() { $hasBeenClosed = false; - if (!is_null($this->stream)) { + + if (null !== $this->stream) { $hasBeenClosed = @fclose($this->stream); - $this->stream=null; + $this->stream = null; } - if (false===$hasBeenClosed) { - throw new StreamException("Error closing stream"); - + + if (false === $hasBeenClosed) { + throw new StreamException('Error closing stream'); } } -} \ No newline at end of file +} diff --git a/src/Streams/StringStream.php b/src/Streams/StringStream.php index 11fbe06..e845f32 100644 --- a/src/Streams/StringStream.php +++ b/src/Streams/StringStream.php @@ -1,4 +1,5 @@ buffer); - if ($length<0) { - throw new \InvalidArgumentException("Cannot read a negative count of bytes from a stream"); + if ($length < 0) { + throw new \InvalidArgumentException('Cannot read a negative count of bytes from a stream'); } - if (0 == $remaining) { - throw new StreamException("End of stream"); + if (0 === $remaining) { + throw new StreamException('End of stream'); } - if ($length>=$remaining) { + if ($length >= $remaining) { // returns all $result = $this->buffer; // No more in the buffer - $this->buffer=''; - } - else { + $this->buffer = ''; + } else { // acquire $length characters from the buffer $result = substr($this->buffer, 0, $length); // remove $length characters from the buffer @@ -68,26 +67,31 @@ class StringStream implements StreamInterface /** * Fake write method, do nothing except return the "writen" length * - * @param string $string The string to write - * @param int|null $length the number of characters to write - * @throws \InvalidArgumentException on invalid length - * @return number of "writen" bytes + * @param string $string The string to write + * @param int|null $length the number of characters to write + * @return int number of "writen" bytes + * @throws \InvalidArgumentException on invalid length */ - public function write(string $string, $length=null) : int + public function write(string $string, int $length = null): int { - if(null === $length) { + if (null === $length) { $length = strlen($string); } - if ($length<0) { - throw new \InvalidArgumentException("Cannot write a negative count of bytes"); + if ($length < 0) { + throw new \InvalidArgumentException('Cannot write a negative count of bytes'); } return min($length, strlen($string)); } + /** + * Close stream connection + * + * @return void + */ public function close() { $this->buffer = ''; } -} \ No newline at end of file +} diff --git a/tests/APIConnectorTest.php b/tests/APIConnectorTest.php index 1e1edc5..72c0c43 100644 --- a/tests/APIConnectorTest.php +++ b/tests/APIConnectorTest.php @@ -3,30 +3,29 @@ namespace RouterOS\Tests; use PHPUnit\Framework\TestCase; - use RouterOS\APIConnector; use RouterOS\Streams\StringStream; use RouterOS\Streams\ResourceStream; use RouterOS\APILengthCoDec; use RouterOS\Interfaces\StreamInterface; - /** * Limit code coverage to the class RouterOS\APIStream - * @coversDefaultClass RouterOS\APIConnector + * + * @coversDefaultClass \RouterOS\APIConnector */ class APIConnectorTest extends TestCase { - /** * Test that constructor is OK with different kinds of resources - * + * * @covers ::__construct * @dataProvider constructProvider - * @param Resource $resource Cannot typehint, PHP refuse it - * @param bool $closeResource shall we close the resource ? + * + * @param StreamInterface $stream Cannot typehint, PHP refuse it + * @param bool $closeResource shall we close the resource ? */ - public function test_construct(StreamInterface $stream, bool $closeResource=false) + public function test_construct(StreamInterface $stream, bool $closeResource = false) { $apiStream = new APIConnector($stream); $this->assertInstanceOf(APIConnector::class, $apiStream); @@ -35,14 +34,14 @@ class APIConnectorTest extends TestCase } } - public function constructProvider() + public function constructProvider(): array { return [ - [ new ResourceStream(fopen(__FILE__, 'r')), ], // Myself, sure I exists - [ new ResourceStream(fsockopen('tcp://127.0.0.1', 18728)), ], // 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 !!! + [new ResourceStream(fopen(__FILE__, 'rb')),], // Myself, sure I exists + [new ResourceStream(fsockopen('tcp://127.0.0.1', 18728)),], // 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 !!! // What else ? ]; } @@ -50,43 +49,50 @@ class APIConnectorTest extends TestCase /** * @covers ::readWord * @dataProvider readWordProvider + * + * @param APIConnector $connector + * @param string $expected */ - - public function test__readWord(APIConnector $connector, $expected) + public function test__readWord(APIConnector $connector, string $expected) { $this->assertSame($expected, $connector->readWord()); } - public function readWordProvider() + public function readWordProvider(): array { - $longString = '=comment='.str_repeat('a',10000); - $length = strlen($longString); - return [ - [ new APIConnector(new StringStream(chr(0))), ''], - [ new APIConnector(new StringStream(chr(3).'!re')), '!re'], - [ new APIConnector(new StringStream(chr(5).'!done')), '!done'], - [ new APIConnector(new StringStream(APILengthCoDec::encodeLength($length).$longString)), $longString], + $longString = '=comment=' . str_repeat('a', 10000); + $length = strlen($longString); + + return [ + [new APIConnector(new StringStream(chr(0))), ''], + [new APIConnector(new StringStream(chr(3) . '!re')), '!re'], + [new APIConnector(new StringStream(chr(5) . '!done')), '!done'], + [new APIConnector(new StringStream(APILengthCoDec::encodeLength($length) . $longString)), $longString], ]; } - /** - * @covers ::writeWord - * @dataProvider writeWordProvider - */ + /** + * @covers ::writeWord + * @dataProvider writeWordProvider + * + * @param APIConnector $connector + * @param string $toWrite + * @param int $expected + */ public function test_writeWord(APIConnector $connector, string $toWrite, int $expected) { $this->assertEquals($expected, $connector->writeWord($toWrite)); } - public function writeWordProvider() + public function writeWordProvider(): array { return [ - [ new APIConnector(new StringStream('Have FUN !!!')), '', 1 ], // length is 0, but have to write it on 1 byte, minimum - [ new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 54), 55 ], // arbitrary value - [ new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 127), 128 ], // maximum value for 1 byte encoding lentgth - [ new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 128), 130 ], // minimum value for 2 bytes encoding lentgth - [ new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 254), 256 ], // special value isn't it ? - [ new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 255), 257 ], // special value isn't it ? + [new APIConnector(new StringStream('Have FUN !!!')), '', 1], // length is 0, but have to write it on 1 byte, minimum + [new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 54), 55], // arbitrary value + [new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 127), 128], // maximum value for 1 byte encoding lentgth + [new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 128), 130], // minimum value for 2 bytes encoding lentgth + [new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 254), 256], // special value isn't it ? + [new APIConnector(new StringStream('Have FUN !!!')), str_repeat(' ', 255), 257], // special value isn't it ? ]; } -} \ No newline at end of file +} diff --git a/tests/APILengthCoDecTest.php b/tests/APILengthCoDecTest.php index 69c37e2..08a0e77 100644 --- a/tests/APILengthCoDecTest.php +++ b/tests/APILengthCoDecTest.php @@ -11,7 +11,7 @@ use RouterOS\Helpers\BinaryStringHelper; /** * Limit code coverage to the class - * @coversDefaultClass RouterOS\APILengthCoDec + * @coversDefaultClass \RouterOS\APILengthCoDec */ class APILengthCoDecTest extends TestCase { @@ -117,4 +117,4 @@ class APILengthCoDecTest extends TestCase [chr(0xFF)], // maximum ]; } -} \ No newline at end of file +} diff --git a/tests/Streams/ResourceStreamTest.php b/tests/Streams/ResourceStreamTest.php index 9cda9a2..d2c466a 100644 --- a/tests/Streams/ResourceStreamTest.php +++ b/tests/Streams/ResourceStreamTest.php @@ -4,22 +4,23 @@ namespace RouterOS\Tests\Streams; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Constraint\IsType; - use RouterOS\Streams\ResourceStream; -use RouterOS\Exceptions\StreamException; /** * Limit code coverage to the class RouterOS\APIStream - * @coversDefaultClass RouterOS\Streams\ResourceStream + * + * @coversDefaultClass \RouterOS\Streams\ResourceStream */ class ResourceStreamTest extends TestCase { /** * Test that constructor throws an InvalidArgumentException on bad parameter type - * + * * @covers ::__construct * @expectedException \InvalidArgumentException * @dataProvider constructNotResourceProvider + * + * @param $notResource */ public function test__constructNotResource($notResource) @@ -32,37 +33,37 @@ class ResourceStreamTest extends TestCase * * returns data not of type resource */ - public function constructNotResourceProvider() + public function constructNotResourceProvider(): array { return [ [0], // integer [3.14], // float ['a string'], // string [ - [ 0 , 3.14 ] // Array + [0, 3.14] // Array ], - [ new \stdClass() ], // Object + [new \stdClass()], // Object // What else ? ]; } /** * Test that constructor is OK with different kinds of resources - * + * * @covers ::__construct * @dataProvider constructProvider - * @param resource $resource Cannot typehint, PHP refuse it - * @param bool $closeResource shall we close the resource ? + * + * @param resource $resource Cannot typehint, PHP refuse it + * @param bool $closeResource shall we close the resource ? */ - public function test_construct($resource, bool $closeResource=true) + public function test_construct($resource, bool $closeResource = true) { $resourceStream = new ResourceStream($resource); $stream = $this->getObjectAttribute($resourceStream, 'stream'); $this->assertInternalType(IsType::TYPE_RESOURCE, $stream); - if ($closeResource) - { + if ($closeResource) { fclose($resource); } } @@ -70,142 +71,157 @@ class ResourceStreamTest extends TestCase /** * Data provider for test__construct * - * returns data of type resource + * @return array data of type resource */ - public function constructProvider() + public function constructProvider(): array { return [ - [ fopen(__FILE__, 'r'), ], // Myself, sure I exists - [ fsockopen('tcp://127.0.0.1', 18728), ], // Socket - [ STDIN, false ], // Try it, but do not close STDIN please !!! + [fopen(__FILE__, 'rb'),], // Myself, sure I exists + [fsockopen('tcp://127.0.0.1', 18728),], // Socket + [STDIN, false], // Try it, but do not close STDIN please !!! // What else ? ]; } /** * Test that read function return expected values, and that consecutive reads return data - * + * * @covers ::read * @dataProvider readProvider - * @param resource $resource Cannot typehint, PHP refuse it - * @param string $expected the rsult we should have + * + * @param ResourceStream $stream Cannot typehint, PHP refuse it + * @param string $expected the result we should have + * @throws \RouterOS\Exceptions\StreamException + * @throws \InvalidArgumentException */ public function test__read(ResourceStream $stream, string $expected) { $this->assertSame($expected, $stream->read(strlen($expected))); } - public function readProvider() + public function readProvider(): array { - $resource = fopen(__FILE__, 'r'); - $me = new ResourceStream($resource); + $resource = fopen(__FILE__, 'rb'); + $me = new ResourceStream($resource); + return [ - [ $me, '<'], // Read for byte - [ $me, '?php'], // Read following bytes. File statrts with "read($length); } - public function readBadLengthProvider() + public function readBadLengthProvider(): array { - $resource = fopen(__FILE__, 'r'); - $me = new ResourceStream($resource); + $resource = fopen(__FILE__, 'rb'); + $me = new ResourceStream($resource); + return [ - [ $me, 0 ], - [ $me, -1 ], + [$me, 0], + [$me, -1], ]; - fclose($resource); } + /** * Test read to invalid resource - * + * * @covers ::read * @dataProvider readBadResourceProvider - * @expectedException RouterOS\Exceptions\StreamException - * @param resource $resource Cannot typehint, PHP refuse it + * @expectedException \RouterOS\Exceptions\StreamException + * + * @param ResourceStream $stream Cannot typehint, PHP refuse it + * @param int $length */ public function test__readBadResource(ResourceStream $stream, int $length) { $stream->read($length); } - public function readBadResourceProvider() + public function readBadResourceProvider(): array { - $resource = fopen(__FILE__, 'r'); - $me = new ResourceStream($resource); + $resource = fopen(__FILE__, 'rb'); + $me = new ResourceStream($resource); fclose($resource); return [ - [ $me, 1 ], + [$me, 1], ]; } /** * Test that write function returns writen length - * + * * @covers ::write * @dataProvider writeProvider - * @param ResourceStram $resource to test - * @param string $toWrite the writed string + * + * @param ResourceStream $stream to test + * @param string $toWrite the writed string + * @throws \RouterOS\Exceptions\StreamException */ public function test__write(ResourceStream $stream, string $toWrite) { - $this->assertEquals(strlen($toWrite) , $stream->write($toWrite)); + $this->assertEquals(strlen($toWrite), $stream->write($toWrite)); } - public function writeProvider() + public function writeProvider(): array { - $resource = fopen("/dev/null", 'w'); - $null = new ResourceStream($resource); + $resource = fopen('/dev/null', 'wb'); + $null = new ResourceStream($resource); + return [ - [ $null, 'yyaagagagag'], // Take that + [$null, 'yyaagagagag'], // Take that ]; - fclose($resource); } /** * Test write to invalid resource - * + * * @covers ::write * @dataProvider writeBadResourceProvider - * @expectedException RouterOS\Exceptions\StreamException - * @param resource $resource to test - * @param string $toWrite the writed string + * @expectedException \RouterOS\Exceptions\StreamException + * + * @param ResourceStream $stream to test + * @param string $toWrite the written string */ public function test__writeBadResource(ResourceStream $stream, string $toWrite) { $stream->write($toWrite); } - public function writeBadResourceProvider() + public function writeBadResourceProvider(): array { - $resource = fopen('/dev/null', 'w'); - $me = new ResourceStream($resource); + $resource = fopen('/dev/null', 'wb'); + $me = new ResourceStream($resource); fclose($resource); + return [ - [ $me, 'sasasaas' ], // Take that + [$me, 'sasasaas'], // Take that ]; } /** * Test double close resource - * + * * @covers ::close * @dataProvider doubleCloseProvider - * @expectedException RouterOS\Exceptions\StreamException - * @param resource $resource to test + * @expectedException \RouterOS\Exceptions\StreamException + * + * @param ResourceStream $stream to test */ public function test_doubleClose(ResourceStream $stream) { @@ -213,22 +229,23 @@ class ResourceStreamTest extends TestCase $stream->close(); } - public function doubleCloseProvider() + public function doubleCloseProvider(): array { return [ - [ new ResourceStream(fopen('/dev/null', 'w')), 'sasasaas' ], // Take that + [new ResourceStream(fopen('/dev/null', 'wb')), 'sasasaas'], // Take that ]; } /** * Test write to closed resource - * + * * @covers ::close * @covers ::write * @dataProvider writeClosedResourceProvider - * @expectedException RouterOS\Exceptions\StreamException - * @param resource $resource to test - * @param string $toWrite the writed string + * @expectedException \RouterOS\Exceptions\StreamException + * + * @param ResourceStream $stream to test + * @param string $toWrite the written string */ public function test_close(ResourceStream $stream, string $toWrite) { @@ -236,11 +253,11 @@ class ResourceStreamTest extends TestCase $stream->write($toWrite); } - public function writeClosedResourceProvider() + public function writeClosedResourceProvider(): array { return [ - [ new ResourceStream(fopen('/dev/null', 'w')), 'sasasaas' ], // Take that + [new ResourceStream(fopen('/dev/null', 'wb')), 'sasasaas'], // Take that ]; } -} \ No newline at end of file +} diff --git a/tests/Streams/StringStreamTest.php b/tests/Streams/StringStreamTest.php index ebabf89..4fb4f1c 100644 --- a/tests/Streams/StringStreamTest.php +++ b/tests/Streams/StringStreamTest.php @@ -10,66 +10,70 @@ use RouterOS\Exceptions\StreamException; /** * Limit code coverage to the class RouterOS\APIStream - * @coversDefaultClass RouterOS\Streams\StringStream + * + * @coversDefaultClass \RouterOS\Streams\StringStream */ class StringStreamTest extends TestCase { /** * @covers ::__construct * @dataProvider constructProvider + * + * @param string $string */ public function test__construct(string $string) { $this->assertInstanceOf(StringStream::class, new StringStream($string)); } - public function constructProvider() + public function constructProvider(): array { return [ - [ chr(0) ], - [ '' ], - [ '1' ], - [ 'lkjl'.chr(0).'kjkljllkjkljljklkjkljlkjljlkjkljkljlkjjll'], + [chr(0)], + [''], + ['1'], + ['lkjl' . chr(0) . 'kjkljllkjkljljklkjkljlkjljlkjkljkljlkjjll'], ]; - } + } /** - * test that write function returns the effective writen bytes + * Test that write function returns the effective written bytes + * * @covers ::write * @dataProvider writeProvider - * @param string $toWrite the string to write - * @param int|null $length the count if bytes to write - * @param int $expected the number of bytes that must be writen + * + * @param string $string the string to write + * @param int|null $length the count if bytes to write + * @param int $expected the number of bytes that must be writen */ public function test__write(string $string, $length, int $expected) { $stream = new StringStream('Does not matters'); - if (is_null($length)) { + if (null === $length) { $this->assertEquals($expected, $stream->write($string)); - } - else { + } else { $this->assertEquals($expected, $stream->write($string, $length)); } } - public function writeProvider() + public function writeProvider(): array { return [ - [ '', 0, 0 ], - [ '', 10, 0 ], - [ '', null, 0 ], - [ 'Yabala', 0, 0], - [ 'Yabala', 1, 1], - [ 'Yabala', 6, 6], - [ 'Yabala', 100, 6], - [ 'Yabala', null, 6], - [ chr(0), 0, 0], - [ chr(0), 1, 1], - [ chr(0), 100, 1], - [ chr(0), null, 1], + ['', 0, 0], + ['', 10, 0], + ['', null, 0], + ['Yabala', 0, 0], + ['Yabala', 1, 1], + ['Yabala', 6, 6], + ['Yabala', 100, 6], + ['Yabala', null, 6], + [chr(0), 0, 0], + [chr(0), 1, 1], + [chr(0), 100, 1], + [chr(0), null, 1], ]; } @@ -80,11 +84,13 @@ class StringStreamTest extends TestCase public function test__writeWithNegativeLength() { $stream = new StringStream('Does not matters'); - $stream->write("PLOP", -1); + $stream->write('PLOP', -1); } /** * Test read function + * + * @throws \RouterOS\Exceptions\StreamException */ public function test__read() { @@ -99,7 +105,9 @@ class StringStreamTest extends TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException \InvalidArgumentException + * + * @throws \RouterOS\Exceptions\StreamException */ public function test__readBadLength() { @@ -111,12 +119,20 @@ class StringStreamTest extends TestCase * @covers ::read * @dataProvider readWhileEmptyProvider * @expectedException \RouterOS\Exceptions\StreamException + * + * @param StringStream $stream + * @param int $length + * @throws \RouterOS\Exceptions\StreamException */ public function test__readWhileEmpty(StringStream $stream, int $length) { - $stream->read($length); + $stream->read($length); } + /** + * @return \Generator + * @throws StreamException + */ public function readWhileEmptyProvider() { $stream = new StringStream('123456789'); @@ -133,7 +149,7 @@ class StringStreamTest extends TestCase } /** - * @expectedException \RouterOS\Exceptions\StreamException + * @expectedException \RouterOS\Exceptions\StreamException */ public function testReadClosed() { @@ -141,4 +157,4 @@ class StringStreamTest extends TestCase $stream->close(); $stream->read(1); } -} \ No newline at end of file +}