Merge branch '1.2' into 1.3

This commit is contained in:
gwoo 2009-07-02 09:27:00 -07:00
commit bc359259a2
28 changed files with 8705 additions and 1623 deletions

View file

@ -830,7 +830,7 @@ if (!function_exists('file_put_contents')) {
function array_intersect_key($arr1, $arr2) { function array_intersect_key($arr1, $arr2) {
$res = array(); $res = array();
foreach ($arr1 as $key => $value) { foreach ($arr1 as $key => $value) {
if (isset($arr2[$key])) { if (array_key_exists($key, $arr2)) {
$res[$key] = $arr1[$key]; $res[$key] = $arr1[$key];
} }
} }

View file

@ -196,7 +196,7 @@ class ApiShell extends Shell {
$contents = $File->read(); $contents = $File->read();
if (preg_match_all('%(/\\*\\*[\\s\\S]*?\\*/)(\\s+function\\s+\\w+)(\\(.+\\))%', $contents, $result, PREG_PATTERN_ORDER)) { if (preg_match_all('%(/\\*\\*[\\s\\S]*?\\*/)(\\s+function\\s+\\w+)(\\(.*\\))%', $contents, $result, PREG_PATTERN_ORDER)) {
foreach ($result[2] as $key => $method) { foreach ($result[2] as $key => $method) {
$method = str_replace('function ', '', trim($method)); $method = str_replace('function ', '', trim($method));
@ -204,7 +204,7 @@ class ApiShell extends Shell {
$parsed[$method] = array( $parsed[$method] = array(
'comment' => r(array('/*', '*/', '*'), '', trim($result[1][$key])), 'comment' => r(array('/*', '*/', '*'), '', trim($result[1][$key])),
'method' => $method, 'method' => $method,
'parameters' => trim($result[3][$key]), 'parameters' => trim($result[3][$key])
); );
} }
} }

View file

@ -243,8 +243,11 @@ class ControllerTask extends Shell {
* @access private * @access private
*/ */
function bakeActions($controllerName, $admin = null, $wannaUseSession = true) { function bakeActions($controllerName, $admin = null, $wannaUseSession = true) {
$currentModelName = $this->_modelName($controllerName); $currentModelName = $modelImport = $this->_modelName($controllerName);
if (!App::import('Model', $currentModelName)) { if ($this->plugin) {
$modelImport = $this->plugin . '.' . $modelImport;
}
if (!App::import('Model', $modelImport)) {
$this->err(__('You must have a model for this class to build scaffold methods. Please try again.', true)); $this->err(__('You must have a model for this class to build scaffold methods. Please try again.', true));
exit; exit;
} }

View file

@ -168,7 +168,6 @@ class FileEngine extends CacheEngine {
if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) { if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) {
$this->__File->close(); $this->__File->close();
$this->__File->delete();
return false; return false;
} }
$data = $this->__File->read(true); $data = $this->__File->read(true);

View file

@ -263,6 +263,9 @@ class AuthComponent extends Object {
*/ */
function startup(&$controller) { function startup(&$controller) {
$methods = array_flip($controller->methods); $methods = array_flip($controller->methods);
$controllerAction = strtolower($controller->params['action']);
$lowerAllowedActions = array_map('strtolower', $this->allowedActions);
$isErrorOrTests = ( $isErrorOrTests = (
strtolower($controller->name) == 'cakeerror' || strtolower($controller->name) == 'cakeerror' ||
(strtolower($controller->name) == 'tests' && Configure::read() > 0) (strtolower($controller->name) == 'tests' && Configure::read() > 0)
@ -273,7 +276,7 @@ class AuthComponent extends Object {
$isMissingAction = ( $isMissingAction = (
$controller->scaffold === false && $controller->scaffold === false &&
!isset($methods[strtolower($controller->params['action'])]) !isset($methods[$controllerAction])
); );
if ($isMissingAction) { if ($isMissingAction) {
@ -295,7 +298,7 @@ class AuthComponent extends Object {
$isAllowed = ( $isAllowed = (
$this->allowedActions == array('*') || $this->allowedActions == array('*') ||
in_array($controller->params['action'], $this->allowedActions) in_array($controllerAction, $lowerAllowedActions)
); );
if ($loginAction != $url && $isAllowed) { if ($loginAction != $url && $isAllowed) {

View file

@ -674,8 +674,8 @@ class EmailComponent extends Object{
return false; return false;
} }
if (isset($this->smtpOptions['host'])) { if (isset($this->smtpOptions['client'])) {
$host = $this->smtpOptions['host']; $host = $this->smtpOptions['client'];
} else { } else {
$host = env('HTTP_HOST'); $host = env('HTTP_HOST');
} }

View file

@ -389,7 +389,9 @@ class Controller extends Object {
if ($var === 'components') { if ($var === 'components') {
$normal = Set::normalize($this->{$var}); $normal = Set::normalize($this->{$var});
$app = Set::normalize($appVars[$var]); $app = Set::normalize($appVars[$var]);
if ($app !== $normal) {
$this->{$var} = Set::merge($app, $normal); $this->{$var} = Set::merge($app, $normal);
}
} else { } else {
$this->{$var} = Set::merge( $this->{$var} = Set::merge(
$this->{$var}, array_diff($appVars[$var], $this->{$var}) $this->{$var}, array_diff($appVars[$var], $this->{$var})
@ -413,7 +415,9 @@ class Controller extends Object {
if ($var === 'components') { if ($var === 'components') {
$normal = Set::normalize($this->{$var}); $normal = Set::normalize($this->{$var});
$app = Set::normalize($appVars[$var]); $app = Set::normalize($appVars[$var]);
$this->{$var} = Set::merge($normal, array_diff_assoc($app, $normal)); if ($app !== $normal) {
$this->{$var} = Set::merge($app, $normal);
}
} else { } else {
$this->{$var} = Set::merge( $this->{$var} = Set::merge(
$this->{$var}, array_diff($appVars[$var], $this->{$var}) $this->{$var}, array_diff($appVars[$var], $this->{$var})

View file

@ -366,12 +366,13 @@ class File extends Object {
function md5($maxsize = 5) { function md5($maxsize = 5) {
if ($maxsize === true) { if ($maxsize === true) {
return md5_file($this->path); return md5_file($this->path);
} else { }
$size = $this->size(); $size = $this->size();
if ($size && $size < ($maxsize * 1024) * 1024) { if ($size && $size < ($maxsize * 1024) * 1024) {
return md5_file($this->path); return md5_file($this->path);
} }
}
return false; return false;
} }
/** /**

View file

@ -232,20 +232,6 @@ class DboMysqli extends DboMysqlBase {
return $data; return $data;
} }
/**
* Begin a transaction
*
* @param unknown_type $model
* @return boolean True on success, false on fail
* (i.e. if the database/model does not support transactions).
*/
function begin(&$model) {
if (parent::begin($model) && $this->execute('START TRANSACTION')) {
$this->_transactionStarted = true;
return true;
}
return false;
}
/** /**
* Returns a formatted error message from previous database operation. * Returns a formatted error message from previous database operation.
* *

View file

@ -275,6 +275,9 @@ class DboPostgres extends DboSource {
case 'inet': case 'inet':
case 'float': case 'float':
case 'integer': case 'integer':
case 'date':
case 'datetime':
case 'timestamp':
if ($data === '') { if ($data === '') {
return $read ? 'NULL' : 'DEFAULT'; return $read ? 'NULL' : 'DEFAULT';
} }

View file

@ -370,6 +370,10 @@ class Model extends Overloadable {
$this->useTable = $table; $this->useTable = $table;
} }
if ($ds !== null) {
$this->useDbConfig = $ds;
}
if (is_subclass_of($this, 'AppModel')) { if (is_subclass_of($this, 'AppModel')) {
$appVars = get_class_vars('AppModel'); $appVars = get_class_vars('AppModel');
$merge = array('_findMethods'); $merge = array('_findMethods');
@ -1468,7 +1472,7 @@ class Model extends Overloadable {
if (Set::numeric(array_keys($data))) { if (Set::numeric(array_keys($data))) {
while ($validates) { while ($validates) {
foreach ($data as $key => $record) { foreach ($data as $key => $record) {
if (!$currentValidates = $this->__save($this, $record, $options)) { if (!$currentValidates = $this->__save($record, $options)) {
$validationErrors[$key] = $this->validationErrors; $validationErrors[$key] = $this->validationErrors;
} }
@ -1521,7 +1525,7 @@ class Model extends Overloadable {
if (isset($associations[$association])) { if (isset($associations[$association])) {
switch ($associations[$association]) { switch ($associations[$association]) {
case 'belongsTo': case 'belongsTo':
if ($this->__save($this->{$association}, $values, $options)) { if ($this->{$association}->__save($values, $options)) {
$data[$this->alias][$this->belongsTo[$association]['foreignKey']] = $this->{$association}->id; $data[$this->alias][$this->belongsTo[$association]['foreignKey']] = $this->{$association}->id;
} else { } else {
$validationErrors[$association] = $this->{$association}->validationErrors; $validationErrors[$association] = $this->{$association}->validationErrors;
@ -1534,7 +1538,7 @@ class Model extends Overloadable {
} }
} }
} }
if (!$this->__save($this, $data, $options)) { if (!$this->__save($data, $options)) {
$validationErrors[$this->alias] = $this->validationErrors; $validationErrors[$this->alias] = $this->validationErrors;
$validates = false; $validates = false;
} }
@ -1552,7 +1556,7 @@ class Model extends Overloadable {
switch ($type) { switch ($type) {
case 'hasOne': case 'hasOne':
$values[$this->{$type}[$association]['foreignKey']] = $this->id; $values[$this->{$type}[$association]['foreignKey']] = $this->id;
if (!$this->__save($this->{$association}, $values, $options)) { if (!$this->{$association}->__save($values, $options)) {
$validationErrors[$association] = $this->{$association}->validationErrors; $validationErrors[$association] = $this->{$association}->validationErrors;
$validates = false; $validates = false;
} }
@ -1625,12 +1629,12 @@ class Model extends Overloadable {
* @access private * @access private
* @see Model::saveAll() * @see Model::saveAll()
*/ */
function __save(&$model, $data, $options) { function __save($data, $options) {
if ($options['validate'] === 'first' || $options['validate'] === 'only') { if ($options['validate'] === 'first' || $options['validate'] === 'only') {
if (!($model->create($data) && $model->validates($options))) { if (!($this->create($data) && $this->validates($options))) {
return false; return false;
} }
} elseif (!($model->create(null) !== null && $model->save($data, $options))) { } elseif (!($this->create(null) !== null && $this->save($data, $options))) {
return false; return false;
} }
return true; return true;

View file

@ -918,7 +918,7 @@ class Set extends Object {
* to null (useful for Set::merge). You can optionally group the values by what is obtained when * to null (useful for Set::merge). You can optionally group the values by what is obtained when
* following the path specified in $groupPath. * following the path specified in $groupPath.
* *
* @param array $data Array from where to extract keys and values * @param mixed $data Array or object from where to extract keys and values
* @param mixed $path1 As an array, or as a dot-separated string. * @param mixed $path1 As an array, or as a dot-separated string.
* @param mixed $path2 As an array, or as a dot-separated string. * @param mixed $path2 As an array, or as a dot-separated string.
* @param string $groupPath As an array, or as a dot-separated string. * @param string $groupPath As an array, or as a dot-separated string.

View file

@ -264,7 +264,8 @@ class CacheHelper extends AppHelper {
$controller->params = $this->params = unserialize(stripslashes(\'' . addslashes(serialize($this->params)) . '\')); $controller->params = $this->params = unserialize(stripslashes(\'' . addslashes(serialize($this->params)) . '\'));
$controller->action = $this->action = unserialize(\'' . serialize($this->action) . '\'); $controller->action = $this->action = unserialize(\'' . serialize($this->action) . '\');
$controller->data = $this->data = unserialize(stripslashes(\'' . addslashes(serialize($this->data)) . '\')); $controller->data = $this->data = unserialize(stripslashes(\'' . addslashes(serialize($this->data)) . '\'));
$controller->themeWeb = $this->themeWeb = \'' . $this->themeWeb . '\';'; $controller->themeWeb = $this->themeWeb = \'' . $this->themeWeb . '\';
Router::setRequestInfo(array($this->params, array(\'base\' => $this->base, \'webroot\' => $this->webroot)));';
if ($useCallbacks == true) { if ($useCallbacks == true) {
$file .= ' $file .= '
@ -275,7 +276,6 @@ class CacheHelper extends AppHelper {
} }
$file .= ' $file .= '
Router::setRequestInfo(array($this->params, array(\'base\' => $this->base, \'webroot\' => $this->webroot)));
$loadedHelpers = array(); $loadedHelpers = array();
$loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers); $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
foreach (array_keys($loadedHelpers) as $helper) { foreach (array_keys($loadedHelpers) as $helper) {

View file

@ -319,8 +319,104 @@ class JavascriptHelper extends AppHelper {
* @return string Escaped string. * @return string Escaped string.
*/ */
function escapeString($string) { function escapeString($string) {
$escape = array('\n' => '\\\n', "\r\n" => '\n', "\r" => '\n', "\n" => '\n', '"' => '\"', "'" => "\\'"); App::import('Core', 'Multibyte');
return str_replace(array_keys($escape), array_values($escape), $string); $escape = array("\r\n" => "\n", "\r" => "\n");
$string = str_replace(array_keys($escape), array_values($escape), $string);
return $this->_utf8ToHex($string);
}
/**
* Encode a string into JSON. Converts and escapes necessary characters.
*
* @return void
**/
function _utf8ToHex($string) {
$length = strlen($string);
$return = '';
for ($i = 0; $i < $length; ++$i) {
$ord = ord($string{$i});
switch (true) {
case $ord == 0x08:
$return .= '\b';
break;
case $ord == 0x09:
$return .= '\t';
break;
case $ord == 0x0A:
$return .= '\n';
break;
case $ord == 0x0C:
$return .= '\f';
break;
case $ord == 0x0D:
$return .= '\r';
break;
case $ord == 0x22:
case $ord == 0x2F:
case $ord == 0x5C:
case $ord == 0x27:
$return .= '\\' . $string{$i};
break;
case (($ord >= 0x20) && ($ord <= 0x7F)):
$return .= $string{$i};
break;
case (($ord & 0xE0) == 0xC0):
if ($i + 1 >= $length) {
$i += 1;
$return .= '?';
break;
}
$charbits = $string{$i} . $string{$i + 1};
$char = Multibyte::utf8($charbits);
$return .= sprintf('\u%04s', dechex($char[0]));
$i += 1;
break;
case (($ord & 0xF0) == 0xE0):
if ($i + 2 >= $length) {
$i += 2;
$return .= '?';
break;
}
$charbits = $string{$i} . $string{$i + 1} . $string{$i + 2};
$char = Multibyte::utf8($charbits);
$return .= sprintf('\u%04s', dechex($char[0]));
$i += 2;
break;
case (($ord & 0xF8) == 0xF0):
if ($i + 3 >= $length) {
$i += 3;
$return .= '?';
break;
}
$charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3};
$char = Multibyte::utf8($charbits);
$return .= sprintf('\u%04s', dechex($char[0]));
$i += 3;
break;
case (($ord & 0xFC) == 0xF8):
if ($i + 4 >= $length) {
$i += 4;
$return .= '?';
break;
}
$charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4};
$char = Multibyte::utf8($charbits);
$return .= sprintf('\u%04s', dechex($char[0]));
$i += 4;
break;
case (($ord & 0xFE) == 0xFC):
if ($i + 5 >= $length) {
$i += 5;
$return .= '?';
break;
}
$charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4} . $string{$i + 5};
$char = Multibyte::utf8($charbits);
$return .= sprintf('\u%04s', dechex($char[0]));
$i += 5;
break;
}
}
return $return;
} }
/** /**
* Attach an event to an element. Used with the Prototype library. * Attach an event to an element. Used with the Prototype library.

View file

@ -800,7 +800,7 @@ class View extends Object {
} }
} }
$paths = $this->_paths($this->plugin); $paths = $this->_paths(Inflector::underscore($this->plugin));
foreach ($paths as $path) { foreach ($paths as $path) {
if (file_exists($path . $name . $this->ext)) { if (file_exists($path . $name . $this->ext)) {
@ -840,7 +840,7 @@ class View extends Object {
if (!is_null($this->layoutPath)) { if (!is_null($this->layoutPath)) {
$subDir = $this->layoutPath . DS; $subDir = $this->layoutPath . DS;
} }
$paths = $this->_paths($this->plugin); $paths = $this->_paths(Inflector::underscore($this->plugin));
$file = 'layouts' . DS . $subDir . $name; $file = 'layouts' . DS . $subDir . $name;
$exts = array($this->ext, '.ctp', '.thtml'); $exts = array($this->ext, '.ctp', '.thtml');

View file

@ -607,6 +607,9 @@ class XmlNode extends Object {
if (is_array($this->attributes) && count($this->attributes) > 0) { if (is_array($this->attributes) && count($this->attributes) > 0) {
foreach ($this->attributes as $key => $val) { foreach ($this->attributes as $key => $val) {
if (is_bool($val) && $val === false) {
$val = 0;
}
$d .= ' ' . $key . '="' . htmlspecialchars($val, ENT_QUOTES, Configure::read('App.encoding')) . '"'; $d .= ' ' . $key . '="' . htmlspecialchars($val, ENT_QUOTES, Configure::read('App.encoding')) . '"';
} }
} }
@ -682,6 +685,19 @@ class XmlNode extends Object {
$out[$child->name] = $value; $out[$child->name] = $value;
} }
continue; continue;
} elseif (count($child->children) === 0 && $child->value == '') {
$value = $child->attributes;
if (isset($out[$child->name]) || isset($multi[$key])) {
if (!isset($multi[$key])) {
$multi[$key] = array($out[$child->name]);
unset($out[$child->name]);
}
$multi[$key][] = $value;
} else {
$out[$key] = $value;
}
continue;
} else { } else {
$value = $child->toArray($camelize); $value = $child->toArray($camelize);
} }

View file

@ -0,0 +1,118 @@
<?php
/* SVN FILE: $Id$ */
/**
* TestTaskTest file
*
* Test Case for test generation shell task
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework (http://www.cakephp.org)
* Copyright 2006-2008, Cake Software Foundation, Inc.
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.tests.cases.console.libs.tasks
* @since CakePHP v 1.2.0.7726
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Core', 'Shell');
if (!defined('DISABLE_AUTO_DISPATCH')) {
define('DISABLE_AUTO_DISPATCH', true);
}
if (!class_exists('ShellDispatcher')) {
ob_start();
$argv = false;
require CAKE . 'console' . DS . 'cake.php';
ob_end_clean();
}
if (!class_exists('ApiShell')) {
require CAKE . 'console' . DS . 'libs' . DS . 'api.php';
}
Mock::generatePartial(
'ShellDispatcher', 'ApiShellMockShellDispatcher',
array('getInput', 'stdout', 'stderr', '_stop', '_initEnvironment')
);
Mock::generatePartial(
'ApiShell', 'MockApiShell',
array('in', 'out', 'createFile', 'hr', '_stop')
);
/**
* TestTaskTest class
*
* @package cake
* @subpackage cake.tests.cases.console.libs.tasks
*/
class TestTaskTest extends CakeTestCase {
/**
* setUp method
*
* @return void
* @access public
*/
function startTest() {
$this->Dispatcher =& new ApiShellMockShellDispatcher();
$this->Shell =& new MockApiShell($this->Dispatcher);
$this->Shell->Dispatch = new $this->Dispatcher;
}
/**
* tearDown method
*
* @return void
* @access public
*/
function endTest() {
ClassRegistry::flush();
}
/**
* Test that method names are detected properly including those with no arguments.
*
* @access public
* @return void
*/
function testMethodNameDetection () {
$this->Shell->setReturnValueAt(0, 'in', 'q');
$this->Shell->expectAt(0, 'out', array('Controller'));
$expected = array(
array(
'1. afterFilter()',
'2. beforeFilter()',
'3. beforeRender()',
'4. constructClasses()',
'5. disableCache()',
'6. flash($message, $url, $pause = 1)',
'7. header($status)',
'8. isAuthorized()',
'9. loadModel($modelClass = null, $id = null)',
'10. paginate($object = null, $scope = array(), $whitelist = array())',
'11. postConditions($data = array(), $op = null, $bool = \'AND\', $exclusive = false)',
'12. redirect($url, $status = null, $exit = true)',
'13. referer($default = null, $local = false)',
'14. render($action = null, $layout = null, $file = null)',
'15. set($one, $two = null)',
'16. setAction($action)',
'17. validate()',
'18. validateErrors()'
)A
);
$this->Shell->expectAt(1, 'out', $expected);
$this->Shell->args = array('controller');
$this->Shell->paths['controller'] = CAKE_CORE_INCLUDE_PATH . DS . LIBS . 'controller' . DS;
$this->Shell->main();
}
}
?>

View file

@ -436,6 +436,21 @@ class ComponentTest extends CakeTestCase {
$this->assertEqual($Controller->Orange->settings, $expected); $this->assertEqual($Controller->Orange->settings, $expected);
$this->assertEqual($Controller->ParamTest->test, 'value'); $this->assertEqual($Controller->ParamTest->test, 'value');
} }
/**
* Ensure that settings are not duplicated when passed into component initialize.
*
* @return void
**/
function testComponentParamsNoDuplication() {
$Controller =& new ComponentTestController();
$Controller->components = array('Orange' => array('setting' => array('itemx')));
$Controller->constructClasses();
$Controller->Component->initialize($Controller);
$expected = array('setting' => array('itemx'), 'colour' => 'blood orange');
$this->assertEqual($Controller->Orange->settings, $expected, 'Params duplication has occured %s');
}
/** /**
* Test mutually referencing components. * Test mutually referencing components.
* *

View file

@ -728,7 +728,36 @@ class AuthTest extends CakeTestCase {
$this->Controller->params['action'] = 'Add'; $this->Controller->params['action'] = 'Add';
$this->assertFalse($this->Controller->Auth->startup($this->Controller)); $this->assertFalse($this->Controller->Auth->startup($this->Controller));
} }
/**
* test that allow() and allowedActions work with camelCase method names.
*
* @return void
**/
function testAllowedActionsWithCamelCaseMethods() {
$url = '/auth_test/camelCase';
$this->Controller->params = Router::parse($url);
$this->Controller->params['url']['url'] = Router::normalize($url);
$this->Controller->Auth->initialize($this->Controller);
$this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
$this->Controller->Auth->userModel = 'AuthUser';
$this->Controller->Auth->allow('*');
$result = $this->Controller->Auth->startup($this->Controller);
$this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
$url = '/auth_test/camelCase';
$this->Controller->params = Router::parse($url);
$this->Controller->params['url']['url'] = Router::normalize($url);
$this->Controller->Auth->initialize($this->Controller);
$this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
$this->Controller->Auth->userModel = 'AuthUser';
$this->Controller->Auth->allowedActions = array('delete', 'camelCase', 'add');
$result = $this->Controller->Auth->startup($this->Controller);
$this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
$this->Controller->Auth->allowedActions = array('delete', 'add');
$result = $this->Controller->Auth->startup($this->Controller);
$this->assertFalse($result, 'startup() should return false, as action is not allowed. %s');
}
/** /**
* testLoginRedirect method * testLoginRedirect method
* *

View file

@ -0,0 +1,222 @@
<?php
/* SVN FILE: $Id$ */
/**
* Controller Merge vars Test file
*
* Isolated from the Controller and Component test as to not pollute their AppController class
*
* 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.tests.cases.libs.controller
* @since CakePHP(tm) v 1.2.3
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
if (!class_exists('AppController')) {
/**
* Test case AppController requred
*
* @package cake.tests.cases.libs.controller
**/
class AppController extends Controller {
/**
* components
*
* @var array
**/
var $components = array('MergeVar' => array('flag', 'otherFlag', 'redirect' => false));
/**
* helpers
*
* @var array
**/
var $helpers = array('MergeVar' => array('format' => 'html', 'terse'));
}
} elseif (!defined('APP_CONTROLLER_EXISTS')) {
define('APP_CONTROLLER_EXISTS', true);
}
/**
* MergeVar Component
*
* @package cake.tests.cases.libs.controller
**/
class MergeVarComponent extends Object {
}
/**
* Additional controller for testing
*
* @package cake.tests.cases.libs.controller
**/
class MergeVariablesController extends AppController {
/**
* name
*
* @var string
**/
var $name = 'MergeVariables';
/**
* uses
*
* @var arrays
**/
var $uses = array();
}
/**
* MergeVarPlugin App Controller
*
* @package cake.tests.cases.libs.controller
**/
class MergeVarPluginAppController extends AppController {
/**
* components
*
* @var array
**/
var $components = array('Auth' => array('setting' => 'val', 'otherVal'));
/**
* helpers
*
* @var array
**/
var $helpers = array('Javascript');
}
/**
* MergePostsController
*
* @package cake.tests.cases.libs.controller
**/
class MergePostsController extends MergeVarPluginAppController {
/**
* name
*
* @var string
**/
var $name = 'MergePosts';
/**
* uses
*
* @var array
**/
var $uses = array();
}
/**
* Test Case for Controller Merging of Vars.
*
* @package cake.tests.cases.libs.controller
**/
class ControllerMergeVarsTestCase extends CakeTestCase {
/**
* end test
*
* @return void
**/
function endTest() {
ClassRegistry::flush();
}
/**
* test that component settings are not duplicated when merging component settings
*
* @return void
**/
function testComponentParamMergingNoDuplication() {
$Controller =& new MergeVariablesController();
$Controller->constructClasses();
$expected = array('MergeVar' => array('flag', 'otherFlag', 'redirect' => false));
$this->assertEqual($Controller->components, $expected, 'Duplication of settings occured. %s');
}
/**
* test component merges with redeclared components
*
* @return void
**/
function testComponentMergingWithRedeclarations() {
$Controller =& new MergeVariablesController();
$Controller->components['MergeVar'] = array('remote', 'redirect' => true);
$Controller->constructClasses();
$expected = array('MergeVar' => array('flag', 'otherFlag', 'redirect' => true, 'remote'));
$this->assertEqual($Controller->components, $expected, 'Merging of settings is wrong. %s');
}
/**
* test merging of helpers array, ensure no duplication occurs
*
* @return void
**/
function testHelperSettingMergingNoDuplication() {
$Controller =& new MergeVariablesController();
$Controller->constructClasses();
$expected = array('MergeVar' => array('format' => 'html', 'terse'));
$this->assertEqual($Controller->helpers, $expected, 'Duplication of settings occured. %s');
}
/**
* test merging of vars with plugin
*
* @return void
**/
function testMergeVarsWithPlugin() {
$Controller =& new MergePostsController();
$Controller->components = array('Email' => array('ports' => 'open'));
$Controller->plugin = 'MergeVarPlugin';
$Controller->constructClasses();
$expected = array(
'MergeVar' => array('flag', 'otherFlag', 'redirect' => false),
'Auth' => array('setting' => 'val', 'otherVal'),
'Email' => array('ports' => 'open')
);
$this->assertEqual($Controller->components, $expected, 'Components are unexpected %s');
$expected = array(
'Javascript',
'MergeVar' => array('format' => 'html', 'terse')
);
$this->assertEqual($Controller->helpers, $expected, 'Helpers are unexpected %s');
$Controller =& new MergePostsController();
$Controller->components = array();
$Controller->plugin = 'MergeVarPlugin';
$Controller->constructClasses();
$expected = array(
'MergeVar' => array('flag', 'otherFlag', 'redirect' => false),
'Auth' => array('setting' => 'val', 'otherVal'),
);
$this->assertEqual($Controller->components, $expected, 'Components are unexpected %s');
}
/**
* Ensure that __mergeVars is not being greedy and merging with
* AppController when you make an instance of Controller
*
* @return void
**/
function testMergeVarsNotGreedy() {
$Controller =& new Controller();
$Controller->components = array();
$Controller->uses = array();
$Controller->constructClasses();
$this->assertTrue(isset($Controller->Session));
}
}

View file

@ -297,5 +297,21 @@ class DboMysqliTest extends CakeTestCase {
$expected = 'float'; $expected = 'float';
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }
/**
* undocumented function
*
* @return void
* @access public
*/
function testTransactions() {
$this->db->begin($this->model);
$this->assertTrue($this->db->_transactionStarted);
$beginSqlCalls = Set::extract('/.[query=START TRANSACTION]', $this->db->_queriesLog);
$this->assertEqual(1, count($beginSqlCalls));
$this->db->commit($this->model);
$this->assertFalse($this->db->_transactionStarted);
}
} }
?> ?>

View file

@ -290,6 +290,21 @@ class DboPostgresTest extends CakeTestCase {
$this->assertEqual($this->db2->value('1', 'boolean'), 'TRUE'); $this->assertEqual($this->db2->value('1', 'boolean'), 'TRUE');
$this->assertEqual($this->db2->value(null, 'boolean'), "NULL"); $this->assertEqual($this->db2->value(null, 'boolean'), "NULL");
} }
/**
* test that date columns do not generate errors with null and nullish values.
*
* @return void
**/
function testDateAsNull() {
$this->assertEqual($this->db2->value(null, 'date'), 'NULL');
$this->assertEqual($this->db2->value('', 'date'), 'NULL');
$this->assertEqual($this->db2->value('', 'datetime'), 'NULL');
$this->assertEqual($this->db2->value(null, 'datetime'), 'NULL');
$this->assertEqual($this->db2->value('', 'timestamp'), 'NULL');
$this->assertEqual($this->db2->value(null, 'timestamp'), 'NULL');
}
/** /**
* Tests that different Postgres boolean 'flavors' are properly returned as native PHP booleans * Tests that different Postgres boolean 'flavors' are properly returned as native PHP booleans
* *

File diff suppressed because it is too large Load diff

View file

@ -1864,6 +1864,7 @@ class ValidationTest1 extends CakeTestModel {
*/ */
function customValidatorWithParams($data, $validator, $or = true, $ignore_on_same = 'id') { function customValidatorWithParams($data, $validator, $or = true, $ignore_on_same = 'id') {
$this->validatorParams = get_defined_vars(); $this->validatorParams = get_defined_vars();
unset($this->validatorParams['this']);
return true; return true;
} }
/** /**
@ -2543,7 +2544,7 @@ class Basket extends CakeTestModel {
'FilmFile' => array( 'FilmFile' => array(
'className' => 'FilmFile', 'className' => 'FilmFile',
'foreignKey' => 'object_id', 'foreignKey' => 'object_id',
'conditions' => 'Basket.type = "file"', 'conditions' => "Basket.type = 'file'",
'fields' => '', 'fields' => '',
'order' => '' 'order' => ''
) )

View file

@ -402,6 +402,7 @@ class JavascriptTest extends CakeTestCase {
$this->Javascript->useNative = $oldNative; $this->Javascript->useNative = $oldNative;
} }
/** /**
* testScriptBlock method * testScriptBlock method
* *
@ -653,11 +654,11 @@ class JavascriptTest extends CakeTestCase {
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$result = $this->Javascript->escapeString('CakePHP: \'Rapid Development Framework\''); $result = $this->Javascript->escapeString('CakePHP: \'Rapid Development Framework\'');
$expected = 'CakePHP: \\\'Rapid Development Framework\\\''; $expected = "CakePHP: \\'Rapid Development Framework\\'";
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$result = $this->Javascript->escapeString('my \\"string\\"'); $result = $this->Javascript->escapeString('my \\"string\\"');
$expected = 'my \\\"string\\\"'; $expected = 'my \\\\\\"string\\\\\\"';
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
$result = $this->Javascript->escapeString('my string\nanother line'); $result = $this->Javascript->escapeString('my string\nanother line');
@ -672,6 +673,58 @@ class JavascriptTest extends CakeTestCase {
$expected = 'String with \\\n string that looks like newline'; $expected = 'String with \\\n string that looks like newline';
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }
/**
* test string escaping and compare to json_encode()
*
* @return void
**/
function testStringJsonEncodeCompliance() {
if (!function_exists('json_encode')) {
return;
}
$this->Javascript->useNative = false;
$data = array();
$data['mystring'] = "simple string";
$this->assertEqual(json_encode($data), $this->Javascript->object($data));
$data['mystring'] = "strïng with spécial chârs";
$this->assertEqual(json_encode($data), $this->Javascript->object($data));
$data['mystring'] = "a two lines\nstring";
$this->assertEqual(json_encode($data), $this->Javascript->object($data));
$data['mystring'] = "a \t tabbed \t string";
$this->assertEqual(json_encode($data), $this->Javascript->object($data));
$data['mystring'] = "a \"double-quoted\" string";
$this->assertEqual(json_encode($data), $this->Javascript->object($data));
$data['mystring'] = 'a \\"double-quoted\\" string';
$this->assertEqual(json_encode($data), $this->Javascript->object($data));
}
/**
* test that text encoded with Javascript::object decodes properly
*
* @return void
**/
function testObjectDecodeCompatibility() {
if (!function_exists('json_decode')) {
return;
}
$this->Javascript->useNative = false;
$data = array("simple string");
$result = $this->Javascript->object($data);
$this->assertEqual(json_decode($result), $data);
$data = array('my \"string\"');
$result = $this->Javascript->object($data);
$this->assertEqual(json_decode($result), $data);
$data = array('my \\"string\\"');
$result = $this->Javascript->object($data);
$this->assertEqual(json_decode($result), $data);
}
/** /**
* testAfterRender method * testAfterRender method
* *

View file

@ -267,6 +267,29 @@ class ViewTest extends CakeTestCase {
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }
/** /**
* test that CamelCase plugins still find their view files.
*
* @return void
**/
function testCamelCasePluginGetTemplate() {
$this->Controller->plugin = 'TestPlugin';
$this->Controller->name = 'TestPlugin';
$this->Controller->viewPath = 'tests';
$this->Controller->action = 'index';
$View = new TestView($this->Controller);
Configure::write('pluginPaths', array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS));
Configure::write('viewPaths', array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS));
$expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS .'test_plugin' . DS . 'views' . DS .'tests' . DS .'index.ctp';
$result = $View->getViewFileName('index');
$this->assertEqual($result, $expected);
$expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS .'test_plugin' . DS . 'views' . DS . 'layouts' . DS .'default.ctp';
$result = $View->getLayoutFileName();
$this->assertEqual($result, $expected);
}
/**
* testGetTemplate method * testGetTemplate method
* *
* @access public * @access public

View file

@ -97,6 +97,38 @@ class XmlTest extends CakeTestCase {
$result = preg_replace("/\n/",'', $xml->toString(false)); $result = preg_replace("/\n/",'', $xml->toString(false));
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }
/**
* test serialization of boolean and null values. false = 0, true = 1, null = ''
*
* @return void
**/
function testSerializationOfBooleanAndBooleanishValues() {
$xml =& new Xml(array('data' => array('example' => false)));
$result = $xml->toString(false);
$expected = '<data example="0" />';
$this->assertEqual($result, $expected, 'Boolean values incorrectly handled. %s');
$xml =& new Xml(array('data' => array('example' => true)));
$result = $xml->toString(false);
$expected = '<data example="1" />';
$this->assertEqual($result, $expected, 'Boolean values incorrectly handled. %s');
$xml =& new Xml(array('data' => array('example' => null)));
$result = $xml->toString(false);
$expected = '<data example="" />';
$this->assertEqual($result, $expected, 'Boolean values incorrectly handled. %s');
$xml =& new Xml(array('data' => array('example' => 0)));
$result = $xml->toString(false);
$expected = '<data example="0" />';
$this->assertEqual($result, $expected, 'Boolean-ish values incorrectly handled. %s');
$xml =& new Xml(array('data' => array('example' => 1)));
$result = $xml->toString(false);
$expected = '<data example="1" />';
$this->assertEqual($result, $expected, 'Boolean-ish values incorrectly handled. %s');
}
/** /**
* testSimpleArray method * testSimpleArray method
* *
@ -647,6 +679,67 @@ class XmlTest extends CakeTestCase {
$result = $xml->toString(); $result = $xml->toString();
$this->assertEqual($source, $result); $this->assertEqual($source, $result);
} }
/**
* test that elements with empty tag values do not collapse and corrupt data structures
*
* @access public
* @return void
**/
function testElementCollapsing() {
$xmlDataThatFails = '<resultpackage>
<result qid="46b1c46ed6208"><![CDATA[46b1c46ed3af9]]></result>
<result qid="46b1c46ed332a"><![CDATA[]]></result>
<result qid="46b1c46ed90e6"><![CDATA[46b1c46ed69d8]]></result>
<result qid="46b1c46ed71a7"><![CDATA[46b1c46ed5a38]]></result>
<result qid="46b1c46ed8146"><![CDATA[46b1c46ed98b6]]></result>
<result qid="46b1c46ed7978"><![CDATA[]]></result>
<result qid="46b1c46ed4a98"><![CDATA[]]></result>
<result qid="46b1c46ed42c8"><![CDATA[]]></result>
<result qid="46b1c46ed5268"><![CDATA[46b1c46ed8917]]></result>
</resultpackage>';
$Xml = new Xml();
$Xml->load('<?xml version="1.0" encoding="UTF-8" ?>' . $xmlDataThatFails);
$result = $Xml->toArray(false);
$this->assertTrue(is_array($result));
$expected = array(
'resultpackage' => array(
'result' => array(
0 => array(
'value' => '46b1c46ed3af9',
'qid' => '46b1c46ed6208'),
1 => array(
'qid' => '46b1c46ed332a'),
2 => array(
'value' => '46b1c46ed69d8',
'qid' => '46b1c46ed90e6'),
3 => array(
'value' => '46b1c46ed5a38',
'qid' => '46b1c46ed71a7'),
4 => array(
'value' => '46b1c46ed98b6',
'qid' => '46b1c46ed8146'),
5 => array(
'qid' => '46b1c46ed7978'),
6 => array(
'qid' => '46b1c46ed4a98'),
7 => array(
'qid' => '46b1c46ed42c8'),
8 => array(
'value' => '46b1c46ed8917',
'qid' => '46b1c46ed5268'),
)
));
$this->assertEqual(
count($result['resultpackage']['result']), count($expected['resultpackage']['result']),
'Incorrect array length %s');
$this->assertFalse(
isset($result['resultpackage']['result'][0][0]['qid']), 'Nested array exists, data is corrupt. %s');
$this->assertEqual($result, $expected);
}
/** /**
* testMixedParsing method * testMixedParsing method
* *

View file

@ -1,9 +1,7 @@
<?php <?php
/* SVN FILE: $Id$ */ /* SVN FILE: $Id$ */
/** /**
* Short description for file. * CakeWebTestCase a simple wrapper around WebTestCase
*
* Long description for file
* *
* PHP versions 4 and 5 * PHP versions 4 and 5
* *
@ -25,11 +23,11 @@
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/ */
/** /**
* Short description * Ignore base class.
*/ */
SimpleTestOptions::ignore('CakeWebTestCase'); SimpleTest::ignore('CakeWebTestCase');
/** /**
* Short description for class. * Simple wrapper for the WebTestCase provided by SimpleTest
* *
* @package cake * @package cake
* @subpackage cake.cake.tests.lib * @subpackage cake.cake.tests.lib