From d1bf685ea867e9d166ff416f62015e8bc5fd3b4e Mon Sep 17 00:00:00 2001 From: Jesper Skytte Marcussen Date: Thu, 13 Oct 2022 10:39:51 +0200 Subject: [PATCH] Added lots of new tests for `InitCommand` (#11106) This commit adds tests for all the different input options. --- .../Composer/Test/Command/InitCommandTest.php | 562 ++++++++++++++++++ 1 file changed, 562 insertions(+) diff --git a/tests/Composer/Test/Command/InitCommandTest.php b/tests/Composer/Test/Command/InitCommandTest.php index ae1a6184c..6030868ef 100644 --- a/tests/Composer/Test/Command/InitCommandTest.php +++ b/tests/Composer/Test/Command/InitCommandTest.php @@ -13,7 +13,9 @@ 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 { @@ -134,4 +136,564 @@ class InitCommandTest extends TestCase 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 + { + $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()); + } + + public function testRunRequireOne(): 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()); + } + + public function testRunRequireMultiple(): 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', + ], + ]); + } + + public function testRunRequireDevOne(): 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', + ], + ]); + } + + 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 + { + $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/' + ]; + + $file = new JsonFile($dir . '/composer.json'); + $this->assertEquals($expected, $file->read()); + } + + public function testRunInvalidHomepage(): 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', + '--homepage' => 'not-a-url', + ], ['capture_stderr_separately' => true]); + + $this->assertSame(1, $appTester->getStatusCode()); + $this->assertMatchesRegularExpression("/homepage\s*:\s*Invalid URL format/", $appTester->getErrorOutput()); + } + + public function testRunDescription(): 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', + '--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()); + } + + public function testRunType(): 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()); + } + + public function testRunLicense(): 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', + '--license' => 'MIT' + ]); + + $this->assertSame(0, $appTester->getStatusCode()); + + $expected = [ + 'name' => 'test/pkg', + 'require' => [], + 'license' => 'MIT' + ]; + + $file = new JsonFile($dir . '/composer.json'); + $this->assertEquals($expected, $file->read()); + } }