diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5b2298c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: CI + +on: [push] + +jobs: + build-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4.1.6 + - name: Composer (php-actions) + uses: php-actions/composer@v6 + - name: PHP Static Analysis + uses: php-actions/composer@v6 + with: + command: phpstan + - name: PHP Check style + uses: php-actions/composer@v6 + with: + command: phpcs + - name: PHP Mess detector + uses: php-actions/composer@v6 + with: + command: phpmd + - name: PHP Unit tests + uses: php-actions/composer@v6 + with: + command: phpunit diff --git a/.gitignore b/.gitignore index c7c91bd..673d77e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,15 @@ /sql/* /.dbup/* /.idea/* +/.vscode/* /.DS_Store /phpunit.phar /composer.phar /php-cs-fixer.phar -/phpunit.xml /composer.lock + +.phpunit.result.cache + +.phpunit.cache/ + +dbup.phar diff --git a/CHANGELOG.md b/CHANGELOG.md index e96eef6..abaefd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,13 @@ CHANGELOG ========= +* 0.6 (2024-05-30) + + * 220e42d feat: added a few analyzers + * fe92f76 fix: type hints and other changes, from static analyzers + * 0.5 (2014-10-06) + * c44b0f8 Fix url of phpunit.phar * 327bbf1 Option --ini is optional in CreateCommand. * 4bdd259 Fixing timstamp pattern to day with leading zeros in CreateCommand. diff --git a/composer.json b/composer.json index 3460be2..eec613d 100644 --- a/composer.json +++ b/composer.json @@ -1,20 +1,24 @@ { "name": "brtriver/dbup", + "version": "0.6", "description": "simple migration tool with PDO", "keywords": ["migration", "database"], "homepage": "http://1ms.jp/", "type": "library", "require": { - "php": ">=5.4.0", + "php": ">=8.1.0", "ext-pdo": "*", - "symfony/console": "~2.5.0", - "symfony/finder": "~2.5.0", - "symfony/event-dispatcher": "~2.5.0" + "symfony/console": "^3.2", + "symfony/finder": "^7.0", + "symfony/event-dispatcher": "^3.2" }, "require-dev": { - "phpunit/phpunit": "4.2.*", - "phake/phake": "v1.0.3", - "hamcrest/hamcrest-php": "1.2.0" + "phpunit/phpunit": "^11.1", + "phake/phake": "^4.5", + "hamcrest/hamcrest-php": "^2.0", + "phpstan/phpstan": "^1.11", + "squizlabs/php_codesniffer": "^3.10", + "phpmd/phpmd": "^2.15" }, "suggest": { "ext-pdo-mysql": "In order to use ikou with MySQL databases.", @@ -29,7 +33,19 @@ } ], "autoload": { - "psr-0": { "Dbup": "src/" } + "psr-0": { + "Dbup": [ + "src/", + "tests/" + ] + } }, - "bin": ["dbup"] -} \ No newline at end of file + "bin": ["dbup"], + "scripts": { + "phpstan" : "vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=-1", + "phpcs" : "vendor/bin/phpcs --standard=phpcs.xml --no-cache -s -n --file-list=phpcs.list", + "phpcbf" : "vendor/bin/phpcbf --standard=PSR12 --file-list=phpcs.list", + "phpmd" : "vendor/bin/phpmd --ignore-violations-on-exit src,dbup text phpmd.xml", + "phpunit" : "vendor/bin/phpunit" + } +} diff --git a/dbup b/dbup index 18f2c78..0d8c368 100644 --- a/dbup +++ b/dbup @@ -1,4 +1,3 @@ -#!/usr/bin/env php + dbup coding standard based on PSR12. + + + + + + + + + + + + diff --git a/phpmd.xml b/phpmd.xml new file mode 100644 index 0000000..b7b9033 --- /dev/null +++ b/phpmd.xml @@ -0,0 +1,16 @@ + + + + dbup rules for PHP Mess Detector + + + + + + + + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..4073e6c --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,6 @@ +parameters: + phpVersion: 80100 + level: 4 + paths: + - src + - dbup diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..a123a57 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,16 @@ + + + + + ./tests/Dbup/ + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index b2c7008..0000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - ./tests/Dbup/ - - - - - ./src - - - \ No newline at end of file diff --git a/src/Dbup/Application.php b/src/Dbup/Application.php index 349e1b7..483012a 100644 --- a/src/Dbup/Application.php +++ b/src/Dbup/Application.php @@ -23,16 +23,14 @@ class Application extends BaseApplication { const NAME = 'dbup'; - const VERSION = '0.5'; + const VERSION = '0.6'; /** sql file pattern */ const PATTERN = '/^V(\d+?)__.*\.sql$/i'; - /** @var null PDO */ - public $pdo = null; - public $baseDir = '.'; - public $sqlFilesDir; - public $appliedFilesDir; - /** @var string Logo AA */ - private static $logo =<<appliedFilesDir = $this->baseDir . '/.dbup/applied'; } - public function getIni() + public function getIni(): string { return $this->baseDir . '/.dbup/properties.ini'; } - public function getFinder() + public function getFinder(): Finder { return new Finder(); } - public function createPdo($dsn, $user, $password, $driverOptions) + public function createPdo(string $dsn, string|null $user, string|null $password, array|null $driverOptions): void { $this->pdo = new PdoDatabase($dsn, $user, $password, $driverOptions); } - public function parseIniFile($path) + public function parseIniFile(string $path): array|false { $ini = file_get_contents($path); $replaced = preg_replace_callback('/%%(DBUP_[^%]+)%%/', function ($matches) { list($whole, $key) = $matches; - return isset($_SERVER[$key]) ? $_SERVER[$key] : $whole; + return $_SERVER[$key] ?? $whole; }, $ini); return parse_ini_string($replaced, true); } - public function setConfigFromIni($path) + public function setConfigFromIni(string $path): void { $parse = $this->parseIniFile($path); if (!isset($parse['pdo'])) { throw new RuntimeException('cannot find [pdo] section in your properties.ini'); } $pdo = $parse['pdo']; - $dsn = (isset($pdo['dsn']))? $pdo['dsn']: ''; - $user = (isset($pdo['user']))? $pdo['user']: ''; - $password = (isset($pdo['password']))? $pdo['password']: ''; - $driverOptions = (isset($parse['pdo_options']))? $parse['pdo_options']: []; + $dsn = (isset($pdo['dsn'])) ? $pdo['dsn'] : ''; + $user = (isset($pdo['user'])) ? $pdo['user'] : ''; + $password = (isset($pdo['password'])) ? $pdo['password'] : ''; + $driverOptions = (isset($parse['pdo_options'])) ? $parse['pdo_options'] : []; if (isset($parse['path'])) { $path = $parse['path']; - $this->sqlFilesDir = (isset($path['sql']))? $path['sql']: $this->sqlFilesDir; - $this->appliedFilesDir = (isset($path['applied']))? $path['applied']: $this->appliedFilesDir; + $this->sqlFilesDir = (isset($path['sql'])) ? $path['sql'] : $this->sqlFilesDir; + $this->appliedFilesDir = (isset($path['applied'])) ? $path['applied'] : $this->appliedFilesDir; } $this->createPdo($dsn, $user, $password, $driverOptions); } - public function getHelp() + public function getHelp(): string { return self::$logo . parent::getHelp(); } /** * sort closure for Finder - * @return callable sort closure for Finder */ - public function sort() + public function sort(): \Closure { return function (\SplFileInfo $a, \SplFileInfo $b) { preg_match(self::PATTERN, $a->getFileName(), $version_a); @@ -119,28 +116,23 @@ public function sort() /** * get sql files - * @return Finder */ - public function getSqlFiles() + public function getSqlFiles(): Finder { $sqlFinder = $this->getFinder(); - $files = $sqlFinder->files() + return $sqlFinder->files() ->in($this->sqlFilesDir) ->name(self::PATTERN) ->sort($this->sort()) ; - - return $files; } /** * find sql file by the file name - * @param $fileName - * @return mixed * @throws Exception\RuntimeException */ - public function getSqlFileByName($fileName) + public function getSqlFileByName(string $fileName): \SplFileInfo|null { $sqlFinder = $this->getFinder(); @@ -153,33 +145,33 @@ public function getSqlFileByName($fileName) throw new RuntimeException('cannot find File:' . $fileName); } - foreach ($files as $file){ - return $file; + /** @var SplFileInfo $file */ + foreach ($files as $file) { + break; } + + return $file ?? null; } /** * get applied files - * @return Finder */ - public function getAppliedFiles() + public function getAppliedFiles(): Finder { $appliedFinder = $this->getFinder(); - $files = $appliedFinder->files() + return $appliedFinder->files() ->in($this->appliedFilesDir) ->name(self::PATTERN) ->sort($this->sort()) ; - - return $files; } /** * get migration status - * @return array Statuses with applied datetime and file name + * @return Status[] Statuses with applied datetime and file name */ - public function getStatuses() + public function getStatuses(): array { $files = $this->getSqlFiles(); $appliedFiles = $this->getAppliedFiles(); @@ -189,9 +181,9 @@ public function getStatuses() * @param $file * @return bool if applied, return true. */ - $isApplied = function($file) use ($appliedFiles){ + $isApplied = function ($file) use ($appliedFiles) { foreach ($appliedFiles as $appliedFile) { - if ($appliedFile->getFileName() === $file->getFileName()){ + if ($appliedFile->getFileName() === $file->getFileName()) { return true; } } @@ -200,8 +192,8 @@ public function getStatuses() $statuses = []; - foreach($files as $file){ - $appliedAt = $isApplied($file)? date('Y-m-d H:i:s', $file->getMTime()): ""; + foreach ($files as $file) { + $appliedAt = $isApplied($file) ? date('Y-m-d H:i:s', $file->getMTime()) : ""; $statuses[] = new Status($appliedAt, $file); } @@ -210,8 +202,9 @@ public function getStatuses() /** * get up candidates sql files + * @return Status[] */ - public function getUpCandidates() + public function getUpCandidates(): array { $statuses = $this->getStatuses(); @@ -225,12 +218,12 @@ public function getUpCandidates() // make statuses without being applied $candidates = []; - $isSkipped = ($latest === '')? false: true; + $isSkipped = !(($latest === '')); foreach ($statuses as $status) { if (false === $isSkipped) { $candidates[] = $status; } - if($status->file->getFileName() !== $latest) { + if ($status->file->getFileName() !== $latest) { continue; } else { $isSkipped = false; @@ -242,18 +235,25 @@ public function getUpCandidates() /** * update database - * @param $file sql file to apply */ - public function up($file) + public function up(\SplFileInfo $file): void { - if (false === ($contents = file_get_contents($file->getPathName()))) { + $contents = file_get_contents($file->getPathName()); + if (false === $contents) { throw new RuntimeException($file->getPathName() . ' is not found.'); } $queries = explode(';', $contents); + + /** @var \PDO|null $dbh */ + $dbh = null; + + /** @var string|null $cleanedQuery */ + $cleanedQuery = null; + try { $dbh = $this->pdo->connection(true); $dbh->beginTransaction(); - foreach($queries as $query) { + foreach ($queries as $query) { $cleanedQuery = trim($query); if ('' === $cleanedQuery) { continue; @@ -261,10 +261,14 @@ public function up($file) $stmt = $dbh->prepare($cleanedQuery); $stmt->execute(); } - $dbh->commit(); - } catch(\PDOException $e) { - $dbh->rollBack(); - throw new RuntimeException($e->getMessage() . PHP_EOL . $query); + if ($dbh->inTransaction()) { + $dbh->commit(); + } + } catch (\PDOException $e) { + if ($dbh != null) { + $dbh->rollBack(); + } + throw new RuntimeException($e->getMessage() . PHP_EOL . (($cleanedQuery == null) ? "" : $cleanedQuery)); } $this->copyToAppliedDir($file); @@ -272,13 +276,11 @@ public function up($file) /** * copy applied sql file to the applied directory. - * - * @param SplFileInfo $file */ - public function copyToAppliedDir($file) + public function copyToAppliedDir(\SplFileInfo $file): void { - if (false === @copy($file->getPathName(), $this->appliedFilesDir . '/' . $file->getFileName())) { - throw new RuntimeException('cannot copy the sql file to applied directory. check the '. $this->appliedFilesDir . ' directory.'); + if (false === copy($file->getPathName(), $this->appliedFilesDir . '/' . $file->getFileName())) { + throw new RuntimeException('cannot copy the sql file to applied directory. check the ' . $this->appliedFilesDir . ' directory.'); } } } diff --git a/src/Dbup/Command/CompileCommand.php b/src/Dbup/Command/CompileCommand.php index 31c8899..9e2eb84 100644 --- a/src/Dbup/Command/CompileCommand.php +++ b/src/Dbup/Command/CompileCommand.php @@ -12,11 +12,8 @@ namespace Dbup\Command; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use Dbup\Exception\RuntimeException; use Dbup\Util\Compiler; /** @@ -24,7 +21,7 @@ */ class CompileCommand extends Command { - protected function configure() + protected function configure(): void { $this ->setName('compile') @@ -35,9 +32,11 @@ protected function configure() ; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int|null { $compiler = new Compiler(); $compiler->compile(); + + return null; } } diff --git a/src/Dbup/Command/CreateCommand.php b/src/Dbup/Command/CreateCommand.php index b546798..fb12bf9 100644 --- a/src/Dbup/Command/CreateCommand.php +++ b/src/Dbup/Command/CreateCommand.php @@ -2,6 +2,7 @@ namespace Dbup\Command; +use Dbup\Application; use Dbup\Exception\RuntimeException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -11,8 +12,7 @@ class CreateCommand extends Command { - - protected function configure () + protected function configure(): void { $this->setName('create') ->setDescription('Create a migration') @@ -27,9 +27,11 @@ protected function configure () '); } - protected function execute (InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int|null { $ini = $input->getOption('ini'); + + /** @var Application $app */ $app = $this->getApplication(); if (!$ini) { @@ -53,5 +55,7 @@ protected function execute (InputInterface $input, OutputInterface $output) } $output->writeln("Migration '{$fileName}' created."); + + return null; } } diff --git a/src/Dbup/Command/InitCommand.php b/src/Dbup/Command/InitCommand.php index b13530c..288938b 100644 --- a/src/Dbup/Command/InitCommand.php +++ b/src/Dbup/Command/InitCommand.php @@ -12,9 +12,7 @@ namespace Dbup\Command; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Dbup\Exception\RuntimeException; @@ -23,7 +21,7 @@ */ class InitCommand extends Command { - protected function configure() + protected function configure(): void { $this ->setName('init') @@ -35,7 +33,7 @@ protected function configure() ; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int|null { $path = './.dbup/properties.ini'; $output->writeln('create properties.ini: ' . $path); @@ -50,7 +48,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } } - $properties =<<writeln('create directory ' . $dir); if (!is_dir($dir)) { if (false === mkdir($dir, 0777 - umask(), true)) { @@ -85,7 +83,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } } - $sample =<<writeln('done.'); + + return null; } } diff --git a/src/Dbup/Command/StatusCommand.php b/src/Dbup/Command/StatusCommand.php index 69442b7..30b5add 100644 --- a/src/Dbup/Command/StatusCommand.php +++ b/src/Dbup/Command/StatusCommand.php @@ -11,19 +11,21 @@ namespace Dbup\Command; +use Dbup\Application; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Dbup\Exception\RuntimeException; +use Symfony\Component\Console\Helper\TableHelper; /** * @author Masao Maeda */ class StatusCommand extends Command { - protected function configure() + protected function configure(): void { $this ->setName('status') @@ -43,8 +45,9 @@ protected function configure() ; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int|null { + /** @var Application $app */ $app = $this->getApplication(); $ini = $input->getOption('ini'); if (!$ini) { @@ -61,17 +64,18 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln('dbup migration status'); $rows = []; - foreach($statuses as $status){ - $appliedAt = $status->appliedAt === '' ? "appending...": $status->appliedAt; + foreach ($statuses as $status) { + $appliedAt = $status->appliedAt === '' ? "appending..." : $status->appliedAt; $rows[] = [$appliedAt, $status->file->getFileName()]; } - $table = $app->getHelperSet()->get('table'); + $table = new Table($output); $table ->setHeaders(['Applied At', 'Migration Sql File']) ->setRows($rows) ; - $table->render($output); + $table->render(); + return null; } } diff --git a/src/Dbup/Command/UpCommand.php b/src/Dbup/Command/UpCommand.php index c833798..89fd65d 100644 --- a/src/Dbup/Command/UpCommand.php +++ b/src/Dbup/Command/UpCommand.php @@ -11,7 +11,9 @@ namespace Dbup\Command; +use Dbup\Application; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -23,7 +25,7 @@ */ class UpCommand extends Command { - protected function configure() + protected function configure(): void { $this ->setName('up') @@ -64,8 +66,9 @@ protected function configure() ; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int|null { + /** @var Application $app */ $app = $this->getApplication(); $ini = $input->getOption('ini'); if (!$ini) { @@ -81,13 +84,14 @@ protected function execute(InputInterface $input, OutputInterface $output) } $app->setConfigFromIni($ini); - if ($fileName = $input->getArgument('file')) { + $fileName = $input->getArgument('file'); + if ($fileName) { $file = $app->getSqlFileByName($fileName); $output->writeln('applying specific sql file ... :' . $file->getFileName()); if (!$isDryRun) { $app->up($file); } - $sql =file_get_contents($file->getPathName()); + $sql = file_get_contents($file->getPathName()); $output->writeln(<<executed sql: $sql @@ -100,21 +104,22 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln('success to up.'); + return null; } - protected function upAllUnAppliedFiles($app, OutputInterface $output, $isDryRun) + protected function upAllUnAppliedFiles($app, OutputInterface $output, $isDryRun): void { $statuses = $app->getUpCandidates(); - $progress = $app->getHelperSet()->get('progress'); - $progress->start($output, count($statuses)); + $progress = new ProgressBar($output); + $progress->start(count($statuses)); foreach ($statuses as $status) { $output->writeln('applying... :' . $status->file->getFileName()); if (!$isDryRun) { $app->up($status->file); } - $sql =file_get_contents($status->file->getPathName()); + $sql = file_get_contents($status->file->getPathName()); $output->writeln(<<executed sql: $sql @@ -125,6 +130,5 @@ protected function upAllUnAppliedFiles($app, OutputInterface $output, $isDryRun) } $progress->finish(); - } } diff --git a/src/Dbup/Database/PdoDatabase.php b/src/Dbup/Database/PdoDatabase.php index f9e0b83..d3a4c52 100644 --- a/src/Dbup/Database/PdoDatabase.php +++ b/src/Dbup/Database/PdoDatabase.php @@ -1,17 +1,18 @@ dsn = $dsn; $this->user = $user; @@ -19,15 +20,17 @@ public function __construct($dsn, $user, $password, $driverOptions = []) $this->driverOptions = $driverOptions; } - public function connection($new = false){ + public function connection($new = false): \PDO + { if (null === $this->connection || true === $new) { try { - $this->connection = new \PDO($this->dsn, $this->user, $this->password, $this->driverOptions); + $this->connection = new PDO($this->dsn, $this->user, $this->password, $this->driverOptions); $this->connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - } catch(\PDOException $e) { + $this->connection->setAttribute(\PDO::ATTR_AUTOCOMMIT, false); + } catch (\PDOException $e) { throw new RuntimeException($e->getMessage()); } } return $this->connection; } -} \ No newline at end of file +} diff --git a/src/Dbup/Exception/RuntimeException.php b/src/Dbup/Exception/RuntimeException.php index af06b2b..9096ba8 100644 --- a/src/Dbup/Exception/RuntimeException.php +++ b/src/Dbup/Exception/RuntimeException.php @@ -1,4 +1,7 @@ appliedAt = $appliedAt; $this->file = $file; } -} \ No newline at end of file +} diff --git a/src/Dbup/Util/Compiler.php b/src/Dbup/Util/Compiler.php index f45cfe6..fb95724 100644 --- a/src/Dbup/Util/Compiler.php +++ b/src/Dbup/Util/Compiler.php @@ -1,32 +1,38 @@ setSignatureAlgorithm(\Phar::SHA1); - $phar->startBuffering(); - // CLI Component files + $output = new ConsoleOutput(); + $progress = new ProgressBar($output); + $progress->start(count($this->getFiles())); + foreach ($this->getFiles() as $file) { $phar->addFromString($file->getPathName(), file_get_contents($file)); + $progress->advance(); } + $progress->finish(); $this->addDbup($phar); - // Stubs $phar->setStub($this->getStub()); $phar->stopBuffering(); - unset($phar); chmod($pharFile, 0777); } @@ -34,17 +40,16 @@ public function compile($pharFile = 'dbup.phar') /** * Remove the shebang from the file before add it to the PHAR file. * - * @param \Phar $phar PHAR instance + * @param Phar $phar PHAR instance */ - protected function addDbup(\Phar $phar) + protected function addDbup(\Phar $phar): void { $content = file_get_contents(__DIR__ . '/../../../dbup'); $content = preg_replace('{^#!/usr/bin/env php\s*}', '', $content); - $phar->addFromString('dbup', $content); } - protected function getStub() + protected function getStub(): string { return <<files()->exclude('tests')->name('*.php')->in(array('vendor', 'src')); - + $srcIterator = $finder + ->files() + ->in([ + 'vendor', + 'src' + ]) + ->exclude([ + 'phpunit', + 'phake', + 'hamcrest', + 'phpstan', + 'squizlabs', + 'phpmd' + ]) + ->name('*.php'); return iterator_to_array($srcIterator); } -} \ No newline at end of file +} diff --git a/tests/Dbup/ApplicationTest.php b/tests/Dbup/Tests/ApplicationTest.php similarity index 66% rename from tests/Dbup/ApplicationTest.php rename to tests/Dbup/Tests/ApplicationTest.php index a011cd2..78bd50c 100644 --- a/tests/Dbup/ApplicationTest.php +++ b/tests/Dbup/Tests/ApplicationTest.php @@ -2,22 +2,33 @@ namespace Dbup\Tests; use Dbup\Application; +use PHPUnit\Framework\TestCase; use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\SplFileInfo; -Class ApplicationTest extends \PHPUnit_Framework_TestCase +Class ApplicationTest extends TestCase { public $app; public $pdo; - public function setUP() + private \PDO $dbh; + private \PDOStatement $stmt; + + public function setUp() : void { $this->app = \Phake::partialMock('Dbup\Application'); $this->pdo = \Phake::mock('Dbup\Database\PdoDatabase'); - $this->dbh = \Phake::mock('\Pdo'); + $this->dbh = \Phake::mock('\PDO'); \Phake::when($this->pdo)->connection(\Phake::anyParameters())->thenReturn($this->dbh); $this->stmt = \Phake::mock('\PDOStatement'); \Phake::when($this->dbh)->prepare(\Phake::anyParameters())->thenReturn($this->stmt); + + \Hamcrest\Util::registerGlobalFunctions(); + } + + public function tearDown(): void + { + $this->addToAssertionCount(\Hamcrest\MatcherAssert::getCount()); } public function testSetPropertiesWhenInstanceIsMade() @@ -38,7 +49,7 @@ public function testParseIniFileReplaceVariables() $_SERVER['DBUP_TEST_HOST'] = 'replaced_host'; $_SERVER['OTHER_PREFIX_DBUP_TEST_PASSWORD'] = 'replaced_password'; - $ini = __DIR__ . '/.dbup/properties.ini.replace'; + $ini = __DIR__ . '/../.dbup/properties.ini.replace'; $parsed = $this->app->parseIniFile($ini)['pdo']; assertThat($parsed['dsn'], is('replaced_dbms:dbname=replaced_user_replaced_host_%%DBUP_TEST_NOT_REPLACED%%;host=replaced_host')); @@ -48,7 +59,7 @@ public function testParseIniFileReplaceVariables() public function testSetConfigFromIni() { - $ini = __DIR__ . '/.dbup/properties.ini'; + $ini = __DIR__ . '/../.dbup/properties.ini'; $this->app->setConfigFromIni($ini); assertThat($this->app->sqlFilesDir, is('/etc/dbup/sql')); @@ -56,18 +67,16 @@ public function testSetConfigFromIni() \Phake::verify($this->app)->createPdo('mysql:dbname=testdatabase;host=localhost', 'testuser', 'testpassword', ['\PDO::MYSQL_ATTR_LOCAL_INFILE' => 1]); } - /** - * @expectedException Dbup\Exception\RuntimeException - */ public function testCatchExceptionSetConfigFromEmptyIni() { - $ini = __DIR__ . '/.dbup/properties.ini.empty'; + $this->expectException(\Dbup\Exception\RuntimeException::class); + $ini = __DIR__ . '/../.dbup/properties.ini.empty'; $this->app->setConfigFromIni($ini); } public function testSetConfigFromMinIni() { - $ini = __DIR__ . '/.dbup/properties.ini.min'; + $ini = __DIR__ . '/../.dbup/properties.ini.min'; $this->app->setConfigFromIni($ini); \Phake::verify($this->app)->createPdo('mysql:dbname=testdatabase;host=localhost', '', '', []); @@ -75,24 +84,22 @@ public function testSetConfigFromMinIni() public function testGetSqlFileByName() { - $this->app->sqlFilesDir = __DIR__ . '/sql'; + $this->app->sqlFilesDir = __DIR__ . '/../sql'; $file = $this->app->getSqlFileByName('V1__sample_select.sql'); assertThat($file->getFileName(), is('V1__sample_select.sql')); } - /** - * @expectedException Dbup\Exception\RuntimeException - */ public function testCatchExceptionWhenNotFoundSqlFileByName() { - $this->app->sqlFilesDir = __DIR__ . '/sql'; + $this->expectException(\Dbup\Exception\RuntimeException::class); + $this->app->sqlFilesDir = __DIR__ . '/../sql'; $this->app->getSqlFileByName('hoge'); } public function testGetStatuses() { - $this->app->sqlFilesDir = __DIR__ . '/sql'; - $this->app->appliedFilesDir = __DIR__ . '/.dbup/applied'; + $this->app->sqlFilesDir = __DIR__ . '/../sql'; + $this->app->appliedFilesDir = __DIR__ . '/../.dbup/applied'; $statuses = $this->app->getStatuses(); @@ -107,8 +114,8 @@ public function testGetStatuses() public function testGetUpCandidates() { - $this->app->sqlFilesDir = __DIR__ . '/sql'; - $this->app->appliedFilesDir = __DIR__ . '/.dbup/applied'; + $this->app->sqlFilesDir = __DIR__ . '/../sql'; + $this->app->appliedFilesDir = __DIR__ . '/../.dbup/applied'; $candidates = $this->app->getUpCandidates(); @@ -117,63 +124,59 @@ public function testGetUpCandidates() assertThat($candidates[1]->file->getFileName(), is('V12__sample12_select.sql')); } - /** - * @expectedException Dbup\Exception\RuntimeException - */ public function testCatchExceptionCopyToAppliedDir() { - $this->app->appliedFilesDir = __DIR__ . '/nondir'; - $file = new \SplFileInfo(__DIR__ . '/samples/plural.sql'); + $this->expectException(\Dbup\Exception\RuntimeException::class); + $this->app->appliedFilesDir = __DIR__ . '/../../nondir'; + $file = new \SplFileInfo(__DIR__ . '/../samples/plural.sql'); $this->app->copyToAppliedDir($file); } public function testCopyToAppliedDir() { - @unlink(__DIR__ . '/.dbup/applied/single.sql'); + @unlink(__DIR__ . '/../.dbup/applied/single.sql'); - $this->app->appliedFilesDir = __DIR__ . '/.dbup/applied'; - $file = new \SplFileInfo(__DIR__ . '/samples/single.sql'); + $this->app->appliedFilesDir = __DIR__ . '/../.dbup/applied'; + $file = new \SplFileInfo(__DIR__ . '/../samples/single.sql'); $this->app->copyToAppliedDir($file); - assertThat(file_exists(__DIR__ . '/.dbup/applied/single.sql'), is(true)); + assertThat(file_exists(__DIR__ . '/../.dbup/applied/single.sql'), is(true)); - @unlink(__DIR__ . '/.dbup/applied/single.sql'); + @unlink(__DIR__ . '/../.dbup/applied/single.sql'); } public function testUpWithSingleStatementSqlFile() { - $this->app->appliedFilesDir = __DIR__ . '/.dbup/applied'; + $this->app->appliedFilesDir = __DIR__ . '/../.dbup/applied'; $this->app->pdo = $this->pdo; - $file = new \SplFileInfo(__DIR__ . '/samples/single.sql'); + $file = new \SplFileInfo(__DIR__ . '/../samples/single.sql'); $this->app->up($file); \Phake::verify($this->dbh, \Phake::times(1))->prepare('select 1+1'); - @unlink(__DIR__ . '/.dbup/applied/single.sql'); + @unlink(__DIR__ . '/../.dbup/applied/single.sql'); } public function testUpWithPluralStatementsSqlFile() { - $this->app->appliedFilesDir = __DIR__ . '/.dbup/applied'; + $this->app->appliedFilesDir = __DIR__ . '/../.dbup/applied'; $this->app->pdo = $this->pdo; - $file = new \SplFileInfo(__DIR__ . '/samples/plural.sql'); + $file = new \SplFileInfo(__DIR__ . '/../samples/plural.sql'); $this->app->up($file); \Phake::verify($this->dbh, \Phake::times(1))->prepare('select 1+1'); \Phake::verify($this->dbh, \Phake::times(1))->prepare('select 2+2'); - @unlink(__DIR__ . '/.dbup/applied/plural.sql'); + @unlink(__DIR__ . '/../.dbup/applied/plural.sql'); } - /** - * @expectedException Dbup\Exception\RuntimeException - */ public function testCatchExceptionWhenUp() { + $this->expectException(\Dbup\Exception\RuntimeException::class); $this->app->pdo = $this->pdo; - $file = new \SplFileInfo(__DIR__ . '/samples/single.sql'); + $file = new \SplFileInfo(__DIR__ . '/../samples/single.sql'); \Phake::when($this->dbh)->prepare(\Phake::anyParameters())->thenThrow(new \PDOException); @@ -185,14 +188,14 @@ public function testCatchExceptionWhenUp() */ public function testUpWithSingleStatementWithEmptyLineSqlFile() { - $this->app->appliedFilesDir = __DIR__ . '/.dbup/applied'; + $this->app->appliedFilesDir = __DIR__ . '/../.dbup/applied'; $this->app->pdo = $this->pdo; - $file = new \SplFileInfo(__DIR__ . '/samples/singleWithEmpty.sql'); + $file = new \SplFileInfo(__DIR__ . '/../samples/singleWithEmpty.sql'); $this->app->up($file); \Phake::verify($this->dbh, \Phake::times(1))->prepare(\Phake::anyParameters()); - @unlink(__DIR__ . '/.dbup/applied/single.sql'); + @unlink(__DIR__ . '/../.dbup/applied/single.sql'); } } diff --git a/tests/Dbup/Command/CreateCommandTest.php b/tests/Dbup/Tests/Command/CreateCommandTest.php similarity index 66% rename from tests/Dbup/Command/CreateCommandTest.php rename to tests/Dbup/Tests/Command/CreateCommandTest.php index 857c153..e8cf751 100644 --- a/tests/Dbup/Command/CreateCommandTest.php +++ b/tests/Dbup/Tests/Command/CreateCommandTest.php @@ -3,11 +3,22 @@ use Dbup\Application; use Dbup\Command\CreateCommand; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Dbup\Command\InitCommand; -class CreateCommandTest extends \PHPUnit_Framework_TestCase +class CreateCommandTest extends TestCase { + public function setUp() : void + { + \Hamcrest\Util::registerGlobalFunctions(); + } + + public function tearDown(): void + { + $this->addToAssertionCount(\Hamcrest\MatcherAssert::getCount()); + } + public function testCreate() { $application = \Phake::partialMock('Dbup\Application'); @@ -19,7 +30,7 @@ public function testCreate() [ 'command' => $command->getName(), 'name' => 'foo', - '--ini' => __DIR__ . '/../.dbup/properties.ini.test', + '--ini' => __DIR__ . '/../../.dbup/properties.ini.test', ] ); @@ -30,6 +41,6 @@ public function testCreate() assertThat(1, count($matches)); $migration = str_replace("'", "", $matches[0]); - unlink(__DIR__ . '/../../../' . $migration); + unlink(__DIR__ . '/../../../../' . $migration); } } diff --git a/tests/Dbup/Command/InitCommandTest.php b/tests/Dbup/Tests/Command/InitCommandTest.php similarity index 66% rename from tests/Dbup/Command/InitCommandTest.php rename to tests/Dbup/Tests/Command/InitCommandTest.php index 743d53f..8a81473 100644 --- a/tests/Dbup/Command/InitCommandTest.php +++ b/tests/Dbup/Tests/Command/InitCommandTest.php @@ -2,24 +2,35 @@ namespace Dbup\Tests\Command; use Dbup\Application; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Dbup\Command\InitCommand; -class InitCommandTest extends \PHPUnit_Framework_TestCase +class InitCommandTest extends TestCase { + public function setUp() : void + { + \Hamcrest\Util::registerGlobalFunctions(); + } + + public function tearDown(): void + { + $this->addToAssertionCount(\Hamcrest\MatcherAssert::getCount()); + } + public function testInitializeDirsAndFiles() { /** * dirs and files to create. */ $dirs = [ - __DIR__ . '/../../../sql', - __DIR__ . '/../../../.dbup/applied', - __DIR__ . '/../../../.dbup', + __DIR__ . '/../../../../sql', + __DIR__ . '/../../../../.dbup/applied', + __DIR__ . '/../../../../.dbup', ]; $files = [ - __DIR__ . '/../../../sql/V1__sample_select.sql', - __DIR__ . '/../../../.dbup/properties.ini', + __DIR__ . '/../../../../sql/V1__sample_select.sql', + __DIR__ . '/../../../../.dbup/properties.ini', ]; /** diff --git a/tests/Dbup/Command/statusCommandTest.php b/tests/Dbup/Tests/Command/StatusCommandTest.php similarity index 68% rename from tests/Dbup/Command/statusCommandTest.php rename to tests/Dbup/Tests/Command/StatusCommandTest.php index 08202db..af81bf4 100644 --- a/tests/Dbup/Command/statusCommandTest.php +++ b/tests/Dbup/Tests/Command/StatusCommandTest.php @@ -2,11 +2,22 @@ namespace Dbup\Tests\Command; use Dbup\Application; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Dbup\Command\StatusCommand; -class StatusCommandTest extends \PHPUnit_Framework_TestCase +class StatusCommandTest extends TestCase { + public function setUp() : void + { + \Hamcrest\Util::registerGlobalFunctions(); + } + + public function tearDown(): void + { + $this->addToAssertionCount(\Hamcrest\MatcherAssert::getCount()); + } + public function testSpecificPropertiesIni() { $application = new Application(); @@ -15,17 +26,15 @@ public function testSpecificPropertiesIni() $command = $application->find('status'); $commandTester = new CommandTester($command); $commandTester->execute(['command' => $command->getName(), - '--ini' => __DIR__ . '/../.dbup/properties.ini.test', + '--ini' => __DIR__ . '/../../.dbup/properties.ini.test', ]); assertThat($commandTester->getDisplay(), is(containsString('| appending... | V12__sample12_select.sql |'))); } - /** - * @expectedException Dbup\Exception\RuntimeException - */ public function testCatchExceptionNonExistIni() { + $this->expectException(\Dbup\Exception\RuntimeException::class); $application = new Application(); $application->add(new StatusCommand()); diff --git a/tests/Dbup/Command/upCommandTest.php b/tests/Dbup/Tests/Command/UpCommandTest.php similarity index 79% rename from tests/Dbup/Command/upCommandTest.php rename to tests/Dbup/Tests/Command/UpCommandTest.php index 494e8a9..9958ab3 100644 --- a/tests/Dbup/Command/upCommandTest.php +++ b/tests/Dbup/Tests/Command/UpCommandTest.php @@ -2,11 +2,22 @@ namespace Dbup\Tests\Command; use Dbup\Application; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Dbup\Command\UpCommand; -class UpCommandTest extends \PHPUnit_Framework_TestCase +class UpCommandTest extends TestCase { + public function setUp() : void + { + \Hamcrest\Util::registerGlobalFunctions(); + } + + public function tearDown(): void + { + $this->addToAssertionCount(\Hamcrest\MatcherAssert::getCount()); + } + public function testDryRunMode() { $application = \Phake::partialMock('Dbup\Application'); @@ -15,7 +26,7 @@ public function testDryRunMode() $command = $application->find('up'); $commandTester = new CommandTester($command); $commandTester->execute(['command' => $command->getName(), - '--ini' => __DIR__ . '/../.dbup/properties.ini.test', + '--ini' => __DIR__ . '/../../.dbup/properties.ini.test', '--dry-run' => true, ]); assertThat($commandTester->getDisplay(), is(containsString('now up is dry-run mode (--dry-run), so display only'))); @@ -28,13 +39,12 @@ public function testSomeUp() $application = \Phake::partialMock('Dbup\Application'); /** want not to run, so change up method to mock */ \Phake::when($application)->up(\Phake::anyParameters())->thenReturn(null); - $application->add(new UpCommand()); $command = $application->find('up'); $commandTester = new CommandTester($command); $commandTester->execute(['command' => $command->getName(), - '--ini' => __DIR__ . '/../.dbup/properties.ini.test', + '--ini' => __DIR__ . '/../../.dbup/properties.ini.test', ]); \Phake::verify($application, \Phake::times(2))->up(\Phake::anyParameters()); @@ -51,7 +61,7 @@ public function testSpecificSqlFile() $command = $application->find('up'); $commandTester = new CommandTester($command); $commandTester->execute(['command' => $command->getName(), - '--ini' => __DIR__ . '/../.dbup/properties.ini.test', + '--ini' => __DIR__ . '/../../.dbup/properties.ini.test', 'file' => 'V12__sample12_select.sql', ]); diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index 406ca78..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,3 +0,0 @@ -add('Dbup\Tests', __DIR__); \ No newline at end of file