From 54a4d24a03697391584ee0408a87553c28452053 Mon Sep 17 00:00:00 2001 From: Mariano Iglesias Date: Fri, 8 Apr 2011 14:50:36 -0300 Subject: [PATCH] Fixes issue with fixture records defining fields in wrong order, or adding fields in some records that are not defined in others Fixes #1559 --- .../cases/libs/cake_test_fixture.test.php | 104 +++++++++++++++++- cake/tests/lib/cake_test_fixture.php | 16 ++- 2 files changed, 111 insertions(+), 9 deletions(-) diff --git a/cake/tests/cases/libs/cake_test_fixture.test.php b/cake/tests/cases/libs/cake_test_fixture.test.php index 6e6667dde..40bacc56c 100644 --- a/cake/tests/cases/libs/cake_test_fixture.test.php +++ b/cake/tests/cases/libs/cake_test_fixture.test.php @@ -64,6 +64,53 @@ class CakeTestFixtureTestFixture extends CakeTestFixture { ); } +/** + * StringFieldsTestFixture class + * + * @package cake + * @subpackage cake.cake.tests.cases.libs + */ +class StringsTestFixture extends CakeTestFixture { + +/** + * name Property + * + * @var string + */ + var $name = 'Strings'; + +/** + * table property + * + * @var string + */ + var $table = 'strings'; + +/** + * Fields array + * + * @var array + */ + var $fields = array( + 'id' => array('type' => 'integer', 'key' => 'primary'), + 'name' => array('type' => 'string', 'length' => '255'), + 'email' => array('type' => 'string', 'length' => '255'), + 'age' => array('type' => 'integer', 'default' => 10) + ); + +/** + * Records property + * + * @var array + */ + var $records = array( + array('name' => 'John Doe', 'email' => 'john.doe@email.com', 'age' => 20), + array('email' => 'jane.doe@email.com', 'name' => 'Jane Doe', 'age' => 30), + array('name' => 'Mark Doe', 'email' => 'mark.doe@email.com') + ); +} + + /** * CakeTestFixtureImportFixture class * @@ -122,7 +169,20 @@ class FixturePrefixTest extends Model { var $useDbConfig = 'test_suite'; } -Mock::generate('DboSource', 'FixtureMockDboSource'); +Mock::generate('DboSource', 'BaseFixtureMockDboSource'); + +class FixtureMockDboSource extends BaseFixtureMockDboSource { + var $insertMulti; + + function value($string) { + return is_string($string) ? '\'' . $string . '\'' : $string; + } + + function insertMulti($table, $fields, $values) { + $this->insertMulti = compact('table', 'fields', 'values'); + return true; + } +} /** * Test case for CakeTestFixture @@ -203,7 +263,7 @@ class CakeTestFixtureTest extends CakeTestCase { $Fixture->init(); $this->assertEqual(array_keys($Fixture->fields), array('id', 'name', 'created')); $this->assertEqual($Fixture->table, 'fixture_tests'); - + $keys = array_flip(ClassRegistry::keys()); $this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys)); @@ -301,7 +361,7 @@ class CakeTestFixtureTest extends CakeTestCase { } /** - * test that importing with records works. Make sure to try with postgres as its + * test that importing with records works. Make sure to try with postgres as its * handling of aliases is a workaround at best. * * @return void @@ -334,7 +394,7 @@ class CakeTestFixtureTest extends CakeTestCase { $defaultDb->config = $defaultConfig; - $Source->drop($newTestSuiteDb); + $Source->drop($newTestSuiteDb); } /** @@ -364,12 +424,44 @@ class CakeTestFixtureTest extends CakeTestCase { */ function testInsert() { $Fixture =& new CakeTestFixtureTestFixture(); - $this->criticDb->setReturnValue('insertMulti', true); - $this->criticDb->expectAtLeastOnce('insertMulti'); + $this->criticDb->insertMulti = array(); $return = $Fixture->insert($this->criticDb); + $this->assertTrue(!empty($this->criticDb->insertMulti)); $this->assertTrue($this->criticDb->fullDebug); $this->assertTrue($return); + $this->assertEqual('fixture_tests', $this->criticDb->insertMulti['table']); + $this->assertEqual(array('name', 'created'), $this->criticDb->insertMulti['fields']); + $expected = array( + '(\'Gandalf\', \'2009-04-28 19:20:00\')', + '(\'Captain Picard\', \'2009-04-28 19:20:00\')', + '(\'Chewbacca\', \'2009-04-28 19:20:00\')' + ); + $this->assertEqual($expected, $this->criticDb->insertMulti['values']); + } + +/** + * test the insert method + * + * @access public + * @return void + */ + function testInsertStrings() { + $Fixture =& new StringsTestFixture(); + + $this->criticDb->insertMulti = array(); + $return = $Fixture->insert($this->criticDb); + $this->assertTrue(!empty($this->criticDb->insertMulti)); + $this->assertTrue($this->criticDb->fullDebug); + $this->assertTrue($return); + $this->assertEqual('strings', $this->criticDb->insertMulti['table']); + $this->assertEqual(array('name', 'email', 'age'), $this->criticDb->insertMulti['fields']); + $expected = array( + '(\'John Doe\', \'john.doe@email.com\', 20)', + '(\'Jane Doe\', \'jane.doe@email.com\', 30)', + '(\'Mark Doe\', \'mark.doe@email.com\', NULL)', + ); + $this->assertEqual($expected, $this->criticDb->insertMulti['values']); } /** diff --git a/cake/tests/lib/cake_test_fixture.php b/cake/tests/lib/cake_test_fixture.php index 91264d891..49c9ec3ea 100644 --- a/cake/tests/lib/cake_test_fixture.php +++ b/cake/tests/lib/cake_test_fixture.php @@ -69,7 +69,7 @@ class CakeTestFixture extends Object { function init() { if (isset($this->import) && (is_string($this->import) || is_array($this->import))) { $import = array_merge( - array('connection' => 'default', 'records' => false), + array('connection' => 'default', 'records' => false), is_array($this->import) ? $this->import : array('model' => $this->import) ); @@ -175,9 +175,18 @@ class CakeTestFixture extends Object { $values = array(); if (isset($this->records) && !empty($this->records)) { + $fields = array(); + foreach($this->records as $record) { + $fields = array_merge($fields, array_keys(array_intersect_key($record, $this->fields))); + } + $fields = array_unique($fields); + $default = array_fill_keys($fields, null); foreach ($this->records as $record) { - $fields = array_keys($record); - $values[] = '(' . implode(', ', array_map(array(&$db, 'value'), array_values($record))) . ')'; + $recordValues = array(); + foreach(array_merge($default, array_map(array(&$db, 'value'), $record)) as $value) { + $recordValues[] = is_null($value) ? 'NULL' : $value; + } + $values[] = '(' . implode(', ', $recordValues) . ')'; } return $db->insertMulti($this->table, $fields, $values); } @@ -185,6 +194,7 @@ class CakeTestFixture extends Object { } } + /** * Truncates the current fixture. Can be overwritten by classes extending CakeFixture to trigger other events before / after * truncate.