Skip to content
Permalink
Browse files

Adding ability to generate fixtures from data in app tables, with cus…

…tom conditions. Test cases added.
  • Loading branch information...
markstory committed Jul 21, 2009
1 parent 10f5ae2 commit 19eca9003d09818c998070394026e75903c1fa20
Showing with 95 additions and 17 deletions.
  1. +77 −17 cake/console/libs/tasks/fixture.php
  2. +18 −0 cake/tests/cases/console/libs/tasks/fixture.test.php
@@ -144,8 +144,8 @@ function importOptions($modelName) {
}
if ($doRecords == 'n') {
$prompt = sprintf(__("Would you like to build this fixture with data from %s's table?", true), $modelName);
$fromDb = $this->in($prompt, array('y', 'n'), 'n');
if (strtolower($fromDb) == 'y') {
$fromTable = $this->in($prompt, array('y', 'n'), 'n');
if (strtolower($fromTable) == 'y') {
$options['fromTable'] = true;
}
}
@@ -161,14 +161,13 @@ function importOptions($modelName) {
* @access private
*/
function bake($model, $useTable = false, $importOptions = array()) {
$table = $schema = $records = $import = null;
$table = $schema = $records = $import = $modelImport = $recordImport = null;
if (!$useTable) {
$useTable = Inflector::tableize($model);
} elseif ($useTable != Inflector::tableize($model)) {
$table = $useTable;
}
$modelImport = $import = $recordImport = null;
if (!empty($importOptions)) {
if (isset($importOptions['schema'])) {
$modelImport = "'model' => '{$importOptions['schema']}'";
@@ -179,7 +178,9 @@ function bake($model, $useTable = false, $importOptions = array()) {
if ($modelImport && $recordImport) {
$modelImport .= ', ';
}
$import = sprintf("array(%s%s)", $modelImport, $recordImport);
if (!empty($modelImport) || !empty($recordImport)) {
$import = sprintf("array(%s%s)", $modelImport, $recordImport);
}
}
$this->_Schema = new CakeSchema();
@@ -195,12 +196,15 @@ function bake($model, $useTable = false, $importOptions = array()) {
$schema = $this->_generateSchema($tableInfo);
}
if (is_null($recordImport)) {
if (!isset($importOptions['records']) && !isset($importOptions['fromTable'])) {
$recordCount = 1;
if (isset($this->params['count'])) {
$recordCount = $this->params['count'];
}
$records = $this->_generateRecords($tableInfo, $recordCount);
$records = $this->_makeRecordString($this->_generateRecords($tableInfo, $recordCount));
}
if (isset($importOptions['fromTable'])) {
$records = $this->_makeRecordString($this->_getRecordsFromTable($model, $useTable));
}
$out = $this->generateFixtureFile($model, compact('records', 'table', 'schema', 'import', 'fields'));
return $out;
@@ -265,13 +269,12 @@ function _generateSchema($tableInfo) {
* Generate String representation of Records
*
* @param array $table Table schema array
* @return string
* @return array Array of records to use in the fixture.
**/
function _generateRecords($tableInfo, $recordCount = 1) {
$out = "array(\n";
$records = array();
for ($i = 0; $i < $recordCount; $i++) {
$records = array();
$record = array();
foreach ($tableInfo as $field => $fieldInfo) {
if (empty($fieldInfo['type'])) {
continue;
@@ -281,9 +284,17 @@ function _generateRecords($tableInfo, $recordCount = 1) {
$insert = $i + 1;
break;
case 'string';
$insert = "Lorem ipsum dolor sit amet";
if (!empty($fieldInfo['length'])) {
$insert = substr($insert, 0, (int)$fieldInfo['length'] - 2);
$isPrimaryUuid = (
isset($fieldInfo['key']) && strtolower($fieldInfo['key']) == 'primary' &&
isset($fieldInfo['length']) && $fieldInfo['length'] == 36
);
if ($isPrimaryUuid) {
$insert = String::uuid();
} else {
$insert = "Lorem ipsum dolor sit amet";
if (!empty($fieldInfo['length'])) {
$insert = substr($insert, 0, (int)$fieldInfo['length'] - 2);
}
}
$insert = "'$insert'";
break;
@@ -316,15 +327,64 @@ function _generateRecords($tableInfo, $recordCount = 1) {
$insert .= " duis vestibulum nunc mattis convallis.'";
break;
}
$records[] = "\t\t\t'$field' => $insert";
$record[$field] = $insert;
}
$records[] = $record;
}
return $records;
}
/**
* Convert a $records array into a a string.
*
* @param array $records Array of records to be converted to string
* @return string A string value of the $records array.
**/
function _makeRecordString($records) {
$out = "array(\n";
foreach ($records as $record) {
$values = array();
foreach ($record as $field => $value) {
$values[] = "\t\t\t'$field' => $value";
}
$out .= "\t\tarray(\n";
$out .= implode(",\n", $records);
$out .= implode(",\n", $values);
$out .= "\n\t\t),\n";
}
$out .= "\t)";
return $out;
}
/**
* Interact with the user to get a custom SQL condition and use that to extract data
* to build a fixture.
*
* @param string $modelName name of the model to take records from.
* @param string $useTable Name of table to use.
* @return array Array of records.
**/
function _getRecordsFromTable($modelName, $useTable = null) {
$condition = null;
$prompt = __("Please provide a SQL fragment to use as conditions\nExample: WHERE 1=1 LIMIT 10", true);
while (!$condition) {
$condition = $this->in($prompt, null, 'WHERE 1=1 LIMIT 10');
}
App::import('Core', 'Model');
$modelObject =& new Model(array('name' => $modelName, 'table' => $useTable, 'ds' => $this->connection));
$records = $modelObject->find('all', array(
'conditions' => $condition,
'recursive' => -1
));
$db =& $modelObject->getDataSource();
$schema = $modelObject->schema();
$out = array();
foreach ($records as $record) {
$row = array();
foreach ($record[$modelObject->alias] as $field => $value) {
$row[$field] = $db->value($value, $schema[$field]['type']);
}
$out[] = $row;
}
return $out;
}
/**
* Displays help contents
*
@@ -339,7 +399,7 @@ function help() {
$this->out("\nfixture all\n\tbakes all fixtures.");
$this->out("");
$this->out('Parameters:');
$this->out("\t-count The number of records to include in the fixture(s).");
$this->out("\t-count When using generated data, the number of records to include in the fixture(s).");
$this->out("\t-connection Which database configuration to use for baking.");
$this->out("\t-plugin lowercased_underscored name of plugin to bake fixtures for.");
$this->out("");
@@ -125,6 +125,24 @@ function testImportOptions() {
$expected = array('fromTable' => true);
$this->assertEqual($result, $expected);
}
/**
* test generating a fixture with database conditions.
*
* @return void
**/
function testImportRecordsFromDatabaseWithConditions() {
$this->Task->setReturnValueAt(0, 'in', 'WHERE 1=1 LIMIT 10');
$this->Task->connection = 'test_suite';
$this->Task->path = '/my/path/';
$result = $this->Task->bake('Article', false, array('fromTable' => true, 'schema' => 'Article', 'records' => false));
debug($result, true);
$this->assertPattern('/class ArticleFixture extends CakeTestFixture/', $result);
$this->assertPattern('/var \$records/', $result);
$this->assertPattern('/var \$import/', $result);
$this->assertPattern("/'title' => 'First Article'/", $result, 'Missing import data %s');
$this->assertPattern('/Second Article/', $result, 'Missing import data %s');
$this->assertPattern('/Third Article/', $result, 'Missing import data %s');
}
/**
* test that execute passes runs bake depending with named model.
*

0 comments on commit 19eca90

Please sign in to comment.
You can’t perform that action at this time.