PageRenderTime 123ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 0ms

/tr/src/lmbTestShellUI.class.php

https://bitbucket.org/idler/mmp/
PHP | 285 lines | 232 code | 38 blank | 15 comment | 17 complexity | acae104a974089cb6af215ccdad24af0 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0
  1. <?php
  2. /*
  3. * Limb PHP Framework
  4. *
  5. * @link http://limb-project.com
  6. * @copyright Copyright &copy; 2004-2009 BIT(http://bit-creative.com)
  7. * @license LGPL http://www.gnu.org/copyleft/lesser.html
  8. */
  9. require_once(dirname(__FILE__) . '/lmbTestGetopt.class.php');
  10. require_once(dirname(__FILE__) . '/lmbTestOptions.class.php');
  11. /**
  12. * class lmbTestShellUI.
  13. *
  14. * @package tests_runner
  15. * @version $Id: lmbTestShellUI.class.php 7486 2009-01-26 19:13:20Z pachanga $
  16. */
  17. class lmbTestShellUI
  18. {
  19. protected $test_path;
  20. protected $argv;
  21. protected $posix_opts = true;
  22. protected $call_exit = true;
  23. protected $reporter;
  24. function __construct($argv = null)
  25. {
  26. try
  27. {
  28. $this->argv = is_array($argv) ? $argv : lmbTestGetopt::readPHPArgv();
  29. }
  30. catch(Exception $e)
  31. {
  32. $this->_error($e->getMessage() . "\n");
  33. }
  34. }
  35. function setReporter($reporter)
  36. {
  37. $this->reporter = $reporter;
  38. }
  39. function setPosixMode($flag = true)
  40. {
  41. $this->posix_opts = $flag;
  42. }
  43. function exitAfterRun($flag = true)
  44. {
  45. $this->call_exit = $flag;
  46. }
  47. function help($script = '')
  48. {
  49. $version = $this->_getVersion();
  50. $usage = <<<EOD
  51. Usage:
  52. limb_unit [OPTIONS] <file|dir> [<file1|dir1>, ... <fileN|dirN>]
  53. Advanced SimpleTest unit tests runner. Finds and executes unit tests within filesystem.
  54. Arguments:
  55. <file|dir> [<file1|dir1>, ... <fileN|dirN>] - a list of files/directories, globs are supported(e.g. '*')
  56. KEY1=value1 [KEY2=value2, ... KEYN=valueN] - a list of arbitrary key=value pairs which will be declared
  57. as constants using PHP define call
  58. Options:
  59. -h, --help Displays this help and exit
  60. -V, --verbose Be extra verbose
  61. -c, --config=/file.php PHP configuration file path
  62. -I, --include='filter1;filter2' Sets file filters used for including test files during
  63. recursive traversal of directories.
  64. '*Test.class.php;*test.php;*Test.php' by default.
  65. -G, --groups=group1[,group2] Comma separated list of test groups defined in annotations
  66. tags which should be executed(e.g @group group1,group2)
  67. -T, --tests=Foo[,Bar] Comma separated list of test classes which should be
  68. executed
  69. -M, --methods=testFoo[,testBar] Comma separated list of test methods which should be
  70. executed
  71. -C, --cover='path1;path2' Sets paths delimitered with ';' which should be analyzed
  72. for test coverage(requires XDebug extension!)
  73. --cover-report=dir Sets coverage report directory
  74. --cover-exclude='path1;path2' Sets paths delimitered with ';' which should be excluded
  75. from coverage analysis
  76. $version
  77. EOD;
  78. return $usage;
  79. }
  80. protected function _help($code = 0)
  81. {
  82. echo $this->help();
  83. exit($code);
  84. }
  85. protected function _error($message, $code = 1)
  86. {
  87. echo "ERROR: $message\n\n";
  88. echo $this->_getVersion();
  89. echo "\n";
  90. exit($code);
  91. }
  92. protected function _version()
  93. {
  94. echo $this->_getVersion() . "\n";
  95. exit();
  96. }
  97. protected function _getVersion()
  98. {
  99. list(, $number, $status) = explode('-', trim(file_get_contents(dirname(__FILE__) . '/../VERSION')));
  100. $version = "limb_unit-$number-$status";
  101. if(is_dir(dirname(__FILE__) . '/.svn'))
  102. $version .= "-dev";
  103. return $version;
  104. }
  105. static function getShortOpts()
  106. {
  107. return 'hVvI:c:C:T:M:G:';
  108. }
  109. static function getLongOpts()
  110. {
  111. return array('help', 'verbose', 'version', 'include=', 'config=',
  112. 'cover=', 'cover-report=', 'cover-exclude=',
  113. 'tests=', 'methods=', 'groups=');
  114. }
  115. function run()
  116. {
  117. $res = $this->_doRun();
  118. if($this->call_exit)
  119. exit($res ? 0 : 1);
  120. else
  121. return $res;
  122. }
  123. function runEmbedded()
  124. {
  125. return $this->_doRun();
  126. }
  127. protected function _doRun()
  128. {
  129. $short_opts = self :: getShortOpts();
  130. $long_opts = self :: getLongOpts();
  131. lmbTestGetopt :: defineAndExtractConstants($this->argv);
  132. try
  133. {
  134. if($this->posix_opts)
  135. $options = lmbTestGetopt :: getopt($this->argv, $short_opts, $long_opts);
  136. else
  137. $options = lmbTestGetopt :: getopt2($this->argv, $short_opts, $long_opts);
  138. }
  139. catch(Exception $e)
  140. {
  141. $this->_help(1);
  142. }
  143. $config_file = null;
  144. $cover_include = '';
  145. $cover_exclude = '';
  146. $cover_report_dir = null;
  147. foreach($options[0] as $option)
  148. {
  149. switch($option[0])
  150. {
  151. case 'h':
  152. case '--help':
  153. $this->_help(0);
  154. break;
  155. case 'V':
  156. case '--verbose':
  157. lmbTestOptions :: set('verbose', true);
  158. break;
  159. case 'v':
  160. case '--version':
  161. $this->_version();
  162. break;
  163. case 'c':
  164. case '--config':
  165. $config_file = $option[1];
  166. break;
  167. case 'I':
  168. case '--include':
  169. lmbTestOptions :: set('file_filter', $option[1]);
  170. break;
  171. case 'G':
  172. case '--groups':
  173. lmbTestOptions :: set('groups_filter', array_map('trim', explode(',', trim($option[1]))));
  174. break;
  175. case 'T':
  176. case '--tests':
  177. lmbTestOptions :: set('tests_filter', array_map('trim', explode(',', trim($option[1]))));
  178. break;
  179. case 'M':
  180. case '--methods':
  181. lmbTestOptions :: set('methods_filter', array_map('trim', explode(',', trim($option[1]))));
  182. break;
  183. case 'C':
  184. case '--cover':
  185. $cover_include = $option[1];
  186. break;
  187. case '--cover-report':
  188. $cover_report_dir = $option[1];
  189. break;
  190. case '--cover-exclude':
  191. $cover_exclude = $option[1];
  192. break;
  193. }
  194. }
  195. if(!$config_file)
  196. $config_file = getenv('LIMB_TESTS_RUNNER_CONFIG');
  197. if($config_file)
  198. {
  199. if(!$php = @file_get_contents(realpath($config_file)))
  200. $this->_error("Could not read configuration file '$config_file'\n");
  201. if(!$this->_phpLint($php, $error))
  202. $this->_error("Configuration file '$config_file' is invalid(check syntax)\n$error");
  203. if(!include_once(realpath($config_file)))
  204. $this->_error("Could not include configuration file '$config_file'\n");
  205. }
  206. if(!is_array($options[1]) || !count($options[1]))
  207. $paths = array('.');
  208. else
  209. $paths = $options[1];
  210. if(!$cover_report_dir && defined('LIMB_TESTS_RUNNER_COVERAGE_REPORT_DIR'))
  211. $cover_report_dir = LIMB_TESTS_RUNNER_COVERAGE_REPORT_DIR;
  212. require_once(dirname(__FILE__) . '/lmbTestRunner.class.php');
  213. $runner = new lmbTestRunner();
  214. if($this->reporter)
  215. $runner->setReporter($this->reporter);
  216. if($cover_include)
  217. $runner->useCoverage($cover_include, $cover_exclude, $cover_report_dir);
  218. try
  219. {
  220. require_once(dirname(__FILE__) . '/lmbTestTreeGlobNode.class.php');
  221. $node = new lmbTestTreeGlobNode($paths);
  222. $res = $runner->run($node);
  223. }
  224. //it's an exception which is used to pass user errors up to the interface,
  225. //we don't need to show backtrace in this case, only error message
  226. catch(lmbTestUserException $e)
  227. {
  228. $this->_error($e->getMessage());
  229. }
  230. catch(Exception $e)
  231. {
  232. $this->_error($e->__toString());
  233. }
  234. return $res;
  235. }
  236. protected function _phpLint($php_code, &$error = '')
  237. {
  238. $php_code = preg_replace('~<\?php~', '', $php_code);
  239. $php_code = preg_replace('~\?>~', '', $php_code);
  240. ob_start();
  241. $result = create_function('', $php_code);
  242. if(!$result)
  243. $error = ob_get_contents();
  244. ob_end_clean();
  245. return $result;
  246. }
  247. }