You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
8.2 KiB
PHTML
272 lines
8.2 KiB
PHTML
2 years ago
|
<?php declare(strict_types=1);
|
||
|
|
||
|
/*
|
||
|
* This file is part of Composer.
|
||
|
*
|
||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||
|
*
|
||
|
* For the full copyright and license information, please view the LICENSE
|
||
|
* file that was distributed with this source code.
|
||
|
*/
|
||
|
|
||
|
namespace Composer\Test\Command;
|
||
|
|
||
|
use Composer\Command\InitCommand;
|
||
|
use Composer\Util\Filesystem;
|
||
|
use Composer\Command\InstallCommand;
|
||
|
use Symfony\Component\Console\Tester\ApplicationTester;
|
||
|
use Composer\Command\RequireCommand;
|
||
|
use Symfony\Component\Console\Input\ArrayInput;
|
||
|
use Composer\Console\Application;
|
||
|
use Composer\Test\TestCase;
|
||
|
use Symfony\Component\Process\Process;
|
||
|
|
||
|
class InstallCommandTest extends TestCase
|
||
|
{
|
||
|
/**
|
||
|
* @var string
|
||
|
*/
|
||
|
private $start_directory;
|
||
|
private $working_directory = null;
|
||
|
private $local_repositories = [];
|
||
|
|
||
|
public function setUp(): void
|
||
|
{
|
||
|
$this->working_directory = null;
|
||
|
$this->local_repositories = [];
|
||
|
$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();
|
||
|
|
||
|
if(null !== $this->working_directory) {
|
||
|
$fs->removeDirectory($this->working_directory);
|
||
|
}
|
||
|
|
||
|
foreach($this->local_repositories as $repository) {
|
||
|
$fs->removeDirectory($repository);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* testcase: UC01-007
|
||
|
*/
|
||
|
public function testInstallVersionLockedPackages(): void
|
||
|
{
|
||
|
// Arrange
|
||
|
$this->makeLocalRepo('test/one', '1.0.0', 'Test\\One\\');
|
||
|
$this->makeLocalRepo('test/one', '1.0.1', 'Test\\One\\');
|
||
|
$this->makeLocalRepo('test/one', '1.0.2', 'Test\\One\\');
|
||
|
$this->makeLocalRepo('test/one', '1.0.3', 'Test\\One\\');
|
||
|
$this->makeLocalRepo('test/one', '0.0.3', 'Test\\One\\');
|
||
|
$this->makeLocalRepo('test/one', '2.0.0', 'Test\\One\\');
|
||
|
|
||
|
$this->makeLocalRepo('test/two', '1.0.0', 'Test\\Two\\');
|
||
|
$this->makeLocalRepo('test/two', '1.2.0', 'Test\\Two\\');
|
||
|
$this->makeLocalRepo('test/two', '1.5.0', 'Test\\Two\\');
|
||
|
|
||
|
$this->makeWorkingDirectory();
|
||
|
|
||
|
$application = new Application();
|
||
|
$application->setAutoExit(false);
|
||
|
$application->add(new InstallCommand());
|
||
|
$tester = new ApplicationTester($application);
|
||
|
|
||
|
// Confirmation 1: install multiple dependencies
|
||
|
$this->requirePackage('test/one 1.0.2');
|
||
|
$this->requirePackage('test/two 1.2.0');
|
||
|
|
||
|
// Confirmation 3: remove "vendor" folder
|
||
|
$fs = new Filesystem();
|
||
|
$fs->removeDirectory($this->working_directory . '/vendor');
|
||
|
|
||
|
// Act
|
||
|
$tester->run([
|
||
|
// Confirmation 4: install all dependencies
|
||
|
'command' => 'install',
|
||
|
'-d' => $this->working_directory,
|
||
|
]);
|
||
|
|
||
|
// Assert
|
||
|
$tester->assertCommandIsSuccessful();
|
||
|
|
||
|
// Confirmation 2: System created composer.lock with dependencies and
|
||
|
// version numbers.
|
||
|
$this->assertPackageVersionLocked('test/one', '1.0.2');
|
||
|
$this->assertPackageVersionLocked('test/two', '1.2.0');
|
||
|
|
||
|
// Confirmation 5: System has installed exact versions of dependencies
|
||
|
// that have been set in composer.lock
|
||
|
$this->assertPackageVersionInstalled('test/one', '1.0.2');
|
||
|
$this->assertPackageVersionInstalled('test/two', '1.2.0');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* testcase: UC01-008
|
||
|
*/
|
||
|
public function testInstallVersionLockedPackagesRepoUnavailable(): void
|
||
|
{
|
||
|
// Arrange
|
||
|
$this->makeLocalRepo('test/one', '1.0.2', 'Test\\One\\');
|
||
|
$one_two_repo = $this->makeLocalRepo('test/two', '1.2.0', 'Test\\Two\\');
|
||
|
|
||
|
$this->makeWorkingDirectory();
|
||
|
|
||
|
$application = new Application();
|
||
|
$application->setAutoExit(false);
|
||
|
$application->add(new InstallCommand());
|
||
|
$tester = new ApplicationTester($application);
|
||
|
|
||
|
// Confirmation 1: install multiple dependencies
|
||
|
$this->requirePackage('test/one 1.0.2');
|
||
|
$this->requirePackage('test/two 1.2.0');
|
||
|
|
||
|
$fs = new Filesystem();
|
||
|
// Confirmation 3: remove "vendor" folder
|
||
|
$fs->removeDirectory($this->working_directory . '/vendor');
|
||
|
|
||
|
// Remove the repository of one of the dependencies to make it
|
||
|
// unavailable.
|
||
|
$fs->removeDirectory($one_two_repo);
|
||
|
|
||
|
// Act
|
||
|
$tester->run([
|
||
|
// Confirmation 4: install all dependencies
|
||
|
'command' => 'install',
|
||
|
'-d' => $this->working_directory,
|
||
|
]);
|
||
|
|
||
|
// Assert
|
||
|
|
||
|
// Confirmation 2: System created composer.lock with dependencies and
|
||
|
// version numbers.
|
||
|
$this->assertPackageVersionLocked('test/one', '1.0.2');
|
||
|
$this->assertPackageVersionLocked('test/two', '1.2.0');
|
||
|
|
||
|
// Confirm that dependency installation failed and system communicated
|
||
|
// this with its exit code and text output.
|
||
|
$this->assertNotEquals(0, $tester->getStatusCode());
|
||
|
$this->assertStringContainsString(
|
||
|
'is not found for package test/two',
|
||
|
$tester->getDisplay()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
private function assertPackageVersionLocked(string $package, string $version): void
|
||
|
{
|
||
|
$lockfile = json_decode(
|
||
|
file_get_contents($this->working_directory . '/composer.lock'),
|
||
|
true
|
||
|
);
|
||
|
$packages = $lockfile['packages'];
|
||
|
$installed_package = null;
|
||
|
foreach($packages as $package_lock) {
|
||
|
if ($package_lock['name'] === $package) {
|
||
|
$installed_package = $package_lock;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$this->assertNotNull($installed_package);
|
||
|
$this->assertEquals($version, $installed_package['version']);
|
||
|
}
|
||
|
|
||
|
|
||
|
private function assertPackageVersionInstalled(string $package, string $version): void
|
||
|
{
|
||
|
$install_directory = $this->working_directory . '/vendor/' . $package;
|
||
|
$this->assertTrue(file_exists($install_directory));
|
||
|
|
||
|
$manifest = json_decode(
|
||
|
file_get_contents($install_directory . '/composer.json'),
|
||
|
true
|
||
|
);
|
||
|
|
||
|
$this->assertEquals($version, $manifest['version']);
|
||
|
}
|
||
|
|
||
|
private function requirePackage(string $package): void
|
||
|
{
|
||
|
// Arrange
|
||
|
$application = new Application();
|
||
|
$application->setAutoExit(false);
|
||
|
$application->add(new RequireCommand());
|
||
|
|
||
|
$tester = new ApplicationTester($application);
|
||
|
$tester->run([
|
||
|
'command' => 'require',
|
||
|
'packages' => [ $package ],
|
||
|
'-d' => $this->working_directory,
|
||
|
]);
|
||
|
|
||
|
$output = $tester->getDisplay();
|
||
|
|
||
|
$tester->assertCommandIsSuccessful();
|
||
|
}
|
||
|
|
||
|
|
||
|
private function makeLocalRepo(string $name, string $version, string $autoload): string
|
||
|
{
|
||
|
$local_repository = $this->getUniqueTmpDirectory();
|
||
|
|
||
|
$repo_manifest = [
|
||
|
'name' => $name,
|
||
|
'version' => $version,
|
||
|
'type' => 'library',
|
||
|
'autoload' => [
|
||
|
'psr-4' => [
|
||
|
$autoload => 'src/',
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
|
||
|
file_put_contents(
|
||
|
$local_repository.'/composer.json',
|
||
|
json_encode(
|
||
|
$repo_manifest,
|
||
|
JSON_UNESCAPED_SLASHES,
|
||
|
)
|
||
|
);
|
||
|
|
||
|
$this->local_repositories[] = $local_repository;
|
||
|
|
||
|
return $local_repository;
|
||
|
}
|
||
|
|
||
|
private function makeWorkingDirectory(): void
|
||
|
{
|
||
|
$this->working_directory = $this->getUniqueTmpDirectory();
|
||
|
|
||
|
$manifest = [
|
||
|
'name' => 'test/something',
|
||
|
'require' => (object) null,
|
||
|
'repositories' => [
|
||
|
[
|
||
|
'packagist.org' => false
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
|
||
|
foreach($this->local_repositories as $repository) {
|
||
|
$manifest['repositories'][] = [
|
||
|
'type' => 'path',
|
||
|
'url' => $repository,
|
||
|
'canonical' => false,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
file_put_contents(
|
||
|
$this->working_directory.'/composer.json',
|
||
|
json_encode($manifest, JSON_UNESCAPED_SLASHES)
|
||
|
);
|
||
|
}
|
||
|
}
|