diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..4f6e451 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,17 @@ + + + + + + tests/Unit + + + diff --git a/tests/Unit/VersionBumpTest.php b/tests/Unit/VersionBumpTest.php new file mode 100644 index 0000000..f6dd408 --- /dev/null +++ b/tests/Unit/VersionBumpTest.php @@ -0,0 +1,164 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +declare(strict_types=1); + +namespace MokoStandards\Tests\Unit; + +use PHPUnit\Framework\TestCase; + +/** + * Tests for cli/version_bump.php + */ +class VersionBumpTest extends TestCase +{ + private string $tmpDir; + private string $script; + + protected function setUp(): void + { + $this->tmpDir = sys_get_temp_dir() . '/moko-test-' . uniqid(); + mkdir($this->tmpDir, 0755, true); + $this->script = dirname(__DIR__, 2) . '/cli/version_bump.php'; + } + + protected function tearDown(): void + { + $this->rmdir($this->tmpDir); + } + + public function testPatchBump(): void + { + $this->writeReadme('01.02.03'); + $output = $this->execute(); + $this->assertStringContainsString('01.02.04', $output); + $this->assertReadmeVersion('01.02.04'); + } + + public function testPatchBumpRollover(): void + { + $this->writeReadme('01.02.99'); + $this->execute(); + $this->assertReadmeVersion('01.03.00'); + } + + public function testMinorBump(): void + { + $this->writeReadme('01.02.03'); + $this->execute(['--minor']); + $this->assertReadmeVersion('01.03.00'); + } + + public function testMajorBump(): void + { + $this->writeReadme('01.02.03'); + $this->execute(['--major']); + $this->assertReadmeVersion('02.00.00'); + } + + public function testBumpsFromHtmlComment(): void + { + file_put_contents( + "{$this->tmpDir}/README.md", + "\nSome content\n" + ); + + $this->execute(); + $content = file_get_contents("{$this->tmpDir}/README.md"); + $this->assertStringContainsString('03.05.02', $content); + $this->assertStringContainsString('Some content', $content); + } + + public function testBumpsWhenXmlHasSuffix(): void + { + $this->writeReadme('01.00.00'); + mkdir("{$this->tmpDir}/src", 0755, true); + file_put_contents( + "{$this->tmpDir}/src/test.xml", + '' + . '01.00.00-dev' + ); + + $output = $this->execute(); + $this->assertStringContainsString('01.00.01', $output); + } + + public function testFailsWithNoVersion(): void + { + file_put_contents( + "{$this->tmpDir}/README.md", + "# No version\n" + ); + + $code = 0; + $this->execute([], $code); + $this->assertSame(1, $code); + } + + private function writeReadme(string $version): void + { + file_put_contents( + "{$this->tmpDir}/README.md", + "\n" + ); + } + + private function assertReadmeVersion(string $expected): void + { + $content = file_get_contents("{$this->tmpDir}/README.md"); + $this->assertMatchesRegularExpression( + '/VERSION:\s*' . preg_quote($expected, '/') . '/', + $content + ); + } + + /** + * @param string[] $extraArgs + */ + private function execute( + array $extraArgs = [], + int &$exitCode = 0 + ): string { + $cmd = ['php', $this->script, '--path', $this->tmpDir]; + $cmd = array_merge($cmd, $extraArgs); + + $descriptors = [ + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], + ]; + + $proc = proc_open($cmd, $descriptors, $pipes); + $stdout = stream_get_contents($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + $exitCode = proc_close($proc); + + return $stdout ?: ''; + } + + private function rmdir(string $dir): void + { + if (!is_dir($dir)) { + return; + } + + $iter = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator( + $dir, + \FilesystemIterator::SKIP_DOTS + ), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ($iter as $file) { + $file->isDir() + ? rmdir($file->getPathname()) + : unlink($file->getPathname()); + } + + rmdir($dir); + } +} diff --git a/tests/Unit/VersionReadTest.php b/tests/Unit/VersionReadTest.php new file mode 100644 index 0000000..9715c29 --- /dev/null +++ b/tests/Unit/VersionReadTest.php @@ -0,0 +1,133 @@ + + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +declare(strict_types=1); + +namespace MokoStandards\Tests\Unit; + +use PHPUnit\Framework\TestCase; + +/** + * Tests for cli/version_read.php + */ +class VersionReadTest extends TestCase +{ + private string $tmpDir; + private string $script; + + protected function setUp(): void + { + $this->tmpDir = sys_get_temp_dir() . '/moko-test-' . uniqid(); + mkdir($this->tmpDir, 0755, true); + $this->script = dirname(__DIR__, 2) . '/cli/version_read.php'; + } + + protected function tearDown(): void + { + $this->rmdir($this->tmpDir); + } + + public function testReadsVersionFromReadme(): void + { + file_put_contents( + "{$this->tmpDir}/README.md", + "# Test\n\n" + ); + + $this->assertSame('02.03.04', trim($this->runScript())); + } + + public function testReadsVersionFromXmlManifest(): void + { + mkdir("{$this->tmpDir}/src", 0755, true); + file_put_contents( + "{$this->tmpDir}/src/test.xml", + '' + . '05.01.00' + ); + + $this->assertSame('05.01.00', trim($this->runScript())); + } + + public function testStripsStabilitySuffixFromXml(): void + { + mkdir("{$this->tmpDir}/src", 0755, true); + file_put_contents( + "{$this->tmpDir}/src/test.xml", + '' + . '01.00.00-dev' + ); + + $this->assertSame('01.00.00', trim($this->runScript())); + } + + public function testReturnsHigherOfReadmeAndManifest(): void + { + file_put_contents( + "{$this->tmpDir}/README.md", + "\n" + ); + mkdir("{$this->tmpDir}/src", 0755, true); + file_put_contents( + "{$this->tmpDir}/src/test.xml", + '' + . '01.03.00' + ); + + $this->assertSame('01.03.00', trim($this->runScript())); + } + + public function testExitsNonZeroWhenNoVersion(): void + { + file_put_contents( + "{$this->tmpDir}/README.md", + "# No version here\n" + ); + + $code = 0; + $this->runScript($code); + $this->assertSame(1, $code); + } + + private function runScript(int &$exitCode = 0): string + { + $proc = proc_open( + ['php', $this->script, '--path', $this->tmpDir], + [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], + $pipes + ); + + $stdout = stream_get_contents($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + $exitCode = proc_close($proc); + + return $stdout ?: ''; + } + + private function rmdir(string $dir): void + { + if (!is_dir($dir)) { + return; + } + + $iter = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator( + $dir, + \FilesystemIterator::SKIP_DOTS + ), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ($iter as $file) { + $file->isDir() + ? rmdir($file->getPathname()) + : unlink($file->getPathname()); + } + + rmdir($dir); + } +}