Last active
August 29, 2015 14:08
-
-
Save deizel/cf5a4991d59c0dc2e694 to your computer and use it in GitHub Desktop.
Auto-load fixture fields from Config/Schema/schema.php (depends on Migrations plugin)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
App::uses('MigrationShell', 'Migrations.Console/Command'); | |
/** | |
* Schema Reader - reads schema.php from disk | |
* | |
* Steals functionality from private method in Migrations.MigrationShell::_getSchema() | |
*/ | |
class SchemaReader extends MigrationShell { | |
/** | |
* Load and construct the schema class if exists | |
* | |
* @param string $type Can be 'app' or a plugin name | |
* @return mixed False in case of no file found, schema object | |
*/ | |
// @codingStandardsIgnoreStart | |
public function load($type = 'app') { | |
return parent::_getSchema($type); | |
} | |
// @codingStandardsIgnoreEnd | |
} | |
class SchemaFixture extends CakeTestFixture { | |
/** | |
* Initialize the fixture. | |
* | |
* - Init fields array property | |
* | |
* @return void | |
* @throws MissingModelException Whe importing from a model that does not exist. | |
*/ | |
public function init() { | |
$usingSchema = $this->_initFields(); | |
if ($usingSchema) { | |
$this->_checkRecords(); | |
} | |
parent::init(); | |
} | |
/** | |
* Init fields array property | |
* | |
* If `$this->fields` is empty, grab schema from `Config/schema.php` | |
* | |
* @return bool True if using schema.php fields, false otherwise. | |
*/ | |
protected function _initFields() { | |
if (!empty($this->fields)) { | |
return false; | |
} | |
$SchemaReader = new SchemaReader(); | |
$Schema = $SchemaReader->load(); | |
if (!$Schema) { | |
return false; | |
} | |
$table = Inflector::tableize($this->name); | |
if (empty($Schema->tables[$table])) { | |
return false; | |
} | |
$fields = $Schema->tables[$table]; | |
unset($fields['indexes'], $fields['tableParameters']); | |
$this->fields = $fields; | |
return true; | |
} | |
/** | |
* Check all records against fixture fields | |
* | |
* @return void | |
* @throws CakeException when fields in fixture records don't match schema | |
*/ | |
protected function _checkRecords() { | |
$missing = $extra = array(); | |
foreach ($this->records as $index => $record) { | |
$missingDiff = array_keys(array_diff_key($this->fields, $record)); | |
$extraDiff = array_keys(array_diff_key($record, $this->fields)); | |
$missing = array_unique(array_merge($missing, $missingDiff)); | |
$extra = array_unique(array_merge($extra, $extraDiff)); | |
} | |
$problems = array(); | |
if (!empty($missing)) { | |
$problems[] = 'missing fields (' . implode(', ', $missing) . ')'; | |
} | |
if (!empty($extra)) { | |
$problems[] = 'extra fields (' . implode(', ', $extra) . ')'; | |
} | |
if (!empty($problems)) { | |
$message = 'Fixture invalid: '; | |
$message .= $this->name . 'Fixture has records with ' . implode(' and ', $problems); | |
throw new CakeException($message); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment