| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- <?php
- /*
- * This file is part of Psy Shell.
- *
- * (c) 2012-2023 Justin Hileman
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Psy\Test\VersionUpdater;
- use Psy\Exception\ErrorException;
- use Psy\Shell;
- use Psy\VersionUpdater\Checker;
- use Psy\VersionUpdater\Downloader;
- use Psy\VersionUpdater\Installer;
- use Psy\VersionUpdater\SelfUpdate;
- use Symfony\Component\Console\Input\ArgvInput;
- use Symfony\Component\Console\Input\InputDefinition;
- use Symfony\Component\Console\Input\InputOption;
- use Symfony\Component\Console\Output\OutputInterface;
- /**
- * @group isolation-fail
- */
- class SelfUpdateTest extends \Psy\Test\TestCase
- {
- private function getSelfUpdater(Checker $checker, Installer $installer): SelfUpdate
- {
- $selfUpdate = new SelfUpdate($checker, $installer);
- $selfUpdate->setDownloader($this->getMockDownloader());
- return $selfUpdate;
- }
- public function testSuccessWhenCurrentVersionIsLatest()
- {
- $installer = $this->getMockInstaller();
- $checker = $this->getMockChecker(true);
- $output = $this->getMockOutput();
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $returnValue = $selfUpdate->run($this->getInput(), $output);
- $this->assertEquals(SelfUpdate::SUCCESS, $returnValue);
- }
- public function testFailWhenCurrentVersionIsNotWritable()
- {
- $installer = $this->getMockInstaller(['isInstallLocationWritable']);
- $installer
- ->method('isInstallLocationWritable')
- ->willReturn(false);
- $checker = $this->getMockChecker();
- $output = $this->getMockOutput();
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $returnValue = $selfUpdate->run($this->getInput(), $output);
- $this->assertEquals(SelfUpdate::FAILURE, $returnValue);
- }
- public function testFailWhenTempDirectoryIsNotWritable()
- {
- $installer = $this->getMockInstaller(['isTempDirectoryWritable']);
- $installer
- ->method('isTempDirectoryWritable')
- ->willReturn(false);
- $checker = $this->getMockChecker();
- $output = $this->getMockOutput();
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $returnValue = $selfUpdate->run($this->getInput(), $output);
- $this->assertEquals(SelfUpdate::FAILURE, $returnValue);
- }
- public function testFailWhenDownloadingThrowsAnException()
- {
- $installer = $this->getMockInstaller();
- $checker = $this->getMockChecker();
- $output = $this->getMockOutput('TestCase Exception');
- $downloader = $this->getMockDownloader(['download']);
- $downloader
- ->method('download')
- ->willThrowException(new ErrorException('TestCase Exception'));
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $selfUpdate->setDownloader($downloader);
- $returnValue = $selfUpdate->run($this->getInput(), $output);
- $this->assertEquals(SelfUpdate::FAILURE, $returnValue);
- }
- public function testFailWhenDownloadingFails()
- {
- $installer = $this->getMockInstaller();
- $checker = $this->getMockChecker();
- $output = $this->getMockOutput('Download failed.');
- $downloader = $this->getMockDownloader(['download']);
- $downloader
- ->method('download')
- ->willReturn(false);
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $selfUpdate->setDownloader($downloader);
- $returnValue = $selfUpdate->run($this->getInput(), $output);
- $this->assertEquals(SelfUpdate::FAILURE, $returnValue);
- }
- public function testFailWhenDownloadedArchiveIsNotValid()
- {
- $installer = $this->getMockInstaller(['isValidSource']);
- $installer
- ->method('isValidSource')
- ->willReturn(false);
- $checker = $this->getMockChecker();
- $output = $this->getMockOutput('not a valid archive');
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $returnValue = $selfUpdate->run($this->getInput(), $output);
- $this->assertEquals(SelfUpdate::FAILURE, $returnValue);
- }
- public function testFailWhenCreateBackupFails()
- {
- $installer = $this->getMockInstaller(['createBackup']);
- $installer
- ->method('createBackup')
- ->willReturn(false);
- $checker = $this->getMockChecker();
- $output = $this->getMockOutput('Failed to create a backup');
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $returnValue = $selfUpdate->run($this->getInput(), $output);
- $this->assertEquals(SelfUpdate::FAILURE, $returnValue);
- }
- public function testBackupIsRestoredWhenInstallFails()
- {
- $installer = $this->getMockInstaller(['install', 'restoreFromBackup']);
- $installer
- ->method('install')
- ->willReturn(false);
- $installer
- ->expects($this->once())
- ->method('restoreFromBackup');
- $checker = $this->getMockChecker();
- $output = $this->getMockOutput();
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $returnValue = $selfUpdate->run($this->getInput(), $output);
- $this->assertEquals(SelfUpdate::FAILURE, $returnValue);
- }
- public function testExceptionIsNotCaughtWhenRestoreFails()
- {
- $this->expectException(ErrorException::class);
- $installer = $this->getMockInstaller(['restoreFromBackup', 'install']);
- $installer
- ->method('install')
- ->willReturn(false);
- $installer
- ->method('restoreFromBackup')
- ->willThrowException(new ErrorException('Uncaught Exception'));
- $checker = $this->getMockChecker();
- $output = $this->getMockOutput();
- $selfUpdate = $this->getSelfUpdater($checker, $installer);
- $selfUpdate->run($this->getInput(), $output);
- $this->fail('Expected ErrorException not thrown');
- }
- private function getInput()
- {
- $input = new ArgvInput([]);
- // build a simple input with options that are used in SelfUpdate
- $input->bind(new InputDefinition([
- new InputOption('verbose', 'v', InputOption::VALUE_NONE),
- ]));
- return $input;
- }
- /**
- * Use the more strict onlyMethods if it's available, otherwise use the deprecated setMethods.
- *
- * @return void
- */
- private function setMockMethods($mockBuilder, array $methods)
- {
- if (\method_exists($mockBuilder, 'onlyMethods')) {
- $mockBuilder->onlyMethods($methods);
- } else {
- $mockBuilder->setMethods($methods);
- }
- }
- private function getMockChecker(bool $isLatest = false, string $version = Shell::VERSION)
- {
- $builder = $this->getMockBuilder(Checker::class);
- $this->setMockMethods($builder, ['getLatest', 'isLatest']);
- $checker = $builder->getMock();
- $checker->method('getLatest')->willReturn($version);
- $checker->method('isLatest')->willReturn($isLatest);
- return $checker;
- }
- private function getMockInstaller(array $skipMethods = [])
- {
- $methods = \get_class_methods(Installer::class);
- $builder = $this->getMockBuilder(Installer::class);
- $this->setMockMethods($builder, $methods);
- $installer = $builder->getMock();
- $skipMethods = \array_merge($skipMethods, ['getTempDirectory', 'getBackupFilename', '__construct']);
- foreach ($methods as $method) {
- if (!\in_array($method, $skipMethods)) {
- $installer->method($method)->willReturn(true);
- }
- }
- return $installer;
- }
- private function getMockDownloader(array $skipMethods = [])
- {
- $methods = \get_class_methods(Downloader::class);
- $builder = $this->getMockBuilder(Downloader::class);
- $this->setMockMethods($builder, $methods);
- $downloader = $builder->getMock();
- $skipMethods = \array_merge($skipMethods, ['getFilename', '__construct']);
- foreach ($methods as $method) {
- if (!\in_array($method, $skipMethods)) {
- $downloader->method($method)->willReturn(true);
- }
- }
- return $downloader;
- }
- private function getMockOutput(string $expectOutput = null)
- {
- $methods = \get_class_methods(OutputInterface::class);
- $builder = $this->getMockBuilder(OutputInterface::class);
- $this->setMockMethods($builder, $methods);
- $output = $builder->getMock();
- if ($expectOutput) {
- $output
- ->expects($this->atLeastOnce())
- ->method('writeln')
- ->with(
- $this->stringContains($expectOutput)
- );
- }
- return $output;
- }
- }
|