diff --git a/src/ClientContextInterface.php b/src/ClientContextInterface.php index d7e61a3b..cb3db5ff 100644 --- a/src/ClientContextInterface.php +++ b/src/ClientContextInterface.php @@ -92,6 +92,7 @@ use Predis\Command\CommandInterface; * @method $this blpop(array|string $keys, $timeout) * @method $this brpop(array|string $keys, $timeout) * @method $this brpoplpush($source, $destination, $timeout) + * @method $this lcs(string $key1, string $key2, bool $len = false, bool $idx = false, int $minMatchLen = 0, bool $withMatchLen = false) * @method $this lindex($key, $index) * @method $this linsert($key, $whence, $pivot, $value) * @method $this llen($key) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index c560121b..c6730f04 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -101,6 +101,7 @@ use Predis\Response\Status; * @method array|null blpop(array|string $keys, int|float $timeout) * @method array|null brpop(array|string $keys, int|float $timeout) * @method string|null brpoplpush(string $source, string $destination, int|float $timeout) + * @method mixed lcs(string $key1, string $key2, bool $len = false, bool $idx = false, int $minMatchLen = 0, bool $withMatchLen = false) * @method string|null lindex(string $key, int $index) * @method int linsert(string $key, $whence, $pivot, $value) * @method int llen(string $key) diff --git a/src/Command/Redis/LCS.php b/src/Command/Redis/LCS.php new file mode 100644 index 00000000..e3f91697 --- /dev/null +++ b/src/Command/Redis/LCS.php @@ -0,0 +1,65 @@ +filterArguments(); + } + + public function parseResponse($data) + { + if (is_array($data)) { + return [$data[0] => $data[1], $data[2] => $data[3]]; + } + + return $data; + } +} diff --git a/tests/Predis/Command/Redis/LCS_Test.php b/tests/Predis/Command/Redis/LCS_Test.php new file mode 100644 index 00000000..839084a3 --- /dev/null +++ b/tests/Predis/Command/Redis/LCS_Test.php @@ -0,0 +1,200 @@ +getCommand(); + $command->setArguments($actualArguments); + + $this->assertSameValues($expectedArguments, $command->getArguments()); + } + + /** + * @group disconnected + * @dataProvider responsesProvider + */ + public function testParseResponse($actualResponse, $expectedResponse): void + { + $this->assertSame($expectedResponse, $this->getCommand()->parseResponse($actualResponse)); + } + + /** + * @group connected + * @dataProvider stringsProvider + * @param array $stringsArguments + * @param array $functionArguments + * @param $expectedResponse + * @return void + * @requiresRedisVersion >= 7.0.0 + */ + public function testReturnsLongestCommonSubsequenceFromGivenStrings( + array $stringsArguments, + array $functionArguments, + $expectedResponse + ): void { + $redis = $this->getClient(); + + $redis->mset(...$stringsArguments); + + $this->assertSame($expectedResponse, $redis->lcs(...$functionArguments)); + } + + public function argumentsProvider(): array + { + return [ + 'with required arguments' => [ + ['key1', 'key2'], + ['key1', 'key2'], + ], + 'with LEN argument' => [ + ['key1', 'key2', true], + ['key1', 'key2', 'LEN'], + ], + 'with IDX argument' => [ + ['key1', 'key2', false, true], + ['key1', 'key2', 'IDX'], + ], + 'with MINMATCHLEN argument' => [ + ['key1', 'key2', false, false, 2], + ['key1', 'key2', 'MINMATCHLEN', 2], + ], + 'with WITHMATCHLEN argument' => [ + ['key1', 'key2', false, false, 0, true], + ['key1', 'key2', 'WITHMATCHLEN'], + ], + 'with all arguments' => [ + ['key1', 'key2', true, true, 2, true], + ['key1', 'key2', 'LEN', 'IDX', 'MINMATCHLEN', 2, 'WITHMATCHLEN'], + ], + ]; + } + + public function responsesProvider(): array + { + return [ + 'non-array response' => [ + 1, + 1, + ], + 'array response' => [ + ['matches', [[[0, 1], [1, 2]]], 'len', 2], + ['matches' => [[[0, 1], [1, 2]]], 'len' => 2], + ], + ]; + } + + public function stringsProvider(): array + { + return [ + 'with required arguments' => [ + ['key1', 'value1', 'key2', '2value'], + ['key1', 'key2'], + 'value', + ], + 'only length' => [ + ['key1', 'value1', 'key2', '2value'], + ['key1', 'key2', true], + 5, + ], + 'with matching indexes - single match' => [ + ['key1', 'value1', 'key2', '2value'], + ['key1', 'key2', false, true], + [ + 'matches' => [ + [ + [0, 4], + [1, 5], + ], + ], + 'len' => 5, + ], + ], + 'with matching indexes - multiple match' => [ + ['key1', 'value1test', 'key2', '2valuetest'], + ['key1', 'key2', false, true], + [ + 'matches' => [ + [ + [6, 9], + [6, 9], + ], + [ + [0, 4], + [1, 5], + ], + ], + 'len' => 9, + ], + ], + 'with matching indexes - MINMATCHLEN modifier' => [ + ['key1', 'value1test', 'key2', '2valuetest'], + ['key1', 'key2', false, true, 5], + [ + 'matches' => [ + [ + [0, 4], + [1, 5], + ], + ], + 'len' => 9, + ], + ], + 'with matching indexes - WITHMATCHLEN modifier' => [ + ['key1', 'value1test', 'key2', '2valuetest'], + ['key1', 'key2', false, true, 5, true], + [ + 'matches' => [ + [ + [0, 4], + [1, 5], + 5, + ], + ], + 'len' => 9, + ], + ], + 'with wrong/empty keys arguments' => [ + ['key1', 'value1', 'key2', '2value'], + ['key3', 'key4'], + '', + ], + ]; + } +}