From 7107cd663142fe79b98fde39529516344e729685 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 19 May 2012 11:35:55 -0400 Subject: [PATCH 1/4] Fix fatal error when checking for PHPUnit. Doubly including PHPUnit/Autoload.php causes fatal errors. Having access to one of the PHPUnit classes means phpunit exists as well. Fixes #2890 --- lib/Cake/Console/Shell.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php index 788bb8b39..40c8c04ef 100644 --- a/lib/Cake/Console/Shell.php +++ b/lib/Cake/Console/Shell.php @@ -680,12 +680,14 @@ class Shell extends Object { * @return boolean Success */ protected function _checkUnitTest() { - if (App::import('Vendor', 'phpunit', array('file' => 'PHPUnit' . DS . 'Autoload.php'))) { - return true; - } - if (@include 'PHPUnit' . DS . 'Autoload.php') { + if (class_exists('PHPUnit_Framework_TestCase')) { + return true; + } elseif (@include 'PHPUnit' . DS . 'Autoload.php') { + return true; + } elseif (App::import('Vendor', 'phpunit', array('file' => 'PHPUnit' . DS . 'Autoload.php'))) { return true; } + $prompt = __d('cake_console', 'PHPUnit is not installed. Do you want to bake unit test files anyway?'); $unitTest = $this->in($prompt, array('y', 'n'), 'y'); $result = strtolower($unitTest) == 'y' || strtolower($unitTest) == 'yes'; From 7dbd6bc3a2bb17501fb411c6a0605e3908a9d0c5 Mon Sep 17 00:00:00 2001 From: Ceeram Date: Tue, 15 May 2012 16:57:42 +0200 Subject: [PATCH 2/4] make sure model data is moved to alias, even when first key in data is assoc model add extra tests for saveAll and validate first ensure db values dont get reset to default values --- lib/Cake/Model/Model.php | 38 +++++++---- lib/Cake/Test/Case/Model/ModelReadTest.php | 2 +- .../Test/Case/Model/ModelValidationTest.php | 67 +++++++++++++++++-- lib/Cake/Test/Case/Model/ModelWriteTest.php | 10 +-- lib/Cake/Test/Case/Model/models.php | 7 +- 5 files changed, 98 insertions(+), 26 deletions(-) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 8a2a9b223..77b740350 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -1129,9 +1129,7 @@ class Model extends Object implements CakeEventListener { if (is_array($one)) { $data = $one; if (empty($one[$this->alias])) { - if ($this->getAssociated(key($one)) === null) { - $data = array($this->alias => $one); - } + $data = $this->_setAliasData($one); } } else { $data = array($this->alias => array($one => $two)); @@ -1160,6 +1158,24 @@ class Model extends Object implements CakeEventListener { return $data; } +/** + * Move values to alias + * + * @param array $data + * @return array + */ + protected function _setAliasData($data) { + $models = array_keys($this->getAssociated()); + $schema = array_keys($this->schema()); + foreach ($data as $field => $value) { + if (in_array($field, $schema) || !in_array($field, $models)) { + $data[$this->alias][$field] = $value; + unset($data[$field]); + } + } + return $data; + } + /** * Normalize Xml::toArray() to use in Model::save() * @@ -2118,7 +2134,8 @@ class Model extends Object implements CakeEventListener { if ($options['deep']) { $validates = $this->validateAssociated($record, $options); } else { - $validates = $this->create($record) && $this->validates($options); + $this->create(null); + $validates = $this->set($record) && $this->validates($options); $data[$key] = $this->data; } if ($validates === false || (is_array($validates) && in_array(false, $validates, true))) { @@ -2318,21 +2335,14 @@ class Model extends Object implements CakeEventListener { public function validateAssociated(&$data, $options = array()) { $options = array_merge(array('atomic' => true, 'deep' => false), $options); $this->validationErrors = $validationErrors = $return = array(); - if (!($this->create($data) && $this->validates($options))) { + $this->create(null); + if (!($this->set($data) && $this->validates($options))) { $validationErrors[$this->alias] = $this->validationErrors; $return[$this->alias] = false; } else { $return[$this->alias] = true; } - - if (empty($options['deep'])) { - $data = $this->data; - } else { - $modelData = $this->data; - $recordData = $modelData[$this->alias]; - unset($modelData[$this->alias]); - $data = $modelData + array_merge($data, $recordData); - } + $data = $this->data; $associations = $this->getAssociated(); foreach ($data as $association => &$values) { diff --git a/lib/Cake/Test/Case/Model/ModelReadTest.php b/lib/Cake/Test/Case/Model/ModelReadTest.php index 88b1b1711..f0e4bc4fb 100644 --- a/lib/Cake/Test/Case/Model/ModelReadTest.php +++ b/lib/Cake/Test/Case/Model/ModelReadTest.php @@ -7868,7 +7868,7 @@ class ModelReadTest extends BaseModelTest { $Article = new CustomArticle(); $data = array('user_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N'); $Article->create($data); - $Article->save(); + $Article->save(null, false); $this->assertEquals(4, $Article->id); $result = $Article->find('published'); diff --git a/lib/Cake/Test/Case/Model/ModelValidationTest.php b/lib/Cake/Test/Case/Model/ModelValidationTest.php index 6b6accf96..eb90ebbfa 100644 --- a/lib/Cake/Test/Case/Model/ModelValidationTest.php +++ b/lib/Cake/Test/Case/Model/ModelValidationTest.php @@ -1016,22 +1016,34 @@ class ModelValidationTest extends BaseModelTest { ); $result = $model->saveAll($data, array('validate' => 'first')); $this->assertTrue($result); + $this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice'); - $title = $model->field('title', array('body' => 'foo0')); + $model->findMethods['unPublished'] = true; + $data = array( + 'CustomArticle' => array( + 'body' => 'foo1' + ) + ); + $result = $model->saveAll($data, array('validate' => 'first', 'deep' => true)); + $this->assertTrue($result); + $title = $model->field('title', array('body' => 'foo1')); $this->assertEquals('foo', $title); + $this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice'); $data = array( - array('body' => 'foo1'), array('body' => 'foo2'), - array('body' => 'foo3') + array('body' => 'foo3'), + array('body' => 'foo4') ); $result = $model->saveAll($data, array('validate' => 'first')); $this->assertTrue($result); + $result = $model->saveAll($data, array('validate' => 'first', 'deep' => true)); + $this->assertTrue($result); - $this->assertEquals('foo', $model->field('title', array('body' => 'foo1'))); $this->assertEquals('foo', $model->field('title', array('body' => 'foo2'))); $this->assertEquals('foo', $model->field('title', array('body' => 'foo3'))); + $this->assertEquals('foo', $model->field('title', array('body' => 'foo4'))); } /** @@ -1040,7 +1052,7 @@ class ModelValidationTest extends BaseModelTest { * * @return void */ - public function testValidateAssociatedWithBeforeValidate() { + public function testValidateFirstAssociatedWithBeforeValidate() { $this->loadFixtures('Article', 'User'); $model = new CustomArticle(); $model->validate = array( @@ -1070,4 +1082,49 @@ class ModelValidationTest extends BaseModelTest { $this->assertEquals('foo', $model->field('title', array('body' => 'foo3'))); } +/** + * testValidateFirstWithDefaults method + * + * return @void + */ + public function testFirstWithDefaults() { + $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag'); + $TestModel = new Article(); + + $result = $TestModel->find('first', array( + 'conditions' => array('Article.id' => 1) + )); + $expected = array( + 'Article' => array( + 'id' => 1, + 'user_id' => 1, + 'title' => 'First Article', + 'body' => 'First Article Body', + 'published' => 'Y', + 'created' => '2007-03-18 10:39:23' + ), + ); + unset($result['Article']['updated']); + $this->assertEquals($expected['Article'], $result['Article']); + + $data = array( + 'Article' => array( + 'id' => 1, + 'title' => 'First Article (modified)' + ), + 'Comment' => array( + array('comment' => 'Article comment', 'user_id' => 1) + ) + ); + $result = $TestModel->saveAll($data, array('validate' => 'first')); + $this->assertTrue($result); + + $result = $TestModel->find('first', array( + 'conditions' => array('Article.id' => 1) + )); + $expected['Article']['title'] = 'First Article (modified)'; + unset($result['Article']['updated']); + $this->assertEquals($expected['Article'], $result['Article']); + } + } \ No newline at end of file diff --git a/lib/Cake/Test/Case/Model/ModelWriteTest.php b/lib/Cake/Test/Case/Model/ModelWriteTest.php index f72b2a8bc..0c8b4e054 100644 --- a/lib/Cake/Test/Case/Model/ModelWriteTest.php +++ b/lib/Cake/Test/Case/Model/ModelWriteTest.php @@ -4277,7 +4277,7 @@ class ModelWriteTest extends BaseModelTest { 'author_id' => '3', 'title' => 'Just update the title', 'body' => 'Second Post Body', - 'published' => 'N', + 'published' => 'Y', 'created' => '2007-03-18 10:41:23' )), array( @@ -4366,7 +4366,7 @@ class ModelWriteTest extends BaseModelTest { 'author_id' => '3', 'title' => 'Just update the title', 'body' => 'Second Post Body', - 'published' => 'N', + 'published' => 'Y', 'created' => '2007-03-18 10:41:23' ) ), @@ -4734,7 +4734,7 @@ class ModelWriteTest extends BaseModelTest { 'password' => '5f4dcc3b5aa765d61d8327deb882cf90' ))); - $result = $TestModel->find('all'); + $result = $TestModel->find('all', array('order' => array('Post.id ' => 'ASC'))); $expected = array( 'Post' => array( 'id' => '4', @@ -5631,7 +5631,7 @@ class ModelWriteTest extends BaseModelTest { 'author_id' => '3', 'title' => 'Just update the title', 'body' => 'Second Post Body', - 'published' => 'N', + 'published' => 'Y', 'created' => '2007-03-18 10:41:23' ) ), @@ -5727,7 +5727,7 @@ class ModelWriteTest extends BaseModelTest { 'author_id' => '3', 'title' => 'Just update the title', 'body' => 'Second Post Body', - 'published' => 'N', + 'published' => 'Y', )), array( 'Post' => array( diff --git a/lib/Cake/Test/Case/Model/models.php b/lib/Cake/Test/Case/Model/models.php index fe0db80a2..e9e79a1b6 100644 --- a/lib/Cake/Test/Case/Model/models.php +++ b/lib/Cake/Test/Case/Model/models.php @@ -3119,7 +3119,7 @@ class TranslatedItem2 extends CakeTestModel { /** * translateModel property * - * @var string + * @var string */ public $translateModel = 'TranslateWithPrefix'; @@ -4975,6 +4975,11 @@ class CustomArticle extends AppModel { **/ public function beforeValidate($options = array()) { $this->data[$this->alias]['title'] = 'foo'; + if ($this->findMethods['unPublished'] === true) { + $this->findMethods['unPublished'] = false; + } else { + $this->findMethods['unPublished'] = 'true again'; + } } } From 16847b0d970fbca8c716728a55c90ba9f0962bc6 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sat, 19 May 2012 21:14:23 -0430 Subject: [PATCH 3/4] Backporting changes form 2.2 to fix some edge cases on deep saving. Fixes #2879 --- lib/Cake/Model/Model.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 77b740350..2eecea436 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -2343,6 +2343,11 @@ class Model extends Object implements CakeEventListener { $return[$this->alias] = true; } $data = $this->data; + if (!empty($options['deep']) && isset($data[$this->alias])) { + $recordData = $data[$this->alias]; + unset($data[$this->alias]); + $data = array_merge($data, $recordData); + } $associations = $this->getAssociated(); foreach ($data as $association => &$values) { From 3f7cbf561b46aa254fe14fdd1a44440c93daab81 Mon Sep 17 00:00:00 2001 From: Kyle Robinson Young Date: Sat, 19 May 2012 22:04:06 -0700 Subject: [PATCH 4/4] Update PHPUnit install instructions --- lib/Cake/TestSuite/templates/phpunit.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/Cake/TestSuite/templates/phpunit.php b/lib/Cake/TestSuite/templates/phpunit.php index 2a3dc6e7f..ae111f762 100644 --- a/lib/Cake/TestSuite/templates/phpunit.php +++ b/lib/Cake/TestSuite/templates/phpunit.php @@ -25,13 +25,11 @@

PHPUnit can be installed with pear, using the pear installer.

To install with the PEAR installer run the following commands:

    -
  • pear channel-discover pear.phpunit.de
  • -
  • pear channel-discover components.ez.no
  • -
  • pear channel-discover pear.symfony-project.com
  • -
  • pear install phpunit/PHPUnit-3.6.4
  • +
  • pear config-set auto_discover 1
  • +
  • pear install pear.phpunit.de/PHPUnit

Once PHPUnit is installed make sure its located on PHP's include_path by checking your php.ini

-

For full instructions on how to install PHPUnit, see the PHPUnit installation guide.

+

For full instructions on how to install PHPUnit, see the PHPUnit installation guide.

Download PHPUnit