Mercurial > hg > Members > shoshi > webvirt
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cake/console/libs/testsuite.php Sun Jul 24 21:08:31 2011 +0900 @@ -0,0 +1,370 @@ +<?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 <http://book.cakephp.org/view/1196/Testing> + * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The Open Group Test Suite License + * Redistributions of files must retain the above copyright notice. + * + * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://book.cakephp.org/view/1196/Testing 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 + */ +class TestSuiteShell extends Shell { + +/** + * The test category, "app", "core" or the name of a plugin + * + * @var string + * @access public + */ + var $category = ''; + +/** + * "group", "case" or "all" + * + * @var string + * @access public + */ + var $type = ''; + +/** + * Path to the test case/group file + * + * @var string + * @access public + */ + var $file = ''; + +/** + * Storage for plugins that have tests + * + * @var string + * @access public + */ + var $plugins = array(); + +/** + * Convenience variable to avoid duplicated code + * + * @var string + * @access public + */ + var $isPluginTest = false; + +/** + * Stores if the user wishes to get a code coverage analysis report + * + * @var string + * @access public + */ + var $doCoverage = false; + +/** + * Initialization method installs Simpletest and loads all plugins + * + * @return void + * @access public + */ + function initialize() { + $corePath = App::core('cake'); + if (isset($corePath[0])) { + define('TEST_CAKE_CORE_INCLUDE_PATH', rtrim($corePath[0], DS) . DS); + } else { + define('TEST_CAKE_CORE_INCLUDE_PATH', CAKE_CORE_INCLUDE_PATH); + } + + $this->__installSimpleTest(); + + require_once CAKE . 'tests' . DS . 'lib' . DS . 'test_manager.php'; + require_once CAKE . 'tests' . DS . 'lib' . DS . 'reporter' . DS . 'cake_cli_reporter.php'; + + $plugins = App::objects('plugin'); + foreach ($plugins as $p) { + $this->plugins[] = Inflector::underscore($p); + } + $this->parseArgs(); + $this->getManager(); + } + +/** + * Parse the arguments given into the Shell object properties. + * + * @return void + * @access public + */ + function parseArgs() { + if (empty($this->args)) { + return; + } + $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; + } + } + +/** + * Gets a manager instance, and set the app/plugin properties. + * + * @return void + */ + function getManager() { + $this->Manager = new TestManager(); + $this->Manager->appTest = ($this->category === 'app'); + if ($this->isPluginTest) { + $this->Manager->pluginTest = $this->category; + } + } + +/** + * Main entry point to this shell + * + * @return void + * @access public + */ + function main() { + $this->out(__('CakePHP Test Shell', true)); + $this->hr(); + + if (count($this->args) == 0) { + $this->error(__('Sorry, you did not pass any arguments!', true)); + } + + if ($this->__canRun()) { + $message = sprintf(__('Running %s %s %s', true), $this->category, $this->type, $this->file); + $this->out($message); + + $exitCode = 0; + if (!$this->__run()) { + $exitCode = 1; + } + $this->_stop($exitCode); + } else { + $this->error(__('Sorry, the tests could not be found.', true)); + } + } + +/** + * Help screen + * + * @return void + * @access public + */ + function help() { + $this->out('Usage: '); + $this->out("\tcake testsuite category test_type file"); + $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"); + $this->out(); + $this->out('Examples: '); + $this->out("\t\tcake testsuite app all"); + $this->out("\t\tcake testsuite core all"); + $this->out(); + $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"); + $this->out(); + $this->out("\t\tcake testsuite core case file"); + $this->out("\t\tcake testsuite core case router"); + $this->out("\t\tcake testsuite core case set"); + $this->out(); + $this->out("\t\tcake testsuite app group mygroup"); + $this->out("\t\tcake testsuite core group acl"); + $this->out("\t\tcake testsuite core group socket"); + $this->out(); + $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'"); + $this->out(); + $this->out('Code Coverage Analysis: '); + $this->out("\n\nAppend 'cov' to any of the above in order to enable code coverage analysis"); + } + +/** + * 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 + */ + function __canRun() { + $isNeitherAppNorCore = !in_array($this->category, array('app', 'core')); + $isPlugin = in_array(Inflector::underscore($this->category), $this->plugins); + + if ($isNeitherAppNorCore && !$isPlugin) { + $message = sprintf( + __('%s is an invalid test category (either "app", "core" or name of a plugin)', true), + $this->category + ); + $this->error($message); + return false; + } + + $folder = $this->__findFolderByCategory($this->category); + if (!file_exists($folder)) { + $this->err(sprintf(__('%s not found', true), $folder)); + return false; + } + + if (!in_array($this->type, array('all', 'group', 'case'))) { + $this->err(sprintf(__('%s is invalid. Should be case, group or all', true), $this->type)); + return false; + } + + $fileName = $this->__getFileName($folder, $this->isPluginTest); + if ($fileName === true || file_exists($folder . $fileName)) { + return true; + } + + $message = sprintf( + __('%s %s %s is an invalid test identifier', true), + $this->category, $this->type, $this->file + ); + $this->err($message); + return false; + } +/** + * Executes the tests depending on our settings + * + * @return void + * @access private + */ + function __run() { + $Reporter = new CakeCliReporter('utf-8', array( + 'app' => $this->Manager->appTest, + 'plugin' => $this->Manager->pluginTest, + 'group' => ($this->type === 'group'), + 'codeCoverage' => $this->doCoverage + )); + + if ($this->type == 'all') { + return $this->Manager->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', true)); + $this->_stop(0); + } + } + + if ($this->type == 'group') { + $ucFirstGroup = ucfirst($this->file); + if ($this->doCoverage) { + require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php'; + CodeCoverageManager::init($ucFirstGroup, $Reporter); + CodeCoverageManager::start(); + } + $result = $this->Manager->runGroupTest($ucFirstGroup, $Reporter); + return $result; + } + + $folder = $folder = $this->__findFolderByCategory($this->category); + $case = $this->__getFileName($folder, $this->isPluginTest); + + if ($this->doCoverage) { + require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php'; + CodeCoverageManager::init($case, $Reporter); + CodeCoverageManager::start(); + } + $result = $this->Manager->runTestCase($case, $Reporter); + return $result; + } + +/** + * Gets the concrete filename for the inputted test name and category/type + * + * @param string $folder Folder name to look for files in. + * @param boolean $isPlugin If the test case is a plugin. + * @return mixed Either string filename or boolean false on failure. Or true if the type is 'all' + * @access private + */ + function __getFileName($folder, $isPlugin) { + $ext = $this->Manager->getExtension($this->type); + switch ($this->type) { + case 'all': + return true; + case 'group': + return $this->file . $ext; + case 'case': + if ($this->category == 'app' || $isPlugin) { + return $this->file . $ext; + } + $coreCase = $this->file . $ext; + $coreLibCase = 'libs' . DS . $this->file . $ext; + + if ($this->category == 'core' && file_exists($folder . DS . $coreCase)) { + return $coreCase; + } elseif ($this->category == 'core' && file_exists($folder . DS . $coreLibCase)) { + return $coreLibCase; + } + } + return false; + } + +/** + * Finds the correct folder to look for tests for based on the input category and type. + * + * @param string $category The category of the test. Either 'app', 'core' or a plugin name. + * @return string the folder path + * @access private + */ + function __findFolderByCategory($category) { + $folder = ''; + $paths = array( + 'core' => CAKE, + 'app' => APP + ); + $typeDir = $this->type === 'group' ? 'groups' : 'cases'; + + if (array_key_exists($category, $paths)) { + $folder = $paths[$category] . 'tests' . DS . $typeDir . DS; + } else { + $pluginPath = App::pluginPath($category); + if (is_dir($pluginPath . 'tests')) { + $folder = $pluginPath . 'tests' . DS . $typeDir . DS; + } + } + return $folder; + } + +/** + * 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.', true)); + exit; + } + } +}