From ff49b3bb47371221ddce8f6e07c56bdfef659a8d Mon Sep 17 00:00:00 2001 From: Jakob Vibe Date: Thu, 5 Oct 2023 18:44:09 +0200 Subject: [PATCH 1/2] Added tests --- .../Composer/Test/Command/InitCommandTest.php | 589 ++---------------- 1 file changed, 45 insertions(+), 544 deletions(-) diff --git a/tests/Composer/Test/Command/InitCommandTest.php b/tests/Composer/Test/Command/InitCommandTest.php index 6030868ef4e4..9965dc9a55c7 100644 --- a/tests/Composer/Test/Command/InitCommandTest.php +++ b/tests/Composer/Test/Command/InitCommandTest.php @@ -13,9 +13,7 @@ namespace Composer\Test\Command; use Composer\Command\InitCommand; -use Composer\Json\JsonFile; use Composer\Test\TestCase; -use Symfony\Component\Console\Tester\ApplicationTester; class InitCommandTest extends TestCase { @@ -126,574 +124,77 @@ public function testNamespaceFromMissingPackageName(): void $this->assertNull($namespace); } - /** - * @return array{name: string, email: string|null} - */ - private function callParseAuthorString(InitCommand $command, string $string): array - { - $reflMethod = new \ReflectionMethod($command, 'parseAuthorString'); - $reflMethod->setAccessible(true); - - return $reflMethod->invoke($command, $string); - } - - public function testRunNoInteraction(): void - { - $this->expectException(\RuntimeException::class); - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run(['command' => 'init', '--no-interaction' => true]); - } - - public function testRunInvalidNameArgument(): void - { - $this->expectException(\InvalidArgumentException::class); - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run(['command' => 'init', '--no-interaction' => true, '--name' => 'test']); - } - - public function testRunNameArgument(): void - { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run(['command' => 'init', '--no-interaction' => true, '--name' => 'test/pkg']); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunInvalidAuthorArgumentInvalidEmail(): void - { - $this->expectException(\InvalidArgumentException::class); - - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--author' => 'Mr. Test ', - ]); - } - - public function testRunAuthorArgument(): void - { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--author' => 'Mr. Test ', - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'authors' => [ - [ - 'name' => 'Mr. Test', - 'email' => 'test@example.org', - ] - ], - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunAuthorArgumentMissingEmail(): void - { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--author' => 'Mr. Test', - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'authors' => [ - [ - 'name' => 'Mr. Test', - ] - ], - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunSingleRepositoryArgument(): void - { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--repository' => [ - '{"type":"vcs","url":"http://packages.example.com"}' - ], - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'repositories' => [ - [ - 'type' => 'vcs', - 'url' => 'http://packages.example.com' - ] - ] - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunMultipleRepositoryArguments(): void - { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--repository' => [ - '{"type":"vcs","url":"http://vcs.example.com"}', - '{"type":"composer","url":"http://composer.example.com"}', - '{"type":"composer","url":"http://composer2.example.com","options":{"ssl":{"verify_peer":"true"}}}', - ], - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'repositories' => [ - [ - 'type' => 'vcs', - 'url' => 'http://vcs.example.com' - ], - [ - 'type' => 'composer', - 'url' => 'http://composer.example.com' - ], - [ - 'type' => 'composer', - 'url' => 'http://composer2.example.com', - 'options' => [ - 'ssl' => [ - 'verify_peer' => 'true' - ] - ] - ] - ] - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunStability(): void - { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--stability' => 'dev', - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'minimum-stability' => 'dev', - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunInvalidStability(): void + public function testFormatAuthors(): void { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--stability' => 'bogus', - ], ['capture_stderr_separately' => true]); - - $this->assertSame(1, $appTester->getStatusCode()); - - $this->assertMatchesRegularExpression("/minimum-stability\s+:\s+Does not have a value in the enumeration/", $appTester->getErrorOutput()); + $authorWithEmail = 'John Smith '; + $authorWithoutEmail = 'John Smith'; + $command = new DummyInitCommand; + $authors = $command->formatAuthors($authorWithEmail); + $this->assertEquals(['name' => 'John Smith', 'email' => 'john@example.com'], $authors[0]); + $authors = $command->formatAuthors($authorWithoutEmail); + $this->assertEquals(['name' => 'John Smith'], $authors[0]); } - public function testRunRequireOne(): void + public function testGetGitConfig(): void { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--require' => [ - 'first/pkg:1.0.0' - ], - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [ - 'first/pkg' => '1.0.0' - ], - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); + $command = new DummyInitCommand; + $gitConfig = $command->getGitConfig(); + $this->assertIsArray($gitConfig); + $this->assertArrayHasKey('user.name', $gitConfig); + $this->assertArrayHasKey('user.email', $gitConfig); + $this->assertArrayHasKey('remote.origin.url', $gitConfig); } - public function testRunRequireMultiple(): void + public function testAddVendorIgnore(): void { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--require' => [ - 'first/pkg:1.0.0', - 'second/pkg:^3.4' - ], - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [ - 'first/pkg' => '1.0.0', - 'second/pkg' => '^3.4', - ], - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunInvalidRequire(): void - { - $this->expectException(\UnexpectedValueException::class); - $this->expectExceptionMessage("Option first is missing a version constraint, use e.g. first:^1.0"); - - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--require' => [ - 'first', - ], - ]); + $command = new DummyInitCommand; + $ignoreFile = $this->getUniqueTmpDirectory().'/ignore'; + $command->addVendorIgnore($ignoreFile); + $this->assertFileExists($ignoreFile); + $this->assertStringContainsString('/vendor/', file_get_contents($ignoreFile)); } - public function testRunRequireDevOne(): void + public function testHasVendorIgnore(): void { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--require-dev' => [ - 'first/pkg:1.0.0' - ], - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'require-dev' => [ - 'first/pkg' => '1.0.0' - ], - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunRequireDevMultiple(): void - { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--require-dev' => [ - 'first/pkg:1.0.0', - 'second/pkg:^3.4' - ], - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'require-dev' => [ - 'first/pkg' => '1.0.0', - 'second/pkg' => '^3.4', - ], - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunInvalidRequireDev(): void - { - $this->expectException(\UnexpectedValueException::class); - $this->expectExceptionMessage("Option first is missing a version constraint, use e.g. first:^1.0"); - - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--require-dev' => [ - 'first', - ], - ]); + $command = new DummyInitCommand; + $ignoreFile = $this->getUniqueTmpDirectory().'/ignore'; + $this->assertFalse($command->hasVendorIgnore($ignoreFile)); + $command->addVendorIgnore($ignoreFile); + $this->assertTrue($command->hasVendorIgnore($ignoreFile)); } - public function testRunAutoload(): void - { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--autoload' => 'testMapping/' - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'autoload' => [ - 'psr-4' => [ - 'Test\\Pkg\\' => 'testMapping/', - ] - ], - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); - } - - public function testRunHomepage(): void + /** + * @return array{name: string, email: string|null} + */ + private function callParseAuthorString(InitCommand $command, string $string): array { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--homepage' => 'https://example.org/' - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'homepage' => 'https://example.org/' - ]; + $reflMethod = new \ReflectionMethod($command, 'parseAuthorString'); + $reflMethod->setAccessible(true); - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); + return $reflMethod->invoke($command, $string); } +} - public function testRunInvalidHomepage(): void +class DummyInitCommand extends InitCommand +{ + public function formatAuthors(string $author): array { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--homepage' => 'not-a-url', - ], ['capture_stderr_separately' => true]); - - $this->assertSame(1, $appTester->getStatusCode()); - $this->assertMatchesRegularExpression("/homepage\s*:\s*Invalid URL format/", $appTester->getErrorOutput()); + return parent::formatAuthors($author); } - public function testRunDescription(): void + public function getGitConfig(): array { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--description' => 'My first example package' - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'description' => 'My first example package' - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); + return parent::getGitConfig(); } - public function testRunType(): void + public function addVendorIgnore(string $ignoreFile, string $vendor = '/vendor/'): void { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--type' => 'library' - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'type' => 'library' - ]; - - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); + parent::addVendorIgnore($ignoreFile, $vendor); } - public function testRunLicense(): void + public function hasVendorIgnore(string $ignoreFile, string $vendor = 'vendor'): bool { - $dir = $this->initTempComposer(); - unlink($dir . '/composer.json'); - unlink($dir . '/auth.json'); - - $appTester = $this->getApplicationTester(); - $appTester->run([ - 'command' => 'init', - '--no-interaction' => true, - '--name' => 'test/pkg', - '--license' => 'MIT' - ]); - - $this->assertSame(0, $appTester->getStatusCode()); - - $expected = [ - 'name' => 'test/pkg', - 'require' => [], - 'license' => 'MIT' - ]; + return parent::hasVendorIgnore($ignoreFile, $vendor); - $file = new JsonFile($dir . '/composer.json'); - $this->assertEquals($expected, $file->read()); } } From 207de4ef6c8d1aa8e7a0c95a87c27213ca8c3bef Mon Sep 17 00:00:00 2001 From: Jakob Vibe Date: Thu, 5 Oct 2023 19:03:58 +0200 Subject: [PATCH 2/2] PhpStan fixes --- tests/Composer/Test/Command/InitCommandTest.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/Composer/Test/Command/InitCommandTest.php b/tests/Composer/Test/Command/InitCommandTest.php index 9965dc9a55c7..140ddd024e27 100644 --- a/tests/Composer/Test/Command/InitCommandTest.php +++ b/tests/Composer/Test/Command/InitCommandTest.php @@ -139,7 +139,6 @@ public function testGetGitConfig(): void { $command = new DummyInitCommand; $gitConfig = $command->getGitConfig(); - $this->assertIsArray($gitConfig); $this->assertArrayHasKey('user.name', $gitConfig); $this->assertArrayHasKey('user.email', $gitConfig); $this->assertArrayHasKey('remote.origin.url', $gitConfig); @@ -148,16 +147,19 @@ public function testGetGitConfig(): void public function testAddVendorIgnore(): void { $command = new DummyInitCommand; - $ignoreFile = $this->getUniqueTmpDirectory().'/ignore'; + $ignoreFile = self::getUniqueTmpDirectory().'/ignore'; $command->addVendorIgnore($ignoreFile); $this->assertFileExists($ignoreFile); - $this->assertStringContainsString('/vendor/', file_get_contents($ignoreFile)); + if (file_exists($ignoreFile)) { + $content = (string) file_get_contents($ignoreFile); + $this->assertStringContainsString('/vendor/', $content); + } } public function testHasVendorIgnore(): void { $command = new DummyInitCommand; - $ignoreFile = $this->getUniqueTmpDirectory().'/ignore'; + $ignoreFile = self::getUniqueTmpDirectory().'/ignore'; $this->assertFalse($command->hasVendorIgnore($ignoreFile)); $command->addVendorIgnore($ignoreFile); $this->assertTrue($command->hasVendorIgnore($ignoreFile));