Project

General

Profile

1
<?php
2

    
3
/*
4
 * This file is part of the Predis package.
5
 *
6
 * (c) Daniele Alessandri <suppakilla@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

    
12
namespace Predis;
13

    
14
use PredisTestCase;
15
use Predis\Connection\ConnectionFactory;
16
use Predis\Connection\MasterSlaveReplication;
17
use Predis\Connection\PredisCluster;
18
use Predis\Profile\ServerProfile;
19

    
20
/**
21
 *
22
 */
23
class ClientTest extends PredisTestCase
24
{
25
    /**
26
     * @group disconnected
27
     */
28
    public function testConstructorWithoutArguments()
29
    {
30
        $client = new Client();
31

    
32
        $connection = $client->getConnection();
33
        $this->assertInstanceOf('Predis\Connection\SingleConnectionInterface', $connection);
34

    
35
        $parameters = $connection->getParameters();
36
        $this->assertSame($parameters->host, '127.0.0.1');
37
        $this->assertSame($parameters->port, 6379);
38

    
39
        $options = $client->getOptions();
40
        $this->assertSame($options->profile->getVersion(), ServerProfile::getDefault()->getVersion());
41

    
42
        $this->assertFalse($client->isConnected());
43
    }
44

    
45
    /**
46
     * @group disconnected
47
     */
48
    public function testConstructorWithNullArgument()
49
    {
50
        $client = new Client(null);
51

    
52
        $connection = $client->getConnection();
53
        $this->assertInstanceOf('Predis\Connection\SingleConnectionInterface', $connection);
54

    
55
        $parameters = $connection->getParameters();
56
        $this->assertSame($parameters->host, '127.0.0.1');
57
        $this->assertSame($parameters->port, 6379);
58

    
59
        $options = $client->getOptions();
60
        $this->assertSame($options->profile->getVersion(), ServerProfile::getDefault()->getVersion());
61

    
62
        $this->assertFalse($client->isConnected());
63
    }
64

    
65
    /**
66
     * @group disconnected
67
     */
68
    public function testConstructorWithNullAndNullArguments()
69
    {
70
        $client = new Client(null, null);
71

    
72
        $connection = $client->getConnection();
73
        $this->assertInstanceOf('Predis\Connection\SingleConnectionInterface', $connection);
74

    
75
        $parameters = $connection->getParameters();
76
        $this->assertSame($parameters->host, '127.0.0.1');
77
        $this->assertSame($parameters->port, 6379);
78

    
79
        $options = $client->getOptions();
80
        $this->assertSame($options->profile->getVersion(), ServerProfile::getDefault()->getVersion());
81

    
82
        $this->assertFalse($client->isConnected());
83
    }
84

    
85
    /**
86
     * @group disconnected
87
     */
88
    public function testConstructorWithArrayArgument()
89
    {
90
        $client = new Client($arg1 = array('host' => 'localhost', 'port' => 7000));
91

    
92
        $parameters = $client->getConnection()->getParameters();
93
        $this->assertSame($parameters->host, $arg1['host']);
94
        $this->assertSame($parameters->port, $arg1['port']);
95
    }
96

    
97
    /**
98
     * @group disconnected
99
     */
100
    public function testConstructorWithArrayOfArrayArgument()
101
    {
102
        $arg1 = array(
103
            array('host' => 'localhost', 'port' => 7000),
104
            array('host' => 'localhost', 'port' => 7001),
105
        );
106

    
107
        $client = new Client($arg1);
108

    
109
        $this->assertInstanceOf('Predis\Connection\ClusterConnectionInterface', $client->getConnection());
110
    }
111

    
112
    /**
113
     * @group disconnected
114
     */
115
    public function testConstructorWithStringArgument()
116
    {
117
        $client = new Client('tcp://localhost:7000');
118

    
119
        $parameters = $client->getConnection()->getParameters();
120
        $this->assertSame($parameters->host, 'localhost');
121
        $this->assertSame($parameters->port, 7000);
122
    }
123

    
124
    /**
125
     * @group disconnected
126
     */
127
    public function testConstructorWithArrayOfStringArgument()
128
    {
129
        $client = new Client($arg1 = array('tcp://localhost:7000', 'tcp://localhost:7001'));
130

    
131
        $this->assertInstanceOf('Predis\Connection\ClusterConnectionInterface', $client->getConnection());
132
    }
133

    
134
    /**
135
     * @group disconnected
136
     */
137
    public function testConstructorWithArrayOfConnectionsArgument()
138
    {
139
        $connection1 = $this->getMock('Predis\Connection\SingleConnectionInterface');
140
        $connection2 = $this->getMock('Predis\Connection\SingleConnectionInterface');
141

    
142
        $client = new Client(array($connection1, $connection2));
143

    
144
        $this->assertInstanceOf('Predis\Connection\ClusterConnectionInterface', $cluster = $client->getConnection());
145
        $this->assertSame($connection1, $cluster->getConnectionById(0));
146
        $this->assertSame($connection2, $cluster->getConnectionById(1));
147
    }
148

    
149
    /**
150
     * @group disconnected
151
     */
152
    public function testConstructorWithConnectionArgument()
153
    {
154
        $factory = new ConnectionFactory();
155
        $connection = $factory->create('tcp://localhost:7000');
156

    
157
        $client = new Client($connection);
158

    
159
        $this->assertInstanceOf('Predis\Connection\SingleConnectionInterface', $client->getConnection());
160
        $this->assertSame($connection, $client->getConnection());
161

    
162
        $parameters = $client->getConnection()->getParameters();
163
        $this->assertSame($parameters->host, 'localhost');
164
        $this->assertSame($parameters->port, 7000);
165
    }
166

    
167
    /**
168
     * @group disconnected
169
     */
170
    public function testConstructorWithClusterArgument()
171
    {
172
        $cluster = new PredisCluster();
173

    
174
        $factory = new ConnectionFactory();
175
        $factory->createAggregated($cluster, array('tcp://localhost:7000', 'tcp://localhost:7001'));
176

    
177
        $client = new Client($cluster);
178

    
179
        $this->assertInstanceOf('Predis\Connection\ClusterConnectionInterface', $client->getConnection());
180
        $this->assertSame($cluster, $client->getConnection());
181
    }
182

    
183
    /**
184
     * @group disconnected
185
     */
186
    public function testConstructorWithReplicationArgument()
187
    {
188
        $replication = new MasterSlaveReplication();
189

    
190
        $factory = new ConnectionFactory();
191
        $factory->createAggregated($replication, array('tcp://host1?alias=master', 'tcp://host2?alias=slave'));
192

    
193
        $client = new Client($replication);
194

    
195
        $this->assertInstanceOf('Predis\Connection\ReplicationConnectionInterface', $client->getConnection());
196
        $this->assertSame($replication, $client->getConnection());
197
    }
198

    
199
    /**
200
     * @group disconnected
201
     */
202
    public function testConstructorWithCallableArgument()
203
    {
204
        $connection = $this->getMock('Predis\Connection\ConnectionInterface');
205

    
206
        $callable = $this->getMock('stdClass', array('__invoke'));
207
        $callable->expects($this->once())
208
                 ->method('__invoke')
209
                 ->with($this->isInstanceOf('Predis\Option\ClientOptions'))
210
                 ->will($this->returnValue($connection));
211

    
212
        $client = new Client($callable);
213

    
214
        $this->assertSame($connection, $client->getConnection());
215
    }
216

    
217
    /**
218
     * @group disconnected
219
     * @expectedException InvalidArgumentException
220
     * @expectedExceptionMessage Callable parameters must return instances of Predis\Connection\ConnectionInterface
221
     */
222
    public function testConstructorWithCallableArgumentButInvalidReturnType()
223
    {
224
        $wrongType = $this->getMock('stdClass');
225

    
226
        $callable = $this->getMock('stdClass', array('__invoke'));
227
        $callable->expects($this->once())
228
                 ->method('__invoke')
229
                 ->with($this->isInstanceOf('Predis\Option\ClientOptions'))
230
                 ->will($this->returnValue($wrongType));
231

    
232
        $client = new Client($callable);
233
    }
234

    
235
    /**
236
     * @group disconnected
237
     */
238
    public function testConstructorWithNullAndArrayArgument()
239
    {
240
        $factory = $this->getMock('Predis\Connection\ConnectionFactoryInterface');
241

    
242
        $arg2 = array('profile' => '2.0', 'prefix' => 'prefix:', 'connections' => $factory);
243
        $client = new Client(null, $arg2);
244

    
245
        $profile = $client->getProfile();
246
        $this->assertSame($profile->getVersion(), ServerProfile::get('2.0')->getVersion());
247
        $this->assertInstanceOf('Predis\Command\Processor\KeyPrefixProcessor', $profile->getProcessor());
248
        $this->assertSame('prefix:', $profile->getProcessor()->getPrefix());
249

    
250
        $this->assertSame($factory, $client->getConnectionFactory());
251
    }
252

    
253
    /**
254
     * @group disconnected
255
     */
256
    public function testConstructorWithArrayAndOptionReplicationArgument()
257
    {
258
        $arg1 = array('tcp://host1?alias=master', 'tcp://host2?alias=slave');
259
        $arg2 = array('replication' => true);
260
        $client = new Client($arg1, $arg2);
261

    
262
        $this->assertInstanceOf('Predis\Connection\ReplicationConnectionInterface', $connection = $client->getConnection());
263
        $this->assertSame('host1', $connection->getConnectionById('master')->getParameters()->host);
264
        $this->assertSame('host2', $connection->getConnectionById('slave')->getParameters()->host);
265
    }
266

    
267
    /**
268
     * @group disconnected
269
     */
270
    public function testConnectAndDisconnect()
271
    {
272
        $connection = $this->getMock('Predis\Connection\ConnectionInterface');
273
        $connection->expects($this->once())->method('connect');
274
        $connection->expects($this->once())->method('disconnect');
275

    
276
        $client = new Client($connection);
277
        $client->connect();
278
        $client->disconnect();
279
    }
280

    
281
    /**
282
     * @group disconnected
283
     */
284
    public function testIsConnectedChecksConnectionState()
285
    {
286
        $connection = $this->getMock('Predis\Connection\ConnectionInterface');
287
        $connection->expects($this->once())->method('isConnected');
288

    
289
        $client = new Client($connection);
290
        $client->isConnected();
291
    }
292

    
293
    /**
294
     * @group disconnected
295
     */
296
    public function testQuitIsAliasForDisconnect()
297
    {
298
        $connection = $this->getMock('Predis\Connection\ConnectionInterface');
299
        $connection->expects($this->once())->method('disconnect');
300

    
301
        $client = new Client($connection);
302
        $client->quit();
303
    }
304

    
305
    /**
306
     * @group disconnected
307
     */
308
    public function testCreatesNewCommandUsingSpecifiedProfile()
309
    {
310
        $ping = ServerProfile::getDefault()->createCommand('ping', array());
311

    
312
        $profile = $this->getMock('Predis\Profile\ServerProfileInterface');
313
        $profile->expects($this->once())
314
                ->method('createCommand')
315
                ->with('ping', array())
316
                ->will($this->returnValue($ping));
317

    
318
        $client = new Client(null, array('profile' => $profile));
319
        $this->assertSame($ping, $client->createCommand('ping', array()));
320
    }
321

    
322
    /**
323
     * @group disconnected
324
     */
325
    public function testExecuteCommandReturnsParsedReplies()
326
    {
327
        $profile = ServerProfile::getDefault();
328

    
329
        $ping = $profile->createCommand('ping', array());
330
        $hgetall = $profile->createCommand('hgetall', array('metavars', 'foo', 'hoge'));
331

    
332
        $connection= $this->getMock('Predis\Connection\ConnectionInterface');
333
        $connection->expects($this->at(0))
334
                   ->method('executeCommand')
335
                   ->with($ping)
336
                   ->will($this->returnValue('PONG'));
337
        $connection->expects($this->at(1))
338
                   ->method('executeCommand')
339
                   ->with($hgetall)
340
                   ->will($this->returnValue(array('foo', 'bar', 'hoge', 'piyo')));
341

    
342
        $client = new Client($connection);
343

    
344
        $this->assertTrue($client->executeCommand($ping));
345
        $this->assertSame(array('foo' => 'bar', 'hoge' => 'piyo'), $client->executeCommand($hgetall));
346
    }
347

    
348
    /**
349
     * @group disconnected
350
     * @expectedException Predis\ServerException
351
     * @expectedExceptionMessage Operation against a key holding the wrong kind of value
352
     */
353
    public function testExecuteCommandThrowsExceptionOnRedisError()
354
    {
355
        $ping = ServerProfile::getDefault()->createCommand('ping', array());
356
        $expectedResponse = new ResponseError('ERR Operation against a key holding the wrong kind of value');
357

    
358
        $connection= $this->getMock('Predis\Connection\ConnectionInterface');
359
        $connection->expects($this->once())
360
                   ->method('executeCommand')
361
                   ->will($this->returnValue($expectedResponse));
362

    
363
        $client = new Client($connection);
364
        $client->executeCommand($ping);
365
    }
366

    
367
    /**
368
     * @group disconnected
369
     */
370
    public function testExecuteCommandReturnsErrorResponseOnRedisError()
371
    {
372
        $ping = ServerProfile::getDefault()->createCommand('ping', array());
373
        $expectedResponse = new ResponseError('ERR Operation against a key holding the wrong kind of value');
374

    
375
        $connection= $this->getMock('Predis\Connection\ConnectionInterface');
376
        $connection->expects($this->once())
377
                   ->method('executeCommand')
378
                   ->will($this->returnValue($expectedResponse));
379

    
380
        $client = new Client($connection, array('exceptions' => false));
381
        $response = $client->executeCommand($ping);
382

    
383
        $this->assertSame($response, $expectedResponse);
384
    }
385

    
386
    /**
387
     * @group disconnected
388
     */
389
    public function testCallingRedisCommandExecutesInstanceOfCommand()
390
    {
391
        $ping = ServerProfile::getDefault()->createCommand('ping', array());
392

    
393
        $connection = $this->getMock('Predis\Connection\ConnectionInterface');
394
        $connection->expects($this->once())
395
                   ->method('executeCommand')
396
                   ->with($this->isInstanceOf('Predis\Command\ConnectionPing'))
397
                   ->will($this->returnValue('PONG'));
398

    
399
        $profile = $this->getMock('Predis\Profile\ServerProfileInterface');
400
        $profile->expects($this->once())
401
                ->method('createCommand')
402
                ->with('ping', array())
403
                ->will($this->returnValue($ping));
404

    
405
        $options = array('profile' => $profile);
406
        $client = $this->getMock('Predis\Client', null, array($connection, $options));
407

    
408
        $this->assertTrue($client->ping());
409
    }
410

    
411
    /**
412
     * @group disconnected
413
     * @expectedException Predis\ServerException
414
     * @expectedExceptionMessage Operation against a key holding the wrong kind of value
415
     */
416
    public function testCallingRedisCommandThrowsExceptionOnServerError()
417
    {
418
        $expectedResponse = new ResponseError('ERR Operation against a key holding the wrong kind of value');
419

    
420
        $connection = $this->getMock('Predis\Connection\ConnectionInterface');
421
        $connection->expects($this->once())
422
                   ->method('executeCommand')
423
                   ->with($this->isInstanceOf('Predis\Command\ConnectionPing'))
424
                   ->will($this->returnValue($expectedResponse));
425

    
426
        $client = new Client($connection);
427
        $client->ping();
428
    }
429

    
430
    /**
431
     * @group disconnected
432
     */
433
    public function testCallingRedisCommandReturnsErrorResponseOnRedisError()
434
    {
435
        $expectedResponse = new ResponseError('ERR Operation against a key holding the wrong kind of value');
436

    
437
        $connection = $this->getMock('Predis\Connection\ConnectionInterface');
438
        $connection->expects($this->once())
439
                   ->method('executeCommand')
440
                   ->with($this->isInstanceOf('Predis\Command\ConnectionPing'))
441
                   ->will($this->returnValue($expectedResponse));
442

    
443
        $client = new Client($connection, array('exceptions' => false));
444
        $response = $client->ping();
445

    
446
        $this->assertSame($response, $expectedResponse);
447
    }
448

    
449
    /**
450
     * @group disconnected
451
     * @expectedException Predis\ClientException
452
     * @expectedExceptionMessage 'invalidcommand' is not a registered Redis command
453
     */
454
    public function testThrowsExceptionOnNonRegisteredRedisCommand()
455
    {
456
        $client = new Client();
457
        $client->invalidCommand();
458
    }
459

    
460
    /**
461
     * @group disconnected
462
     */
463
    public function testGetConnectionFromAggregatedConnectionWithAlias()
464
    {
465
        $client = new Client(array('tcp://host1?alias=node01', 'tcp://host2?alias=node02'));
466

    
467
        $this->assertInstanceOf('Predis\Connection\ClusterConnectionInterface', $cluster = $client->getConnection());
468
        $this->assertInstanceOf('Predis\Connection\SingleConnectionInterface', $node01 = $client->getConnectionById('node01'));
469
        $this->assertInstanceOf('Predis\Connection\SingleConnectionInterface', $node02 = $client->getConnectionById('node02'));
470

    
471
        $this->assertSame('host1', $node01->getParameters()->host);
472
        $this->assertSame('host2', $node02->getParameters()->host);
473
    }
474

    
475
    /**
476
     * @group disconnected
477
     * @expectedException Predis\NotSupportedException
478
     * @expectedExceptionMessage Retrieving connections by ID is supported only when using aggregated connections
479
     */
480
    public function testGetConnectionByIdWorksOnlyWithAggregatedConnections()
481
    {
482
        $client = new Client();
483

    
484
        $client->getConnectionById('node01');
485
    }
486

    
487
    /**
488
     * @group disconnected
489
     */
490
    public function testCreateClientWithConnectionFromAggregatedConnection()
491
    {
492
        $client = new Client(array('tcp://host1?alias=node01', 'tcp://host2?alias=node02'), array('prefix' => 'pfx:'));
493

    
494
        $this->assertInstanceOf('Predis\Connection\ClusterConnectionInterface', $cluster = $client->getConnection());
495
        $this->assertInstanceOf('Predis\Connection\SingleConnectionInterface', $node01 = $client->getConnectionById('node01'));
496
        $this->assertInstanceOf('Predis\Connection\SingleConnectionInterface', $node02 = $client->getConnectionById('node02'));
497

    
498
        $clientNode02 = $client->getClientFor('node02');
499

    
500
        $this->assertInstanceOf('Predis\Client', $clientNode02);
501
        $this->assertSame($node02, $clientNode02->getConnection());
502
        $this->assertSame($client->getOptions(), $clientNode02->getOptions());
503
    }
504

    
505
    /**
506
     * @group disconnected
507
     */
508
    public function testGetClientForReturnsInstanceOfSubclass()
509
    {
510
        $nodes = array('tcp://host1?alias=node01', 'tcp://host2?alias=node02');
511
        $client = $this->getMock('Predis\Client', array('dummy'), array($nodes), 'SubclassedClient');
512

    
513
        $this->assertInstanceOf('SubclassedClient', $client->getClientFor('node02'));
514
    }
515

    
516
    /**
517
     * @group disconnected
518
     */
519
    public function testPipelineWithoutArgumentsReturnsPipelineContext()
520
    {
521
        $client = new Client();
522

    
523
        $this->assertInstanceOf('Predis\Pipeline\PipelineContext', $client->pipeline());
524
    }
525

    
526
    /**
527
     * @group disconnected
528
     */
529
    public function testPipelineWithArrayReturnsPipelineContextWithOptions()
530
    {
531
        $client = new Client();
532
        $executor = $this->getMock('Predis\Pipeline\PipelineExecutorInterface');
533

    
534
        $options = array('executor' => $executor);
535
        $this->assertInstanceOf('Predis\Pipeline\PipelineContext', $pipeline = $client->pipeline($options));
536
        $this->assertSame($executor, $pipeline->getExecutor());
537

    
538
        $options = array('executor' => function ($client, $options) use ($executor) { return $executor; });
539
        $this->assertInstanceOf('Predis\Pipeline\PipelineContext', $pipeline = $client->pipeline($options));
540
        $this->assertSame($executor, $pipeline->getExecutor());
541
    }
542

    
543
    /**
544
     * @group disconnected
545
     */
546
    public function testPipelineWithCallableExecutesPipeline()
547
    {
548
        $callable = $this->getMock('stdClass', array('__invoke'));
549
        $callable->expects($this->once())
550
                 ->method('__invoke')
551
                 ->with($this->isInstanceOf('Predis\Pipeline\PipelineContext'));
552

    
553
        $client = new Client();
554
        $client->pipeline($callable);
555
    }
556

    
557
    /**
558
     * @group disconnected
559
     */
560
    public function testPipelineWithArrayAndCallableExecutesPipelineWithOptions()
561
    {
562
        $executor = $this->getMock('Predis\Pipeline\PipelineExecutorInterface');
563
        $options = array('executor' => $executor);
564

    
565
        $test = $this;
566
        $mockCallback = function ($pipeline) use ($executor, $test) {
567
            $reflection = new \ReflectionProperty($pipeline, 'executor');
568
            $reflection->setAccessible(true);
569

    
570
            $test->assertSame($executor, $reflection->getValue($pipeline));
571
        };
572

    
573
        $callable = $this->getMock('stdClass', array('__invoke'));
574
        $callable->expects($this->once())
575
                 ->method('__invoke')
576
                 ->with($this->isInstanceOf('Predis\Pipeline\PipelineContext'))
577
                 ->will($this->returnCallback($mockCallback));
578

    
579
        $client = new Client();
580
        $client->pipeline($options, $callable);
581
    }
582

    
583
    /**
584
     * @group disconnected
585
     */
586
    public function testPubSubLoopWithoutArgumentsReturnsPubSubContext()
587
    {
588
        $client = new Client();
589

    
590
        $this->assertInstanceOf('Predis\PubSub\PubSubContext', $client->pubSubLoop());
591
    }
592

    
593
    /**
594
     * @group disconnected
595
     */
596
    public function testPubSubLoopWithArrayReturnsPubSubContextWithOptions()
597
    {
598
        $connection = $this->getMock('Predis\Connection\SingleConnectionInterface');
599
        $options = array('subscribe' => 'channel');
600

    
601
        $client = new Client($connection);
602

    
603
        $this->assertInstanceOf('Predis\PubSub\PubSubContext', $pubsub = $client->pubSubLoop($options));
604

    
605
        $reflection = new \ReflectionProperty($pubsub, 'options');
606
        $reflection->setAccessible(true);
607

    
608
        $this->assertSame($options, $reflection->getValue($pubsub));
609
    }
610

    
611
    /**
612
     * @group disconnected
613
     */
614
    public function testPubSubLoopWithArrayAndCallableExecutesPubSub()
615
    {
616
        // NOTE: we use a subscribe count of 0 in the fake message to trick
617
        //       the context and to make it think that it can be closed
618
        //       since there are no more subscriptions active.
619

    
620
        $message = array('subscribe', 'channel', 0);
621
        $options = array('subscribe' => 'channel');
622

    
623
        $connection = $this->getMock('Predis\Connection\SingleConnectionInterface');
624
        $connection->expects($this->once())
625
                   ->method('read')
626
                   ->will($this->returnValue($message));
627

    
628
        $callable = $this->getMock('stdClass', array('__invoke'));
629
        $callable->expects($this->once())
630
                 ->method('__invoke');
631

    
632
        $client = new Client($connection);
633
        $client->pubSubLoop($options, $callable);
634
    }
635

    
636
    /**
637
     * @group disconnected
638
     */
639
    public function testPubSubIsAliasForPubSubLoop()
640
    {
641
        $client = new Client();
642

    
643
        $this->assertInstanceOf('Predis\PubSub\PubSubContext', $client->pubSub());
644
    }
645

    
646
    /**
647
     * @group disconnected
648
     */
649
    public function testMultiExecWithoutArgumentsReturnsMultiExecContext()
650
    {
651
        $client = new Client();
652

    
653
        $this->assertInstanceOf('Predis\Transaction\MultiExecContext', $client->multiExec());
654
    }
655

    
656
    /**
657
     * @group disconnected
658
     */
659
    public function testMethodTransactionIsAliasForMethodMultiExec()
660
    {
661
        $client = new Client();
662

    
663
        $this->assertInstanceOf('Predis\Transaction\MultiExecContext', $client->transaction());
664
    }
665

    
666
    /**
667
     * @group disconnected
668
     */
669
    public function testMultiExecWithArrayReturnsMultiExecContextWithOptions()
670
    {
671
        $options = array('cas' => true, 'retry' => 3);
672

    
673
        $client = new Client();
674

    
675
        $this->assertInstanceOf('Predis\Transaction\MultiExecContext', $tx = $client->multiExec($options));
676

    
677
        $reflection = new \ReflectionProperty($tx, 'options');
678
        $reflection->setAccessible(true);
679

    
680
        $this->assertSame($options, $reflection->getValue($tx));
681
    }
682

    
683
    /**
684
     * @group disconnected
685
     */
686
    public function testMultiExecWithArrayAndCallableExecutesMultiExec()
687
    {
688
        // NOTE: we use CAS since testing the actual MULTI/EXEC context
689
        //       here is not the point.
690
        $options = array('cas' => true, 'retry' => 3);
691

    
692
        $connection = $this->getMock('Predis\Connection\SingleConnectionInterface');
693
        $connection->expects($this->once())
694
                   ->method('executeCommand')
695
                   ->will($this->returnValue(new ResponseQueued()));
696

    
697
        $txCallback = function ($tx) {
698
            $tx->ping();
699
        };
700

    
701
        $callable = $this->getMock('stdClass', array('__invoke'));
702
        $callable->expects($this->once())
703
                 ->method('__invoke')
704
                 ->will($this->returnCallback($txCallback));
705

    
706
        $client = new Client($connection);
707
        $client->multiExec($options, $callable);
708
    }
709

    
710
    /**
711
     * @group disconnected
712
     */
713
    public function testMonitorReturnsMonitorContext()
714
    {
715
        $connection = $this->getMock('Predis\Connection\SingleConnectionInterface');
716
        $client = new Client($connection);
717

    
718
        $this->assertInstanceOf('Predis\Monitor\MonitorContext', $monitor = $client->monitor());
719
    }
720

    
721
    /**
722
     * @group disconnected
723
     */
724
    public function testClientResendScriptedCommandUsingEvalOnNoScriptErrors()
725
    {
726
        $command = $this->getMockForAbstractClass('Predis\Command\ScriptedCommand', array(), '', true, true, true, array('parseResponse'));
727
        $command->expects($this->once())
728
                ->method('getScript')
729
                ->will($this->returnValue('return redis.call(\'exists\', KEYS[1])'));
730
        $command->expects($this->once())
731
                ->method('parseResponse')
732
                ->with('OK')
733
                ->will($this->returnValue(true));
734

    
735
        $connection = $this->getMock('Predis\Connection\SingleConnectionInterface');
736
        $connection->expects($this->at(0))
737
                   ->method('executeCommand')
738
                   ->with($command)
739
                   ->will($this->returnValue(new ResponseError('NOSCRIPT')));
740
        $connection->expects($this->at(1))
741
                   ->method('executeCommand')
742
                   ->with($this->isInstanceOf('Predis\Command\ServerEval'))
743
                   ->will($this->returnValue('OK'));
744

    
745
        $client = new Client($connection);
746

    
747
        $this->assertTrue($client->executeCommand($command));
748
    }
749

    
750
    // ******************************************************************** //
751
    // ---- HELPER METHODS ------------------------------------------------ //
752
    // ******************************************************************** //
753

    
754
    /**
755
     * Returns an URI string representation of the specified connection parameters.
756
     *
757
     * @param  Array  $parameters Array of connection parameters.
758
     * @return String URI string.
759
     */
760
    protected function getParametersString(Array $parameters)
761
    {
762
        $defaults = $this->getDefaultParametersArray();
763

    
764
        $scheme = isset($parameters['scheme']) ? $parameters['scheme'] : $defaults['scheme'];
765
        $host = isset($parameters['host']) ? $parameters['host'] : $defaults['host'];
766
        $port = isset($parameters['port']) ? $parameters['port'] : $defaults['port'];
767

    
768
        unset($parameters['scheme'], $parameters['host'], $parameters['port']);
769
        $uriString = "$scheme://$host:$port/?";
770

    
771
        foreach ($parameters as $k => $v) {
772
            $uriString .= "$k=$v&";
773
        }
774

    
775
        return $uriString;
776
    }
777
}
(2-2/8)