diff --git a/tests/Composer/Test/Command/RequireCommandTest.php b/tests/Composer/Test/Command/RequireCommandTest.php index 63662721d..11c1049a5 100644 --- a/tests/Composer/Test/Command/RequireCommandTest.php +++ b/tests/Composer/Test/Command/RequireCommandTest.php @@ -19,12 +19,14 @@ use Composer\Command\RequireCommand; use Symfony\Component\Console\Input\ArrayInput; use Composer\Console\Application; use Composer\Test\TestCase; +use Symfony\Component\Process\Process; class RequireCommandTest extends TestCase { /** * @var string */ + private $start_directory; private $working_directory; private $local_repository; @@ -55,6 +57,7 @@ class RequireCommandTest extends TestCase $manifest = [ 'name' => 'test/something', + 'require' => (object) null, 'repositories' => [ [ 'type' => 'path', @@ -71,17 +74,25 @@ class RequireCommandTest extends TestCase json_encode($manifest, JSON_UNESCAPED_SLASHES) ); + $this->start_directory = getcwd(); } protected function tearDown(): void { parent::tearDown(); + // Reset the working directory. Some commands leave the working + // directory contaminated when they exit with an error. + chdir($this->start_directory); + $fs = new Filesystem(); $fs->removeDirectory($this->working_directory); $fs->removeDirectory($this->local_repository); } + /** + * testcase: UC01-001 + */ public function testInstallPackage(): void { // Arrange @@ -89,21 +100,51 @@ class RequireCommandTest extends TestCase $application->setAutoExit(false); $application->add(new RequireCommand()); + $local_repository_class_code = 'local_repository . '/src'; + $local_repository_class_file = $local_repository_class_file_dir . '/TestClass.php'; + + mkdir($local_repository_class_file_dir, 0777, true); + file_put_contents($local_repository_class_file, $local_repository_class_code); + + $check_autoload_code = 'include "./vendor/autoload.php";' + . 'use TestVendor\\Testpackage\\TestClass;' + . '(new TestClass())->printTestClass();'; + $check_autoload_process = new Process(['php', '-r', $check_autoload_code]); + $check_autoload_process->setWorkingDirectory($this->working_directory); + // Act $tester = new ApplicationTester($application); $tester->run([ 'command' => 'require', + // Confirmation 1: provide dependency name of format vendor/package 'packages' => [ 'testvendor/testpackage' ], '-d' => $this->working_directory, ]); + $check_autoload_process->run(); + // Assert $output = $tester->getDisplay(); + + // Confirmation 4: exit code 0 $tester->assertCommandIsSuccessful(); + $this->assertStringContainsString('Installing testvendor/testpackage', $output); + + // Confirmation 2: dependency is present in vendor directory $this->assertTrue(file_exists($this->working_directory . '/vendor/testvendor/testpackage')); + + // Confirmation 3: dependency classes can be autoloaded + $this->assertEquals(0, $check_autoload_process->getExitCode()); + $this->assertEquals('TestClass', $check_autoload_process->getOutput()); } + /** + * testcase: UC01-002 + */ public function testInstallPackageSaveToComposerJson(): void { // Arrange @@ -113,6 +154,8 @@ class RequireCommandTest extends TestCase // Act $tester = new ApplicationTester($application); + + // Confirmation 1: Install dependency $tester->run([ 'command' => 'require', 'packages' => [ 'testvendor/testpackage 1.0.0' ], @@ -124,11 +167,15 @@ class RequireCommandTest extends TestCase file_get_contents($this->working_directory . '/composer.json'), true ); + + // Confirmation 2: dependency has been added to composer.json $this->assertArrayHasKey('testvendor/testpackage', $manifest['require']); $this->assertEquals('1.0.0', $manifest['require']['testvendor/testpackage']); } - + /** + * testcase: UC01-003 + */ public function testInstallPackagesSaveToComposerLock(): void { // Arrange @@ -161,6 +208,9 @@ class RequireCommandTest extends TestCase $this->assertEquals('1.0.0', $installed_package['version']); } + /** + * testcase: UC01-004 + */ public function testInstallMisspelledPackage(): void { // Arrange @@ -196,4 +246,81 @@ class RequireCommandTest extends TestCase ); } + /** + * testcase: UC01-005 + */ + public function testInstallNoPackage(): void + { + // Arrange + $application = new Application(); + $application->setAutoExit(false); + $application->add(new RequireCommand()); + + // Act + $tester = new ApplicationTester($application); + $tester->run([ + 'command' => 'require', + 'packages' => [ '-' ], + '-d' => $this->working_directory, + ]); + + // Assert + $this->assertNotEquals(0, $tester->getStatusCode()); + $output = $tester->getDisplay(); + + $this->assertStringContainsString( + 'Could not find package -.', + $output + ); + + // Assert + $manifest = json_decode( + file_get_contents($this->working_directory . '/composer.json'), + true + ); + + // Confirmation 2: dependency has not been added to composer.json + $this->assertEquals(0, count($manifest['require'])); + } + + /** + * testcase: UC01-006 + */ + public function testInstallLongPackageName(): void + { + // Arrange + $application = new Application(); + $application->setAutoExit(false); + $application->add(new RequireCommand()); + + $package_name = $this->generateRandomString(8000); + + // Act + $tester = new ApplicationTester($application); + $tester->run([ + 'command' => 'require', + 'packages' => [ $package_name ], + '-d' => $this->working_directory, + ]); + + // Assert + $this->assertNotEquals(0, $tester->getStatusCode()); + $output = $tester->getDisplay(); + + $this->assertStringContainsString( + 'Could not find a matching version of package ', + $output + ); + } + + + private function generateRandomString(int $length): string { + $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + return $randomString; + } }