Subversion-Projekte lars-tiefland.cakephp

Revision

Blame | Letzte Änderung | Log anzeigen | RSS feed

<?php
/* SVN FILE: $Id: testsuite.php 7945 2008-12-19 02:16:01Z gwoo $ */
/**
 * 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>
 * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
 *
 *  Licensed under The Open Group Test Suite License
 *  Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
 * @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
 * @version       $Revision: 7945 $
 * @modifiedby    $LastChangedBy: gwoo $
 * @lastmodified  $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
 * @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;
/**
 * The headline for the test output
 *
 * @var string
 * @access public
 */
        var $headline = 'CakePHP Test Shell';
/**
 * Initialization method installs Simpletest and loads all plugins
 *
 * @return void
 * @access public
 */
        function initialize() {
                $corePath = Configure::corePaths('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 . 'cli_reporter.php';

                $plugins = Configure::listObjects('plugin');
                foreach ($plugins as $p) {
                        $this->plugins[] = Inflector::underscore($p);
                }
        }
/**
 * 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);
                }
        }
/**
 * 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\t cake testsuite app all");
                $this->out("\t\t cake testsuite core all");
                $this->out('');
                $this->out("\t\t cake testsuite app case behaviors/debuggable");
                $this->out("\t\t cake testsuite app case models/my_model");
                $this->out("\t\t cake testsuite app case controllers/my_controller");
                $this->out('');
                $this->out("\t\t cake testsuite core case file");
                $this->out("\t\t cake testsuite core case router");
                $this->out("\t\t cake testsuite core case set");
                $this->out('');
                $this->out("\t\t cake testsuite app group mygroup");
                $this->out("\t\t cake testsuite core group acl");
                $this->out("\t\t cake testsuite core group socket");
                $this->out('');
                $this->out("\t\t cake testsuite bugs case models/bug  // for the plugin 'bugs' and its test case 'bug'");
                $this->out("\t\t cake testsuite bugs group bug  // for the plugin bugs and its test group 'bug'");
                $this->out("\t\t cake testsuite bugs_me case models/bug  // for the plugin 'bugs_me' and its test case 'bug'");
                $this->out("\t\t cake testsuite bugs_me group bug  // for the plugin bugs_me 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) {
                        $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;
                                }

                                if ($this->category == 'core' && file_exists($folder.DS.'cases'.DS.'libs'.DS.$this->file.'.test.php')) {
                                        return true;
                                }

                                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;
        }
/**
 * 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;
                }

                $case = 'libs'.DS.$this->file.'.test.php';
                if ($this->category == 'app') {
                        $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;
        }
/**
 * 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)) {
                        $folder = $paths[$category];
                } else {
                        $folder = APP.'plugins'.DS.Inflector::underscore($category).DS;
                }
                return $folder.'tests';
        }
/**
 * 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;
                }
        }
/**
 * 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;
                }
        }
}
?>