source: Dev/branches/cakephp/cake/tests/lib/test_manager.php @ 126

Last change on this file since 126 was 126, checked in by fpvanagthoven, 14 years ago

Cakephp branch.

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