Created
November 7, 2017 02:47
-
-
Save geerpm/b60eb36e745cba8f2d64a41072ee6627 to your computer and use it in GitHub Desktop.
Auto generate Fixture *records* for cakephp3.x test (phpunit)
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 | |
/** | |
* 現dbからfixture用のデータを出力する | |
* src/Shell/GenFixtureFromDbShell.php | |
* | |
* $ bin/cake gen_fixture_from_db [tablename] [idStr] [overwrite] | |
* @idStr | |
* - 1,2,3,4 | |
* - 1..5 | |
* - empty means All records | |
* @overwrite boolean | |
* | |
* e.g. | |
* $ bin/cake gen_fixture_from_db users | |
* $ bin/cake gen_fixture_from_db users 1,3,8 | |
* $ bin/cake gen_fixture_from_db users 1..4 | |
* $ bin/cake gen_fixture_from_db users 1..4,8,9..13 true | |
*/ | |
namespace App\Shell; | |
use Cake\Console\Shell; | |
use Cake\Datasource\ConnectionManager; | |
use Cake\Utility\Inflector; | |
class GenFixtureFromDbShell extends Shell | |
{ | |
/** | |
* cakephp db config | |
* @var string | |
*/ | |
const DB_CONFIG_NAME = 'default'; | |
/** | |
* filter | |
* @param array $row as a record at the table | |
* @return array | |
*/ | |
protected function filter($row) | |
{ | |
$row = (array)$row; | |
foreach ($row as $k => $v) { | |
if (is_numeric($v) && strpos($v, '.') === false) { | |
$row[$k] = (int)$v; | |
} | |
} | |
return $row; | |
} | |
/** | |
* main() | |
* @param string table name | |
* @param string $idStr | |
* @param bool $overwrite | |
* @return void | |
*/ | |
public function main($table, $idStr = '', $overwrite = false) | |
{ | |
$table = preg_replace('/\W/', '', $table); | |
list($idList, $idRange) = $this->parseIdStr($idStr); | |
$sql = $this->buildQuery($table, $idList, $idRange); | |
$conn = ConnectionManager::get(self::DB_CONFIG_NAME); | |
$dbResult = $conn->execute($sql)->fetchAll('assoc'); | |
$result = []; | |
foreach ($dbResult as $row) { | |
$row = $this->filter($row); | |
$result[] = $row; | |
} | |
$className = Inflector::camelize($table) . 'Fixture'; | |
$filepath = $this->safeSavingFilePath($className, $overwrite); | |
$date = date('Y-m-d H:i:s'); | |
$var = var_export($result, true); | |
$file = <<<EOT | |
<?php | |
/** | |
* {$table} fixture | |
* auto generated by GenFixtureFromDbShell | |
* {$date} | |
*/ | |
namespace App\Test\Fixture; | |
use Cake\TestSuite\Fixture\TestFixture; | |
class {$className} extends TestFixture | |
{ | |
/** | |
* records set | |
* @var array | |
*/ | |
public \$records = {$var}; | |
} | |
EOT; | |
echo "$filepath" . PHP_EOL; | |
echo $file . PHP_EOL; | |
file_put_contents("$filepath", $file); | |
} | |
/** | |
* parse id param argument | |
* @param string $idStr | |
* @return array | |
*/ | |
protected function parseIdStr($idStr) | |
{ | |
$idList = []; | |
$idRange = []; | |
if (! empty($idStr)) { | |
$tmp = explode(',', trim($idStr . ',')); | |
foreach ($tmp as $part) { | |
if (strpos($part, '..') !== false) { | |
$tmp2 = explode('..', $part); | |
$idRange[] = [ | |
'min' => (int)$tmp[0] ?? null, | |
'max' => (int)$tmp[1] ?? null, | |
]; | |
} else { | |
$idList[] = (int)$part; | |
} | |
} | |
} | |
return [$idList, $idRange]; | |
} | |
/** | |
* build query by proccessed id params | |
* @param string $table | |
* @param array $idList | |
* @param array $idRange | |
* @return string as SQL | |
*/ | |
protected function buildQuery($table, $idList, $idRange) | |
{ | |
$sql = "SELECT * FROM {$table} "; | |
$sqlWhere = []; | |
if (count($idList) > 0) { | |
foreach ($idList as $k => $id) $idList[$k] = (int)$id; | |
$sqlWhere[] = '( `id` IN (' . join(',', $idList) . ') )'; | |
} | |
foreach ($idRange as $set) { | |
$where = ''; | |
if ($set['min']) { | |
$where = '`id` >= ' . (int)$set['min']; | |
} | |
if ($set['min'] && $set['max']) { | |
$where .= ' and '; | |
} | |
if ($set['max']) { | |
$where .= '`id` <= ' . (int)$set['max']; | |
} | |
if ($where) { | |
$sqlWhere[] = "( {$where} )"; | |
} | |
} | |
if (count($sqlWhere)) { | |
$sql .= ' WHERE ' . join(' OR ', $sqlWhere); | |
} | |
return $sql; | |
} | |
/** | |
* get available save path | |
* @param string $className | |
* @param bool $overwrite | |
* @return string | |
*/ | |
protected function safeSavingFilePath($className, $overwrite) | |
{ | |
$dir = TESTS . '/Fixture'; | |
if (! file_exists($dir) && ! mkdir($dir, 0755, true)) { | |
throw new \Exception("Fixture directory not exist (And failed make)"); | |
} | |
$filename = $className . '.php'; | |
if (file_exists("{$dir}/{$filename}") && ! $overwrite) { | |
throw new \Exception('Fixture already exist. you can overwrite with the option: set 3rd arg = true ' . "{$dir}/{$filename}"); | |
} | |
return "{$dir}/{$filename}"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment