Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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