Skip to content

Instantly share code, notes, and snippets.

@deizel
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deizel/cf5a4991d59c0dc2e694 to your computer and use it in GitHub Desktop.
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)
<?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