2008-05-30 11:40:08 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Test Suite Shell
|
|
|
|
*
|
|
|
|
* This Shell allows the running of test suites via the cake command line
|
|
|
|
*
|
|
|
|
* PHP versions 4 and 5
|
|
|
|
*
|
|
|
|
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
|
2009-11-06 06:46:59 +00:00
|
|
|
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
2008-05-30 11:40:08 +00:00
|
|
|
*
|
|
|
|
* Licensed under The Open Group Test Suite License
|
|
|
|
* Redistributions of files must retain the above copyright notice.
|
|
|
|
*
|
2009-11-06 06:46:59 +00:00
|
|
|
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
2008-10-30 17:30:26 +00:00
|
|
|
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
|
|
|
|
* @package cake
|
|
|
|
* @subpackage cake.cake.console.libs
|
|
|
|
* @since CakePHP(tm) v 1.2.0.4433
|
|
|
|
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
|
2008-05-30 11:40:08 +00:00
|
|
|
*/
|
|
|
|
class TestSuiteShell extends Shell {
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* The test category, "app", "core" or the name of a plugin
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
var $category = '';
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* "group", "case" or "all"
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
var $type = '';
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Path to the test case/group file
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
var $file = '';
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Storage for plugins that have tests
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
var $plugins = array();
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Convenience variable to avoid duplicated code
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
var $isPluginTest = false;
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Stores if the user wishes to get a code coverage analysis report
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
var $doCoverage = false;
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* The headline for the test output
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
var $headline = 'CakePHP Test Shell';
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Initialization method installs Simpletest and loads all plugins
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
function initialize() {
|
2009-07-22 16:11:38 +00:00
|
|
|
$corePath = App::core('cake');
|
2008-05-30 11:40:08 +00:00
|
|
|
if (isset($corePath[0])) {
|
|
|
|
define('TEST_CAKE_CORE_INCLUDE_PATH', rtrim($corePath[0], DS) . DS);
|
|
|
|
} else {
|
2009-08-02 20:19:16 +00:00
|
|
|
define('TEST_CAKE_CORE_INCLUDE_PATH', CAKE_CORE_INCLUDE_PATH);
|
2008-05-30 11:40:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->__installSimpleTest();
|
|
|
|
|
|
|
|
require_once CAKE . 'tests' . DS . 'lib' . DS . 'test_manager.php';
|
|
|
|
require_once CAKE . 'tests' . DS . 'lib' . DS . 'cli_reporter.php';
|
|
|
|
|
2009-06-10 23:13:39 +00:00
|
|
|
$plugins = App::objects('plugin');
|
2008-05-30 11:40:08 +00:00
|
|
|
foreach ($plugins as $p) {
|
|
|
|
$this->plugins[] = Inflector::underscore($p);
|
|
|
|
}
|
|
|
|
}
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Main entry point to this shell
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
function main() {
|
|
|
|
$this->out($this->headline);
|
|
|
|
$this->hr();
|
|
|
|
|
|
|
|
if (count($this->args) > 0) {
|
|
|
|
$this->category = $this->args[0];
|
|
|
|
|
|
|
|
if (!in_array($this->category, array('app', 'core'))) {
|
|
|
|
$this->isPluginTest = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($this->args[1])) {
|
|
|
|
$this->type = $this->args[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($this->args[2])) {
|
|
|
|
if ($this->args[2] == 'cov') {
|
|
|
|
$this->doCoverage = true;
|
|
|
|
} else {
|
|
|
|
$this->file = Inflector::underscore($this->args[2]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($this->args[3]) && $this->args[3] == 'cov') {
|
|
|
|
$this->doCoverage = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$this->err('Sorry, you did not pass any arguments!');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->__canRun()) {
|
|
|
|
$this->out('Running '.$this->category.' '.$this->type.' '.$this->file);
|
|
|
|
|
|
|
|
$exitCode = 0;
|
|
|
|
if (!$this->__run()) {
|
|
|
|
$exitCode = 1;
|
|
|
|
}
|
|
|
|
exit($exitCode);
|
|
|
|
} else {
|
|
|
|
$this->err('Sorry, the tests could not be found.');
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Help screen
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
function help() {
|
|
|
|
$this->out('Usage: ');
|
|
|
|
$this->out("\tcake testsuite category test_type file");
|
2009-04-30 23:38:14 +00:00
|
|
|
$this->out("\t\t- category - \"app\", \"core\" or name of a plugin");
|
|
|
|
$this->out("\t\t- test_type - \"case\", \"group\" or \"all\"");
|
|
|
|
$this->out("\t\t- test_file - file name with folder prefix and without the (test|group).php suffix");
|
2009-09-26 21:08:37 +00:00
|
|
|
$this->out();
|
2008-05-30 11:40:08 +00:00
|
|
|
$this->out('Examples: ');
|
2009-04-30 23:38:14 +00:00
|
|
|
$this->out("\t\tcake testsuite app all");
|
|
|
|
$this->out("\t\tcake testsuite core all");
|
2009-09-26 21:08:37 +00:00
|
|
|
$this->out();
|
2009-04-30 23:38:14 +00:00
|
|
|
$this->out("\t\tcake testsuite app case behaviors/debuggable");
|
|
|
|
$this->out("\t\tcake testsuite app case models/my_model");
|
|
|
|
$this->out("\t\tcake testsuite app case controllers/my_controller");
|
2009-09-26 21:08:37 +00:00
|
|
|
$this->out();
|
2009-04-30 23:38:14 +00:00
|
|
|
$this->out("\t\tcake testsuite core case file");
|
|
|
|
$this->out("\t\tcake testsuite core case router");
|
|
|
|
$this->out("\t\tcake testsuite core case set");
|
2009-09-26 21:08:37 +00:00
|
|
|
$this->out();
|
2009-04-30 23:38:14 +00:00
|
|
|
$this->out("\t\tcake testsuite app group mygroup");
|
|
|
|
$this->out("\t\tcake testsuite core group acl");
|
|
|
|
$this->out("\t\tcake testsuite core group socket");
|
2009-09-26 21:08:37 +00:00
|
|
|
$this->out();
|
2009-04-30 23:38:14 +00:00
|
|
|
$this->out("\t\tcake testsuite bugs case models/bug");
|
|
|
|
$this->out("\t\t // for the plugin 'bugs' and its test case 'models/bug'");
|
|
|
|
$this->out("\t\tcake testsuite bugs group bug");
|
|
|
|
$this->out("\t\t // for the plugin bugs and its test group 'bug'");
|
2009-09-26 21:08:37 +00:00
|
|
|
$this->out();
|
2008-05-30 11:40:08 +00:00
|
|
|
$this->out('Code Coverage Analysis: ');
|
|
|
|
$this->out("\n\nAppend 'cov' to any of the above in order to enable code coverage analysis");
|
|
|
|
}
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Checks if the arguments supplied point to a valid test file and thus the shell can be run.
|
|
|
|
*
|
|
|
|
* @return bool true if it's a valid test file, false otherwise
|
|
|
|
* @access private
|
|
|
|
*/
|
2008-06-20 20:17:23 +00:00
|
|
|
function __canRun() {
|
2008-05-30 11:40:08 +00:00
|
|
|
$isNeitherAppNorCore = !in_array($this->category, array('app', 'core'));
|
|
|
|
$isPlugin = in_array(Inflector::underscore($this->category), $this->plugins);
|
|
|
|
|
|
|
|
if ($isNeitherAppNorCore && !$isPlugin) {
|
|
|
|
$this->err($this->category.' is an invalid test category (either "app", "core" or name of a plugin)');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$folder = $this->__findFolderByCategory($this->category);
|
|
|
|
if (!file_exists($folder)) {
|
|
|
|
$this->err($folder . ' not found');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!in_array($this->type, array('all', 'group', 'case'))) {
|
|
|
|
$this->err($this->type.' is invalid. Should be case, group or all');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($this->type) {
|
|
|
|
case 'all':
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case 'group':
|
|
|
|
if (file_exists($folder.DS.'groups'.DS.$this->file.'.group.php')) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'case':
|
|
|
|
if ($this->category == 'app' && file_exists($folder.DS.'cases'.DS.$this->file.'.test.php')) {
|
|
|
|
return true;
|
|
|
|
}
|
2009-08-02 21:20:59 +00:00
|
|
|
$coreCaseExists = file_exists($folder.DS.'cases'.DS.$this->file.'.test.php');
|
|
|
|
$coreLibCaseExists = file_exists($folder.DS.'cases'.DS.'libs'.DS.$this->file.'.test.php');
|
|
|
|
if ($this->category == 'core' && ($coreCaseExists || $coreLibCaseExists)) {
|
2009-08-02 20:19:16 +00:00
|
|
|
return true;
|
2008-05-30 11:40:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($isPlugin && file_exists($folder.DS.'cases'.DS.$this->file.'.test.php')) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->err($this->category.' '.$this->type.' '.$this->file.' is an invalid test identifier');
|
|
|
|
return false;
|
|
|
|
}
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Executes the tests depending on our settings
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
* @access private
|
|
|
|
*/
|
|
|
|
function __run() {
|
|
|
|
$reporter = new CLIReporter();
|
|
|
|
$this->__setGetVars();
|
|
|
|
|
|
|
|
if ($this->type == 'all') {
|
|
|
|
return TestManager::runAllTests($reporter);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->doCoverage) {
|
|
|
|
if (!extension_loaded('xdebug')) {
|
|
|
|
$this->out('You must install Xdebug to use the CakePHP(tm) Code Coverage Analyzation. Download it from http://www.xdebug.org/docs/install');
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->type == 'group') {
|
|
|
|
$ucFirstGroup = ucfirst($this->file);
|
|
|
|
|
|
|
|
$path = CORE_TEST_GROUPS;
|
|
|
|
if ($this->category == 'app') {
|
|
|
|
$path = APP_TEST_GROUPS;
|
|
|
|
} elseif ($this->isPluginTest) {
|
|
|
|
$path = APP.'plugins'.DS.$this->category.DS.'tests'.DS.'groups';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->doCoverage) {
|
|
|
|
require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php';
|
|
|
|
CodeCoverageManager::start($ucFirstGroup, $reporter);
|
|
|
|
}
|
|
|
|
$result = TestManager::runGroupTest($ucFirstGroup, $reporter);
|
|
|
|
if ($this->doCoverage) {
|
|
|
|
CodeCoverageManager::report();
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
2009-08-02 21:20:59 +00:00
|
|
|
if ($this->category === 'core') {
|
|
|
|
$coreCaseExists = file_exists(CORE_TEST_CASES.DS.$this->file.'.test.php');
|
|
|
|
if ($coreCaseExists) {
|
|
|
|
$case = $this->file . '.test.php';
|
|
|
|
} else {
|
|
|
|
$case = 'libs' . DS . $this->file . '.test.php';
|
|
|
|
}
|
|
|
|
} elseif ($this->category === 'app') {
|
2008-05-30 11:40:08 +00:00
|
|
|
$case = $this->file.'.test.php';
|
|
|
|
} elseif ($this->isPluginTest) {
|
|
|
|
$case = $this->file.'.test.php';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->doCoverage) {
|
|
|
|
require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php';
|
|
|
|
CodeCoverageManager::start($case, $reporter);
|
|
|
|
}
|
|
|
|
|
|
|
|
$result = TestManager::runTestCase($case, $reporter);
|
|
|
|
if ($this->doCoverage) {
|
|
|
|
CodeCoverageManager::report();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Finds the correct folder to look for tests for based on the input category
|
|
|
|
*
|
|
|
|
* @return string the folder path
|
|
|
|
* @access private
|
|
|
|
*/
|
|
|
|
function __findFolderByCategory($category) {
|
|
|
|
$folder = '';
|
|
|
|
$paths = array(
|
|
|
|
'core' => CAKE,
|
|
|
|
'app' => APP
|
|
|
|
);
|
|
|
|
|
|
|
|
if (array_key_exists($category, $paths)) {
|
2009-04-30 23:38:14 +00:00
|
|
|
$folder = $paths[$category] . 'tests';
|
2008-05-30 11:40:08 +00:00
|
|
|
} else {
|
2009-04-30 23:38:14 +00:00
|
|
|
$scoredCategory = Inflector::underscore($category);
|
|
|
|
$folder = APP . 'plugins' . DS . $scoredCategory . DS;
|
2009-06-07 22:24:10 +00:00
|
|
|
$pluginPaths = App::path('plugins');
|
2009-04-30 23:38:14 +00:00
|
|
|
foreach ($pluginPaths as $path) {
|
|
|
|
if (file_exists($path . $scoredCategory . DS . 'tests')) {
|
|
|
|
$folder = $path . $scoredCategory . DS . 'tests';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-05-30 11:40:08 +00:00
|
|
|
}
|
2009-04-30 23:38:14 +00:00
|
|
|
return $folder;
|
2008-05-30 11:40:08 +00:00
|
|
|
}
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* Sets some get vars needed for TestManager
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
* @access private
|
|
|
|
*/
|
|
|
|
function __setGetVars() {
|
|
|
|
if (in_array($this->category, $this->plugins)) {
|
|
|
|
$_GET['plugin'] = $this->category;
|
|
|
|
} elseif (in_array(Inflector::Humanize($this->category), $this->plugins)) {
|
|
|
|
$_GET['plugin'] = Inflector::Humanize($this->category);
|
|
|
|
} elseif ($this->category == 'app') {
|
|
|
|
$_GET['app'] = true;
|
|
|
|
}
|
|
|
|
if ($this->type == 'group') {
|
|
|
|
$_GET['group'] = true;
|
|
|
|
}
|
|
|
|
}
|
2009-07-24 19:18:37 +00:00
|
|
|
|
2008-05-30 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* tries to install simpletest and exits gracefully if it is not there
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
* @access private
|
|
|
|
*/
|
|
|
|
function __installSimpleTest() {
|
|
|
|
if (!App::import('Vendor', 'simpletest' . DS . 'reporter')) {
|
|
|
|
$this->err('Sorry, Simpletest could not be found. Download it from http://simpletest.org and install it to your vendors directory.');
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|