diff --git a/tests/Predis/ClientTest.php b/tests/Predis/ClientTest.php index 019e7c9f..ca84264a 100644 --- a/tests/Predis/ClientTest.php +++ b/tests/Predis/ClientTest.php @@ -210,7 +210,8 @@ class ClientTest extends PredisTestCase $cluster = new Connection\Cluster\PredisCluster(); $factory = new Connection\Factory(); - $factory->aggregate($cluster, array('tcp://localhost:7000', 'tcp://localhost:7001')); + $cluster->add($factory->create('tcp://localhost:7000')); + $cluster->add($factory->create('tcp://localhost:7001')); $client = new Client($cluster); @@ -226,7 +227,8 @@ class ClientTest extends PredisTestCase $replication = new Connection\Replication\MasterSlaveReplication(); $factory = new Connection\Factory(); - $factory->aggregate($replication, array('tcp://host1?alias=master', 'tcp://host2?alias=slave')); + $replication->add($factory->create('tcp://host1?alias=master')); + $replication->add($factory->create('tcp://host2?alias=slave')); $client = new Client($replication); @@ -329,7 +331,11 @@ class ClientTest extends PredisTestCase $fncluster ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface'), $arg1) + ->with( + $arg1, + $this->isInstanceOf('Predis\Configuration\OptionsInterface'), + $this->isInstanceOf('Predis\Configuration\OptionInterface') + ) ->willReturn($connection); $fnreplication = $this->getMockBuilder('stdClass') @@ -372,7 +378,11 @@ class ClientTest extends PredisTestCase $fnreplication ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface'), $arg1) + ->with( + $arg1, + $this->isInstanceOf('Predis\Configuration\OptionsInterface'), + $this->isInstanceOf('Predis\Configuration\OptionInterface') + ) ->willReturn($connection); $fnaggregate = $this->getMockBuilder('stdClass') @@ -397,7 +407,16 @@ class ClientTest extends PredisTestCase { $arg1 = array('tcp://host1', 'tcp://host2'); - $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connections = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); + $connections + ->expects($this->never()) + ->method('create'); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface') + ->getMock(); + $connection + ->expects($this->never()) + ->method('add'); $fnaggregate = $this->getMockBuilder('stdClass') ->addMethods(array('__invoke')) @@ -405,14 +424,13 @@ class ClientTest extends PredisTestCase $fnaggregate ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface'), $arg1) + ->with( + $arg1, + $this->isInstanceOf('Predis\Configuration\OptionsInterface'), + $this->isInstanceOf('Predis\Configuration\OptionInterface') + ) ->willReturn($connection); - $connections = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); - $connections - ->expects($this->never()) - ->method('aggregate'); - $arg2 = array('aggregate' => $fnaggregate, 'connections' => $connections); $client = new Client($arg1, $arg2); @@ -1280,7 +1298,11 @@ class ClientTest extends PredisTestCase $callable ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface'), $parameters) + ->with( + $parameters, + $this->isInstanceOf('Predis\Configuration\OptionsInterface'), + $this->isInstanceOf('Predis\Configuration\OptionInterface') + ) ->willReturn($connection); return $callable; diff --git a/tests/Predis/Configuration/Option/AggregateTest.php b/tests/Predis/Configuration/Option/AggregateTest.php index db6931ca..4cb395b2 100644 --- a/tests/Predis/Configuration/Option/AggregateTest.php +++ b/tests/Predis/Configuration/Option/AggregateTest.php @@ -11,9 +11,12 @@ namespace Predis\Configuration\Option; +use PHPUnit\Framework\MockObject\MockObject; use PredisTestCase; use Predis\Configuration\OptionsInterface; +use function PHPSTORM_META\expectedArguments; + /** * */ @@ -38,6 +41,7 @@ class AggregateTest extends PredisTestCase public function testAcceptsCallableAsConnectionInitializer(): void { $option = new Aggregate(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); @@ -49,11 +53,162 @@ class AggregateTest extends PredisTestCase $callable ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface')) + ->with($parameters, $options, $option) ->willReturn($connection); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, $callable)); - $this->assertSame($connection, $initializer($parameters = array())); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperDoesNotTriggerAggregationByDefault(): void + { + $option = new Aggregate(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->never()) + ->method('__get') + ->with('connections'); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->never()) + ->method('add'); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperDoesNotTriggerAggregationWhenSecondArgumentIsFalse(): void + { + $option = new Aggregate(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->never()) + ->method('__get') + ->with('connections'); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->never()) + ->method('add'); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, false)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperTriggersAggregationWhenSecondArgumentIsTrue(): void + { + $option = new Aggregate(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + $factory = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); + $factory + ->expects($this->exactly(2)) + ->method('create') + ->withConsecutive( + [$parameters[0]], + [$parameters[1]] + ) + ->willReturnOnConsecutiveCalls( + $nodeConnection1 = $this->getMockConnection($parameters[0]), + $nodeConnection2 = $this->getMockConnection($parameters[1]) + ); + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->once()) + ->method('__get') + ->with('connections') + ->willReturn($factory); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface') + ->getMock(); + $connection + ->expects($this->exactly(2)) + ->method('add') + ->withConsecutive( + [$nodeConnection1], + [$nodeConnection2] + ); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, true)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperDoesNotTriggerAggregationWhenFirstArgumentIsEmptyAndSecondArgumentIsTrue(): void + { + $option = new Aggregate(); + $parameters = []; + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->never()) + ->method('__get') + ->with('connections'); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->never()) + ->method('add'); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, true)); } /** @@ -62,9 +217,12 @@ class AggregateTest extends PredisTestCase public function testThrowsExceptionOnInvalidReturnTypeOfConnectionInitializer(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('Predis\Configuration\Option\Aggregate expects a valid connection type returned by callable initializer'); + $this->expectExceptionMessageMatches( + '/^Predis\\\Configuration\\\Option\\\Aggregate expects the supplied callable to return an instance of Predis\\\Connection\\\AggregateConnectionInterface, but .* was returned$/' + ); $option = new Aggregate(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); @@ -76,12 +234,12 @@ class AggregateTest extends PredisTestCase $callable ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface')) + ->with($parameters, $options, $option) ->willReturn($connection); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, $callable)); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); - $initializer($parameters = array()); + $initializer($parameters); } /** @@ -90,14 +248,89 @@ class AggregateTest extends PredisTestCase public function testThrowsExceptionOnInstanceOfAggregateConnectionInterface(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('Predis\Configuration\Option\Aggregate expects a valid callable'); + $this->expectExceptionMessage('Predis\Configuration\Option\Aggregate expects a callable object acting as an aggregate connection initializer'); $option = new Aggregate(); /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); - $cluster = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); - $option->filter($options, $cluster); + $option->filter($options, $connection); + } + + /** + * @group disconnected + */ + public function ___AggregateConnectionSkipCreationOnConnectionInstance(): void + { + list(, $connectionClass) = $this->getMockConnectionClass(); + + /** @var ClusterInterface|MockObject */ + $cluster = $this->getMockBuilder('Predis\Connection\Cluster\ClusterInterface')->getMock(); + $cluster + ->expects($this->exactly(2)) + ->method('add') + ->with($this->isInstanceOf('Predis\Connection\NodeConnectionInterface')); + + /** @var Factory|MockObject */ + $factory = $this->getMockBuilder('Predis\Connection\Factory') + ->onlyMethods(array('create')) + ->getMock(); + $factory + ->expects($this->never()) + ->method('create'); + + $factory->aggregate($cluster, array(new $connectionClass(), new $connectionClass())); + } + + /** + * @group disconnected + */ + public function ___AggregateConnectionWithMixedParameters(): void + { + list(, $connectionClass) = $this->getMockConnectionClass(); + + /** @var ClusterInterface|MockObject */ + $cluster = $this->getMockBuilder('Predis\Connection\Cluster\ClusterInterface')->getMock(); + $cluster + ->expects($this->exactly(4)) + ->method('add') + ->with($this->isInstanceOf('Predis\Connection\NodeConnectionInterface')); + + /** @var Factory|MockObject */ + $factory = $this->getMockBuilder('Predis\Connection\Factory') + ->onlyMethods(array('create')) + ->getMock(); + $factory + ->expects($this->exactly(3)) + ->method('create') + ->willReturnCallback(function () use ($connectionClass) { + return new $connectionClass(); + }); + + $factory->aggregate($cluster, array(null, 'tcp://127.0.0.1', array('scheme' => 'tcp'), new $connectionClass())); + } + + /** + * @group disconnected + */ + public function ___AggregateConnectionWithEmptyListOfParameters(): void + { + /** @var ClusterInterface|MockObject */ + $cluster = $this->getMockBuilder('Predis\Connection\Cluster\ClusterInterface')->getMock(); + $cluster + ->expects($this->never()) + ->method('add'); + + /** @var Factory|MockObject */ + $factory = $this->getMockBuilder('Predis\Connection\Factory') + ->onlyMethods(array('create')) + ->getMock(); + $factory + ->expects($this->never()) + ->method('create'); + + $factory->aggregate($cluster, array()); } } diff --git a/tests/Predis/Configuration/Option/ClusterTest.php b/tests/Predis/Configuration/Option/ClusterTest.php index 28057060..aed5370c 100644 --- a/tests/Predis/Configuration/Option/ClusterTest.php +++ b/tests/Predis/Configuration/Option/ClusterTest.php @@ -30,8 +30,8 @@ class ClusterTest extends PredisTestCase /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); - $this->assertInstanceOf('Closure', $initializer = $option->getDefault($options)); - $this->assertInstanceOf('Predis\Connection\Cluster\PredisCluster', $initializer($options)); + $this->assertInstanceOf('closure', $initializer = $option->getDefault($options)); + $this->assertInstanceOf('Predis\Connection\Cluster\PredisCluster', $initializer($parameters = [])); } /** @@ -40,6 +40,7 @@ class ClusterTest extends PredisTestCase public function testAcceptsCallableAsConnectionInitializer(): void { $option = new Cluster(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); @@ -51,11 +52,179 @@ class ClusterTest extends PredisTestCase $callable ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface')) + ->with($parameters, $options, $option) ->willReturn($connection); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, $callable)); - $this->assertSame($connection, $initializer($parameters = array())); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperTriggersAggregationByDefault(): void + { + $option = new Cluster(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + $factory = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); + $factory + ->expects($this->exactly(2)) + ->method('create') + ->withConsecutive( + [$parameters[0]], + [$parameters[1]] + ) + ->willReturnOnConsecutiveCalls( + $nodeConnection1 = $this->getMockConnection($parameters[0]), + $nodeConnection2 = $this->getMockConnection($parameters[1]) + ); + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->once()) + ->method('__get') + ->with('connections') + ->willReturn($factory); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->exactly(2)) + ->method('add') + ->withConsecutive( + [$nodeConnection1], + [$nodeConnection2] + ); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, true)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperDoesNotTriggerAggregationWhenSecondArgumentIsFalse(): void + { + $option = new Cluster(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->never()) + ->method('__get') + ->with('connections'); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->never()) + ->method('add'); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, false)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperTriggersAggregationWhenSecondArgumentIsTrue(): void + { + $option = new Cluster(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + $factory = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); + $factory + ->expects($this->exactly(2)) + ->method('create') + ->withConsecutive( + [$parameters[0]], + [$parameters[1]] + ) + ->willReturnOnConsecutiveCalls( + $nodeConnection1 = $this->getMockConnection($parameters[0]), + $nodeConnection2 = $this->getMockConnection($parameters[1]) + ); + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->once()) + ->method('__get') + ->with('connections') + ->willReturn($factory); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->exactly(2)) + ->method('add') + ->withConsecutive( + [$nodeConnection1], + [$nodeConnection2] + ); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, true)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperDoesNotTriggerAggregationWhenFirstArgumentIsEmptyAndSecondArgumentIsTrue(): void + { + $option = new Cluster(); + $parameters = []; + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->never()) + ->method('__get') + ->with('connections'); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->never()) + ->method('add'); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, true)); } /** @@ -64,9 +233,12 @@ class ClusterTest extends PredisTestCase public function testThrowsExceptionOnInvalidReturnTypeOfConnectionInitializer(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('Predis\Configuration\Option\Cluster expects a valid connection type returned by callable initializer'); + $this->expectExceptionMessageMatches( + '/^Predis\\\Configuration\\\Option\\\Cluster expects the supplied callable to return an instance of Predis\\\Connection\\\AggregateConnectionInterface, but .* was returned$/' + ); $option = new Cluster(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); @@ -78,12 +250,12 @@ class ClusterTest extends PredisTestCase $callable ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface')) + ->with($parameters, $options, $option) ->willReturn($connection); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, $callable)); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); - $initializer($parameters = array()); + $initializer($parameters); } /** @@ -100,7 +272,7 @@ class ClusterTest extends PredisTestCase ->method('__get') ->with('connections'); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, 'predis')); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, 'predis')); $this->assertInstanceOf('Predis\Connection\Cluster\PredisCluster', $initializer($parameters = array())); } @@ -126,7 +298,33 @@ class ClusterTest extends PredisTestCase $this->getMockBuilder('Predis\Cluster\Hash\HashGeneratorInterface')->getMock() ); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, 'redis')); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, 'redis')); + $this->assertInstanceOf('Predis\Connection\Cluster\RedisCluster', $initializer($parameters = array())); + } + + /** + * @group disconnected + */ + public function testAcceptsShortNameStringRedisCluster(): void + { + $option = new Cluster(); + + /** @var OptionsInterface|MockObject */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + + $options + ->expects($this->exactly(2)) + ->method('__get') + ->withConsecutive( + array('connections'), + array('crc16') + ) + ->willReturnOnConsecutiveCalls( + $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(), + $this->getMockBuilder('Predis\Cluster\Hash\HashGeneratorInterface')->getMock() + ); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, 'redis-cluster')); $this->assertInstanceOf('Predis\Connection\Cluster\RedisCluster', $initializer($parameters = array())); } @@ -136,7 +334,9 @@ class ClusterTest extends PredisTestCase public function testThrowsExceptionOnInvalidShortNameString(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('String value for the cluster option must be either `predis` or `redis`'); + $this->expectExceptionMessage( + 'Predis\Configuration\Option\Cluster expects either `predis`, `redis` or `redis-cluster` as valid string values, `unknown` given' + ); $option = new Cluster(); @@ -152,7 +352,9 @@ class ClusterTest extends PredisTestCase public function testThrowsExceptionOnInstanceOfClusterInterface(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('Predis\Configuration\Option\Cluster expects a valid callable'); + $this->expectExceptionMessageMatches( + '/Predis\\\Configuration\\\Option\\\Cluster expects either a string or a callable value, .* given/' + ); $option = new Cluster(); diff --git a/tests/Predis/Configuration/Option/ReplicationTest.php b/tests/Predis/Configuration/Option/ReplicationTest.php index fbb2cd85..6bc33399 100644 --- a/tests/Predis/Configuration/Option/ReplicationTest.php +++ b/tests/Predis/Configuration/Option/ReplicationTest.php @@ -30,8 +30,8 @@ class ReplicationTest extends PredisTestCase /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); - $this->assertInstanceOf('Closure', $initializer = $option->getDefault($options)); - $this->assertInstanceOf('Predis\Connection\Replication\MasterSlaveReplication', $initializer($options)); + $this->assertInstanceOf('closure', $initializer = $option->getDefault($options)); + $this->assertInstanceOf('Predis\Connection\Replication\MasterSlaveReplication', $initializer($parameters = [])); } /** @@ -57,8 +57,8 @@ class ReplicationTest extends PredisTestCase $connectionFactory ); - $this->assertInstanceOf('Closure', $initializer = $option->getDefault($options)); - $this->assertInstanceOf('Predis\Connection\Replication\MasterSlaveReplication', $connection = $initializer($options)); + $this->assertInstanceOf('closure', $initializer = $option->getDefault($options)); + $this->assertInstanceOf('Predis\Connection\Replication\MasterSlaveReplication', $connection = $initializer([])); // TODO: I know, I know... $reflection = new \ReflectionProperty($connection, 'autoDiscovery'); @@ -73,6 +73,7 @@ class ReplicationTest extends PredisTestCase public function testAcceptsCallableAsConnectionInitializer(): void { $option = new Replication(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); @@ -84,11 +85,179 @@ class ReplicationTest extends PredisTestCase $callable ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface')) + ->with($parameters, $options, $option) ->willReturn($connection); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, $callable)); - $this->assertSame($connection, $initializer($parameters = array())); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperTriggersAggregationByDefault(): void + { + $option = new Replication(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + $factory = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); + $factory + ->expects($this->exactly(2)) + ->method('create') + ->withConsecutive( + [$parameters[0]], + [$parameters[1]] + ) + ->willReturnOnConsecutiveCalls( + $nodeConnection1 = $this->getMockConnection($parameters[0]), + $nodeConnection2 = $this->getMockConnection($parameters[1]) + ); + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->once()) + ->method('__get') + ->with('connections') + ->willReturn($factory); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->exactly(2)) + ->method('add') + ->withConsecutive( + [$nodeConnection1], + [$nodeConnection2] + ); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, true)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperDoesNotTriggerAggregationWhenSecondArgumentIsFalse(): void + { + $option = new Replication(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->never()) + ->method('__get') + ->with('connections'); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->never()) + ->method('add'); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, false)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperTriggersAggregationWhenSecondArgumentIsTrue(): void + { + $option = new Replication(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; + + $factory = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); + $factory + ->expects($this->exactly(2)) + ->method('create') + ->withConsecutive( + [$parameters[0]], + [$parameters[1]] + ) + ->willReturnOnConsecutiveCalls( + $nodeConnection1 = $this->getMockConnection($parameters[0]), + $nodeConnection2 = $this->getMockConnection($parameters[1]) + ); + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->once()) + ->method('__get') + ->with('connections') + ->willReturn($factory); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->exactly(2)) + ->method('add') + ->withConsecutive( + [$nodeConnection1], + [$nodeConnection2] + ); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, true)); + } + + /** + * @group disconnected + */ + public function testReturnedCallableWrapperDoesNotTriggerAggregationWhenFirstArgumentIsEmptyAndSecondArgumentIsTrue(): void + { + $option = new Replication(); + $parameters = []; + + /** @var MockObject|OptionsInterface */ + $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); + $options + ->expects($this->never()) + ->method('__get') + ->with('connections'); + + $connection = $this->getMockBuilder('Predis\Connection\AggregateConnectionInterface')->getMock(); + $connection + ->expects($this->never()) + ->method('add'); + + $callable = $this->getMockBuilder('stdClass') + ->addMethods(array('__invoke')) + ->getMock(); + $callable + ->expects($this->once()) + ->method('__invoke') + ->with($parameters, $options, $option) + ->willReturn($connection); + + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); + $this->assertSame($connection, $initializer($parameters, true)); } /** @@ -97,9 +266,12 @@ class ReplicationTest extends PredisTestCase public function testThrowsExceptionOnInvalidReturnTypeOfConnectionInitializer(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('Predis\Configuration\Option\Replication expects a valid connection type returned by callable initializer'); + $this->expectExceptionMessageMatches( + '/^Predis\\\Configuration\\\Option\\\Replication expects the supplied callable to return an instance of Predis\\\Connection\\\AggregateConnectionInterface, but .* was returned$/' + ); $option = new Replication(); + $parameters = ['127.0.0.1:6379', '127.0.0.1:6380']; /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); @@ -111,12 +283,12 @@ class ReplicationTest extends PredisTestCase $callable ->expects($this->once()) ->method('__invoke') - ->with($this->isInstanceOf('Predis\Configuration\OptionsInterface')) + ->with($parameters, $options, $option) ->willReturn($connection); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, $callable)); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, $callable)); - $initializer($parameters = array()); + $initializer($parameters); } /** @@ -129,14 +301,14 @@ class ReplicationTest extends PredisTestCase /** @var OptionsInterface */ $options = $this->getMockBuilder('Predis\Configuration\OptionsInterface')->getMock(); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, 'predis')); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, 'predis')); $this->assertInstanceOf('Predis\Connection\Replication\MasterSlaveReplication', $initializer($parameters = array())); } /** * @group disconnected */ - public function testAcceptsShortNameStringRedis(): void + public function testAcceptsShortNameStringSentinel(): void { $option = new Replication(); @@ -158,7 +330,7 @@ class ReplicationTest extends PredisTestCase $this->getMockBuilder('Predis\Connection\NodeConnectionInterface')->getMock(), ); - $this->assertInstanceOf('Closure', $initializer = $option->filter($options, 'sentinel')); + $this->assertInstanceOf('closure', $initializer = $option->filter($options, 'sentinel')); $this->assertInstanceOf('Predis\Connection\Replication\SentinelReplication', $connection = $initializer($parameters)); $this->assertSame($parameters[0], $connection->getSentinelConnection()); @@ -170,7 +342,9 @@ class ReplicationTest extends PredisTestCase public function testThrowsExceptionOnInvalidShortNameString(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('String value for the replication option must be either `predis` or `sentinel`'); + $this->expectExceptionMessage( + 'Predis\Configuration\Option\Replication expects either `predis`, `sentinel` or `redis-sentinel` as valid string values, `unknown` given' + ); $option = new Replication(); @@ -186,7 +360,9 @@ class ReplicationTest extends PredisTestCase public function testThrowsExceptionOnBooleanValue(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('Predis\Configuration\Option\Replication expects a valid callable'); + $this->expectExceptionMessage( + 'Predis\Configuration\Option\Replication expects either a string or a callable value, boolean given' + ); $option = new Replication(); @@ -202,7 +378,9 @@ class ReplicationTest extends PredisTestCase public function testThrowsExceptionOnInstanceOfReplicationInterface(): void { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('Predis\Configuration\Option\Replication expects a valid callable'); + $this->expectExceptionMessageMatches( + '/Predis\\\Configuration\\\Option\\\Replication expects either a string or a callable value, .* given/' + ); $option = new Replication(); diff --git a/tests/Predis/Connection/FactoryTest.php b/tests/Predis/Connection/FactoryTest.php index 95ae06ec..0efecd0b 100644 --- a/tests/Predis/Connection/FactoryTest.php +++ b/tests/Predis/Connection/FactoryTest.php @@ -540,81 +540,6 @@ class FactoryTest extends PredisTestCase $factory->create('test://127.0.0.1'); } - /** - * @group disconnected - */ - public function testAggregateConnectionSkipCreationOnConnectionInstance(): void - { - list(, $connectionClass) = $this->getMockConnectionClass(); - - /** @var ClusterInterface|MockObject */ - $cluster = $this->getMockBuilder('Predis\Connection\Cluster\ClusterInterface')->getMock(); - $cluster - ->expects($this->exactly(2)) - ->method('add') - ->with($this->isInstanceOf('Predis\Connection\NodeConnectionInterface')); - - /** @var Factory|MockObject */ - $factory = $this->getMockBuilder('Predis\Connection\Factory') - ->onlyMethods(array('create')) - ->getMock(); - $factory - ->expects($this->never()) - ->method('create'); - - $factory->aggregate($cluster, array(new $connectionClass(), new $connectionClass())); - } - - /** - * @group disconnected - */ - public function testAggregateConnectionWithMixedParameters(): void - { - list(, $connectionClass) = $this->getMockConnectionClass(); - - /** @var ClusterInterface|MockObject */ - $cluster = $this->getMockBuilder('Predis\Connection\Cluster\ClusterInterface')->getMock(); - $cluster - ->expects($this->exactly(4)) - ->method('add') - ->with($this->isInstanceOf('Predis\Connection\NodeConnectionInterface')); - - /** @var Factory|MockObject */ - $factory = $this->getMockBuilder('Predis\Connection\Factory') - ->onlyMethods(array('create')) - ->getMock(); - $factory - ->expects($this->exactly(3)) - ->method('create') - ->willReturnCallback(function () use ($connectionClass) { - return new $connectionClass(); - }); - - $factory->aggregate($cluster, array(null, 'tcp://127.0.0.1', array('scheme' => 'tcp'), new $connectionClass())); - } - - /** - * @group disconnected - */ - public function testAggregateConnectionWithEmptyListOfParameters(): void - { - /** @var ClusterInterface|MockObject */ - $cluster = $this->getMockBuilder('Predis\Connection\Cluster\ClusterInterface')->getMock(); - $cluster - ->expects($this->never()) - ->method('add'); - - /** @var Factory|MockObject */ - $factory = $this->getMockBuilder('Predis\Connection\Factory') - ->onlyMethods(array('create')) - ->getMock(); - $factory - ->expects($this->never()) - ->method('create'); - - $factory->aggregate($cluster, array()); - } - // ******************************************************************** // // ---- HELPER METHODS ------------------------------------------------ // // ******************************************************************** //