Files
predis/tests/Predis/Command/RedisFactoryTest.php
T
Daniele Alessandri f06a41cfdc Change method to undefine commands in factory.
The previous implementation was not good because we were exposing in the
public API an internal implementation detail of the base factory class,
furthermore it made Predis\Command\Factory::define() confusing. Having a
separate method to undefine commands in the factory is self-explanatory.

We also changed `Predis\Configuration\Option\Commands` accordingly when
a dictionary of $commandID => $classCommand is passed to the "commands"
client option and $classCommand is NULL.

A few minor changes (mostly cosmetic or documentation) were applied too.

From feedback to PR #644.
2020-08-21 14:30:52 +02:00

449 lines
12 KiB
PHP

<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command;
use Predis\Command\Processor\ProcessorChain;
use PredisTestCase;
/**
*
*/
class RedisFactoryTest extends PredisTestCase
{
/**
* @group disconnected
*/
public function testSupportedCommands()
{
$factory = new RedisFactory();
foreach ($this->getExpectedCommands() as $commandID) {
$this->assertTrue($factory->supportsCommand($commandID), "Command factory does not support $commandID");
}
}
/**
* @group disconnected
*/
public function testSupportCommand()
{
$factory = new RedisFactory();
$this->assertTrue($factory->supportsCommand('info'));
$this->assertTrue($factory->supportsCommand('INFO'));
$this->assertFalse($factory->supportsCommand('unknown'));
$this->assertFalse($factory->supportsCommand('UNKNOWN'));
}
/**
* @group disconnected
*/
public function testSupportCommands()
{
$factory = new RedisFactory();
$this->assertTrue($factory->supportsCommands(array('get', 'set')));
$this->assertTrue($factory->supportsCommands(array('GET', 'SET')));
$this->assertFalse($factory->supportsCommands(array('get', 'unknown')));
$this->assertFalse($factory->supportsCommands(array('unknown1', 'unknown2')));
}
/**
* @group disconnected
*/
public function testGetCommandClass()
{
$factory = new RedisFactory();
$this->assertSame('Predis\Command\Redis\PING', $factory->getCommandClass('ping'));
$this->assertSame('Predis\Command\Redis\PING', $factory->getCommandClass('PING'));
$this->assertNull($factory->getCommandClass('unknown'));
$this->assertNull($factory->getCommandClass('UNKNOWN'));
}
/**
* @group disconnected
*/
public function testDefineCommand()
{
$factory = new RedisFactory();
$command = $this->getMockBuilder('Predis\Command\CommandInterface')
->getMock();
$factory->defineCommand('mock', get_class($command));
$this->assertTrue($factory->supportsCommand('mock'));
$this->assertTrue($factory->supportsCommand('MOCK'));
$this->assertSame(get_class($command), $factory->getCommandClass('mock'));
}
/**
* @group disconnected
*/
public function testUndefineCommandInClassAutoload()
{
$factory = new RedisFactory();
$this->assertTrue($factory->supportsCommand('PING'));
$this->assertSame('Predis\Command\Redis\PING', $factory->getCommandClass('PING'));
$factory->undefineCommand('PING');
$this->assertFalse($factory->supportsCommand('PING'));
$this->assertNull($factory->getCommandClass('PING'));
}
/**
* @group disconnected
*/
public function testUndefineCommandInClassMap()
{
$factory = new RedisFactory();
$commandClass = get_class($this->getMockBuilder('Predis\Command\CommandInterface')->getMock());
$factory->defineCommand('MOCK', $commandClass);
$this->assertTrue($factory->supportsCommand('MOCK'));
$this->assertSame($commandClass, $factory->getCommandClass('MOCK'));
$factory->undefineCommand('MOCK');
$this->assertFalse($factory->supportsCommand('MOCK'));
$this->assertNull($factory->getCommandClass('MOCK'));
}
/**
* @group disconnected
*/
public function testDefineInvalidCommand()
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage("Class stdClass must implement Predis\Command\CommandInterface");
$factory = new RedisFactory();
$factory->defineCommand('mock', 'stdClass');
}
/**
* @group disconnected
*/
public function testCreateCommandWithoutArguments()
{
$factory = new RedisFactory();
$command = $factory->createCommand('info');
$this->assertInstanceOf('Predis\Command\CommandInterface', $command);
$this->assertEquals('INFO', $command->getId());
$this->assertEquals(array(), $command->getArguments());
}
/**
* @group disconnected
*/
public function testCreateCommandWithArguments()
{
$factory = new RedisFactory();
$arguments = array('foo', 'bar');
$command = $factory->createCommand('set', $arguments);
$this->assertInstanceOf('Predis\Command\CommandInterface', $command);
$this->assertEquals('SET', $command->getId());
$this->assertEquals($arguments, $command->getArguments());
}
/**
* @group disconnected
*/
public function testCreateUndefinedCommand()
{
$this->expectException('Predis\ClientException');
$this->expectExceptionMessage("Command `UNKNOWN` is not a registered Redis command.");
$factory = new RedisFactory();
$factory->createCommand('unknown');
}
/**
* @group disconnected
*/
public function testGetDefaultProcessor()
{
$factory = new RedisFactory();
$this->assertNull($factory->getProcessor());
}
/**
* @group disconnected
*/
public function testSetProcessor()
{
$processor = $this->getMockBuilder('Predis\Command\Processor\ProcessorInterface')
->getMock();
$factory = new RedisFactory();
$factory->setProcessor($processor);
$this->assertSame($processor, $factory->getProcessor());
}
/**
* @group disconnected
*/
public function testSetAndUnsetProcessor()
{
$processor = $this->getMockBuilder('Predis\Command\Processor\ProcessorInterface')
->getMock();
$factory = new RedisFactory();
$factory->setProcessor($processor);
$this->assertSame($processor, $factory->getProcessor());
$factory->setProcessor(null);
$this->assertNull($factory->getProcessor());
}
/**
* @group disconnected
*/
public function testSingleProcessor()
{
// Could it be that objects passed to the return callback of a mocked
// method are cloned instead of being passed by reference?
$argsRef = null;
$processor = $this->getMockBuilder('Predis\Command\Processor\ProcessorInterface')
->getMock();
$processor
->expects($this->once())
->method('process')
->with($this->isInstanceOf('Predis\Command\CommandInterface'))
->will($this->returnCallback(
function (CommandInterface $cmd) use (&$argsRef) {
$cmd->setRawArguments($argsRef = array_map('strtoupper', $cmd->getArguments()));
}
));
$factory = new RedisFactory();
$factory->setProcessor($processor);
$factory->createCommand('set', array('foo', 'bar'));
$this->assertSame(array('FOO', 'BAR'), $argsRef);
}
/**
* @group disconnected
*/
public function testChainOfProcessors()
{
$processor = $this->getMockBuilder('Predis\Command\Processor\ProcessorInterface')
->getMock();
$processor
->expects($this->exactly(2))
->method('process');
$chain = new ProcessorChain();
$chain->add($processor);
$chain->add($processor);
$factory = new RedisFactory();
$factory->setProcessor($chain);
$factory->createCommand('info');
}
// ******************************************************************** //
// ---- HELPER METHODS ------------------------------------------------ //
// ******************************************************************** //
/**
* Returns the expected list of commands supported by the tested factory.
*
* @return array List of supported commands.
*/
protected function getExpectedCommands()
{
return array(
0 => 'EXISTS',
1 => 'DEL',
2 => 'TYPE',
3 => 'KEYS',
4 => 'RANDOMKEY',
5 => 'RENAME',
6 => 'RENAMENX',
7 => 'EXPIRE',
8 => 'EXPIREAT',
9 => 'TTL',
10 => 'MOVE',
11 => 'SORT',
12 => 'DUMP',
13 => 'RESTORE',
14 => 'SET',
15 => 'SETNX',
16 => 'MSET',
17 => 'MSETNX',
18 => 'GET',
19 => 'MGET',
20 => 'GETSET',
21 => 'INCR',
22 => 'INCRBY',
23 => 'DECR',
24 => 'DECRBY',
25 => 'RPUSH',
26 => 'LPUSH',
27 => 'LLEN',
28 => 'LRANGE',
29 => 'LTRIM',
30 => 'LINDEX',
31 => 'LSET',
32 => 'LREM',
33 => 'LPOP',
34 => 'RPOP',
35 => 'RPOPLPUSH',
36 => 'SADD',
37 => 'SREM',
38 => 'SPOP',
39 => 'SMOVE',
40 => 'SCARD',
41 => 'SISMEMBER',
42 => 'SINTER',
43 => 'SINTERSTORE',
44 => 'SUNION',
45 => 'SUNIONSTORE',
46 => 'SDIFF',
47 => 'SDIFFSTORE',
48 => 'SMEMBERS',
49 => 'SRANDMEMBER',
50 => 'ZADD',
51 => 'ZINCRBY',
52 => 'ZREM',
53 => 'ZRANGE',
54 => 'ZREVRANGE',
55 => 'ZRANGEBYSCORE',
56 => 'ZCARD',
57 => 'ZSCORE',
58 => 'ZREMRANGEBYSCORE',
59 => 'PING',
60 => 'AUTH',
61 => 'SELECT',
62 => 'ECHO',
63 => 'QUIT',
64 => 'INFO',
65 => 'SLAVEOF',
66 => 'MONITOR',
67 => 'DBSIZE',
68 => 'FLUSHDB',
69 => 'FLUSHALL',
70 => 'SAVE',
71 => 'BGSAVE',
72 => 'LASTSAVE',
73 => 'SHUTDOWN',
74 => 'BGREWRITEAOF',
75 => 'SETEX',
76 => 'APPEND',
77 => 'SUBSTR',
78 => 'BLPOP',
79 => 'BRPOP',
80 => 'ZUNIONSTORE',
81 => 'ZINTERSTORE',
82 => 'ZCOUNT',
83 => 'ZRANK',
84 => 'ZREVRANK',
85 => 'ZREMRANGEBYRANK',
86 => 'HSET',
87 => 'HSETNX',
88 => 'HMSET',
89 => 'HINCRBY',
90 => 'HGET',
91 => 'HMGET',
92 => 'HDEL',
93 => 'HEXISTS',
94 => 'HLEN',
95 => 'HKEYS',
96 => 'HVALS',
97 => 'HGETALL',
98 => 'MULTI',
99 => 'EXEC',
100 => 'DISCARD',
101 => 'SUBSCRIBE',
102 => 'UNSUBSCRIBE',
103 => 'PSUBSCRIBE',
104 => 'PUNSUBSCRIBE',
105 => 'PUBLISH',
106 => 'CONFIG',
107 => 'PERSIST',
108 => 'STRLEN',
109 => 'SETRANGE',
110 => 'GETRANGE',
111 => 'SETBIT',
112 => 'GETBIT',
113 => 'RPUSHX',
114 => 'LPUSHX',
115 => 'LINSERT',
116 => 'BRPOPLPUSH',
117 => 'ZREVRANGEBYSCORE',
118 => 'WATCH',
119 => 'UNWATCH',
120 => 'OBJECT',
121 => 'SLOWLOG',
122 => 'CLIENT',
123 => 'PTTL',
124 => 'PEXPIRE',
125 => 'PEXPIREAT',
126 => 'MIGRATE',
127 => 'PSETEX',
128 => 'INCRBYFLOAT',
129 => 'BITOP',
130 => 'BITCOUNT',
131 => 'HINCRBYFLOAT',
132 => 'EVAL',
133 => 'EVALSHA',
134 => 'SCRIPT',
135 => 'TIME',
136 => 'SENTINEL',
137 => 'SCAN',
138 => 'BITPOS',
139 => 'SSCAN',
140 => 'ZSCAN',
141 => 'ZLEXCOUNT',
142 => 'ZRANGEBYLEX',
143 => 'ZREMRANGEBYLEX',
144 => 'ZREVRANGEBYLEX',
145 => 'HSCAN',
146 => 'PUBSUB',
147 => 'PFADD',
148 => 'PFCOUNT',
149 => 'PFMERGE',
150 => 'COMMAND',
151 => 'HSTRLEN',
152 => 'BITFIELD',
153 => 'GEOADD',
154 => 'GEOHASH',
155 => 'GEOPOS',
156 => 'GEODIST',
157 => 'GEORADIUS',
158 => 'GEORADIUSBYMEMBER',
);
}
}