1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
18:
19: 20: 21:
22: if (!defined('TESTS')) {
23: define('TESTS', APP . 'Test' . DS);
24: }
25:
26: 27: 28:
29: define('CORE_TEST_CASES', CAKE . 'Test' . DS . 'Case');
30:
31: 32: 33:
34: if (!defined('APP_TEST_CASES')) {
35: define('APP_TEST_CASES', TESTS . 'Case');
36: }
37:
38: App::uses('CakeTestSuiteCommand', 'TestSuite');
39:
40: 41: 42: 43: 44:
45: class CakeTestSuiteDispatcher {
46:
47: 48: 49: 50: 51:
52: public $params = array(
53: 'codeCoverage' => false,
54: 'case' => null,
55: 'core' => false,
56: 'app' => false,
57: 'plugin' => null,
58: 'output' => 'html',
59: 'show' => 'groups',
60: 'show_passes' => false,
61: 'filter' => false,
62: 'fixture' => null
63: );
64:
65: 66: 67: 68: 69:
70: protected $_baseUrl;
71:
72: 73: 74: 75: 76:
77: protected $_baseDir;
78:
79: 80: 81: 82: 83:
84: protected $_paramsParsed = false;
85:
86: 87: 88: 89: 90:
91: protected static $_Reporter = null;
92:
93: 94: 95:
96: public function __construct() {
97: $this->_baseUrl = $_SERVER['PHP_SELF'];
98: $dir = rtrim(dirname($this->_baseUrl), '\\');
99: $this->_baseDir = ($dir === '/') ? $dir : $dir . '/';
100: }
101:
102: 103: 104: 105: 106:
107: public function dispatch() {
108: $this->_checkPHPUnit();
109: $this->_parseParams();
110:
111: if ($this->params['case']) {
112: $value = $this->_runTestCase();
113: } else {
114: $value = $this->_testCaseList();
115: }
116:
117: $output = ob_get_clean();
118: echo $output;
119: return $value;
120: }
121:
122: 123: 124: 125: 126:
127: public static function run() {
128: $dispatcher = new CakeTestSuiteDispatcher();
129: $dispatcher->dispatch();
130: }
131:
132: 133: 134: 135: 136:
137: protected function _checkPHPUnit() {
138: $found = $this->loadTestFramework();
139: if (!$found) {
140: $baseDir = $this->_baseDir;
141: include CAKE . 'TestSuite' . DS . 'templates' . DS . 'phpunit.php';
142: exit();
143: }
144: }
145:
146: 147: 148: 149: 150:
151: public function loadTestFramework() {
152: if (class_exists('PHPUnit_Framework_TestCase')) {
153: return true;
154: }
155: $phpunitPath = 'phpunit' . DS . 'phpunit';
156: if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
157: $composerGlobalDir[] = env('APPDATA') . DS . 'Composer' . DS . 'vendor' . DS;
158: } else {
159: $composerGlobalDir[] = env('HOME') . DS . '.composer' . DS . 'vendor' . DS;
160: }
161: $vendors = array_merge(App::path('vendors'), $composerGlobalDir);
162: foreach ($vendors as $vendor) {
163: $vendor = rtrim($vendor, DS);
164: if (is_dir($vendor . DS . $phpunitPath)) {
165: ini_set('include_path', $vendor . DS . $phpunitPath . PATH_SEPARATOR . ini_get('include_path'));
166: break;
167: } elseif (is_dir($vendor . DS . 'PHPUnit')) {
168: ini_set('include_path', $vendor . PATH_SEPARATOR . ini_get('include_path'));
169: break;
170: } elseif (is_file($vendor . DS . 'phpunit.phar')) {
171: $backup = $GLOBALS['_SERVER']['SCRIPT_NAME'];
172: $GLOBALS['_SERVER']['SCRIPT_NAME'] = '-';
173: ob_start();
174: $included = include_once $vendor . DS . 'phpunit.phar';
175: ob_end_clean();
176: $GLOBALS['_SERVER']['SCRIPT_NAME'] = $backup;
177: return $included;
178: }
179: }
180: include 'PHPUnit' . DS . 'Autoload.php';
181: return class_exists('PHPUnit_Framework_TestCase');
182: }
183:
184: 185: 186: 187: 188: 189:
190: protected function _checkXdebug() {
191: if (!extension_loaded('xdebug')) {
192: $baseDir = $this->_baseDir;
193: include CAKE . 'TestSuite' . DS . 'templates' . DS . 'xdebug.php';
194: exit();
195: }
196: }
197:
198: 199: 200: 201: 202:
203: protected function _testCaseList() {
204: $command = new CakeTestSuiteCommand('', $this->params);
205: $Reporter = $command->handleReporter($this->params['output']);
206: $Reporter->paintDocumentStart();
207: $Reporter->paintTestMenu();
208: $Reporter->testCaseList();
209: $Reporter->paintDocumentEnd();
210: }
211:
212: 213: 214: 215: 216: 217:
218: public function setParams($params) {
219: $this->params = $params;
220: $this->_paramsParsed = true;
221: }
222:
223: 224: 225: 226: 227:
228: protected function _parseParams() {
229: if (!$this->_paramsParsed) {
230: if (!isset($_SERVER['SERVER_NAME'])) {
231: $_SERVER['SERVER_NAME'] = '';
232: }
233: foreach ($this->params as $key => $value) {
234: if (isset($_GET[$key])) {
235: $this->params[$key] = $_GET[$key];
236: }
237: }
238: if (isset($_GET['code_coverage'])) {
239: $this->params['codeCoverage'] = true;
240: $this->_checkXdebug();
241: }
242: }
243: if (empty($this->params['plugin']) && empty($this->params['core'])) {
244: $this->params['app'] = true;
245: }
246: $this->params['baseUrl'] = $this->_baseUrl;
247: $this->params['baseDir'] = $this->_baseDir;
248: }
249:
250: 251: 252: 253: 254:
255: protected function _runTestCase() {
256: $commandArgs = array(
257: 'case' => $this->params['case'],
258: 'core' => $this->params['core'],
259: 'app' => $this->params['app'],
260: 'plugin' => $this->params['plugin'],
261: 'codeCoverage' => $this->params['codeCoverage'],
262: 'showPasses' => !empty($this->params['show_passes']),
263: 'baseUrl' => $this->_baseUrl,
264: 'baseDir' => $this->_baseDir,
265: );
266:
267: $options = array(
268: '--filter', $this->params['filter'],
269: '--output', $this->params['output'],
270: '--fixture', $this->params['fixture']
271: );
272: restore_error_handler();
273:
274: try {
275: static::time();
276: $command = new CakeTestSuiteCommand('CakeTestLoader', $commandArgs);
277: $command->run($options);
278: } catch (MissingConnectionException $exception) {
279: ob_end_clean();
280: $baseDir = $this->_baseDir;
281: include CAKE . 'TestSuite' . DS . 'templates' . DS . 'missing_connection.php';
282: exit();
283: }
284: }
285:
286: 287: 288: 289: 290: 291:
292: public static function time($reset = false) {
293: static $now;
294: if ($reset || !$now) {
295: $now = time();
296: }
297: return $now;
298: }
299:
300: 301: 302: 303: 304: 305: 306:
307: public static function date($format) {
308: return date($format, static::time());
309: }
310:
311: }
312: