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