generate-command-test.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #!/usr/bin/env php
  2. <?php
  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. use Predis\Commands\ICommand;
  12. use Predis\Commands\IPrefixable;
  13. class CommandTestCaseGenerator
  14. {
  15. private $options;
  16. public function __construct(Array $options)
  17. {
  18. if (!isset($options['class'])) {
  19. throw new RuntimeException("Missing 'class' option.");
  20. }
  21. $this->options = $options;
  22. }
  23. public static function fromCommandLine()
  24. {
  25. $parameters = array(
  26. 'c:' => 'class:',
  27. 'r::' => 'realm::',
  28. 'o::' => 'output::',
  29. 'x::' => 'overwrite::'
  30. );
  31. $getops = getopt(implode(array_keys($parameters)), $parameters);
  32. $options = array(
  33. 'overwrite' => false,
  34. 'tests' => __DIR__.'/../tests',
  35. );
  36. foreach ($getops as $option => $value) {
  37. switch ($option) {
  38. case 'c':
  39. case 'class':
  40. $options['class'] = $value;
  41. break;
  42. case 'r':
  43. case 'realm':
  44. $options['realm'] = $value;
  45. break;
  46. case 'o':
  47. case 'output':
  48. $options['output'] = $value;
  49. break;
  50. case 'x':
  51. case 'overwrite':
  52. $options['overwrite'] = true;
  53. break;
  54. }
  55. }
  56. if (!isset($options['class'])) {
  57. throw new RuntimeException("Missing 'class' option.");
  58. }
  59. $options['fqn'] = "Predis\\Commands\\{$options['class']}";
  60. $options['path'] = "Predis/Commands/{$options['class']}.php";
  61. $source = __DIR__.'/../lib/'.$options['path'];
  62. if (!file_exists($source)) {
  63. throw new RuntimeException("Cannot find class file for {$options['fqn']} in $source.");
  64. }
  65. if (!isset($options['output'])) {
  66. $options['output'] = sprintf("%s/%s", $options['tests'], str_replace('.php', 'Test.php', $options['path']));
  67. }
  68. return new self($options);
  69. }
  70. protected function getTestRealm()
  71. {
  72. if (isset($this->options['realm'])) {
  73. if (!$this->options['realm']) {
  74. throw new RuntimeException('Invalid value for realm has been sepcified (empty).');
  75. }
  76. return $this->options['realm'];
  77. }
  78. $class = array_pop(explode('\\', $this->options['fqn']));
  79. list($realm,) = preg_split('/([[:upper:]][[:lower:]]+)/', $class, 2, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
  80. return strtolower($realm);
  81. }
  82. public function generate()
  83. {
  84. $reflection = new ReflectionClass($class = $this->options['fqn']);
  85. if (!$reflection->isInstantiable()) {
  86. throw new RuntimeException("Class $class must be instantiable, abstract classes or interfaces are not allowed.");
  87. }
  88. if (!$reflection->implementsInterface('Predis\Commands\ICommand')) {
  89. throw new RuntimeException("Class $class must implement the Predis\Commands\ICommand interface.");
  90. }
  91. $instance = $reflection->newInstance();
  92. $buffer = $this->getTestCaseBuffer($instance);
  93. return $buffer;
  94. }
  95. public function save()
  96. {
  97. $options = $this->options;
  98. if (file_exists($options['output']) && !$options['overwrite']) {
  99. throw new RuntimeException("File {$options['output']} already exist. Specify the --overwrite option to overwrite the existing file.");
  100. }
  101. file_put_contents($options['output'], $this->generate());
  102. }
  103. protected function getTestCaseBuffer(ICommand $instance)
  104. {
  105. $id = $instance->getId();
  106. $fqn = get_class($instance);
  107. $class = array_pop(explode('\\', $fqn)) . "Test";
  108. $realm = $this->getTestRealm();
  109. $buffer =<<<PHP
  110. <?php
  111. /*
  112. * This file is part of the Predis package.
  113. *
  114. * (c) Daniele Alessandri <suppakilla@gmail.com>
  115. *
  116. * For the full copyright and license information, please view the LICENSE
  117. * file that was distributed with this source code.
  118. */
  119. namespace Predis\Commands;
  120. use \PHPUnit_Framework_TestCase as StandardTestCase;
  121. /**
  122. * @group commands
  123. * @group realm-$realm
  124. */
  125. class $class extends CommandTestCase
  126. {
  127. /**
  128. * {@inheritdoc}
  129. */
  130. protected function getExpectedCommand()
  131. {
  132. return '$fqn';
  133. }
  134. /**
  135. * {@inheritdoc}
  136. */
  137. protected function getExpectedId()
  138. {
  139. return '$id';
  140. }
  141. /**
  142. * @group disconnected
  143. */
  144. public function testFilterArguments()
  145. {
  146. \$this->markTestIncomplete('This test has not been implemented yet.');
  147. \$arguments = array(/* add arguments */);
  148. \$expected = array(/* add arguments */);
  149. \$command = \$this->getCommand();
  150. \$command->setArguments(\$arguments);
  151. \$this->assertSame(\$expected, \$command->getArguments());
  152. }
  153. /**
  154. * @group disconnected
  155. */
  156. public function testParseResponse()
  157. {
  158. \$this->markTestIncomplete('This test has not been implemented yet.');
  159. \$raw = null;
  160. \$expected = null;
  161. \$command = \$this->getCommand();
  162. \$this->assertSame(\$expected, \$command->parseResponse(\$raw));
  163. }
  164. PHP;
  165. if ($instance instanceof IPrefixable) {
  166. $buffer .=<<<PHP
  167. /**
  168. * @group disconnected
  169. */
  170. public function testPrefixKeys()
  171. {
  172. \$this->markTestIncomplete('This test has not been implemented yet.');
  173. \$arguments = array(/* add arguments */);
  174. \$expected = array(/* add arguments */);
  175. \$command = \$this->getCommandWithArgumentsArray(\$arguments);
  176. \$command->prefixKeys('prefix:');
  177. \$this->assertSame(\$expected, \$command->getArguments());
  178. }
  179. PHP;
  180. }
  181. return "$buffer}\n";
  182. }
  183. }
  184. // ------------------------------------------------------------------------- //
  185. require __DIR__.'/../autoload.php';
  186. $generator = CommandTestCaseGenerator::fromCommandLine();
  187. $generator->save();