Merge remote branch 'origin/2.0' into 2.0-class-loading

Conflicts:
	cake/bootstrap.php
	lib/Cake/Console/Command/TestSuiteShell.php
	lib/Cake/Console/TaskCollection.php
	lib/Cake/Controller/ComponentCollection.php
	lib/Cake/Controller/Controller.php
	lib/Cake/Core/App.php
	lib/Cake/Model/BehaviorCollection.php
	lib/Cake/Network/CakeRequest.php
	lib/Cake/TestSuite/CakeTestSuiteDispatcher.php
	lib/Cake/TestSuite/CakeWebTestCase.php
	lib/Cake/TestSuite/TestManager.php
	lib/Cake/TestSuite/TestRunner.php
	lib/Cake/View/HelperCollection.php
	lib/Cake/tests/cases/libs/model/datasources/dbo/dbo_postgres.test.php
	lib/Cake/tests/cases/libs/test_manager.test.php
This commit is contained in:
José Lorenzo Rodríguez 2011-02-13 23:10:19 -04:30
commit 6e4f4efb79
57 changed files with 853 additions and 876 deletions

View file

@ -27,15 +27,6 @@
*/
class DbAclSchema extends CakeSchema {
public $name = 'DbAcl';
function before($event = array()) {
return true;
}
function after($event = array()) {
}
public $acos = array(
'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
'parent_id' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),

View file

@ -27,15 +27,6 @@
*/
class i18nSchema extends CakeSchema {
public $name = 'i18n';
function before($event = array()) {
return true;
}
function after($event = array()) {
}
public $i18n = array(
'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'),

View file

@ -27,15 +27,6 @@
*/
class SessionsSchema extends CakeSchema {
public $name = 'Sessions';
function before($event = array()) {
return true;
}
function after($event = array()) {
}
public $cake_sessions = array(
'id' => array('type'=>'string', 'null' => false, 'key' => 'primary'),
'data' => array('type'=>'text', 'null' => true, 'default' => NULL),

View file

@ -0,0 +1,141 @@
<?php
class CakeTestLoader implements PHPUnit_Runner_TestSuiteLoader {
/**
* Load a file and find the first test case / suite in that file.
*
* @param string $filePath
* @param string $params
* @return ReflectionClass
*/
public function load($filePath, $params = '') {
$file = $this->_resolveTestFile($filePath, $params);
PHPUnit_Util_Class::collectStart();
PHPUnit_Util_Fileloader::checkAndLoad($file, false);
$loadedClasses = PHPUnit_Util_Class::collectEnd();
if (!empty($loadedClasses)) {
$testCaseClass = 'PHPUnit_Framework_TestCase';
foreach ($loadedClasses as $loadedClass) {
$class = new ReflectionClass($loadedClass);
$classFile = $class->getFileName();
if ($class->isSubclassOf($testCaseClass) &&
!$class->isAbstract()) {
$suiteClassName = $loadedClass;
$testCaseClass = $loadedClass;
if ($classFile == realpath($file)) {
break;
}
}
if ($class->hasMethod('suite')) {
$method = $class->getMethod('suite');
if (!$method->isAbstract() &&
$method->isPublic() &&
$method->isStatic()) {
$suiteClassName = $loadedClass;
if ($classFile == realpath($file)) {
break;
}
}
}
}
}
if (class_exists($suiteClassName, FALSE)) {
$class = new ReflectionClass($suiteClassName);
if ($class->getFileName() == realpath($file)) {
return $class;
}
}
}
/**
* Reload method.
*
* @param ReflectionClass $aClass
* @return void
*/
public function reload(ReflectionClass $aClass) {
return $aClass;
}
/**
* Convert path fragments used by Cake's test runner to absolute paths that can be fed to PHPUnit.
*
* @return void
*/
protected function _resolveTestFile($filePath, $params) {
$basePath = $this->_basePath($params) . DS . $filePath;
$ending = '.test.php';
return (strpos($basePath, $ending) === (strlen($basePath) - strlen($ending))) ? $basePath : $basePath . $ending;
}
/**
* Generates the base path to a set of tests based on the parameters.
*
* @param array $params
* @return string The base path.
*/
protected static function _basePath($params) {
$result = null;
if (!empty($params['core'])) {
$result = CORE_TEST_CASES;
} elseif (!empty($params['app'])) {
$result = APP_TEST_CASES;
} else if (!empty($params['plugin'])) {
$pluginPath = App::pluginPath($params['plugin']);
$result = $pluginPath . 'tests' . DS . 'cases';
}
return $result;
}
/**
* Get the list of files for the test listing.
*
* @return void
*/
public static function generateTestList($params) {
$directory = self::_basePath($params);
$fileList = self::_getRecursiveFileList($directory);
$testCases = array();
foreach ($fileList as $testCaseFile) {
$testCases[$testCaseFile] = str_replace($directory . DS, '', $testCaseFile);
}
return $testCases;
}
/**
* Gets a recursive list of files from a given directory and matches then against
* a given fileTestFunction, like isTestCaseFile()
*
* @param string $directory The directory to scan for files.
* @param mixed $fileTestFunction
*/
protected static function _getRecursiveFileList($directory = '.') {
$fileList = array();
if (!is_dir($directory)) {
return $fileList;
}
$files = new RegexIterator(
new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)),
'/.*\.test.php$/'
);
foreach ($files as $file) {
$fileList[] = $file->getPathname();
}
return $fileList;
}
}

View file

@ -0,0 +1,93 @@
<?php
/**
* TestRunner for CakePHP Test suite.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
require 'PHPUnit/TextUI/TestRunner.php';
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
/**
* A custom test runner for Cake's use of PHPUnit.
*
* @package cake.tests.lib
*/
class CakeTestRunner extends PHPUnit_TextUI_TestRunner {
/**
* Lets us pass in some options needed for cake's webrunner.
*
* @return void
*/
public function __construct($loader, $params) {
parent::__construct($loader);
$this->_params = $params;
}
/**
* Actually run a suite of tests. Cake initializes fixtures here using the chosen fixture manager
*
* @param PHPUnit_Framework_Test $suite
* @param array $arguments
* @return void
*/
public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array()) {
if (isset($arguments['printer'])) {
self::$versionStringPrinted = true;
}
$fixture = $this->_getFixtureManager($arguments);
foreach ($suite->getIterator() as $test) {
if ($test instanceof CakeTestCase) {
$fixture->fixturize($test);
$test->fixtureManager = $fixture;
}
}
$return = parent::doRun($suite, $arguments);
$fixture->shutdown();
return $return;
}
/**
* Create the test result and splice on our code coverage reports.
*
* @return PHPUnit_Framework_TestResult
*/
protected function createTestResult() {
$result = new PHPUnit_Framework_TestResult;
if (isset($this->_params['codeCoverage'])) {
$result->collectCodeCoverageInformation(true);
}
return $result;
}
/**
* Get the fixture manager class specified or use the default one.
*
* @return instance of a fixture manager.
*/
protected function _getFixtureManager($arguments) {
if (isset($arguments['fixtureManager'])) {
if (App::import('Lib', 'test_suite/' . Inflector::underscore($arguments['fixtureManager']))) {
return new $arguments['fixtureManager'];
}
throw new RuntimeException(__('Could not find fixture manager %s.', $arguments['fixtureManager']));
}
if (App::import('Lib', 'test_suite/AppFixtureManager')) {
return new AppFixtureManager();
}
return new CakeFixtureManager();
}
}

View file

@ -0,0 +1,175 @@
<?php
/**
* TestRunner for CakePHP Test suite.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake.tests.libs
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
define('CORE_TEST_CASES', TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'cases');
define('APP_TEST_CASES', TESTS . 'cases');
require 'PHPUnit/TextUI/Command.php';
require_once CAKE_TESTS_LIB . 'cake_test_runner.php';
require_once CAKE_TESTS_LIB . 'cake_test_loader.php';
require_once CAKE_TESTS_LIB . 'cake_test_suite.php';
require_once CAKE_TESTS_LIB . 'cake_test_case.php';
require_once CAKE_TESTS_LIB . 'controller_test_case.php';
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
/**
* Class to customize loading of test suites from CLI
*
* @package cake.tests.lib
*/
class CakeTestSuiteCommand extends PHPUnit_TextUI_Command {
/**
* Construct method
*
* @param array $params list of options to be used for this run
*/
public function __construct($loader, $params = array()) {
$this->arguments['loader'] = $loader;
$this->arguments['test'] = $params['case'];
$this->arguments['testFile'] = $params;
$this->_params = $params;
$this->longOptions['fixture='] = 'handleFixture';
$this->longOptions['output='] = 'handleReporter';
}
/**
* Ugly hack to get around PHPUnit having a hard coded classname for the Runner. :(
*
* @param array $argv
* @param boolean $exit
*/
public function run(array $argv, $exit = true) {
$this->handleArguments($argv);
$runner = $this->getRunner($this->arguments['loader']);
if (is_object($this->arguments['test']) &&
$this->arguments['test'] instanceof PHPUnit_Framework_Test) {
$suite = $this->arguments['test'];
} else {
$suite = $runner->getTest(
$this->arguments['test'],
$this->arguments['testFile'],
$this->arguments['syntaxCheck']
);
}
if (count($suite) == 0) {
$skeleton = new PHPUnit_Util_Skeleton_Test(
$suite->getName(),
$this->arguments['testFile']
);
$result = $skeleton->generate(true);
if (!$result['incomplete']) {
eval(str_replace(array('<?php', '?>'), '', $result['code']));
$suite = new PHPUnit_Framework_TestSuite(
$this->arguments['test'] . 'Test'
);
}
}
if ($this->arguments['listGroups']) {
PHPUnit_TextUI_TestRunner::printVersionString();
print "Available test group(s):\n";
$groups = $suite->getGroups();
sort($groups);
foreach ($groups as $group) {
print " - $group\n";
}
exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
}
unset($this->arguments['test']);
unset($this->arguments['testFile']);
try {
$result = $runner->doRun($suite, $this->arguments);
}
catch (PHPUnit_Framework_Exception $e) {
print $e->getMessage() . "\n";
}
if ($exit) {
if (isset($result) && $result->wasSuccessful()) {
exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
}
else if (!isset($result) || $result->errorCount() > 0) {
exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
}
else {
exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
}
}
}
/**
* Create a runner for the command.
*
* @param $loader The loader to be used for the test run.
* @return CakeTestRunner
*/
public function getRunner($loader) {
return new CakeTestRunner($loader, $this->_params);
}
/**
* Handler for customizing the FixtureManager class/
*
* @param string $class Name of the class that will be the fixture manager
* @return void
*/
public function handleFixture($class) {
$this->arguments['fixtureManager'] = $class;
}
/**
* Handles output flag used to change printing on webrunner.
*
* @return void
*/
public function handleReporter($reporter) {
$object = null;
$type = strtolower($reporter);
$coreClass = 'Cake' . ucwords($reporter) . 'Reporter';
$coreFile = CAKE_TESTS_LIB . 'reporter/cake_' . $type . '_reporter.php';
$appClass = $reporter . 'Reporter';
$appFile = APPLIBS . 'test_suite/reporter/' . $type . '_reporter.php';
if (include_once $coreFile) {
$object = new $coreClass(null, $this->_params);
} elseif (include_once $appFile) {
$object = new $appClass(null, $this->_params);
}
return $this->arguments['printer'] = $object;
}
}

View file

@ -145,8 +145,13 @@ class SchemaShell extends Shell {
}
}
$cacheDisable = Configure::read('Cache.disable');
Configure::write('Cache.disable', true);
$content = $this->Schema->read($options);
$content['file'] = $this->params['file'];
Configure::write('Cache.disable', $cacheDisable);
if ($snapshot === true) {
$Folder = new Folder($this->Schema->path);

View file

@ -284,9 +284,13 @@ class ControllerTask extends BakeTask {
$singularName = Inflector::variable($currentModelName);
$singularHumanName = $this->_singularHumanName($controllerName);
$pluralHumanName = $this->_pluralName($controllerName);
$displayField = $modelObj->displayField;
$primaryKey = $modelObj->primaryKey;
$this->Template->set(compact('plugin', 'admin', 'controllerPath', 'pluralName', 'singularName', 'singularHumanName',
'pluralHumanName', 'modelObj', 'wannaUseSession', 'currentModelName'));
$this->Template->set(compact('plugin', 'admin', 'controllerPath', 'pluralName', 'singularName',
'singularHumanName', 'pluralHumanName', 'modelObj', 'wannaUseSession', 'currentModelName',
'displayField', 'primaryKey'
));
$actions = $this->Template->generate('actions', 'controller_actions');
return $actions;
}

View file

@ -58,8 +58,9 @@ class TemplateTask extends Shell {
$core = array_pop($paths);
$separator = DS === '/' ? '/' : '\\\\';
$core = preg_replace('#shells' . $separator . '$#', '', $core);
$paths[] = $core;
$Folder = new Folder($core . 'templates' . DS . 'default');
$contents = $Folder->read();
$themeFolders = $contents[0];
@ -68,6 +69,7 @@ class TemplateTask extends Shell {
$paths[] = $this->_pluginPath($plugin) . 'console' . DS . 'shells' . DS;
$paths[] = $this->_pluginPath($plugin) . 'vendors' . DS . 'shells' . DS;
}
$paths[] = $core;
// TEMPORARY TODO remove when all paths are DS terminated
foreach ($paths as $i => $path) {

View file

@ -148,6 +148,8 @@ class TestSuiteShell extends Shell {
))->addOption('directive', array(
'help' => __('key[=value] Sets a php.ini value.'),
'default' => false
))->addOption('fixture', array(
'help' => __('Choose a custom fixture manager.'),
));
return $parser;
@ -161,6 +163,7 @@ class TestSuiteShell extends Shell {
public function initialize() {
$this->_dispatcher = new CakeTestSuiteDispatcher();
$this->_dispatcher->loadTestFramework();
require_once CAKE . 'tests' . DS . 'lib' . DS . 'cake_test_suite_command.php';
}
/**
@ -173,6 +176,7 @@ class TestSuiteShell extends Shell {
return;
}
$params = array(
'core' => false,
'app' => false,
'plugin' => null,
'output' => 'text',
@ -180,7 +184,9 @@ class TestSuiteShell extends Shell {
$category = $this->args[0];
if ($category == 'app') {
if ($category == 'core') {
$params['core'] = true;
} elseif ($category == 'app') {
$params['app'] = true;
} elseif ($category != 'core') {
$params['plugin'] = $category;
@ -249,7 +255,7 @@ class TestSuiteShell extends Shell {
restore_error_handler();
restore_error_handler();
$testCli = new TestRunner($runnerArgs);
$testCli = new CakeTestSuiteCommand('CakeTestLoader', $runnerArgs);
$testCli->run($options);
}
@ -260,7 +266,7 @@ class TestSuiteShell extends Shell {
*/
public function available() {
$params = $this->parseArgs();
$testCases = TestManager::getTestCaseList($params);
$testCases = CakeTestLoader::generateTestList($params);
$app = $params['app'];
$plugin = $params['plugin'];

View file

@ -630,7 +630,10 @@ class Shell extends Object {
* @return boolean Success
*/
protected function _checkUnitTest() {
if (App::import('vendor', 'simpletest' . DS . 'simpletest')) {
if (App::import('Vendor', 'phpunit', array('file' => 'PHPUnit' . DS . 'Autoload.php'))) {
return true;
}
if (@include 'PHPUnit' . DS . 'Autoload.php') {
return true;
}
$prompt = 'PHPUnit is not installed. Do you want to bake unit test files anyway?';

View file

@ -15,8 +15,11 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
<<<<<<< HEAD:lib/Cake/Console/TaskCollection.php
App::uses('ObjectCollection', 'Utility');
=======
>>>>>>> origin/2.0:cake/console/libs/task_collection.php
class TaskCollection extends ObjectCollection {
/**
* Shell to use to set params to tasks.

View file

@ -159,7 +159,7 @@ class EmailComponent extends Component {
/**
* Line feed character(s) to be used when sending using mail() function
* If null PHP_EOL is used.
* By default PHP_EOL is used.
* RFC2822 requires it to be CRLF but some Unix
* mail transfer agents replace LF by CRLF automatically
* (which leads to doubling CR if CRLF is used).
@ -167,7 +167,7 @@ class EmailComponent extends Component {
* @var string
* @access public
*/
var $lineFeed = null;
var $lineFeed = PHP_EOL;
/**
* @deprecated see lineLength
@ -824,13 +824,8 @@ class EmailComponent extends Component {
* @access private
*/
function _mail() {
if ($this->lineFeed === null) {
$lineFeed = PHP_EOL;
} else {
$lineFeed = $this->lineFeed;
}
$header = implode($lineFeed, $this->_header);
$message = implode($lineFeed, $this->_message);
$header = implode($this->lineFeed, $this->_header);
$message = implode($this->lineFeed, $this->_message);
if (is_array($this->to)) {
$to = implode(', ', array_map(array($this, '_formatAddress'), $this->to));
} else {

View file

@ -691,7 +691,7 @@ class SecurityComponent extends Component {
$tokenData = array();
if ($this->Session->check('_Token')) {
$tokenData = $this->Session->read('_Token');
if (!empty($tokenData['csrfTokens'])) {
if (!empty($tokenData['csrfTokens']) && is_array($tokenData['csrfTokens'])) {
$token['csrfTokens'] = $this->_expireTokens($tokenData['csrfTokens']);
}
}

View file

@ -15,6 +15,7 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('ObjectCollection', 'Utility');
App::uses('Component', 'Controller');

View file

@ -31,12 +31,12 @@ App::uses('View', 'View');
* automatic model availability, redirection, callbacks, and more.
*
* Controllers should provide a number of 'action' methods. These are public methods on the controller
* that are not prefixed with a '_' and not part of Controller. Each action serves as an endpoint for
* that are not prefixed with a '_' and not part of Controller. Each action serves as an endpoint for
* performing a specific action on a resource or collection of resources. For example adding or editing a new
* object, or listing a set of objects.
*
* You can access request parameters, using `$this->request`. The request object contains all the POST, GET and FILES
* that were part of the request.
* that were part of the request.
*
* After performing the required actions, controllers are responsible for creating a response. This usually
* takes the form of a generated View, or possibly a redirection to another controller action. In either case
@ -86,7 +86,7 @@ class Controller extends Object {
/**
* An instance of a CakeRequest object that contains information about the current request.
* This object contains all the information about a request and several methods for reading
* additional information about the request.
* additional information about the request.
*
* @var CakeRequest
*/
@ -134,6 +134,15 @@ class Controller extends Object {
*/
public $modelNames = array();
/**
* The name of the view file to render. The name specified
* is the filename in /app/views/<sub_folder> without the .ctp extension.
*
* @var string
* @link http://book.cakephp.org/view/962/Page-related-Attributes-layout-and-pageTitle
*/
public $view = null;
/**
* The name of the layout file to render the view inside of. The name specified
* is the filename of the layout in /app/views/layouts without the .ctp
@ -182,7 +191,7 @@ class Controller extends Object {
*
* @var string
*/
public $view = 'View';
public $viewClass = 'View';
/**
* Instance of the View created during rendering. Won't be set until after Controller::render() is called.
@ -425,7 +434,7 @@ class Controller extends Object {
}
$plugin = $pluginName . '.';
}
if (is_subclass_of($this, $this->_mergeParent) || !empty($pluginController)) {
$appVars = get_class_vars($this->_mergeParent);
$uses = $appVars['uses'];
@ -441,7 +450,7 @@ class Controller extends Object {
array_unshift($this->uses, $plugin . $this->modelClass);
}
} elseif (
($this->uses !== null || $this->uses !== false) &&
($this->uses !== null || $this->uses !== false) &&
is_array($this->uses) && !empty($appVars['uses'])
) {
$this->uses = array_merge($this->uses, array_diff($appVars['uses'], $this->uses));
@ -453,7 +462,7 @@ class Controller extends Object {
$merge = array('components', 'helpers');
$appVars = get_class_vars($pluginController);
if (
($this->uses !== null || $this->uses !== false) &&
($this->uses !== null || $this->uses !== false) &&
is_array($this->uses) && !empty($appVars['uses'])
) {
$this->uses = array_merge($this->uses, array_diff($appVars['uses'], $this->uses));
@ -630,7 +639,7 @@ class Controller extends Object {
extract($status, EXTR_OVERWRITE);
}
$response = $this->Components->trigger(
'beforeRedirect',
'beforeRedirect',
array(&$this, $url, $status, $exit),
array('break' => true, 'breakOn' => false, 'collectReturn' => true)
);
@ -809,18 +818,17 @@ class Controller extends Object {
/**
* Instantiates the correct view class, hands it its data, and uses it to render the view output.
*
* @param string $action Action name to render
* @param string $view View to use for rendering
* @param string $layout Layout to use
* @param string $file File to use for rendering
* @return string Full output string of view contents
* @link http://book.cakephp.org/view/980/render
*/
public function render($action = null, $layout = null, $file = null) {
public function render($view = null, $layout = null) {
$this->beforeRender();
$this->Components->trigger('beforeRender', array(&$this));
$viewClass = $this->view;
if ($this->view != 'View') {
$viewClass = $this->viewClass;
if ($this->viewClass != 'View') {
list($plugin, $viewClass) = pluginSplit($viewClass, true);
$viewClass = $viewClass . 'View';
App::uses($viewClass, $plugin . 'View');
@ -859,7 +867,7 @@ class Controller extends Object {
$this->autoRender = false;
$this->View = $View;
return $this->response->body($View->render($action, $layout, $file));
return $this->response->body($View->render($view, $layout));
}
/**

View file

@ -711,7 +711,7 @@ class App {
if (empty(self::$search)) {
return null;
} elseif (is_string(self::$search)) {
$this->search = array(self::$search);
self::$search = array(self::$search);
}
if (empty(self::$__paths)) {

View file

@ -93,15 +93,16 @@ class Configure {
} else {
$duration = '+999 days';
}
$cacheConfigs = Cache::configured();
if (Cache::config('_cake_core_') === false) {
if (!in_array('_cake_core_', $cacheConfigs)) {
Cache::config('_cake_core_', array_merge((array)$cache['settings'], array(
'prefix' => $prefix . 'cake_core_', 'path' => $path . DS . 'persistent' . DS,
'serialize' => true, 'duration' => $duration
)));
}
if (Cache::config('_cake_model_') === false) {
if (!in_array('_cake_model_', $cacheConfigs)) {
Cache::config('_cake_model_', array_merge((array)$cache['settings'], array(
'prefix' => $prefix . 'cake_model_', 'path' => $path . DS . 'models' . DS,
'serialize' => true, 'duration' => $duration

View file

@ -101,6 +101,9 @@ class ExceptionRenderer {
if ($exception instanceof CakeException && !$methodExists) {
$method = '_cakeError';
if (empty($template)) {
$template = 'error500';
}
if ($template == 'internalError') {
$template = 'error500';
}

View file

@ -18,6 +18,7 @@
* @since CakePHP(tm) v 1.2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('ObjectCollection', 'Utility');
/**

View file

@ -28,7 +28,7 @@ App::uses('ConnectionManager', 'Model');
class CakeSchema extends Object {
/**
* Name of the App Schema
* Name of the schema
*
* @var string
* @access public
@ -266,11 +266,16 @@ class CakeSchema extends Object {
}
if (is_object($Object->$class)) {
$withTable = $db->fullTableName($Object->$class, false);
if ($prefix && strpos($withTable, $prefix) !== 0) {
continue;
}
if (in_array($withTable, $currentTables)) {
$key = array_search($withTable, $currentTables);
$tables[$withTable] = $this->__columns($Object->$class);
$tables[$withTable]['indexes'] = $db->index($Object->$class);
$tables[$withTable]['tableParameters'] = $db->readTableParameters($withTable);
$noPrefixWith = str_replace($prefix, '', $withTable);
$tables[$noPrefixWith] = $this->__columns($Object->$class);
$tables[$noPrefixWith]['indexes'] = $db->index($Object->$class);
$tables[$noPrefixWith]['tableParameters'] = $db->readTableParameters($withTable);
unset($currentTables[$key]);
}
}
@ -340,8 +345,6 @@ class CakeSchema extends Object {
$out = "class {$name}Schema extends CakeSchema {\n";
$out .= "\tvar \$name = '{$name}';\n\n";
if ($path !== $this->path) {
$out .= "\tvar \$path = '{$path}';\n\n";
}
@ -577,6 +580,7 @@ class CakeSchema extends Object {
public function __columns(&$Obj) {
$db = ConnectionManager::getDataSource($Obj->useDbConfig);
$fields = $Obj->schema(true);
$columns = $props = array();
foreach ($fields as $name => $value) {
if ($Obj->primaryKey == $name) {

View file

@ -300,6 +300,9 @@ class Mysql extends DboSource {
}
$fields = false;
$cols = $this->_execute('SHOW FULL COLUMNS FROM ' . $this->fullTableName($model));
if (!$cols) {
throw new CakeException(__('Could not describe table for %s', $model->name));
}
foreach ($cols as $column) {
$fields[$column->Field] = array(
@ -611,7 +614,7 @@ class Mysql extends DboSource {
}
}
$result->closeCursor();
if (is_string($name)) {
if (is_string($name) && isset($tables[$name])) {
return $tables[$name];
}
return $tables;

View file

@ -242,6 +242,9 @@ class Postgres extends DboSource {
$this->_sequenceMap[$table][$c->default] = $seq[1];
}
}
if ($fields[$c->name]['type'] == 'boolean' && !empty($fields[$c->name]['default'])) {
$fields[$c->name]['default'] = constant($fields[$c->name]['default']);
}
}
$this->__cacheDescription($table, $fields);
}

View file

@ -705,7 +705,7 @@ class DboSource extends DataSource {
);
}
if (
preg_match('/^([\w-]+(\.[\w-]+|\(.*\))*)\s+' . preg_quote($this->alias) . '\s*([\w-]+)$/', $data, $matches
preg_match('/^([\w-]+(\.[\w-]+|\(.*\))*)\s+' . preg_quote($this->alias) . '\s*([\w-]+)$/i', $data, $matches
)) {
return $this->cacheMethod(
__FUNCTION__, $cacheKey,

View file

@ -332,9 +332,9 @@ class Model extends Object {
public $__backAssociation = array();
public $__backInnerAssociation = array();
public $__backOriginalAssociation = array();
public $__backContainableAssociation = array();
/**
@ -361,6 +361,14 @@ class Model extends Object {
*/
private $__affectedRows = null;
/**
* Has the datasource been configured.
*
* @var boolean
* @see Model::getDataSource
*/
private $__sourceConfigured = false;
/**
* List of valid finder method options, supplied as the first parameter to find().
*
@ -458,16 +466,14 @@ class Model extends Object {
$this->Behaviors = new BehaviorCollection();
if ($this->useTable !== false) {
if ($this->useTable === null) {
$this->useTable = Inflector::tableize($this->name);
}
$this->setSource($this->useTable);
if ($this->displayField == null) {
unset($this->displayField);
}
$this->table = $this->useTable;
$this->tableToModel[$this->table] = $this->alias;
} elseif ($this->table === false) {
$this->table = Inflector::tableize($this->name);
}
@ -1067,7 +1073,7 @@ class Model extends Object {
}
/**
* Check that a method is callable on a model. This will check both the model's own methods, its
* Check that a method is callable on a model. This will check both the model's own methods, its
* inherited methods and methods that could be callable through behaviors.
*
* @param string $method The method to be called.
@ -1146,11 +1152,11 @@ class Model extends Object {
if ($data !== null && $data !== false) {
foreach ($this->schema() as $field => $properties) {
if ($this->primaryKey !== $field && isset($properties['default'])) {
if ($this->primaryKey !== $field && isset($properties['default']) && $properties['default'] !== '') {
$defaults[$field] = $properties['default'];
}
}
$this->set(Set::filter($defaults));
$this->set($defaults);
$this->set($data);
}
if ($filterKey) {
@ -2156,7 +2162,7 @@ class Model extends Object {
if ($query['callbacks'] === true || $query['callbacks'] === 'before') {
$return = $this->Behaviors->trigger(
'beforeFind',
'beforeFind',
array(&$this, $query),
array('break' => true, 'breakOn' => array(false, null), 'modParams' => 1)
);
@ -2321,7 +2327,6 @@ class Model extends Object {
*/
protected function _findNeighbors($state, $query, $results = array()) {
if ($state == 'before') {
$query = array_merge(array('recursive' => 0), $query);
extract($query);
$conditions = (array)$conditions;
if (isset($field) && isset($value)) {
@ -2889,14 +2894,12 @@ class Model extends Object {
/**
* Gets the DataSource to which this model is bound.
* Not safe for use with some versions of PHP4, because this class is overloaded.
*
* @return object A DataSource object
*/
public function getDataSource() {
static $configured = false;
if (!$configured && $this->useTable !== false) {
$configured = true;
if (!$this->__sourceConfigured && $this->useTable !== false) {
$this->__sourceConfigured = true;
$this->setSource($this->useTable);
}
return ConnectionManager::getDataSource($this->useDbConfig);

View file

@ -15,6 +15,7 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Set', 'Utility');
/**
@ -275,10 +276,9 @@ class CakeRequest implements ArrayAccess {
if (empty($base)) {
$base = $this->base;
}
if ($base !== false) {
$this->webroot = $base . '/';
return $base;
return $this->base = $base;
}
if (empty($baseUrl)) {
$replace = array('<', '>', '*', '\'', '"');
@ -305,9 +305,13 @@ class CakeRequest implements ArrayAccess {
if ($base === DS || $base === '.') {
$base = '';
}
$this->webroot = $base .'/';
$this->webroot = $base . '/';
if (!empty($base)) {
$docRoot = env('DOCUMENT_ROOT');
$script = realpath(env('SCRIPT_FILENAME'));
$docRootContainsWebroot = strpos($docRoot, $dir . '/' . $webroot);
if (!empty($base) || !$docRootContainsWebroot) {
if (strpos($this->webroot, $dir) === false) {
$this->webroot .= $dir . '/' ;
}

View file

@ -16,25 +16,10 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
class CakeTestSuite extends PHPUnit_Framework_TestSuite {
/**
* Instance of a fixture manager
* @var CakeFixtureManager
*/
protected $_fixtureManager = null;
/**
* Sets the intances for the fixture manager that will be used by this class.
*
* @param CakeFixtureManager $manager the instance of the manager class
* @return void
* @access public
*/
public function setFixtureManager(CakeFixtureManager $manager) {
$this->_fixtureManager = $manager;
}
/**
* Adds all the files in a directory to the test suite. Does not recurse through directories.
*
@ -71,36 +56,4 @@ class CakeTestSuite extends PHPUnit_Framework_TestSuite {
}
}
/**
* Method that is called before the tests of this test suite are run.
* It will load fixtures accordingly for each test.
*
* @return void
* @access protected
*/
protected function setUp() {
parent::setUp();
if (!$this->_fixtureManager) {
return;
}
foreach ($this->getIterator() as $test) {
if ($test instanceof CakeTestCase) {
$this->_fixtureManager->fixturize($test);
$test->fixtureManager = $this->_fixtureManager;
}
}
}
/**
* Method that is called after all the tests of this test suite are run.
*
* @return void
* @access protected
*/
protected function tearDown() {
parent::tearDown();
if ($this->_fixtureManager) {
$this->_fixtureManager->shutDown();
}
}
}

View file

@ -17,7 +17,6 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('TestManager', 'TestSuite');
/**
* CakeTestSuiteDispatcher handles web requests to the test suite and runs the correct action.
*
@ -37,23 +36,9 @@ class CakeTestSuiteDispatcher {
'output' => 'html',
'show' => 'groups',
'show_passes' => false,
'filter' => false
'filter' => false,
'fixture' => null
);
/**
* The classname for the TestManager being used
*
* @var string
*/
protected $_managerClass = 'TestManager';
/**
* The Instance of the Manager being used.
*
* @var TestManager subclass
*/
public $Manager;
/**
* Baseurl for the request
*
@ -102,6 +87,8 @@ class CakeTestSuiteDispatcher {
$this->_checkPHPUnit();
$this->_parseParams();
require_once CAKE . 'tests' . DS . 'lib' . DS . 'cake_test_suite_command.php';
if ($this->params['case']) {
$value = $this->_runTestCase();
} else {
@ -186,49 +173,14 @@ class CakeTestSuiteDispatcher {
* @return void
*/
function _testCaseList() {
$Reporter =& $this->getReporter();
$command = new CakeTestSuiteCommand('', $this->params);
$Reporter = $command->handleReporter($this->params['output']);
$Reporter->paintDocumentStart();
$Reporter->paintTestMenu();
$Reporter->testCaseList();
$Reporter->paintDocumentEnd();
}
/**
* Sets the Manager to use for the request.
*
* @return string The manager class name
* @static
*/
function &getManager() {
if (empty($this->Manager)) {
$this->Manager = new $this->_managerClass($this->params);
}
return $this->Manager;
}
/**
* Gets the reporter based on the request parameters
*
* @return void
* @static
*/
function &getReporter() {
if (!self::$_Reporter) {
$type = strtolower($this->params['output']);
$coreClass = 'Cake' . ucwords($this->params['output']) . 'Reporter';
$appClass = $this->params['output'] . 'Reporter';
App::uses($coreClass, 'TestSuite/Reporter');
App::uses($appClass, 'TestSuite/Reporter');
if (class_exists($coreClass)) {
self::$_Reporter = new $coreClass(null, $this->params);
} elseif (class_exists($appClass)) {
self::$_Reporter = new $appClass(null, $this->params);
}
}
return self::$_Reporter;
}
/**
* Sets the params, calling this will bypass the auto parameter parsing.
*
@ -260,9 +212,11 @@ class CakeTestSuiteDispatcher {
$this->_checkXdebug();
}
}
if (empty($this->params['plugin']) && empty($this->params['app'])) {
$this->params['core'] = true;
}
$this->params['baseUrl'] = $this->_baseUrl;
$this->params['baseDir'] = $this->_baseDir;
$this->getManager();
}
/**
@ -271,9 +225,26 @@ class CakeTestSuiteDispatcher {
* @return void
*/
function _runTestCase() {
$commandArgs = array(
'case' => $this->params['case'],
'core' =>$this->params['core'],
'app' => $this->params['app'],
'plugin' => $this->params['plugin'],
'codeCoverage' => $this->params['codeCoverage'],
'baseUrl' => $this->_baseUrl,
'baseDir' => $this->_baseDir,
);
$options = array(
'--filter', $this->params['filter'],
'--output', $this->params['output'],
'--fixture', $this->params['fixture']
);
restore_error_handler();
try {
$Reporter = CakeTestSuiteDispatcher::getReporter();
return $this->Manager->runTestCase($this->params['case'], $Reporter, $this->params['codeCoverage']);
$command = new CakeTestSuiteCommand('CakeTestLoader', $commandArgs);
$result = $command->run($options);
} catch (MissingConnectionException $exception) {
ob_end_clean();
$baseDir = $this->_baseDir;

View file

@ -1,26 +0,0 @@
<?php
/**
* CakeWebTestCase a simple wrapper around WebTestCase
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT 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.tests.lib
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Simple wrapper for the WebTestCase provided by SimpleTest
*
* @package cake.tests.lib
*/
class CakeWebTestCase extends WebTestCase {
}

View file

@ -16,6 +16,7 @@
* @since CakePHP(tm) v 1.3
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
require_once 'PHPUnit/TextUi/ResultPrinter.php';
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
@ -25,31 +26,9 @@ PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
* @package cake
* @package cake.tests.lib
*/
class CakeBaseReporter implements PHPUnit_Framework_TestListener {
class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* Time the test runs started.
*
* @var integer
* @access protected
*/
protected $_timeStart = 0;
/**
* Time the test runs ended
*
* @var integer
* @access protected
*/
protected $_timeEnd = 0;
/**
* Duration of all test methods.
*
* @var integer
* @access protected
*/
protected $_timeDuration = 0;
protected $_headerSent = false;
/**
* Array of request parameters. Usually parsed GET params.
@ -70,6 +49,7 @@ class CakeBaseReporter implements PHPUnit_Framework_TestListener {
* The number of assertions done for a test suite
*/
protected $numAssertions = 0;
/**
* Does nothing yet. The first output will
* be sent on the first test start.
@ -100,7 +80,7 @@ class CakeBaseReporter implements PHPUnit_Framework_TestListener {
* @return mixed
*/
public function testCaseList() {
$testList = TestManager::getTestCaseList($this->params);
$testList = CakeTestLoader::generateTestList($this->params);
return $testList;
}
@ -146,6 +126,10 @@ class CakeBaseReporter implements PHPUnit_Framework_TestListener {
return '';
}
public function printResult(PHPUnit_Framework_TestResult $result) {
$this->paintFooter($result);
}
public function paintResult(PHPUnit_Framework_TestResult $result) {
$this->paintFooter($result);
}
@ -200,6 +184,9 @@ class CakeBaseReporter implements PHPUnit_Framework_TestListener {
* @param PHPUnit_Framework_TestSuite $suite
*/
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
if (!$this->_headerSent) {
echo $this->paintHeader();
}
echo __('Running %s', $suite->getName()) . "\n";
}

View file

@ -36,6 +36,7 @@ class CakeHtmlReporter extends CakeBaseReporter {
* @return void
*/
public function paintHeader() {
$this->_headerSent = true;
$this->sendNoCacheHeaders();
$this->paintDocumentStart();
$this->paintTestMenu();
@ -139,10 +140,8 @@ class CakeHtmlReporter extends CakeBaseReporter {
echo "<strong>" . $result->errorCount() . "</strong> exceptions.";
echo "</div>\n";
echo '<div style="padding:0 0 5px;">';
echo '<p><strong>Time taken by tests (in seconds):</strong> ' . $result->time() . '</p>';
if (function_exists('memory_get_peak_usage')) {
echo '<p><strong>Peak memory use: (in bytes):</strong> ' . number_format(memory_get_peak_usage()) . '</p>';
}
echo '<p><strong>Time:</strong> ' . $result->time() . ' seconds</p>';
echo '<p><strong>Peak memory:</strong> ' . number_format(memory_get_peak_usage()) . ' bytes</p>';
echo $this->_paintLinks();
echo '</div>';
if (isset($this->params['codeCoverage']) && $this->params['codeCoverage']) {
@ -271,7 +270,7 @@ class CakeHtmlReporter extends CakeBaseReporter {
$testName = get_class($test) . '(' . $test->getName() . ')';
echo "<li class='fail'>\n";
echo "<span>Exception</span>";
echo "<span>" . get_class($message) . "</span>";
echo "<div class='msg'>" . $this->_htmlEntities($message->getMessage()) . "</div>\n";
echo "<div class='msg'>" . __('Test case: %s', $testName) . "</div>\n";
@ -340,6 +339,9 @@ class CakeHtmlReporter extends CakeBaseReporter {
* @param PHPUnit_Framework_TestSuite $suite
*/
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
if (!$this->_headerSent) {
echo $this->paintHeader();
}
echo '<h2>' . __('Running %s', $suite->getName()) . '</h2>';
}
}

View file

@ -87,10 +87,9 @@ class CakeTextReporter extends CakeBaseReporter {
', Failures: ' . $result->failureCount() .
', Exceptions: ' . $result->errorCount() . "\n";
echo 'Time taken by tests (in seconds): ' . $result->time() . "\n";
if (function_exists('memory_get_peak_usage')) {
echo 'Peak memory use: (in bytes): ' . number_format(memory_get_peak_usage()) . "\n";
}
echo 'Time: ' . $result->time() . " seconds\n";
echo 'Peak memory: ' . number_format(memory_get_peak_usage()) . " bytes\n";
if (isset($this->params['codeCoverage']) && $this->params['codeCoverage']) {
$coverage = $result->getCodeCoverageInformation();
echo $this->paintCoverage($coverage);
@ -129,8 +128,7 @@ class CakeTextReporter extends CakeBaseReporter {
* @return void
*/
public function paintSkip($message) {
parent::paintSkip($message);
echo "Skip: $message\n";
printf("Skip: %s\n", $message->getMessage());
}
/**

View file

@ -1,301 +0,0 @@
<?php
/**
* TestManager for CakePHP Test suite.
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT 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.tests.lib
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
define('CORE_TEST_CASES', LIBS . 'tests' . DS . 'cases');
define('CORE_TEST_GROUPS', LIBS . 'tests' . DS . 'groups');
define('APP_TEST_CASES', TESTS . 'cases');
define('APP_TEST_GROUPS', TESTS . 'groups');
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
App::uses('CakeTestSuite', 'TestSuite');
App::uses('CakeTestCase', 'TestSuite');
App::uses('ControllerTestCase', 'TestSuite');
App::uses('CakeFixtureManager', 'TestSuite/Fixture');
App::uses('CakeTestModel', 'TestSuite/Fixture');
/**
* TestManager is the base class that handles loading and initiating the running
* of TestCase and TestSuite classes that the user has selected.
*
* @package cake.tests.lib
*/
class TestManager {
/**
* Extension suffix for test case files.
*
* @var string
*/
protected static $_testExtension = '.test.php';
/**
* Is this test an AppTest?
*
* @var boolean
*/
public $appTest = false;
/**
* Is this test a plugin test?
*
* @var mixed boolean false or string name of the plugin being used.
*/
public $pluginTest = false;
/**
* String to filter test case method names by.
*
* @var string
*/
public $filter = false;
/**
* TestSuite container for single or grouped test files
*
* @var PHPUnit_Framework_TestSuite
*/
protected $_testSuite = null;
/**
* Object instance responsible for managing the test fixtures
*
* @var CakeFixtureManager
*/
protected $_fixtureManager = null;
/**
* Params to configure test runner
*
* @var CakeFixtureManager
*/
public $params = array();
/**
* Constructor for the TestManager class
*
* @return void
*/
public function __construct($params = array()) {
$this->params = $params;
if (isset($params['app'])) {
$this->appTest = true;
}
if (isset($params['plugin'])) {
$this->pluginTest = htmlentities($params['plugin']);
}
if (
isset($params['filter']) &&
$params['filter'] !== false &&
preg_match('/^[a-zA-Z0-9_]/', $params['filter'])
) {
$this->filter = '/' . $params['filter'] . '/';
}
}
/**
* Runs a specific test case file
*
* @param string $testCaseFile Filename of the test to be run.
* @param PHPUnit_Framework_TestListener $reporter Reporter instance to attach to the test case.
* @throws InvalidArgumentException if the supplied $testCaseFile does not exists
* @return mixed Result of test case being run.
*/
public function runTestCase($testCaseFile, PHPUnit_Framework_TestListener $reporter, $codeCoverage = false) {
$this->loadCase($testCaseFile);
return $this->run($reporter, $codeCoverage);
}
/**
* Runs the main testSuite and attaches to it a reporter
*
* @param PHPUnit_Framework_TestListener $reporter Reporter instance to use with the group test being run.
* @return PHPUnit_Framework_TestResult Result object of the test run.
*/
protected function run($reporter, $codeCoverage = false) {
restore_error_handler();
restore_error_handler();
$result = new PHPUnit_Framework_TestResult;
$result->collectCodeCoverageInformation($codeCoverage);
$result->addListener($reporter);
$reporter->paintHeader();
$testSuite = $this->getTestSuite();
$testSuite->setFixtureManager($this->getFixtureManager());
$testSuite->run($result, $this->filter);
$reporter->paintResult($result);
return $result;
}
/**
* Loads a test case in a test suite, if the test suite is null it will create it
*
* @param string Test file path
* @param PHPUnit_Framework_TestSuite $suite the test suite to load the case in
* @throws InvalidArgumentException if test case file is not found
* @return PHPUnit_Framework_TestSuite the suite with the test case loaded
*/
public function loadCase($testCaseFile, PHPUnit_Framework_TestSuite $suite = null) {
$testCaseFileWithPath = $this->_getTestsPath($this->params) . DS . $testCaseFile;
if (!file_exists($testCaseFileWithPath) || strpos($testCaseFileWithPath, '..')) {
throw new InvalidArgumentException(__('Unable to load test file %s', htmlentities($testCaseFile)));
}
if (!$suite) {
$suite = $this->getTestSuite(__('Individual test case: %s', $testCaseFile));
}
$suite->addTestFile($testCaseFileWithPath);
return $suite;
}
/**
* Returns a list of test cases found in the current valid test case path
*
* @access public
* @static
*/
public static function getTestCaseList($params) {
$directory = self::_getTestsPath($params);
$fileList = self::_getTestFileList($directory);
$testCases = array();
foreach ($fileList as $testCaseFile) {
$testCases[$testCaseFile] = str_replace($directory . DS, '', $testCaseFile);
}
return $testCases;
}
/**
* Returns a list of test files from a given directory
*
* @param string $directory Directory to get test case files from.
* @static
*/
protected static function &_getTestFileList($directory = '.') {
$return = self::_getRecursiveFileList($directory, array('self', '_isTestCaseFile'));
return $return;
}
/**
* Gets a recursive list of files from a given directory and matches then against
* a given fileTestFunction, like isTestCaseFile()
*
* @param string $directory The directory to scan for files.
* @param mixed $fileTestFunction
* @static
*/
protected static function &_getRecursiveFileList($directory = '.', $fileTestFunction) {
$fileList = array();
if (!is_dir($directory)) {
return $fileList;
}
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
foreach ($files as $file) {
if (!$file->isFile()) {
continue;
}
$file = $file->getRealPath();
if (call_user_func_array($fileTestFunction, array($file))) {
$fileList[] = $file;
}
}
return $fileList;
}
/**
* Tests if a file has the correct test case extension
*
* @param string $file
* @return boolean Whether $file is a test case.
* @static
*/
protected static function _isTestCaseFile($file) {
return self::_hasExpectedExtension($file, self::$_testExtension);
}
/**
* Check if a file has a specific extension
*
* @param string $file
* @param string $extension
* @return void
* @static
*/
protected static function _hasExpectedExtension($file, $extension) {
return $extension == strtolower(substr($file, (0 - strlen($extension))));
}
/**
* Returns the given path to the test files depending on a given type of tests (core, app, plugin)
*
* @param array $params Array of parameters for getting test paths.
* Can contain app, type, and plugin params.
* @return string The path tests are located on
* @static
*/
protected static function _getTestsPath($params) {
$result = null;
if (!empty($params['app'])) {
$result = APP_TEST_CASES;
} else if (!empty($params['plugin'])) {
$pluginPath = App::pluginPath($params['plugin']);
$result = $pluginPath . 'tests' . DS . 'cases';
} else {
$result = CORE_TEST_CASES;
}
return $result;
}
/**
* Get the extension for either 'group' or 'test' types.
*
* @param string $type Type of test to get, either 'test' or 'group'
* @return string Extension suffix for test.
*/
public static function getExtension($type = 'test') {
return self::$_testExtension;
}
/**
* Get the container testSuite instance for this runner or creates a new one
*
* @param string $name The name for the container test suite
* @return PHPUnit_Framework_TestSuite container test suite
*/
public function getTestSuite($name = '') {
if (!empty($this->_testSuite)) {
return $this->_testSuite;
}
return $this->_testSuite = new CakeTestSuite($name);
}
/**
* Get an instance of a Fixture manager to be used by the test cases
*
* @return CakeFixtureManager fixture manager
*/
public function getFixtureManager() {
if (!empty($this->_fixtureManager)) {
return $this->_fixtureManager;
}
return $this->_fixtureManager = new CakeFixtureManager;
}
}

View file

@ -1,57 +0,0 @@
<?php
/**
* TestRunner for CakePHP Test suite.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake.tests.libs
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
require 'PHPUnit/TextUI/Command.php';
App::uses('TestManager', 'TestSuite');
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
/**
* Class to customize loading of test suites from CLI
*
* @package cake.tests.lib
*/
class TestRunner extends PHPUnit_TextUI_Command {
/**
* Construct method
*
* @param array $params list of options to be used for this run
*/
public function __construct($params = array()) {
$this->_params = $params;
}
/**
* Sets the proper test suite to use and loads the test file in it.
* this method gets called as a callback from the parent class
*
* @return void
*/
protected function handleCustomTestSuite() {
$manager = new TestManager($this->_params);
if (!empty($this->_params['case'])) {
$this->arguments['test'] = $manager->getTestSuite();
$this->arguments['test']->setFixtureManager($manager->getFixtureManager());
$manager->loadCase($this->_params['case'] . '.test.php', $this->arguments['test']);
}
}
}

View file

@ -243,9 +243,10 @@ class CacheHelper extends AppHelper {
$controller->layout = $this->layout = \'' . $this->_View->layout. '\';
$controller->request = $this->request = unserialize(\'' . str_replace("'", "\\'", serialize($this->request)) . '\');
$controller->theme = $this->theme = \'' . $this->_View->theme . '\';
$controller->viewVars = $this->viewVars = ' . var_export($this->_View->viewVars, true) . ';
$controller->viewVars = unserialize(base64_decode(\'' . base64_encode(serialize($this->_View->viewVars)) . '\'));
Router::setRequestInfo($controller->request);';
if ($useCallbacks == true) {
$file .= '
$controller->constructClasses();

View file

@ -262,7 +262,7 @@ class FormHelper extends AppHelper {
$options['id'] = $this->domId($options['action'] . 'Form');
}
$options['action'] = array_merge($actionDefaults, (array)$options['url']);
if (empty($options['action'][0])) {
if (empty($options['action'][0]) && !empty($id)) {
$options['action'][0] = $id;
}
} elseif (is_string($options['url'])) {
@ -1850,8 +1850,11 @@ class FormHelper extends AppHelper {
if ($time[0] == 0 && $timeFormat == '12') {
$time[0] = 12;
}
$hour = $time[0];
$min = $time[1];
$hour = $min = null;
if (isset($time[1])) {
$hour = $time[0];
$min = $time[1];
}
}
}
}
@ -2199,10 +2202,19 @@ class FormHelper extends AppHelper {
} else {
$secure = (isset($this->request['_Token']) && !empty($this->request['_Token']));
}
$fieldName = null;
if ($secure && !empty($options['name'])) {
preg_match_all('/\[(.*?)\]/', $options['name'], $matches);
if (isset($matches[1])) {
$fieldName = $matches[1];
}
}
$result = parent::_initInputField($field, $options);
if ($secure) {
$this->__secure();
$this->__secure($fieldName);
}
return $result;
}

View file

@ -38,11 +38,11 @@ class HtmlHelper extends AppHelper {
'metalink' => '<link href="%s"%s/>',
'link' => '<a href="%s"%s>%s</a>',
'mailto' => '<a href="mailto:%s" %s>%s</a>',
'form' => '<form %s>',
'form' => '<form%s>',
'formend' => '</form>',
'input' => '<input name="%s" %s/>',
'textarea' => '<textarea name="%s" %s>%s</textarea>',
'hidden' => '<input type="hidden" name="%s" %s/>',
'input' => '<input name="%s"%s/>',
'textarea' => '<textarea name="%s"%s>%s</textarea>',
'hidden' => '<input type="hidden" name="%s"%s/>',
'checkbox' => '<input type="checkbox" name="%s" %s/>',
'checkboxmultiple' => '<input type="checkbox" name="%s[]"%s />',
'radio' => '<input type="radio" name="%s" id="%s" %s />%s',

View file

@ -15,6 +15,7 @@
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('ObjectCollection', 'Utility');
class HelperCollection extends ObjectCollection {
@ -43,7 +44,7 @@ class HelperCollection extends ObjectCollection {
*
* You can alias your helper as an existing helper by setting the 'className' key, i.e.,
* {{{
* public $components = array(
* public $helpers = array(
* 'Html' => array(
* 'className' => 'AliasedHtml'
* );

View file

@ -28,9 +28,9 @@ App::uses('Router', 'Routing');
* in from the controller to render the results of the controller action. Often this is HTML,
* but can also take the form of JSON, XML, PDF's or streaming files.
*
* CakePHP uses a two-step-view pattern. This means that the view content is rendered first,
* CakePHP uses a two-step-view pattern. This means that the view content is rendered first,
* and then inserted into the selected layout. A special `$content_for_layout` variable is available
* in the layout, and it contains the rendered view. This also means you can pass data from the view to the
* in the layout, and it contains the rendered view. This also means you can pass data from the view to the
* layout using `$this->set()`
*
* @package cake.libs.view
@ -87,6 +87,13 @@ class View extends Object {
*/
public $viewVars = array();
/**
* Name of view to use with this View.
*
* @var string
*/
public $view = null;
/**
* Name of layout to use with this View.
*
@ -123,7 +130,7 @@ class View extends Object {
* @var string
*/
public $subDir = null;
/**
* Theme name. If you are using themes, you should remember to use ThemeView as well.
*
@ -212,7 +219,7 @@ class View extends Object {
/**
* An instance of a CakeRequest object that contains information about the current request.
* This object contains all the information about a request and several methods for reading
* additional information about the request.
* additional information about the request.
*
* @var CakeRequest
*/
@ -234,7 +241,7 @@ class View extends Object {
* @var array
*/
private $__passedVars = array(
'viewVars', 'autoLayout', 'ext', 'helpers', 'layout', 'name',
'viewVars', 'autoLayout', 'ext', 'helpers', 'view', 'layout', 'name',
'layoutPath', 'viewPath', 'request', 'plugin', 'passedArgs', 'cacheAction'
);
@ -279,7 +286,7 @@ class View extends Object {
/**
* Renders a piece of PHP with provided parameters and returns HTML, XML, or any other string.
*
* This realizes the concept of Elements, (or "partial layouts") and the $params array is used to send
* This realizes the concept of Elements, (or "partial layouts") and the $params array is used to send
* data to be used in the element. Elements can be cached improving performance by using the `cache` option.
*
* ### Special params
@ -353,8 +360,7 @@ class View extends Object {
}
/**
* Renders view for given action and layout. If $file is given, that is used
* for a view filename (e.g. customFunkyView.ctp).
* Renders view for given view file and layout.
*
* Render triggers helper callbacks, which are fired before and after the view are rendered,
* as well as before and after the layout. The helper callbacks are called
@ -366,14 +372,12 @@ class View extends Object {
*
* If View::$autoRender is false and no `$layout` is provided, the view will be returned bare.
*
* @param string $action Name of action to render for, this will be used as the filename to render, unless
* $file is give as well.
* @param string $view Name of view file to use
* @param string $layout Layout to use.
* @param string $file Custom filename for view. Providing this will render a specific file for the given action.
* @return string Rendered Element
* @throws CakeException if there is an error in the view.
*/
public function render($action = null, $layout = null, $file = null) {
public function render($view = null, $layout = null) {
if ($this->hasRendered) {
return true;
}
@ -382,11 +386,7 @@ class View extends Object {
}
$this->output = null;
if ($file != null) {
$action = $file;
}
if ($action !== false && $viewFileName = $this->_getViewFileName($action)) {
if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
$this->Helpers->trigger('beforeRender', array($viewFileName));
$this->output = $this->_render($viewFileName);
$this->Helpers->trigger('afterRender', array($viewFileName));
@ -447,7 +447,7 @@ class View extends Object {
}
/**
* Render cached view. Works in concert with CacheHelper and Dispatcher to
* Render cached view. Works in concert with CacheHelper and Dispatcher to
* render cached view files.
*
* @param string $filename the cache file to include
@ -699,7 +699,7 @@ class View extends Object {
}
}
$paths = $this->_paths($this->plugin);
$exts = $this->_getExtensions();
foreach ($exts as $ext) {
foreach ($paths as $path) {

View file

@ -57,27 +57,28 @@ class ApiShellTest extends CakeTestCase {
$expected = array(
'1. afterFilter()',
'2. beforeFilter()',
'3. beforeRender()',
'4. constructClasses()',
'5. disableCache()',
'6. flash($message, $url, $pause = 1, $layout = \'flash\')',
'7. getResponse()',
'8. header($status)',
'9. httpCodes($code = NULL)',
'10. isAuthorized()',
'11. loadModel($modelClass = NULL, $id = NULL)',
'12. paginate($object = NULL, $scope = array (), $whitelist = array ())',
'13. postConditions($data = array (), $op = NULL, $bool = \'AND\', $exclusive = false)',
'14. redirect($url, $status = NULL, $exit = true)',
'15. referer($default = NULL, $local = false)',
'16. render($action = NULL, $layout = NULL, $file = NULL)',
'17. set($one, $two = NULL)',
'18. setAction($action)',
'19. setRequest($request)',
'20. shutdownProcess()',
'21. startupProcess()',
'22. validate()',
'23. validateErrors()'
'3. beforeRedirect($url, $status = NULL, $exit = true)',
'4. beforeRender()',
'5. constructClasses()',
'6. disableCache()',
'7. flash($message, $url, $pause = 1, $layout = \'flash\')',
'8. getResponse()',
'9. header($status)',
'10. httpCodes($code = NULL)',
'11. isAuthorized()',
'12. loadModel($modelClass = NULL, $id = NULL)',
'13. paginate($object = NULL, $scope = array (), $whitelist = array ())',
'14. postConditions($data = array (), $op = NULL, $bool = \'AND\', $exclusive = false)',
'15. redirect($url, $status = NULL, $exit = true)',
'16. referer($default = NULL, $local = false)',
'17. render($action = NULL, $layout = NULL, $file = NULL)',
'18. set($one, $two = NULL)',
'19. setAction($action)',
'20. setRequest($request)',
'21. shutdownProcess()',
'22. startupProcess()',
'23. validate()',
'24. validateErrors()'
);
$this->Shell->expects($this->at(2))->method('out')->with($expected);

View file

@ -438,10 +438,10 @@ class TestTaskTest extends CakeTestCase {
$this->assertContains("App::import('Model', 'TestTaskArticle')", $result);
$this->assertContains('class TestTaskArticleTestCase extends CakeTestCase', $result);
$this->assertContains('function startTest()', $result);
$this->assertContains('function setUp()', $result);
$this->assertContains("\$this->TestTaskArticle = ClassRegistry::init('TestTaskArticle')", $result);
$this->assertContains('function endTest()', $result);
$this->assertContains('function tearDown()', $result);
$this->assertContains('unset($this->TestTaskArticle)', $result);
$this->assertContains('function testDoSomething()', $result);
@ -473,11 +473,11 @@ class TestTaskTest extends CakeTestCase {
$this->assertContains('public $autoRender = false', $result);
$this->assertContains('function redirect($url, $status = null, $exit = true)', $result);
$this->assertContains('function startTest()', $result);
$this->assertContains('function setUp()', $result);
$this->assertContains("\$this->TestTaskComments = new TestTestTaskCommentsController()", $result);
$this->assertContains("\$this->TestTaskComments->constructClasses()", $result);
$this->assertContains('function endTest()', $result);
$this->assertContains('function tearDown()', $result);
$this->assertContains('unset($this->TestTaskComments)', $result);
$this->assertContains("'app.test_task_article'", $result);

View file

@ -97,7 +97,7 @@ class TestSuiteShellTest extends CakeTestCase {
$this->Shell->expects($this->once())->method('run')
->with(
array('app' => false, 'plugin' => null, 'output' => 'text', 'case' => 'basics'),
array('app' => false, 'plugin' => null, 'core' => true, 'output' => 'text', 'case' => 'basics'),
array('--filter', 'myFilter', '--colors', '--verbose')
);
$this->Shell->main();

View file

@ -34,7 +34,6 @@ class AllTestSuiteTest extends PHPUnit_Framework_TestSuite {
public static function suite() {
$suite = new PHPUnit_Framework_TestSuite('All Test Suite classes tests');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'test_manager.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_test_case.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_test_fixture.test.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'html_coverage_report.test.php');

View file

@ -927,12 +927,6 @@ class CakeRequestTestCase extends CakeTestCase {
$this->assertEqual($request->base, '/app/index.php');
$this->assertEqual($request->webroot, '/app/webroot/');
Configure::write('App.baseUrl', '/index.php');
$request = new CakeRequest();
$this->assertEqual($request->base, '/index.php');
$this->assertEqual($request->webroot, '/');
Configure::write('App.baseUrl', '/CakeBB/app/webroot/index.php');
$request = new CakeRequest();
$this->assertEqual($request->base, '/CakeBB/app/webroot/index.php');
@ -959,21 +953,51 @@ class CakeRequestTestCase extends CakeTestCase {
$this->assertEqual($request->webroot, '/dbhauser/app/webroot/');
}
/**
* test baseUrl with no rewrite and using the top level index.php.
*
* @return void
*/
function testBaseUrlNoRewriteTopLevelIndex() {
Configure::write('App.baseUrl', '/index.php');
$_SERVER['DOCUMENT_ROOT'] = '/Users/markstory/Sites/cake_dev';
$_SERVER['SCRIPT_FILENAME'] = '/Users/markstory/Sites/cake_dev/index.php';
$request = new CakeRequest();
$this->assertEqual('/index.php', $request->base);
$this->assertEqual('/app/webroot/', $request->webroot);
}
/**
* test baseUrl with no rewrite, and using the app/webroot/index.php file as is normal with virtual hosts.
*
* @return void
*/
function testBaseUrlNoRewriteWebrootIndex() {
Configure::write('App.baseUrl', '/index.php');
$_SERVER['DOCUMENT_ROOT'] = '/Users/markstory/Sites/cake_dev/app/webroot';
$_SERVER['SCRIPT_FILENAME'] = '/Users/markstory/Sites/cake_dev/app/webroot/index.php';
$request = new CakeRequest();
$this->assertEqual('/index.php', $request->base);
$this->assertEqual('/', $request->webroot);
}
/**
* testEnvironmentDetection method
*
* @return void
*/
public function testEnvironmentDetection() {
$dispatcher = new Dispatcher();
$environments = array(
'IIS' => array(
'No rewrite base path' => array(
'App' => array(
'base' => false,
'baseUrl' => '/index.php?',
'server' => 'IIS'
'server' => 'IIS',
'dir' => 'app',
'webroot' => 'webroot'
),
'SERVER' => array(
'HTTPS' => 'off',
@ -985,29 +1009,24 @@ class CakeRequestTestCase extends CakeTestCase {
'REQUEST_METHOD' => 'GET',
'SERVER_NAME' => 'localhost',
'SERVER_PORT' => '80',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'SERVER_SOFTWARE' => 'Microsoft-IIS/5.1',
'APPL_PHYSICAL_PATH' => 'C:\\Inetpub\\wwwroot\\',
'REQUEST_URI' => '/index.php',
'URL' => '/index.php',
'SCRIPT_FILENAME' => 'C:\\Inetpub\\wwwroot\\index.php',
'ORIG_PATH_INFO' => '/index.php',
'PATH_INFO' => '',
'ORIG_PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot\\index.php',
'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot',
'PHP_SELF' => '/index.php',
'HTTP_ACCEPT' => '*/*',
'HTTP_ACCEPT_LANGUAGE' => 'en-us',
'HTTP_CONNECTION' => 'Keep-Alive',
'HTTP_HOST' => 'localhost',
'HTTP_USER_AGENT' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)',
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'SERVER_SOFTWARE' => 'Microsoft-IIS/5.1',
'APPL_PHYSICAL_PATH' => 'C:\\Inetpub\\wwwroot\\',
'REQUEST_URI' => '/index.php',
'URL' => '/index.php',
'SCRIPT_FILENAME' => 'C:\\Inetpub\\wwwroot\\index.php',
'ORIG_PATH_INFO' => '/index.php',
'PATH_INFO' => '',
'ORIG_PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot\\index.php',
'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot',
'PHP_SELF' => '/index.php',
'HTTP_HOST' => 'localhost',
'argv' => array(),
'argc' => 0
),
'reload' => true,
'base' => '/index.php?',
'webroot' => '/',
'webroot' => '/app/webroot/',
'url' => ''
),
'No rewrite with path' => array(
@ -1021,7 +1040,7 @@ class CakeRequestTestCase extends CakeTestCase {
'reload' => false,
'url' => 'posts/add',
'base' => '/index.php?',
'webroot' => '/'
'webroot' => '/app/webroot/'
),
'No rewrite sub dir 1' => array(
'GET' => array(),
@ -1041,7 +1060,7 @@ class CakeRequestTestCase extends CakeTestCase {
'reload' => false,
'url' => '',
'base' => '/index.php?',
'webroot' => '/'
'webroot' => '/app/webroot/'
),
'No rewrite sub dir 1 with path' => array(
'GET' => array('/posts/add' => ''),
@ -1056,7 +1075,7 @@ class CakeRequestTestCase extends CakeTestCase {
'reload' => false,
'url' => 'posts/add',
'base' => '/index.php?',
'webroot' => '/'
'webroot' => '/app/webroot/'
),
'No rewrite sub dir 2' => array(
'App' => array(
@ -1118,7 +1137,7 @@ class CakeRequestTestCase extends CakeTestCase {
'SERVER_ADDR' => '::1',
'SERVER_PORT' => '80',
'REMOTE_ADDR' => '::1',
'DOCUMENT_ROOT' => '/Library/WebServer/Documents/officespace/app/webroot',
'DOCUMENT_ROOT' => '/Library/WebServer/Documents/site/app/webroot',
'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/app/webroot/index.php',
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => '',
@ -1135,15 +1154,9 @@ class CakeRequestTestCase extends CakeTestCase {
),
'No rewrite with path' => array(
'SERVER' => array(
'UNIQUE_ID' => 'VardGqn@17IAAAu7LY8AAAAK',
'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-us) AppleWebKit/523.10.5 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6',
'HTTP_ACCEPT' => 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
'HTTP_ACCEPT_LANGUAGE' => 'en-us',
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',
'HTTP_CONNECTION' => 'keep-alive',
'HTTP_HOST' => 'localhost',
'DOCUMENT_ROOT' => '/Library/WebServer/Documents/officespace/app/webroot',
'SCRIPT_FILENAME' => '/Library/WebServer/Documents/officespace/app/webroot/index.php',
'DOCUMENT_ROOT' => '/Library/WebServer/Documents/site/app/webroot',
'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/app/webroot/index.php',
'QUERY_STRING' => '',
'REQUEST_URI' => '/index.php/posts/add',
'SCRIPT_NAME' => '/index.php',
@ -1165,11 +1178,6 @@ class CakeRequestTestCase extends CakeTestCase {
'webroot' => 'webroot'
),
'SERVER' => array(
'UNIQUE_ID' => '2A-v8sCoAQ8AAAc-2xUAAAAB',
'HTTP_ACCEPT_LANGUAGE' => 'en-us',
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',
'HTTP_COOKIE' => 'CAKEPHP=jcbv51apn84kd9ucv5aj2ln3t3',
'HTTP_CONNECTION' => 'keep-alive',
'HTTP_HOST' => 'cake.1.2',
'SERVER_NAME' => 'cake.1.2',
'SERVER_ADDR' => '127.0.0.1',

View file

@ -438,6 +438,9 @@ TEMPDOC;
* @return void
*/
function testSmtpSendMultipleTo() {
if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
return;
}
$this->Controller->EmailTest->reset();
$this->Controller->EmailTest->to = array('postmaster@localhost', 'root@localhost');
$this->Controller->EmailTest->from = 'noreply@example.com';

View file

@ -134,7 +134,7 @@ class ControllerCommentsController extends ControllerTestAppController {
* @access public
*/
public $name = 'ControllerComments';
protected $_mergeParent = 'ControllerTestAppController';
}
@ -277,7 +277,7 @@ class TestController extends ControllerTestAppController {
* @access public
*/
public $uses = array('ControllerComment', 'ControllerAlias');
protected $_mergeParent = 'ControllerTestAppController';
/**
@ -343,7 +343,7 @@ class TestComponent extends Object {
*/
function beforeRender(&$controller) {
if ($this->viewclass) {
$controller->view = $this->viewclass;
$controller->viewClass = $this->viewclass;
}
}
}
@ -368,7 +368,7 @@ class AnotherTestController extends ControllerTestAppController {
* @access public
*/
public $uses = null;
protected $_mergeParent = 'ControllerTestAppController';
}
@ -627,7 +627,7 @@ class ControllerTest extends CakeTestCase {
$Controller->set(array(1 => 'one', 2 => 'two'));
$expected = array(3 => 'three', 4 => 'four', 1 => 'one', 2 => 'two');
$this->assertEqual($Controller->viewVars, $expected);
}
/**
@ -641,7 +641,7 @@ class ControllerTest extends CakeTestCase {
'views' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'views'. DS)
), true);
$request = new CakeRequest('controller_posts/index');
$request->params['action'] = 'index';
$Controller = new Controller($request, $this->getMock('CakeResponse'));
$Controller->viewPath = 'posts';
@ -649,8 +649,13 @@ class ControllerTest extends CakeTestCase {
$result = $Controller->render('index');
$this->assertPattern('/posts index/', $result);
$Controller->view = 'index';
$result = $Controller->render();
$this->assertPattern('/posts index/', $result);
$result = $Controller->render('/elements/test_element');
$this->assertPattern('/this is the test element/', $result);
$Controller->view = null;
$Controller = new TestController($request);
$Controller->helpers = array('Html');
@ -986,7 +991,7 @@ class ControllerTest extends CakeTestCase {
$this->assertEqual($result, '/posts/index');
$request = $this->getMock('CakeRequest');
$request->expects($this->any())->method('referer')
->with(false)
->will($this->returnValue('http://localhost/posts/index'));

View file

@ -560,8 +560,21 @@ class ExceptionRendererTest extends CakeTestCase {
'/(\/|\\\)sidebox.php/'
),
500
),
array(
new Exception('boom'),
array(
'/Internal Error/'
),
500
),
array(
new RuntimeException('another boom'),
array(
'/Internal Error/'
),
500
)
);
}

View file

@ -210,6 +210,7 @@ class TestAppSchema extends CakeSchema {
public $datatypes = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => '', 'collate' => null, 'comment' => null),
'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
'tableParameters' => array()
);

View file

@ -795,6 +795,21 @@ class DboMysqlTest extends CakeTestCase {
$this->assertEqual($tables, array('cake_table', 'another_table'));
}
/**
* test that listDetailedSources with a named table that doesn't exist.
*
* @return void
*/
function testListDetailedSourcesNamed() {
$this->loadFixtures('Apple');
$result = $this->Dbo->listDetailedSources('imaginary');
$this->assertEquals(array(), $result, 'Should be empty when table does not exist.');
$result = $this->Dbo->listDetailedSources();
$this->assertTrue(isset($result['apples']), 'Key should exist');
}
/**
* Tests that getVersion method sends the correct query for getting the mysql version
* @return void

View file

@ -218,6 +218,7 @@ class DboPostgresTest extends CakeTestCase {
*/
public $fixtures = array('core.user', 'core.binary_test', 'core.comment', 'core.article',
'core.tag', 'core.articles_tag', 'core.attachment', 'core.person', 'core.post', 'core.author',
'core.datatype',
);
/**
* Actual DB connection used in testing
@ -413,6 +414,19 @@ class DboPostgresTest extends CakeTestCase {
$this->assertEquals(false, $this->Dbo2->boolean('', false));
}
/**
* test that default -> false in schemas works correctly.
*
* @return void
*/
function testBooleanDefaultFalseInSchema() {
$this->loadFixtures('Datatype');
$model = new Model(array('name' => 'Datatype', 'table' => 'datatypes', 'ds' => 'test'));
$model->create();
$this->assertIdentical(false, $model->data['Datatype']['bool']);
}
/**
* testLastInsertIdMultipleInsert method
*
@ -423,18 +437,16 @@ class DboPostgresTest extends CakeTestCase {
$this->loadFixtures('User');
$db1 = ConnectionManager::getDataSource('test');
$db2 = clone $db1;
$db2->connect();
$this->assertNotSame($db1->getConnection(), $db2->getConnection());
$table = $db1->fullTableName('users', false);
$password = '5f4dcc3b5aa765d61d8327deb882cf99';
$db1->execute(
"INSERT INTO {$table} (\"user\", password) VALUES ('mariano', '{$password}')"
);
$db2->execute("INSERT INTO {$table} (\"user\", password) VALUES ('hoge', '{$password}')");
$this->assertEqual($db1->lastInsertId($table), 5);
$this->assertEqual($db2->lastInsertId($table), 6);
$db1->execute("INSERT INTO {$table} (\"user\", password) VALUES ('hoge', '{$password}')");
$this->assertEqual($db1->lastInsertId($table), 6);
}
/**
@ -554,7 +566,8 @@ class DboPostgresTest extends CakeTestCase {
$db1 = ConnectionManager::getDataSource('test');
$db1->cacheSources = false;
$db1->reconnect(array('persistent' => false));
$db1->rawQuery('CREATE TABLE ' . $db1->fullTableName('datatypes') . ' (
$db1->rawQuery('CREATE TABLE ' . $db1->fullTableName('datatype_tests') . ' (
id serial NOT NULL,
"varchar" character varying(40) NOT NULL,
"full_length" character varying NOT NULL,
@ -562,31 +575,34 @@ class DboPostgresTest extends CakeTestCase {
"date" date,
CONSTRAINT test_data_types_pkey PRIMARY KEY (id)
)');
$model = new Model(array('name' => 'Datatype', 'ds' => 'test'));
$model = new Model(array('name' => 'DatatypeTest', 'ds' => 'test'));
$schema = new CakeSchema(array('connection' => 'test'));
$result = $schema->read(array(
'connection' => 'test',
'models' => array('Datatype')
'models' => array('DatatypeTest')
));
$schema->tables = array('datatype_tests' => $result['tables']['missing']['datatype_tests']);
$result = $db1->createSchema($schema, 'datatype_tests');
$schema->tables = array('datatypes' => $result['tables']['missing']['datatypes']);
$result = $db1->createSchema($schema, 'datatypes');
$db1->rawQuery('DROP TABLE ' . $db1->fullTableName('datatypes'));
$this->assertNoPattern('/timestamp DEFAULT/', $result);
$this->assertPattern('/\"full_length\"\s*text\s.*,/', $result);
$this->assertPattern('/timestamp\s*,/', $result);
$db1->query('DROP TABLE ' . $db1->fullTableName('datatype_tests'));
$db1->query($result);
$result2 = $schema->read(array(
'connection' => 'test',
'models' => array('Datatype')
'models' => array('DatatypeTest')
));
$schema->tables = array('datatypes' => $result2['tables']['missing']['datatypes']);
$result2 = $db1->createSchema($schema, 'datatypes');
$schema->tables = array('datatype_tests' => $result2['tables']['missing']['datatype_tests']);
$result2 = $db1->createSchema($schema, 'datatype_tests');
$this->assertEqual($result, $result2);
$db1->query('DROP TABLE ' . $db1->fullTableName('datatypes'));
$db1->query('DROP TABLE ' . $db1->fullTableName('datatype_tests'));
}
/**
@ -600,10 +616,9 @@ class DboPostgresTest extends CakeTestCase {
$this->Dbo->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
$this->Dbo->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
$expected = array(
'PRIMARY' => array('column' => 'id', 'unique' => true),
'pointless_bool' => array('column' => 'bool', 'unique' => false),
'char_index' => array('column' => 'small_char', 'unique' => true),
'PRIMARY' => array('unique' => true, 'column' => 'id'),
'pointless_bool' => array('unique' => false, 'column' => 'bool'),
'char_index' => array('unique' => true, 'column' => 'small_char'),
);
$result = $this->Dbo->index($name);
$this->Dbo->query('DROP TABLE ' . $name);
@ -613,8 +628,8 @@ class DboPostgresTest extends CakeTestCase {
$this->Dbo->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
$this->Dbo->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
$expected = array(
'PRIMARY' => array('column' => 'id', 'unique' => true),
'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => true),
'PRIMARY' => array('unique' => true, 'column' => 'id'),
'multi_col' => array('unique' => true, 'column' => array('small_char', 'bool')),
);
$result = $this->Dbo->index($name);
$this->Dbo->query('DROP TABLE ' . $name);
@ -689,6 +704,7 @@ class DboPostgresTest extends CakeTestCase {
'group2' => array('type' => 'integer', 'null' => true)
)
));
$this->Dbo->rawQuery($this->Dbo->dropSchema($schema1));
$this->Dbo->rawQuery($this->Dbo->createSchema($schema1));
$schema2 = new CakeSchema(array(
@ -700,10 +716,10 @@ class DboPostgresTest extends CakeTestCase {
'group1' => array('type' => 'integer', 'null' => true),
'group2' => array('type' => 'integer', 'null' => true),
'indexes' => array(
'name_idx' => array('column' => 'name', 'unique' => false),
'group_idx' => array('column' => 'group1', 'unique' => false),
'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => false),
'PRIMARY' => array('column' => 'id', 'unique' => true)
'name_idx' => array('unique' => false, 'column' => 'name'),
'group_idx' => array('unique' => false, 'column' => 'group1'),
'compound_idx' => array('unique' => false, 'column' => array('group1', 'group2')),
'PRIMARY' => array('unique' => true, 'column' => 'id')
)
)
));
@ -722,10 +738,10 @@ class DboPostgresTest extends CakeTestCase {
'group1' => array('type' => 'integer', 'null' => true),
'group2' => array('type' => 'integer', 'null' => true),
'indexes' => array(
'name_idx' => array('column' => 'name', 'unique' => true),
'group_idx' => array('column' => 'group2', 'unique' => false),
'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => false),
'another_idx' => array('column' => array('group1', 'name'), 'unique' => false))
'name_idx' => array('unique' => true, 'column' => 'name'),
'group_idx' => array('unique' => false, 'column' => 'group2'),
'compound_idx' => array('unique' => false, 'column' => array('group2', 'group1')),
'another_idx' => array('unique' => false, 'column' => array('group1', 'name')))
)));
$this->Dbo->query($this->Dbo->alterSchema($schema3->compare($schema2)));

View file

@ -583,10 +583,14 @@ class DboSourceTest extends CakeTestCase {
$result = $this->testDb->name(array('my-name', 'Foo-Model.*'));
$expected = array('`my-name`', '`Foo-Model`.*');
$this->assertEqual($result, $expected);
$result = $this->testDb->name(array('Team.P%', 'Team.G/G'));
$expected = array('`Team`.`P%`', '`Team`.`G/G`');
$this->assertEqual($result, $expected);
$result = $this->testDb->name('Model.name as y');
$expected = '`Model`.`name` AS `y`';
$this->assertEqual($result, $expected);
}
/**

View file

@ -3504,11 +3504,14 @@ class ModelReadTest extends BaseModelTest {
$expected = array(
'prev' => null,
'next' => array(
'Article' => array('id' => 2)
'Article' => array('id' => 2),
'Comment' => array(),
'Tag' => array()
));
$this->assertEqual($result, $expected);
$TestModel->id = 2;
$TestModel->recursive = 0;
$result = $TestModel->find('neighbors', array(
'fields' => array('id')
));
@ -3525,12 +3528,14 @@ class ModelReadTest extends BaseModelTest {
$this->assertEqual($result, $expected);
$TestModel->id = 3;
$TestModel->recursive = 1;
$result = $TestModel->find('neighbors', array('fields' => array('id')));
$expected = array(
'prev' => array(
'Article' => array(
'id' => 2
)),
'Article' => array('id' => 2),
'Comment' => array(),
'Tag' => array()
),
'next' => null
);
$this->assertEqual($result, $expected);
@ -4793,7 +4798,7 @@ class ModelReadTest extends BaseModelTest {
}
/**
* test that calling unbindModel() with reset == true multiple times
* test that calling unbindModel() with reset == true multiple times
* leaves associations in the correct state.
*
* @return void

View file

@ -1,110 +0,0 @@
<?php
/**
* TestManagerTest file
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
* Copyright 2005-2010, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT 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.tests.cases.libs
* @since CakePHP(tm) v 1.2.0.4206
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class TestTestManager extends TestManager {
public function setTestSuite($testSuite) {
$this->_testSuite = $testSuite;
}
}
/**
* TestManagerTest class
*
* @package cake.tests.cases.libs
*/
class TestManagerTest extends CakeTestCase {
/**
* Number of times the funcion PHPUnit_Framework_TestSuite::addTestFile() has been called
*
* @var integer
*/
protected $_countFiles = 0;
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->_countFiles = 0;
$this->TestManager = new TestTestManager();
$this->testSuiteStub = $this->getMock('CakeTestSuite');
$this->testSuiteStub
->expects($this->any())
->method('addTestFile')
->will($this->returnCallback(array(&$this, '_countIncludedTestFiles')));
$this->testSuiteStub
->expects($this->any())
->method('addTestSuite')
->will($this->returnCallback(array(&$this, '_countIncludedTestFiles')));
$this->TestManager->setTestSuite($this->testSuiteStub);
$this->Reporter = $this->getMock('CakeHtmlReporter');
}
/**
* Helper method to count the number of times the
* function PHPUnit_Framework_TestSuite::addTestFile() has been called
* @return void
*/
public function _countIncludedTestFiles() {
$this->_countFiles++;
}
protected function _getAllTestFiles($directory = CORE_TEST_CASES, $type = 'test') {
$folder = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
$extension = str_replace('.', '\.', $this->TestManager->getExtension($type));
$out = new RegexIterator($folder, '#^.+'.$extension.'$#i', RecursiveRegexIterator::GET_MATCH);
$files = array();
foreach ($out as $testFile) {
$files[] = $testFile[0];
}
return $files;
}
/**
* Tests that trying to run an unexistent file throws an exception
* @expectedException InvalidArgumentException
*/
public function testRunUnexistentCase() {
$file = md5(time());
$result = $this->TestManager->runTestCase($file, $this->Reporter);
}
/**
* testRunTestCase method
*
* @return void
*/
public function testRunTestCase() {
$file = 'libs/test_manager.test.php';
$result = $this->TestManager->runTestCase($file, $this->Reporter, true);
$this->assertEquals(1, $this->_countFiles);
$this->assertInstanceOf('PHPUnit_Framework_TestResult', $result);
}
}

View file

@ -321,7 +321,6 @@ class CacheHelperTest extends CakeTestCase {
$this->assertPattern('/\$this\-\>viewVars/', $contents);
$this->assertPattern('/extract\(\$this\-\>viewVars, EXTR_SKIP\);/', $contents);
$this->assertPattern('/php echo \$variable/', $contents);
$this->assertPattern('/variableValue/', $contents);
@unlink($filename);
}

View file

@ -667,8 +667,6 @@ class FormHelperTest extends CakeTestCase {
*/
function setUp() {
parent::setUp();
Router::reload();
$this->Controller = new ContactTestController();
$this->View = new View($this->Controller);
@ -709,7 +707,7 @@ class FormHelperTest extends CakeTestCase {
* @return void
*/
function tearDown() {
ClassRegistry::flush();
parent::tearDown();
unset($this->Form->Html, $this->Form, $this->Controller, $this->View);
Configure::write('Security.salt', $this->oldSalt);
}
@ -1081,6 +1079,21 @@ class FormHelperTest extends CakeTestCase {
$this->assertTags($result, $expected);
}
/**
* test securing inputs with custom name attributes.
*
* @return void
*/
function testFormSecureWithCustomNameAttribute() {
$this->Form->request->params['_Token']['key'] = 'testKey';
$this->Form->text('UserForm.published', array('name' => 'data[User][custom]'));
$this->assertEqual('User.custom', $this->Form->fields[0]);
$this->Form->text('UserForm.published', array('name' => 'data[User][custom][another][value]'));
$this->assertEqual('User.custom.another.value', $this->Form->fields[1]);
}
/**
* testFormSecuredInput method
*
@ -4474,6 +4487,16 @@ class FormHelperTest extends CakeTestCase {
$this->assertPattern('/<option[^<>]+value="06"[^<>]+selected="selected"[^>]*>June<\/option>/', $result);
}
/**
* test that bogus non-date time data doesn't cause errors.
*
* @return void
*/
function testDateTimeWithBogusData() {
$result = $this->Form->dateTime('Contact.updated', 'DMY', '12', array('value' => 'CURRENT_TIMESTAMP'));
$this->assertNoPattern('/selected="selected">\d/', $result);
}
/**
* testFormDateTimeMulti method
*
@ -5259,7 +5282,7 @@ class FormHelperTest extends CakeTestCase {
));
$result = $this->Form->postButton('Send', '/', array('data' => array('extra' => 'value')));
$this->assertTrue(strpos($result, '<input type="hidden" name="data[extra]" value="value"/>') !== false);
$this->assertTrue(strpos($result, '<input type="hidden" name="data[extra]" value="value"/>') !== false);
}
/**
@ -5299,7 +5322,7 @@ class FormHelperTest extends CakeTestCase {
));
$result = $this->Form->postLink('Delete', '/posts/delete', array('data' => array('id' => 1)));
$this->assertTrue(strpos($result, '<input type="hidden" name="data[id]" value="1"/>') !== false);
$this->assertTrue(strpos($result, '<input type="hidden" name="data[id]" value="1"/>') !== false);
}
/**
@ -5646,6 +5669,28 @@ class FormHelperTest extends CakeTestCase {
$this->assertTags($result, $expected);
}
/**
* test create() with a custom route
*
* @return void
*/
function testCreateCustomRoute() {
Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
$encoding = strtolower(Configure::read('App.encoding'));
$result = $this->Form->create('User', array('action' => 'login'));
$expected = array(
'form' => array(
'id' => 'UserLoginForm', 'method' => 'post', 'action' => '/login',
'accept-charset' => $encoding
),
'div' => array('style' => 'display:none;'),
'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
'/div'
);
$this->assertTags($result, $expected);
}
/**
* test that inputDefaults are stored and used.
*

View file

@ -1304,7 +1304,7 @@ class HtmlHelperTest extends CakeTestCase {
$result = $this->Html->useTag('formend');
$this->assertTags($result, '/form');
$result = $this->Html->useTag('form', 'test');
$result = $this->Html->useTag('form', ' test');
$this->assertEqual($result, '<form test>');
$result = $this->Html->useTag('form', array('test' => 'ok'));

View file

@ -41,6 +41,7 @@ class DatatypeFixture extends CakeTestFixture {
public $fields = array(
'id' => array('type' => 'integer', 'null'=> false, 'default'=> 0, 'key' => 'primary'),
'float_field' => array('type' => 'float', 'length' => '5,2', 'null' => false, 'default' => null),
'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
);
/**
@ -49,7 +50,7 @@ class DatatypeFixture extends CakeTestFixture {
* @var array
* @access public
*/
public $records = array(
array('id' => 1, 'float_field' => 42.23),
var $records = array(
array('id' => 1, 'float_field' => 42.23, 'bool' => false),
);
}