Mercurial > hg > Members > shoshi > webvirt
comparison cake/console/libs/testsuite.php @ 0:261e66bd5a0c
hg init
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 24 Jul 2011 21:08:31 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * Test Suite Shell | |
4 * | |
5 * This Shell allows the running of test suites via the cake command line | |
6 * | |
7 * PHP versions 4 and 5 | |
8 * | |
9 * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing> | |
10 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
11 * | |
12 * Licensed under The Open Group Test Suite License | |
13 * Redistributions of files must retain the above copyright notice. | |
14 * | |
15 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
16 * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests | |
17 * @package cake | |
18 * @subpackage cake.cake.console.libs | |
19 * @since CakePHP(tm) v 1.2.0.4433 | |
20 * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License | |
21 */ | |
22 class TestSuiteShell extends Shell { | |
23 | |
24 /** | |
25 * The test category, "app", "core" or the name of a plugin | |
26 * | |
27 * @var string | |
28 * @access public | |
29 */ | |
30 var $category = ''; | |
31 | |
32 /** | |
33 * "group", "case" or "all" | |
34 * | |
35 * @var string | |
36 * @access public | |
37 */ | |
38 var $type = ''; | |
39 | |
40 /** | |
41 * Path to the test case/group file | |
42 * | |
43 * @var string | |
44 * @access public | |
45 */ | |
46 var $file = ''; | |
47 | |
48 /** | |
49 * Storage for plugins that have tests | |
50 * | |
51 * @var string | |
52 * @access public | |
53 */ | |
54 var $plugins = array(); | |
55 | |
56 /** | |
57 * Convenience variable to avoid duplicated code | |
58 * | |
59 * @var string | |
60 * @access public | |
61 */ | |
62 var $isPluginTest = false; | |
63 | |
64 /** | |
65 * Stores if the user wishes to get a code coverage analysis report | |
66 * | |
67 * @var string | |
68 * @access public | |
69 */ | |
70 var $doCoverage = false; | |
71 | |
72 /** | |
73 * Initialization method installs Simpletest and loads all plugins | |
74 * | |
75 * @return void | |
76 * @access public | |
77 */ | |
78 function initialize() { | |
79 $corePath = App::core('cake'); | |
80 if (isset($corePath[0])) { | |
81 define('TEST_CAKE_CORE_INCLUDE_PATH', rtrim($corePath[0], DS) . DS); | |
82 } else { | |
83 define('TEST_CAKE_CORE_INCLUDE_PATH', CAKE_CORE_INCLUDE_PATH); | |
84 } | |
85 | |
86 $this->__installSimpleTest(); | |
87 | |
88 require_once CAKE . 'tests' . DS . 'lib' . DS . 'test_manager.php'; | |
89 require_once CAKE . 'tests' . DS . 'lib' . DS . 'reporter' . DS . 'cake_cli_reporter.php'; | |
90 | |
91 $plugins = App::objects('plugin'); | |
92 foreach ($plugins as $p) { | |
93 $this->plugins[] = Inflector::underscore($p); | |
94 } | |
95 $this->parseArgs(); | |
96 $this->getManager(); | |
97 } | |
98 | |
99 /** | |
100 * Parse the arguments given into the Shell object properties. | |
101 * | |
102 * @return void | |
103 * @access public | |
104 */ | |
105 function parseArgs() { | |
106 if (empty($this->args)) { | |
107 return; | |
108 } | |
109 $this->category = $this->args[0]; | |
110 | |
111 if (!in_array($this->category, array('app', 'core'))) { | |
112 $this->isPluginTest = true; | |
113 } | |
114 | |
115 if (isset($this->args[1])) { | |
116 $this->type = $this->args[1]; | |
117 } | |
118 | |
119 if (isset($this->args[2])) { | |
120 if ($this->args[2] == 'cov') { | |
121 $this->doCoverage = true; | |
122 } else { | |
123 $this->file = Inflector::underscore($this->args[2]); | |
124 } | |
125 } | |
126 | |
127 if (isset($this->args[3]) && $this->args[3] == 'cov') { | |
128 $this->doCoverage = true; | |
129 } | |
130 } | |
131 | |
132 /** | |
133 * Gets a manager instance, and set the app/plugin properties. | |
134 * | |
135 * @return void | |
136 */ | |
137 function getManager() { | |
138 $this->Manager = new TestManager(); | |
139 $this->Manager->appTest = ($this->category === 'app'); | |
140 if ($this->isPluginTest) { | |
141 $this->Manager->pluginTest = $this->category; | |
142 } | |
143 } | |
144 | |
145 /** | |
146 * Main entry point to this shell | |
147 * | |
148 * @return void | |
149 * @access public | |
150 */ | |
151 function main() { | |
152 $this->out(__('CakePHP Test Shell', true)); | |
153 $this->hr(); | |
154 | |
155 if (count($this->args) == 0) { | |
156 $this->error(__('Sorry, you did not pass any arguments!', true)); | |
157 } | |
158 | |
159 if ($this->__canRun()) { | |
160 $message = sprintf(__('Running %s %s %s', true), $this->category, $this->type, $this->file); | |
161 $this->out($message); | |
162 | |
163 $exitCode = 0; | |
164 if (!$this->__run()) { | |
165 $exitCode = 1; | |
166 } | |
167 $this->_stop($exitCode); | |
168 } else { | |
169 $this->error(__('Sorry, the tests could not be found.', true)); | |
170 } | |
171 } | |
172 | |
173 /** | |
174 * Help screen | |
175 * | |
176 * @return void | |
177 * @access public | |
178 */ | |
179 function help() { | |
180 $this->out('Usage: '); | |
181 $this->out("\tcake testsuite category test_type file"); | |
182 $this->out("\t\t- category - \"app\", \"core\" or name of a plugin"); | |
183 $this->out("\t\t- test_type - \"case\", \"group\" or \"all\""); | |
184 $this->out("\t\t- test_file - file name with folder prefix and without the (test|group).php suffix"); | |
185 $this->out(); | |
186 $this->out('Examples: '); | |
187 $this->out("\t\tcake testsuite app all"); | |
188 $this->out("\t\tcake testsuite core all"); | |
189 $this->out(); | |
190 $this->out("\t\tcake testsuite app case behaviors/debuggable"); | |
191 $this->out("\t\tcake testsuite app case models/my_model"); | |
192 $this->out("\t\tcake testsuite app case controllers/my_controller"); | |
193 $this->out(); | |
194 $this->out("\t\tcake testsuite core case file"); | |
195 $this->out("\t\tcake testsuite core case router"); | |
196 $this->out("\t\tcake testsuite core case set"); | |
197 $this->out(); | |
198 $this->out("\t\tcake testsuite app group mygroup"); | |
199 $this->out("\t\tcake testsuite core group acl"); | |
200 $this->out("\t\tcake testsuite core group socket"); | |
201 $this->out(); | |
202 $this->out("\t\tcake testsuite bugs case models/bug"); | |
203 $this->out("\t\t // for the plugin 'bugs' and its test case 'models/bug'"); | |
204 $this->out("\t\tcake testsuite bugs group bug"); | |
205 $this->out("\t\t // for the plugin bugs and its test group 'bug'"); | |
206 $this->out(); | |
207 $this->out('Code Coverage Analysis: '); | |
208 $this->out("\n\nAppend 'cov' to any of the above in order to enable code coverage analysis"); | |
209 } | |
210 | |
211 /** | |
212 * Checks if the arguments supplied point to a valid test file and thus the shell can be run. | |
213 * | |
214 * @return bool true if it's a valid test file, false otherwise | |
215 * @access private | |
216 */ | |
217 function __canRun() { | |
218 $isNeitherAppNorCore = !in_array($this->category, array('app', 'core')); | |
219 $isPlugin = in_array(Inflector::underscore($this->category), $this->plugins); | |
220 | |
221 if ($isNeitherAppNorCore && !$isPlugin) { | |
222 $message = sprintf( | |
223 __('%s is an invalid test category (either "app", "core" or name of a plugin)', true), | |
224 $this->category | |
225 ); | |
226 $this->error($message); | |
227 return false; | |
228 } | |
229 | |
230 $folder = $this->__findFolderByCategory($this->category); | |
231 if (!file_exists($folder)) { | |
232 $this->err(sprintf(__('%s not found', true), $folder)); | |
233 return false; | |
234 } | |
235 | |
236 if (!in_array($this->type, array('all', 'group', 'case'))) { | |
237 $this->err(sprintf(__('%s is invalid. Should be case, group or all', true), $this->type)); | |
238 return false; | |
239 } | |
240 | |
241 $fileName = $this->__getFileName($folder, $this->isPluginTest); | |
242 if ($fileName === true || file_exists($folder . $fileName)) { | |
243 return true; | |
244 } | |
245 | |
246 $message = sprintf( | |
247 __('%s %s %s is an invalid test identifier', true), | |
248 $this->category, $this->type, $this->file | |
249 ); | |
250 $this->err($message); | |
251 return false; | |
252 } | |
253 /** | |
254 * Executes the tests depending on our settings | |
255 * | |
256 * @return void | |
257 * @access private | |
258 */ | |
259 function __run() { | |
260 $Reporter = new CakeCliReporter('utf-8', array( | |
261 'app' => $this->Manager->appTest, | |
262 'plugin' => $this->Manager->pluginTest, | |
263 'group' => ($this->type === 'group'), | |
264 'codeCoverage' => $this->doCoverage | |
265 )); | |
266 | |
267 if ($this->type == 'all') { | |
268 return $this->Manager->runAllTests($Reporter); | |
269 } | |
270 | |
271 if ($this->doCoverage) { | |
272 if (!extension_loaded('xdebug')) { | |
273 $this->out(__('You must install Xdebug to use the CakePHP(tm) Code Coverage Analyzation. Download it from http://www.xdebug.org/docs/install', true)); | |
274 $this->_stop(0); | |
275 } | |
276 } | |
277 | |
278 if ($this->type == 'group') { | |
279 $ucFirstGroup = ucfirst($this->file); | |
280 if ($this->doCoverage) { | |
281 require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php'; | |
282 CodeCoverageManager::init($ucFirstGroup, $Reporter); | |
283 CodeCoverageManager::start(); | |
284 } | |
285 $result = $this->Manager->runGroupTest($ucFirstGroup, $Reporter); | |
286 return $result; | |
287 } | |
288 | |
289 $folder = $folder = $this->__findFolderByCategory($this->category); | |
290 $case = $this->__getFileName($folder, $this->isPluginTest); | |
291 | |
292 if ($this->doCoverage) { | |
293 require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php'; | |
294 CodeCoverageManager::init($case, $Reporter); | |
295 CodeCoverageManager::start(); | |
296 } | |
297 $result = $this->Manager->runTestCase($case, $Reporter); | |
298 return $result; | |
299 } | |
300 | |
301 /** | |
302 * Gets the concrete filename for the inputted test name and category/type | |
303 * | |
304 * @param string $folder Folder name to look for files in. | |
305 * @param boolean $isPlugin If the test case is a plugin. | |
306 * @return mixed Either string filename or boolean false on failure. Or true if the type is 'all' | |
307 * @access private | |
308 */ | |
309 function __getFileName($folder, $isPlugin) { | |
310 $ext = $this->Manager->getExtension($this->type); | |
311 switch ($this->type) { | |
312 case 'all': | |
313 return true; | |
314 case 'group': | |
315 return $this->file . $ext; | |
316 case 'case': | |
317 if ($this->category == 'app' || $isPlugin) { | |
318 return $this->file . $ext; | |
319 } | |
320 $coreCase = $this->file . $ext; | |
321 $coreLibCase = 'libs' . DS . $this->file . $ext; | |
322 | |
323 if ($this->category == 'core' && file_exists($folder . DS . $coreCase)) { | |
324 return $coreCase; | |
325 } elseif ($this->category == 'core' && file_exists($folder . DS . $coreLibCase)) { | |
326 return $coreLibCase; | |
327 } | |
328 } | |
329 return false; | |
330 } | |
331 | |
332 /** | |
333 * Finds the correct folder to look for tests for based on the input category and type. | |
334 * | |
335 * @param string $category The category of the test. Either 'app', 'core' or a plugin name. | |
336 * @return string the folder path | |
337 * @access private | |
338 */ | |
339 function __findFolderByCategory($category) { | |
340 $folder = ''; | |
341 $paths = array( | |
342 'core' => CAKE, | |
343 'app' => APP | |
344 ); | |
345 $typeDir = $this->type === 'group' ? 'groups' : 'cases'; | |
346 | |
347 if (array_key_exists($category, $paths)) { | |
348 $folder = $paths[$category] . 'tests' . DS . $typeDir . DS; | |
349 } else { | |
350 $pluginPath = App::pluginPath($category); | |
351 if (is_dir($pluginPath . 'tests')) { | |
352 $folder = $pluginPath . 'tests' . DS . $typeDir . DS; | |
353 } | |
354 } | |
355 return $folder; | |
356 } | |
357 | |
358 /** | |
359 * tries to install simpletest and exits gracefully if it is not there | |
360 * | |
361 * @return void | |
362 * @access private | |
363 */ | |
364 function __installSimpleTest() { | |
365 if (!App::import('Vendor', 'simpletest' . DS . 'reporter')) { | |
366 $this->err(__('Sorry, Simpletest could not be found. Download it from http://simpletest.org and install it to your vendors directory.', true)); | |
367 exit; | |
368 } | |
369 } | |
370 } |