diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index da107c5..a3fa330 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,12 +1,12 @@ on: [push, pull_request] jobs: - run: + run: runs-on: ${{ matrix.operating-system }} strategy: matrix: operating-system: [ubuntu-latest] - php-versions: ['7.3', '7.4', '8.0'] + php-versions: ['8.0', '8.1', '8.2'] name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} steps: - name: Checkout @@ -31,3 +31,5 @@ jobs: with: files: ./coverage.xml verbose: true + - name: Run phpstan + run: ./vendor/bin/phpstan --level=max --xdebug analyse src diff --git a/.gitignore b/.gitignore index 0f0b5c2..b775214 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ vendor/* .idea/* .phpunit.result.cache coverage.xml -.DS_Store \ No newline at end of file +.DS_Store +.vscode/* +var/* diff --git a/composer.json b/composer.json index 1a363d0..7ffb8a2 100644 --- a/composer.json +++ b/composer.json @@ -9,10 +9,11 @@ "search engine" ], "require": { - "php": "^7.3|^8.0" + "php": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^7.0|^9.0" + "phpunit/phpunit": "^7.0|^9.0", + "phpstan/phpstan": "^1.9" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 433ba8e..c7c50a1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "65d3bddfa41df1edbdedfcf7a8ba5028", + "content-hash": "df403c6432b8e7aabec45e7967153537", "packages": [], "packages-dev": [ { @@ -283,6 +283,65 @@ "description": "Library for handling version information and constraints", "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "phpstan/phpstan", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "e08de53a5eec983de78a787a88e72518cf8fe43a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e08de53a5eec983de78a787a88e72518cf8fe43a", + "reference": "e08de53a5eec983de78a787a88e72518cf8fe43a", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.9.0" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-11-03T07:26:48+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "9.2.18", @@ -1635,5 +1694,5 @@ "php": "^7.3|^8.0" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.3.0" } diff --git a/src/Client.php b/src/Client.php index 5b5b235..52222ac 100644 --- a/src/Client.php +++ b/src/Client.php @@ -6,15 +6,23 @@ use Psonic\Contracts\Client as ClientInterface; use Psonic\Contracts\Command as CommandInterface; use Psonic\Contracts\Response as ResponseInterface; +use RuntimeException; + class Client implements ClientInterface { + /** @var resource $resource */ private $resource; + /** @var string */ private $host; + /** @var int */ private $port; + /** @var int|null */ private $errorNo; + /** @var string */ private $errorMessage; + /** @var int */ private $maxTimeout; /** @@ -39,11 +47,17 @@ public function __construct($host = 'localhost', $port = 1491, $timeout = 30) */ public function send(CommandInterface $command): ResponseInterface { - if (!$this->resource) { - throw new ConnectionException(); + if(!is_resource($this->resource)) { + //Fixme: In php8+ a try catch on fwrite throws a TypeError and catches the case of an empty $this->>resource variable + throw new ConnectionException("Not connected to sonic. Empty stream given ". var_export($this->resource, true)); + } + + $result = fwrite($this->resource, $command); + + if($result === false) { + throw new RuntimeException("Unable to write to stream"); } - fwrite($this->resource, $command); return $this->read(); } @@ -53,7 +67,18 @@ public function send(CommandInterface $command): ResponseInterface */ public function read(): ResponseInterface { - $message = explode("\r\n", fgets($this->resource))[0]; + $string = fgets($this->resource); + + if($string === false) { + throw new \RuntimeException("Unable to read from stream"); + } + + if(empty($string)) { + throw new \RuntimeException("Read empty string from stream"); + } + + $message = explode("\r\n", $string)[0]; + return new SonicResponse($message); } @@ -61,20 +86,27 @@ public function read(): ResponseInterface * @throws ConnectionException * connects to the socket */ - public function connect() + public function connect(): void { - if (!$this->resource = stream_socket_client("tcp://{$this->host}:{$this->port}", $this->errorNo, $this->errorMessage, $this->maxTimeout)) { - throw new ConnectionException(); + $resource = stream_socket_client("tcp://{$this->host}:{$this->port}", $this->errorNo, $this->errorMessage, $this->maxTimeout); + if (!$resource) { + throw new ConnectionException("Unable to connect to sonic search engine with given host: $this->host and port: $this->port}. Error code $this->errorNo with $this->errorMessage was produced"); } + $this->resource = $resource; } /** * Disconnects from a socket */ - public function disconnect() + public function disconnect(): void { - stream_socket_shutdown($this->resource, STREAM_SHUT_WR); - $this->resource = null; + $result = stream_socket_shutdown($this->resource, STREAM_SHUT_WR); + + if(!$result) { + throw new \RuntimeException("Unable to shut down stream socket connection"); + } + + fclose($this->resource); } /** diff --git a/src/Commands/Command.php b/src/Commands/Command.php index e3a32fa..b8f3991 100644 --- a/src/Commands/Command.php +++ b/src/Commands/Command.php @@ -6,10 +6,16 @@ abstract class Command implements CommandInterface { - private $command; - private $parameters; + private string $command; + /** + * @var array + */ + private array $parameters; - public function __construct($command, $parameters = []) + /** + * @param array $parameters + */ + public function __construct(string $command, array $parameters = []) { $this->command = $command; $this->parameters = $parameters; @@ -18,8 +24,9 @@ public function __construct($command, $parameters = []) /** * Wrap the string in quotes, and normalize whitespace. Also remove double quotes. */ - protected function wrapInQuotes($string) + protected function wrapInQuotes(string $string):string { + /** @var string $string */ $string = preg_replace('/[\r\n\t"]/', ' ', $string); $string = '"' . str_replace('"', '\"', $string) . '"'; return $string; diff --git a/src/Commands/Control/InfoCommand.php b/src/Commands/Control/InfoCommand.php index 81b24bc..56cd4ff 100644 --- a/src/Commands/Control/InfoCommand.php +++ b/src/Commands/Control/InfoCommand.php @@ -6,8 +6,9 @@ final class InfoCommand extends Command { - private $command = 'INFO'; - private $parameters = []; + private string $command = 'INFO'; + /** @var array $parameters */ + private array $parameters = []; /** * Info Command constructor. @@ -16,4 +17,4 @@ public function __construct() { parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Control/StartControlChannelCommand.php b/src/Commands/Control/StartControlChannelCommand.php index a6302e1..1489a67 100644 --- a/src/Commands/Control/StartControlChannelCommand.php +++ b/src/Commands/Control/StartControlChannelCommand.php @@ -6,8 +6,9 @@ final class StartControlChannelCommand extends Command { - private $command = 'START'; - private $parameters = []; + private string $command = 'START'; + /** @var array $parameters */ + private array $parameters = []; /** * StartControlChannelCommand constructor. @@ -22,4 +23,4 @@ public function __construct($password) parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Control/TriggerCommand.php b/src/Commands/Control/TriggerCommand.php index 9013e08..cbfe7bb 100644 --- a/src/Commands/Control/TriggerCommand.php +++ b/src/Commands/Control/TriggerCommand.php @@ -6,12 +6,12 @@ final class TriggerCommand extends Command { - private $command = 'TRIGGER'; - private $parameters = []; + private string $command = 'TRIGGER'; + /** @var array $parameters */ + private array $parameters = []; /** * TriggerCommand constructor. - * @param string $action */ public function __construct(string $action) { @@ -21,4 +21,4 @@ public function __construct(string $action) parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Ingest/CountCommand.php b/src/Commands/Ingest/CountCommand.php index ea39b50..e23d1ce 100644 --- a/src/Commands/Ingest/CountCommand.php +++ b/src/Commands/Ingest/CountCommand.php @@ -6,8 +6,9 @@ final class CountCommand extends Command { - private $command = 'COUNT'; - private $parameters = []; + private string $command = 'COUNT'; + /** @var array $parameters */ + private array $parameters = []; /** * Counts the number of objects @@ -26,4 +27,4 @@ public function __construct(string $collection, string $bucket = null, string $o parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Ingest/FlushBucketCommand.php b/src/Commands/Ingest/FlushBucketCommand.php index 7216c82..e0f4f4a 100644 --- a/src/Commands/Ingest/FlushBucketCommand.php +++ b/src/Commands/Ingest/FlushBucketCommand.php @@ -6,8 +6,9 @@ final class FlushBucketCommand extends Command { - private $command = 'FLUSHB'; - private $parameters = []; + private string $command = 'FLUSHB'; + /** @var array $parameters */ + private array $parameters = []; /** * Flushes a given bucket in a collection @@ -24,4 +25,4 @@ public function __construct(string $collection, string $bucket) parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Ingest/FlushCollectionCommand.php b/src/Commands/Ingest/FlushCollectionCommand.php index 40bda14..e89bc2e 100644 --- a/src/Commands/Ingest/FlushCollectionCommand.php +++ b/src/Commands/Ingest/FlushCollectionCommand.php @@ -6,8 +6,9 @@ final class FlushCollectionCommand extends Command { - private $command = 'FLUSHC'; - private $parameters = []; + private string $command = 'FLUSHC'; + /** @var array $parameters */ + private array $parameters = []; /** * Flushes a given collection @@ -22,4 +23,4 @@ public function __construct(string $collection) parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Ingest/FlushObjectCommand.php b/src/Commands/Ingest/FlushObjectCommand.php index fdef4a4..0c424fb 100644 --- a/src/Commands/Ingest/FlushObjectCommand.php +++ b/src/Commands/Ingest/FlushObjectCommand.php @@ -6,8 +6,9 @@ final class FlushObjectCommand extends Command { - private $command = 'FLUSHO'; - private $parameters = []; + private string $command = 'FLUSHO'; + /** @var array $parameters */ + private array $parameters = []; /** * Flushes the text from an object @@ -26,4 +27,4 @@ public function __construct(string $collection, string $bucket, string $object) parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Ingest/PopCommand.php b/src/Commands/Ingest/PopCommand.php index 0eeacb5..a75ce94 100644 --- a/src/Commands/Ingest/PopCommand.php +++ b/src/Commands/Ingest/PopCommand.php @@ -6,8 +6,9 @@ final class PopCommand extends Command { - private $command = 'POP'; - private $parameters = []; + private string $command = 'POP'; + /** @var array $parameters */ + private array $parameters = []; /** * pops a text from a given object @@ -28,4 +29,4 @@ public function __construct(string $collection, string $bucket, string $object, parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Ingest/PushCommand.php b/src/Commands/Ingest/PushCommand.php index c03d44f..e68a7df 100644 --- a/src/Commands/Ingest/PushCommand.php +++ b/src/Commands/Ingest/PushCommand.php @@ -6,8 +6,9 @@ final class PushCommand extends Command { - private $command = 'PUSH'; - private $parameters = []; + private string $command = 'PUSH'; + /** @var array $parameters */ + private array $parameters = []; /** * Push a text/object into an object/bucket respectively @@ -30,4 +31,4 @@ public function __construct(string $collection, string $bucket, string $object, parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Ingest/StartIngestChannelCommand.php b/src/Commands/Ingest/StartIngestChannelCommand.php index 6d64baa..f77cfc6 100644 --- a/src/Commands/Ingest/StartIngestChannelCommand.php +++ b/src/Commands/Ingest/StartIngestChannelCommand.php @@ -6,8 +6,9 @@ final class StartIngestChannelCommand extends Command { - private $command = 'START'; - private $parameters = []; + private string $command = 'START'; + /** @var array $parameters */ + private array $parameters = []; /** * StartIngestChannelCommand constructor. @@ -22,4 +23,4 @@ public function __construct($password) parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Misc/PingCommand.php b/src/Commands/Misc/PingCommand.php index 7178f10..f5b7ff2 100644 --- a/src/Commands/Misc/PingCommand.php +++ b/src/Commands/Misc/PingCommand.php @@ -8,8 +8,9 @@ final class PingCommand extends Command { - private $command = 'PING'; - private $parameters = []; + private string $command = 'PING'; + /** @var array $parameters */ + private array $parameters = []; /** * PingCommand constructor. @@ -18,4 +19,4 @@ public function __construct() { parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Misc/QuitChannelCommand.php b/src/Commands/Misc/QuitChannelCommand.php index aed537c..1ded233 100644 --- a/src/Commands/Misc/QuitChannelCommand.php +++ b/src/Commands/Misc/QuitChannelCommand.php @@ -8,8 +8,9 @@ final class QuitChannelCommand extends Command { - private $command = 'QUIT'; - private $parameters = []; + private string $command = 'QUIT'; + /** @var array $parameters */ + private array $parameters = []; /** * QuitChannelCommand constructor. @@ -18,4 +19,4 @@ public function __construct() { parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Search/QueryCommand.php b/src/Commands/Search/QueryCommand.php index bad4c1f..27ede65 100644 --- a/src/Commands/Search/QueryCommand.php +++ b/src/Commands/Search/QueryCommand.php @@ -6,19 +6,11 @@ final class QueryCommand extends Command { - private $command = 'QUERY'; - private $parameters = []; + private string $command = 'QUERY'; + /** @var array $parameters */ + private array $parameters = []; - /** - * QueryCommand constructor. - * @param string $collection - * @param string $bucket - * @param string $terms - * @param null $limit - * @param null $offset - * @param null $locale - */ - public function __construct(string $collection, string $bucket, string $terms, $limit = null, $offset = null, $locale = null) + public function __construct(string $collection, string $bucket, string $terms, int $limit = null, int $offset = null,string $locale = null) { $this->parameters = [ 'collection' => $collection, diff --git a/src/Commands/Search/StartSearchChannelCommand.php b/src/Commands/Search/StartSearchChannelCommand.php index 54ffe41..f8065e9 100644 --- a/src/Commands/Search/StartSearchChannelCommand.php +++ b/src/Commands/Search/StartSearchChannelCommand.php @@ -6,14 +6,11 @@ final class StartSearchChannelCommand extends Command { - private $command = 'START'; - private $parameters = []; + private string $command = 'START'; + /** @var array $parameters */ + private array $parameters = []; - /** - * StartSearchChannelCommand constructor. - * @param string $password - */ - public function __construct($password) + public function __construct(string $password) { $this->parameters = [ 'mode' => 'search', @@ -22,4 +19,4 @@ public function __construct($password) parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Commands/Search/SuggestCommand.php b/src/Commands/Search/SuggestCommand.php index 26f451c..21986c3 100644 --- a/src/Commands/Search/SuggestCommand.php +++ b/src/Commands/Search/SuggestCommand.php @@ -6,17 +6,14 @@ final class SuggestCommand extends Command { - private $command = 'SUGGEST'; - private $parameters = []; + private string $command = 'SUGGEST'; + /** @var array $parameters */ + private array $parameters = []; /** * SuggestCommand constructor. - * @param string $collection - * @param string $bucket - * @param string $terms - * @param null $limit */ - public function __construct(string $collection, string $bucket, string $terms, $limit = null) + public function __construct(string $collection, string $bucket, string $terms,int $limit = null) { $this->parameters = [ 'collection' => $collection, @@ -27,4 +24,4 @@ public function __construct(string $collection, string $bucket, string $terms, $ parent::__construct($this->command, $this->parameters); } -} \ No newline at end of file +} diff --git a/src/Contracts/Client.php b/src/Contracts/Client.php index 322e5ab..b9421a1 100644 --- a/src/Contracts/Client.php +++ b/src/Contracts/Client.php @@ -1,4 +1,4 @@ -send(new StartControlChannelCommand($password)); - if ($bufferSize = $response->get('bufferSize')) { + /** @var string $bufferSize */ + $bufferSize = $response->get('bufferSize'); + if ($bufferSize) { $this->bufferSize = (int)$bufferSize; } return $response; } - /** - * @param $action - * @return Contracts\Response - */ - public function trigger($action) + public function trigger(string $action): Response { return $this->send(new TriggerCommand($action)); } - /** - * @return Contracts\Response - */ - public function consolidate() + public function consolidate(): Response { return $this->trigger('consolidate'); } - public function info() + public function info(): Response { return $this->send(new InfoCommand); } diff --git a/src/Ingest.php b/src/Ingest.php index d4512b9..9359e5e 100644 --- a/src/Ingest.php +++ b/src/Ingest.php @@ -12,6 +12,7 @@ use Psonic\Commands\Ingest\FlushBucketCommand; use Psonic\Commands\Ingest\FlushCollectionCommand; use Psonic\Commands\Ingest\StartIngestChannelCommand; +use Psonic\Contracts\Response; class Ingest extends Channel { @@ -24,17 +25,15 @@ public function __construct(Client $client) parent::__construct($client); } - /** - * @return mixed|Contracts\Response|void - * @throws Exceptions\ConnectionException - */ - public function connect($password = 'SecretPassword') + public function connect(string $password = 'SecretPassword'): Response { parent::connect(); $response = $this->send(new StartIngestChannelCommand($password)); - if ($bufferSize = $response->get('bufferSize')) { + /** @var string $bufferSize */ + $bufferSize = $response->get('bufferSize'); + if ($bufferSize) { $this->bufferSize = (int)$bufferSize; } @@ -88,61 +87,52 @@ public function pop(string $collection, string $bucket, string $object, string $ return $count; } - /** - * @param $collection - * @param null $bucket - * @param null $object - * @return mixed - */ - public function count($collection, $bucket = null, $object = null) + public function count(string $collection,string $bucket = null, string $object = null): int { + /** @var SonicResponse $message */ $message = $this->send(new CountCommand($collection, $bucket, $object)); - return $message->get('count'); + /** @var string $count */ + $count = $message->get('count'); + return (int)$count; } - /** - * @param $collection - * @return mixed - */ - public function flushc($collection) + + public function flushc(string $collection): int { - $message = $this->send(new FlushCollectionCommand($collection)); + /** @var SonicResponse $message */ + $message = $this->send(new FlushCollectionCommand( $collection)); + return $message->getCount(); } - /** - * @param $collection - * @param $bucket - * @return integer - */ - public function flushb($collection, $bucket) + + public function flushb(string $collection, string $bucket): int { + /** @var SonicResponse $message */ $message = $this->send(new FlushBucketCommand($collection, $bucket)); return $message->getCount(); } - /** - * @param $collection - * @param $bucket - * @param $object - * @return mixed - */ - public function flusho($collection, $bucket, $object) + public function flusho(string $collection,string $bucket,string $object): int { + /** @var SonicResponse $message */ $message = $this->send(new FlushObjectCommand($collection, $bucket, $object)); return $message->getCount(); } /** - * @param string $collection - * @param string $bucket - * @param string $key - * @param string $text - * @return array + * @return array */ private function splitString(string $collection, string $bucket, string $key, string $text): array { - return str_split($text, ($this->bufferSize - (strlen($key . $collection . $bucket) + 20))); + $extraBytesRequired = strlen($key . $collection . $bucket) + 20; + $splitLength = $this->bufferSize - $extraBytesRequired; + if($splitLength<=0) { + throw new \RuntimeException("Insufficient buffer size for splitting the message string Given " + . $splitLength + . ". Buffersize should be more than {$extraBytesRequired} to accomodate the collection, bucket and key name(s) length in the message"); + } + return str_split($text, $splitLength); } } diff --git a/src/Search.php b/src/Search.php index ed97068..42b0571 100644 --- a/src/Search.php +++ b/src/Search.php @@ -25,30 +25,28 @@ public function __construct(Client $client) * @return mixed|Contracts\Response|void * @throws Exceptions\ConnectionException */ - public function connect($password = 'SecretPassword') + public function connect(string $password = 'SecretPassword') { parent::connect(); $response = $this->send(new StartSearchChannelCommand($password)); - if ($bufferSize = $response->get('bufferSize')) { + + /** @var string $bufferSize */ + $bufferSize = $response->get('bufferSize'); + + if ($bufferSize) { $this->bufferSize = (int)$bufferSize; } return $response; } + /** - * @param $collection - * @param $bucket - * @param $terms - * @param $limit - * @param $offset - * @param $locale - * @return array - * @throws CommandFailedException + *@return array */ - public function query($collection, $bucket, $terms, $limit = null, $offset = null, $locale = null): array + public function query(string $collection,string $bucket,string $terms,int $limit = null,int $offset = null,string $locale = null): array { $response = $this->send(new QueryCommand($collection, $bucket, $terms, $limit, $offset, $locale)); @@ -56,6 +54,7 @@ public function query($collection, $bucket, $terms, $limit = null, $offset = nul throw new CommandFailedException; } + /** @var SonicResponse $results */ $results = $this->read(); if (!$results->getStatus() == 'EVENT') { @@ -65,15 +64,11 @@ public function query($collection, $bucket, $terms, $limit = null, $offset = nul return $results->getResults(); } + /** - * @param $collection - * @param $bucket - * @param $terms - * @param $limit - * @return array - * @throws CommandFailedException + *@return array */ - public function suggest($collection, $bucket, $terms, $limit = null): array + public function suggest(string $collection,string $bucket,string $terms, int $limit = null): array { $response = $this->send(new SuggestCommand($collection, $bucket, $terms, $limit)); @@ -81,6 +76,7 @@ public function suggest($collection, $bucket, $terms, $limit = null): array throw new CommandFailedException; } + /** @var SonicResponse $results */ $results = $this->read(); if (!$results->getStatus() == 'EVENT') { diff --git a/src/SonicResponse.php b/src/SonicResponse.php index 7aa2bcb..d4680ba 100644 --- a/src/SonicResponse.php +++ b/src/SonicResponse.php @@ -5,19 +5,17 @@ use Psonic\Contracts\Response as ResponseInterface; use Psonic\Exceptions\CommandFailedException; -class SonicResponse implements ResponseInterface +class SonicResponse implements ResponseInterface { - private $message; - private $pieces; - private $results; + private string $message; + /** @var array */ + private array $pieces; + /** @var array */ + private array $results; - /** - * SonicResponse constructor. - * @param $message - */ - public function __construct($message) + public function __construct(string $message) { - $this->message = (string) $message; + $this->message = $message; $this->parse(); } @@ -25,7 +23,7 @@ public function __construct($message) * parses the read buffer into a readable object * @throws CommandFailedException */ - private function parse() + private function parse(): void { $this->pieces = explode(" ", $this->message); @@ -52,46 +50,40 @@ private function parse() } /** - * @return mixed + * @return array */ - public function getResults() + public function getResults(): array { return $this->results; } - /** - * @return string - */ - public function __toString() + public function __toString():string { return implode(" ", $this->pieces); } /** - * @param $key * @return mixed */ - public function get($key) + public function get(string $key) { if(isset($this->pieces[$key])){ return $this->pieces[$key]; } } - /** - * @return mixed - */ public function getStatus(): string { - return $this->get('status'); + /** @var string $status */ + $status = $this->get('status'); + + return $status; } - /** - * @return int - */ public function getCount():int { - return $this->get('count') ?? 0; + /** @var string $count */ + $count = $this->get('count'); + return $count ? (int)$count : 0; } } - \ No newline at end of file diff --git a/tests/Unit/ClientTest.php b/tests/Unit/ClientTest.php index 9662252..19f334a 100644 --- a/tests/Unit/ClientTest.php +++ b/tests/Unit/ClientTest.php @@ -7,9 +7,11 @@ use Psonic\Client; use Psonic\Commands\Misc\PingCommand; +use Psonic\Commands\Search\QueryCommand; use Psonic\Contracts\Command; use Psonic\Contracts\Response; use Psonic\Exceptions\ConnectionException; +use Psonic\Search; use Tests\TestCase; class ClientTest extends TestCase @@ -38,6 +40,7 @@ public function the_client_can_disconnect_from_socket_and_throws_exception_if_co $this->client->connect(); $this->client->disconnect(); $this->expectException(ConnectionException::class); + $this->expectExceptionMessage("Not connected to sonic. Empty stream given NULL"); $this->client->send(new PingCommand); } @@ -76,4 +79,4 @@ public function the_client_can_send_a_command_to_sonic_and_returns_a_response_ob $this->assertInstanceOf(Response::class, $this->client->send(new PingCommand)); } -} \ No newline at end of file +} diff --git a/tests/Unit/IngestChannelTest.php b/tests/Unit/IngestChannelTest.php index ad81d0c..97c2507 100644 --- a/tests/Unit/IngestChannelTest.php +++ b/tests/Unit/IngestChannelTest.php @@ -124,6 +124,20 @@ public function it_can_flush_an_object() $this->assertEquals(1, $this->ingest->flusho($this->collection, $this->bucket, "1234")); } + /** + * @test + **/ + public function it_throws_exception_when_buffer_is_not_enough() + { + $response = $this->ingest->connect($this->password); + $bufferSize = $response->get('bufferSize'); + + $longBucketName = str_repeat('i', $bufferSize); + $this->ingest->flushc($this->collection); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Insufficient buffer size for splitting the message string Given -38. Buffersize should be more than ". $bufferSize+38 ." to accomodate the collection, bucket and key name(s) length in the message"); // 38 is the length of collectionName, bucketname and object key + $this->assertEquals("OK", $this->ingest->push($this->collection, $longBucketName, "1234", "hi Shobi how are you?")->getStatus()); + } // @todo /** * Implement tests for locale based ingestion