123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- #!/usr/bin/env 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.
- */
- // -------------------------------------------------------------------------- //
- // This script can be used to automatically generate a file with the scheleton
- // of a test case to test a Redis command by specifying the name of the class
- // in the Predis\Command namespace (only classes in this namespace are valid).
- // For example, to generate a test case for SET (which is represented by the
- // Predis\Command\Redis\StringSet class):
- //
- // $ ./bin/generate-command-test --class=StringSet
- //
- // Here is a list of optional arguments:
- //
- // --realm: each command has its own realm (commands that operate on strings,
- // lists, sets and such) but while this realm is usually inferred from the name
- // of the specified class, sometimes it can be useful to override it with a
- // custom one.
- //
- // --output: write the generated test case to the specified path instead of
- // the default one.
- //
- // --overwrite: pre-existing test files are not overwritten unless this option
- // is explicitly specified.
- // -------------------------------------------------------------------------- //
- use Predis\Command\CommandInterface;
- use Predis\Command\PrefixableCommandInterface;
- class CommandTestCaseGenerator
- {
- private $options;
- public function __construct(array $options)
- {
- if (!isset($options['class'])) {
- throw new RuntimeException("Missing 'class' option.");
- }
- if (!isset($options['realm'])) {
- throw new RuntimeException("Missing 'realm' option.");
- }
- $this->options = $options;
- }
- public static function fromCommandLine()
- {
- $parameters = array(
- 'c:' => 'class:',
- 'r::' => 'realm::',
- 'o::' => 'output::',
- 'x::' => 'overwrite::'
- );
- $getops = getopt(implode(array_keys($parameters)), $parameters);
- $options = array(
- 'overwrite' => false,
- 'tests' => __DIR__.'/../tests/Predis',
- );
- foreach ($getops as $option => $value) {
- switch ($option) {
- case 'c':
- case 'class':
- $options['class'] = $value;
- break;
- case 'r':
- case 'realm':
- $options['realm'] = $value;
- break;
- case 'o':
- case 'output':
- $options['output'] = $value;
- break;
- case 'x':
- case 'overwrite':
- $options['overwrite'] = true;
- break;
- }
- }
- if (!isset($options['class'])) {
- throw new RuntimeException("Missing 'class' option.");
- }
- if (!isset($options['realm'])) {
- throw new RuntimeException("Missing 'realm' option.");
- }
- $options['fqn'] = "Predis\\Command\\Redis\\{$options['class']}";
- $options['path'] = "Command/Redis/{$options['class']}.php";
- $source = __DIR__.'/../src/'.$options['path'];
- if (!file_exists($source)) {
- throw new RuntimeException("Cannot find class file for {$options['fqn']} in $source.");
- }
- if (!isset($options['output'])) {
- $options['output'] = sprintf("%s/%s", $options['tests'], str_replace('.php', '_Test.php', $options['path']));
- }
- return new self($options);
- }
- protected function getTestRealm()
- {
- if (empty($this->options['realm'])) {
- throw new RuntimeException('Invalid value for realm has been sepcified (empty).');
- }
- return $this->options['realm'];
- }
- public function generate()
- {
- $reflection = new ReflectionClass($class = $this->options['fqn']);
- if (!$reflection->isInstantiable()) {
- throw new RuntimeException("Class $class must be instantiable, abstract classes or interfaces are not allowed.");
- }
- if (!$reflection->implementsInterface('Predis\Command\CommandInterface')) {
- throw new RuntimeException("Class $class must implement Predis\Command\CommandInterface.");
- }
- /*
- * @var CommandInterface
- */
- $instance = $reflection->newInstance();
- $buffer = $this->getTestCaseBuffer($instance);
- return $buffer;
- }
- public function save()
- {
- $options = $this->options;
- if (file_exists($options['output']) && !$options['overwrite']) {
- throw new RuntimeException("File {$options['output']} already exist. Specify the --overwrite option to overwrite the existing file.");
- }
- file_put_contents($options['output'], $this->generate());
- }
- protected function getTestCaseBuffer(CommandInterface $instance)
- {
- $id = $instance->getId();
- $fqn = get_class($instance);
- $fqnParts = explode('\\', $fqn);
- $class = array_pop($fqnParts) . "Test";
- $realm = $this->getTestRealm();
- $buffer =<<<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\Redis;
- /**
- * @group commands
- * @group realm-$realm
- */
- class $class extends PredisCommandTestCase
- {
- /**
- * {@inheritdoc}
- */
- protected function getExpectedCommand()
- {
- return '$fqn';
- }
- /**
- * {@inheritdoc}
- */
- protected function getExpectedId()
- {
- return '$id';
- }
- /**
- * @group disconnected
- */
- public function testFilterArguments()
- {
- \$this->markTestIncomplete('This test has not been implemented yet.');
- \$arguments = array(/* add arguments */);
- \$expected = array(/* add arguments */);
- \$command = \$this->getCommand();
- \$command->setArguments(\$arguments);
- \$this->assertSame(\$expected, \$command->getArguments());
- }
- /**
- * @group disconnected
- */
- public function testParseResponse()
- {
- \$this->markTestIncomplete('This test has not been implemented yet.');
- \$raw = null;
- \$expected = null;
- \$command = \$this->getCommand();
- \$this->assertSame(\$expected, \$command->parseResponse(\$raw));
- }
- PHP;
- if ($instance instanceof PrefixableCommandInterface) {
- $buffer .=<<<PHP
- /**
- * @group disconnected
- */
- public function testPrefixKeys()
- {
- \$this->markTestIncomplete('This test has not been implemented yet.');
- \$arguments = array(/* add arguments */);
- \$expected = array(/* add arguments */);
- \$command = \$this->getCommandWithArgumentsArray(\$arguments);
- \$command->prefixKeys('prefix:');
- \$this->assertSame(\$expected, \$command->getArguments());
- }
- /**
- * @group disconnected
- */
- public function testPrefixKeysIgnoredOnEmptyArguments()
- {
- \$command = \$this->getCommand();
- \$command->prefixKeys('prefix:');
- \$this->assertSame(array(), \$command->getArguments());
- }
- PHP;
- }
- return "$buffer}\n";
- }
- }
- // ------------------------------------------------------------------------- //
- require __DIR__.'/../autoload.php';
- $generator = CommandTestCaseGenerator::fromCommandLine();
- $generator->save();
|