PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/cake/tests/lib/test_manager.php

http://github.com/Datawalke/Coordino
PHP | 421 lines | 199 code | 36 blank | 186 comment | 37 complexity | 82a881d5650b5daf5b387a0b2dfaafe3 MD5 | raw file
  1. <?php
  2. /**
  3. * TestManager for CakePHP Test suite.
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
  8. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The Open Group Test Suite License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
  15. * @package cake
  16. * @subpackage cake.cake.tests.lib
  17. * @since CakePHP(tm) v 1.2.0.4433
  18. * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
  19. */
  20. define('CORE_TEST_CASES', TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'cases');
  21. define('CORE_TEST_GROUPS', TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'groups');
  22. define('APP_TEST_CASES', TESTS . 'cases');
  23. define('APP_TEST_GROUPS', TESTS . 'groups');
  24. /**
  25. * TestManager is the base class that handles loading and initiating the running
  26. * of TestCase and TestSuite classes that the user has selected.
  27. *
  28. * @package cake
  29. * @subpackage cake.cake.tests.lib
  30. */
  31. class TestManager {
  32. /**
  33. * Extension suffix for test case files.
  34. *
  35. * @var string
  36. */
  37. var $_testExtension = '.test.php';
  38. /**
  39. * Extension suffix for group test case files.
  40. *
  41. * @var string
  42. */
  43. var $_groupExtension = '.group.php';
  44. /**
  45. * Is this test an AppTest?
  46. *
  47. * @var boolean
  48. */
  49. var $appTest = false;
  50. /**
  51. * Is this test a plugin test?
  52. *
  53. * @var mixed boolean false or string name of the plugin being used.
  54. */
  55. var $pluginTest = false;
  56. /**
  57. * Constructor for the TestManager class
  58. *
  59. * @return void
  60. * @access public
  61. */
  62. function TestManager() {
  63. $this->_installSimpleTest();
  64. if (isset($_GET['app'])) {
  65. $this->appTest = true;
  66. }
  67. if (isset($_GET['plugin'])) {
  68. $this->pluginTest = htmlentities($_GET['plugin']);
  69. }
  70. }
  71. /**
  72. * Includes the required simpletest files in order for the testsuite to run
  73. *
  74. * @return void
  75. * @access public
  76. */
  77. function _installSimpleTest() {
  78. App::import('Vendor', array(
  79. 'simpletest' . DS . 'unit_tester',
  80. 'simpletest' . DS . 'mock_objects',
  81. 'simpletest' . DS . 'web_tester'
  82. ));
  83. require_once(CAKE_TESTS_LIB . 'cake_web_test_case.php');
  84. require_once(CAKE_TESTS_LIB . 'cake_test_case.php');
  85. }
  86. /**
  87. * Runs all tests in the Application depending on the current appTest setting
  88. *
  89. * @param Object $reporter Reporter object for the tests being run.
  90. * @param boolean $testing Are tests supposed to be auto run. Set to true to return testcase list.
  91. * @return mixed
  92. * @access public
  93. */
  94. function runAllTests(&$reporter, $testing = false) {
  95. $testCases =& $this->_getTestFileList($this->_getTestsPath());
  96. if ($this->appTest) {
  97. $test =& new TestSuite(__('All App Tests', true));
  98. } else if ($this->pluginTest) {
  99. $test =& new TestSuite(sprintf(__('All %s Plugin Tests', true), Inflector::humanize($this->pluginTest)));
  100. } else {
  101. $test =& new TestSuite(__('All Core Tests', true));
  102. }
  103. if ($testing) {
  104. return $testCases;
  105. }
  106. foreach ($testCases as $testCase) {
  107. $test->addTestFile($testCase);
  108. }
  109. return $test->run($reporter);
  110. }
  111. /**
  112. * Runs a specific test case file
  113. *
  114. * @param string $testCaseFile Filename of the test to be run.
  115. * @param Object $reporter Reporter instance to attach to the test case.
  116. * @param boolean $testing Set to true if testing, otherwise test case will be run.
  117. * @return mixed Result of test case being run.
  118. * @access public
  119. */
  120. function runTestCase($testCaseFile, &$reporter, $testing = false) {
  121. $testCaseFileWithPath = $this->_getTestsPath() . DS . $testCaseFile;
  122. if (!file_exists($testCaseFileWithPath) || strpos($testCaseFileWithPath, '..')) {
  123. trigger_error(
  124. sprintf(__("Test case %s cannot be found", true), htmlentities($testCaseFile)),
  125. E_USER_ERROR
  126. );
  127. return false;
  128. }
  129. if ($testing) {
  130. return true;
  131. }
  132. $test =& new TestSuite(sprintf(__('Individual test case: %s', true), $testCaseFile));
  133. $test->addTestFile($testCaseFileWithPath);
  134. return $test->run($reporter);
  135. }
  136. /**
  137. * Runs a specific group test file
  138. *
  139. * @param string $groupTestName GroupTest that you want to run.
  140. * @param Object $reporter Reporter instance to use with the group test being run.
  141. * @return mixed Results of group test being run.
  142. * @access public
  143. */
  144. function runGroupTest($groupTestName, &$reporter) {
  145. $filePath = $this->_getTestsPath('groups') . DS . strtolower($groupTestName) . $this->_groupExtension;
  146. if (!file_exists($filePath) || strpos($filePath, '..')) {
  147. trigger_error(sprintf(
  148. __("Group test %s cannot be found at %s", true),
  149. htmlentities($groupTestName),
  150. htmlentities($filePath)
  151. ),
  152. E_USER_ERROR
  153. );
  154. }
  155. require_once $filePath;
  156. $test =& new TestSuite(sprintf(__('%s group test', true), $groupTestName));
  157. foreach ($this->_getGroupTestClassNames($filePath) as $groupTest) {
  158. $testCase = new $groupTest();
  159. $test->addTestCase($testCase);
  160. if (isset($testCase->label)) {
  161. $test->_label = $testCase->label;
  162. }
  163. }
  164. return $test->run($reporter);
  165. }
  166. /**
  167. * Adds all testcases in a given directory to a given GroupTest object
  168. *
  169. * @param object $groupTest Instance of TestSuite/GroupTest that files are to be added to.
  170. * @param string $directory The directory to add tests from.
  171. * @return void
  172. * @access public
  173. * @static
  174. */
  175. function addTestCasesFromDirectory(&$groupTest, $directory = '.') {
  176. $manager =& new TestManager();
  177. $testCases =& $manager->_getTestFileList($directory);
  178. foreach ($testCases as $testCase) {
  179. $groupTest->addTestFile($testCase);
  180. }
  181. }
  182. /**
  183. * Adds a specific test file and thereby all of its test cases and group tests to a given group test file
  184. *
  185. * @param object $groupTest Instance of TestSuite/GroupTest that a file should be added to.
  186. * @param string $file The file name, minus the suffix to add.
  187. * @return void
  188. * @access public
  189. * @static
  190. */
  191. function addTestFile(&$groupTest, $file) {
  192. $manager =& new TestManager();
  193. if (file_exists($file . $manager->_testExtension)) {
  194. $file .= $manager->_testExtension;
  195. } elseif (file_exists($file . $manager->_groupExtension)) {
  196. $file .= $manager->_groupExtension;
  197. }
  198. $groupTest->addTestFile($file);
  199. }
  200. /**
  201. * Returns a list of test cases found in the current valid test case path
  202. *
  203. * @access public
  204. * @static
  205. */
  206. function &getTestCaseList() {
  207. $manager =& new TestManager();
  208. $return = $manager->_getTestCaseList($manager->_getTestsPath());
  209. return $return;
  210. }
  211. /**
  212. * Builds the list of test cases from a given directory
  213. *
  214. * @param string $directory Directory to get test case list from.
  215. * @access protected
  216. */
  217. function &_getTestCaseList($directory = '.') {
  218. $fileList =& $this->_getTestFileList($directory);
  219. $testCases = array();
  220. foreach ($fileList as $testCaseFile) {
  221. $testCases[$testCaseFile] = str_replace($directory . DS, '', $testCaseFile);
  222. }
  223. return $testCases;
  224. }
  225. /**
  226. * Returns a list of test files from a given directory
  227. *
  228. * @param string $directory Directory to get test case files from.
  229. * @access protected
  230. */
  231. function &_getTestFileList($directory = '.') {
  232. $return = $this->_getRecursiveFileList($directory, array(&$this, '_isTestCaseFile'));
  233. return $return;
  234. }
  235. /**
  236. * Returns a list of group tests found in the current valid test case path
  237. *
  238. * @access public
  239. * @static
  240. */
  241. function &getGroupTestList() {
  242. $manager =& new TestManager();
  243. $return = $manager->_getTestGroupList($manager->_getTestsPath('groups'));
  244. return $return;
  245. }
  246. /**
  247. * Returns a list of group test files from a given directory
  248. *
  249. * @param string $directory The directory to get group test files from.
  250. * @access protected
  251. */
  252. function &_getTestGroupFileList($directory = '.') {
  253. $return = $this->_getRecursiveFileList($directory, array(&$this, '_isTestGroupFile'));
  254. return $return;
  255. }
  256. /**
  257. * Returns a list of group test files from a given directory
  258. *
  259. * @param string $directory The directory to get group tests from.
  260. * @access protected
  261. */
  262. function &_getTestGroupList($directory = '.') {
  263. $fileList =& $this->_getTestGroupFileList($directory);
  264. $groupTests = array();
  265. foreach ($fileList as $groupTestFile) {
  266. $groupTests[$groupTestFile] = str_replace($this->_groupExtension, '', basename($groupTestFile));
  267. }
  268. sort($groupTests);
  269. return $groupTests;
  270. }
  271. /**
  272. * Returns a list of class names from a group test file
  273. *
  274. * @param string $groupTestFile The groupTest file to scan for TestSuite classnames.
  275. * @access protected
  276. */
  277. function &_getGroupTestClassNames($groupTestFile) {
  278. $file = implode("\n", file($groupTestFile));
  279. preg_match("~lass\s+?(.*)\s+?extends TestSuite~", $file, $matches);
  280. if (!empty($matches)) {
  281. unset($matches[0]);
  282. return $matches;
  283. }
  284. $matches = array();
  285. return $matches;
  286. }
  287. /**
  288. * Gets a recursive list of files from a given directory and matches then against
  289. * a given fileTestFunction, like isTestCaseFile()
  290. *
  291. * @param string $directory The directory to scan for files.
  292. * @param mixed $fileTestFunction
  293. * @access protected
  294. */
  295. function &_getRecursiveFileList($directory = '.', $fileTestFunction) {
  296. $fileList = array();
  297. if (!is_dir($directory)) {
  298. return $fileList;
  299. }
  300. $files = glob($directory . DS . '*');
  301. $files = $files ? $files : array();
  302. foreach ($files as $file) {
  303. if (is_dir($file)) {
  304. $fileList = array_merge($fileList, $this->_getRecursiveFileList($file, $fileTestFunction));
  305. } elseif ($fileTestFunction[0]->$fileTestFunction[1]($file)) {
  306. $fileList[] = $file;
  307. }
  308. }
  309. return $fileList;
  310. }
  311. /**
  312. * Tests if a file has the correct test case extension
  313. *
  314. * @param string $file
  315. * @return boolean Whether $file is a test case.
  316. * @access protected
  317. */
  318. function _isTestCaseFile($file) {
  319. return $this->_hasExpectedExtension($file, $this->_testExtension);
  320. }
  321. /**
  322. * Tests if a file has the correct group test extension
  323. *
  324. * @param string $file
  325. * @return boolean Whether $file is a group
  326. * @access protected
  327. */
  328. function _isTestGroupFile($file) {
  329. return $this->_hasExpectedExtension($file, $this->_groupExtension);
  330. }
  331. /**
  332. * Check if a file has a specific extension
  333. *
  334. * @param string $file
  335. * @param string $extension
  336. * @return void
  337. * @access protected
  338. */
  339. function _hasExpectedExtension($file, $extension) {
  340. return $extension == strtolower(substr($file, (0 - strlen($extension))));
  341. }
  342. /**
  343. * Returns the given path to the test files depending on a given type of tests (cases, group, ..)
  344. *
  345. * @param string $type either 'cases' or 'groups'
  346. * @return string The path tests are located on
  347. * @access protected
  348. */
  349. function _getTestsPath($type = 'cases') {
  350. if (!empty($this->appTest)) {
  351. if ($type == 'cases') {
  352. $result = APP_TEST_CASES;
  353. } else if ($type == 'groups') {
  354. $result = APP_TEST_GROUPS;
  355. }
  356. } else if (!empty($this->pluginTest)) {
  357. $_pluginBasePath = APP . 'plugins' . DS . $this->pluginTest . DS . 'tests';
  358. $pluginPath = App::pluginPath($this->pluginTest);
  359. if (file_exists($pluginPath . DS . 'tests')) {
  360. $_pluginBasePath = $pluginPath . DS . 'tests';
  361. }
  362. $result = $_pluginBasePath . DS . $type;
  363. } else {
  364. if ($type == 'cases') {
  365. $result = CORE_TEST_CASES;
  366. } else if ($type == 'groups') {
  367. $result = CORE_TEST_GROUPS;
  368. }
  369. }
  370. return $result;
  371. }
  372. /**
  373. * Get the extension for either 'group' or 'test' types.
  374. *
  375. * @param string $type Type of test to get, either 'test' or 'group'
  376. * @return string Extension suffix for test.
  377. * @access public
  378. */
  379. function getExtension($type = 'test') {
  380. if ($type == 'test' || $type == 'case') {
  381. return $this->_testExtension;
  382. }
  383. return $this->_groupExtension;
  384. }
  385. }