* Jordi Boggiano * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Composer\Test\Installer; use Composer\Installer\InstallationManager; use Composer\Installer\NoopInstaller; use Composer\DependencyResolver\Operation\InstallOperation; use Composer\DependencyResolver\Operation\UpdateOperation; use Composer\DependencyResolver\Operation\UninstallOperation; use Composer\Test\TestCase; class InstallationManagerTest extends TestCase { /** * @var \Composer\Repository\InstalledRepositoryInterface&\PHPUnit\Framework\MockObject\MockObject */ protected $repository; /** * @var \Composer\Util\Loop&\PHPUnit\Framework\MockObject\MockObject */ protected $loop; /** * @var \Composer\IO\IOInterface&\PHPUnit\Framework\MockObject\MockObject */ protected $io; public function setUp(): void { $this->loop = $this->getMockBuilder('Composer\Util\Loop')->disableOriginalConstructor()->getMock(); $this->repository = $this->getMockBuilder('Composer\Repository\InstalledRepositoryInterface')->getMock(); $this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); } public function testAddGetInstaller(): void { $installer = $this->createInstallerMock(); $installer ->expects($this->exactly(2)) ->method('supports') ->will($this->returnCallback(static function ($arg): bool { return $arg === 'vendor'; })); $manager = new InstallationManager($this->loop, $this->io); $manager->addInstaller($installer); self::assertSame($installer, $manager->getInstaller('vendor')); self::expectException('InvalidArgumentException'); $manager->getInstaller('unregistered'); } public function testAddRemoveInstaller(): void { $installer = $this->createInstallerMock(); $installer ->expects($this->exactly(2)) ->method('supports') ->will($this->returnCallback(static function ($arg): bool { return $arg === 'vendor'; })); $installer2 = $this->createInstallerMock(); $installer2 ->expects($this->exactly(1)) ->method('supports') ->will($this->returnCallback(static function ($arg): bool { return $arg === 'vendor'; })); $manager = new InstallationManager($this->loop, $this->io); $manager->addInstaller($installer); self::assertSame($installer, $manager->getInstaller('vendor')); $manager->addInstaller($installer2); self::assertSame($installer2, $manager->getInstaller('vendor')); $manager->removeInstaller($installer2); self::assertSame($installer, $manager->getInstaller('vendor')); } public function testExecute(): void { $manager = $this->getMockBuilder('Composer\Installer\InstallationManager') ->setConstructorArgs([$this->loop, $this->io]) ->onlyMethods(['install', 'update', 'uninstall']) ->getMock(); $installOperation = new InstallOperation($package = $this->createPackageMock()); $removeOperation = new UninstallOperation($package); $updateOperation = new UpdateOperation( $package, $package ); $package->expects($this->any()) ->method('getType') ->will($this->returnValue('library')); $manager ->expects($this->once()) ->method('install') ->with($this->repository, $installOperation); $manager ->expects($this->once()) ->method('uninstall') ->with($this->repository, $removeOperation); $manager ->expects($this->once()) ->method('update') ->with($this->repository, $updateOperation); $manager->addInstaller(new NoopInstaller()); $manager->execute($this->repository, [$installOperation, $removeOperation, $updateOperation]); } public function testInstall(): void { $installer = $this->createInstallerMock(); $manager = new InstallationManager($this->loop, $this->io); $manager->addInstaller($installer); $package = $this->createPackageMock(); $operation = new InstallOperation($package); $package ->expects($this->once()) ->method('getType') ->will($this->returnValue('library')); $installer ->expects($this->once()) ->method('supports') ->with('library') ->will($this->returnValue(true)); $installer ->expects($this->once()) ->method('install') ->with($this->repository, $package); $manager->install($this->repository, $operation); } public function testUpdateWithEqualTypes(): void { $installer = $this->createInstallerMock(); $manager = new InstallationManager($this->loop, $this->io); $manager->addInstaller($installer); $initial = $this->createPackageMock(); $target = $this->createPackageMock(); $operation = new UpdateOperation($initial, $target); $initial ->expects($this->once()) ->method('getType') ->will($this->returnValue('library')); $target ->expects($this->once()) ->method('getType') ->will($this->returnValue('library')); $installer ->expects($this->once()) ->method('supports') ->with('library') ->will($this->returnValue(true)); $installer ->expects($this->once()) ->method('update') ->with($this->repository, $initial, $target); $manager->update($this->repository, $operation); } public function testUpdateWithNotEqualTypes(): void { $libInstaller = $this->createInstallerMock(); $bundleInstaller = $this->createInstallerMock(); $manager = new InstallationManager($this->loop, $this->io); $manager->addInstaller($libInstaller); $manager->addInstaller($bundleInstaller); $initial = $this->createPackageMock(); $initial ->expects($this->once()) ->method('getType') ->will($this->returnValue('library')); $target = $this->createPackageMock(); $target ->expects($this->once()) ->method('getType') ->will($this->returnValue('bundles')); $bundleInstaller ->expects($this->exactly(2)) ->method('supports') ->will($this->returnCallback(static function ($arg): bool { return $arg === 'bundles'; })); $libInstaller ->expects($this->once()) ->method('supports') ->with('library') ->will($this->returnValue(true)); $libInstaller ->expects($this->once()) ->method('uninstall') ->with($this->repository, $initial); $bundleInstaller ->expects($this->once()) ->method('install') ->with($this->repository, $target); $operation = new UpdateOperation($initial, $target); $manager->update($this->repository, $operation); } public function testUninstall(): void { $installer = $this->createInstallerMock(); $manager = new InstallationManager($this->loop, $this->io); $manager->addInstaller($installer); $package = $this->createPackageMock(); $operation = new UninstallOperation($package); $package ->expects($this->once()) ->method('getType') ->will($this->returnValue('library')); $installer ->expects($this->once()) ->method('uninstall') ->with($this->repository, $package); $installer ->expects($this->once()) ->method('supports') ->with('library') ->will($this->returnValue(true)); $manager->uninstall($this->repository, $operation); } public function testInstallBinary(): void { $installer = $this->getMockBuilder('Composer\Installer\LibraryInstaller') ->disableOriginalConstructor() ->getMock(); $manager = new InstallationManager($this->loop, $this->io); $manager->addInstaller($installer); $package = $this->createPackageMock(); $package ->expects($this->once()) ->method('getType') ->will($this->returnValue('library')); $installer ->expects($this->once()) ->method('supports') ->with('library') ->will($this->returnValue(true)); $installer ->expects($this->once()) ->method('ensureBinariesPresence') ->with($package); $manager->ensureBinariesPresence($package); } /** * @return \Composer\Installer\InstallerInterface&\PHPUnit\Framework\MockObject\MockObject */ private function createInstallerMock() { return $this->getMockBuilder('Composer\Installer\InstallerInterface') ->getMock(); } /** * @return \Composer\Package\PackageInterface&\PHPUnit\Framework\MockObject\MockObject */ private function createPackageMock() { $mock = $this->getMockBuilder('Composer\Package\PackageInterface') ->getMock(); return $mock; } }