getCommand(); $command->setArguments($actualArguments); $this->assertSameValues($expectedArguments, $command->getArguments()); } /** * @group disconnected * @dataProvider invalidArgumentsProvider */ public function testSetArgumentsThrowsExceptionOnInvalidArguments( array $arguments, string $expectedExceptionMessage ): void { $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage($expectedExceptionMessage); $this->getCommand()->setArguments($arguments); } /** * @group disconnected */ public function testPrefixKeys(): void { /** @var PrefixableCommand $command */ $command = $this->getCommand(); $actualArguments = ['source', 'destination', 'LEFT', 'RIGHT', 'COUNT', 3, 'OBO']; $prefix = 'prefix:'; $expectedArguments = ['prefix:source', 'prefix:destination', 'LEFT', 'RIGHT', 'COUNT', 3, 'OBO']; $command->setArguments($actualArguments); $command->prefixKeys($prefix); $this->assertSame($expectedArguments, $command->getArguments()); } /** * @group connected * @dataProvider listsProvider * @param array $sourceList * @param array $destinationList * @param array $commandArguments * @param array|null $expectedResponse * @param array $expectedSourceList * @param array $expectedDestinationList * @return void * @requiresRedisVersion >= 8.9.0 */ public function testMovesElementsBetweenLists( array $sourceList, array $destinationList, array $commandArguments, ?array $expectedResponse, array $expectedSourceList, array $expectedDestinationList ): void { $redis = $this->getClient(); if ($sourceList) { $redis->rpush('source', $sourceList); } if ($destinationList) { $redis->rpush('destination', $destinationList); } $this->assertSame($expectedResponse, $redis->lmovem('source', 'destination', ...$commandArguments)); $this->assertSame($expectedSourceList, $redis->lrange('source', 0, -1)); $this->assertSame($expectedDestinationList, $redis->lrange('destination', 0, -1)); } /** * @group connected * @return void * @requiresRedisVersion >= 8.9.0 */ public function testMovesElementsBetweenListsResp3(): void { $redis = $this->getResp3Client(); $redis->rpush('source', ['1', '2', '3', '4', '5']); $redis->rpush('destination', ['6', '7', '8', '9', '10']); $this->assertSame( ['3', '2', '1'], $redis->lmovem('source', 'destination', 'LEFT', 'LEFT', 'COUNT', 3, 'OBO') ); $this->assertSame(['4', '5'], $redis->lrange('source', 0, -1)); $this->assertSame( ['3', '2', '1', '6', '7', '8', '9', '10'], $redis->lrange('destination', 0, -1) ); } /** * @group connected * @return void * @requiresRedisVersion >= 8.9.0 */ public function testThrowsExceptionOnWrongType(): void { $redis = $this->getClient(); $this->expectException(ServerException::class); $this->expectExceptionMessage('Operation against a key holding the wrong kind of value'); $redis->set('source', 'foo'); $redis->lmovem('source', 'destination', 'LEFT', 'RIGHT'); } public function argumentsProvider(): array { return [ 'with required arguments only' => [ ['source', 'destination', 'LEFT', 'RIGHT'], ['source', 'destination', 'LEFT', 'RIGHT'], ], 'with COUNT quantifier' => [ ['source', 'destination', 'LEFT', 'LEFT', 'COUNT', 3, 'OBO'], ['source', 'destination', 'LEFT', 'LEFT', 'COUNT', 3, 'OBO'], ], 'with EXACTLY quantifier' => [ ['source', 'destination', 'RIGHT', 'RIGHT', 'EXACTLY', 2, 'BULK'], ['source', 'destination', 'RIGHT', 'RIGHT', 'EXACTLY', 2, 'BULK'], ], 'with lowercase quantifier and ordering' => [ ['source', 'destination', 'LEFT', 'RIGHT', 'count', 3, 'bulk'], ['source', 'destination', 'LEFT', 'RIGHT', 'COUNT', 3, 'BULK'], ], ]; } public function invalidArgumentsProvider(): array { return [ 'with invalid quantifier' => [ ['source', 'destination', 'LEFT', 'RIGHT', 'WRONG', 3, 'OBO'], 'Quantifier argument accepts only: COUNT, EXACTLY values', ], 'with missing count' => [ ['source', 'destination', 'LEFT', 'RIGHT', 'COUNT'], 'COUNT quantifier requires a count argument', ], 'with missing ordering' => [ ['source', 'destination', 'LEFT', 'RIGHT', 'EXACTLY', 2], 'EXACTLY quantifier requires an ordering argument', ], 'with invalid ordering' => [ ['source', 'destination', 'LEFT', 'RIGHT', 'COUNT', 3, 'WRONG'], 'Ordering argument accepts only: OBO, BULK values', ], ]; } public function listsProvider(): array { return [ 'moves single element without quantifier' => [ ['1', '2', '3', '4', '5'], [], ['LEFT', 'RIGHT'], ['1'], ['2', '3', '4', '5'], ['1'], ], 'with COUNT and OBO - reversed block order' => [ ['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10'], ['LEFT', 'LEFT', 'COUNT', 3, 'OBO'], ['3', '2', '1'], ['4', '5'], ['3', '2', '1', '6', '7', '8', '9', '10'], ], 'with COUNT and BULK - preserved relative order' => [ ['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10'], ['LEFT', 'LEFT', 'COUNT', 3, 'BULK'], ['1', '2', '3'], ['4', '5'], ['1', '2', '3', '6', '7', '8', '9', '10'], ], 'with mixed directions - RIGHT to RIGHT' => [ ['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10'], ['RIGHT', 'RIGHT', 'COUNT', 3, 'BULK'], ['3', '4', '5'], ['1', '2'], ['6', '7', '8', '9', '10', '3', '4', '5'], ], 'with COUNT greater than source length - moves fewer' => [ ['1', '2'], [], ['LEFT', 'RIGHT', 'COUNT', 5, 'BULK'], ['1', '2'], [], ['1', '2'], ], 'with EXACTLY and enough elements' => [ ['john', 'doe'], [], ['LEFT', 'RIGHT', 'EXACTLY', 2, 'BULK'], ['john', 'doe'], [], ['john', 'doe'], ], 'with EXACTLY and too few elements - moves nothing' => [ ['john'], [], ['LEFT', 'RIGHT', 'EXACTLY', 2, 'BULK'], null, ['john'], [], ], 'with empty source - moves nothing' => [ [], ['6', '7'], ['LEFT', 'RIGHT', 'COUNT', 2, 'BULK'], null, [], ['6', '7'], ], ]; } }