diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index d756d9b9d..1b790ad5e 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -36,9 +36,9 @@ class ConsoleIO extends BaseIO /** @var HelperSet */ protected $helperSet; /** @var string */ - protected $lastMessage; + protected $lastMessage = ''; /** @var string */ - protected $lastMessageErr; + protected $lastMessageErr = ''; /** @var float */ private $startTime; diff --git a/src/Composer/Package/Archiver/ArchiveManager.php b/src/Composer/Package/Archiver/ArchiveManager.php index 13dd7c7fe..356c53646 100644 --- a/src/Composer/Package/Archiver/ArchiveManager.php +++ b/src/Composer/Package/Archiver/ArchiveManager.php @@ -88,7 +88,7 @@ class ArchiveManager } $nameParts = array($baseName); - if (preg_match('{^[a-f0-9]{40}$}', $package->getDistReference())) { + if (null !== $package->getDistReference() && preg_match('{^[a-f0-9]{40}$}', $package->getDistReference())) { array_push($nameParts, $package->getDistReference(), $package->getDistType()); } else { array_push($nameParts, $package->getPrettyVersion(), $package->getDistReference()); diff --git a/src/Composer/Package/BasePackage.php b/src/Composer/Package/BasePackage.php index a7a075099..f8199a0bb 100644 --- a/src/Composer/Package/BasePackage.php +++ b/src/Composer/Package/BasePackage.php @@ -217,6 +217,10 @@ abstract class BasePackage implements PackageInterface throw new \UnexpectedValueException('Display mode '.$displayMode.' is not supported'); } + if (null === $reference) { + return $this->getPrettyVersion(); + } + // if source reference is a sha1 hash -- truncate if ($truncate && \strlen($reference) === 40 && $this->getSourceType() !== 'svn') { return $this->getPrettyVersion() . ' ' . substr($reference, 0, 7); diff --git a/src/Composer/Package/Package.php b/src/Composer/Package/Package.php index 1f1cdf553..9afbd6429 100644 --- a/src/Composer/Package/Package.php +++ b/src/Composer/Package/Package.php @@ -27,11 +27,14 @@ class Package extends BasePackage protected $installationSource; protected $sourceType; protected $sourceUrl; + /** @var ?string */ protected $sourceReference; protected $sourceMirrors; protected $distType; protected $distUrl; + /** @var ?string */ protected $distReference; + /** @var ?string */ protected $distSha1Checksum; protected $distMirrors; protected $version; diff --git a/src/Composer/Package/PackageInterface.php b/src/Composer/Package/PackageInterface.php index 7f0fb1023..355cf49f0 100644 --- a/src/Composer/Package/PackageInterface.php +++ b/src/Composer/Package/PackageInterface.php @@ -131,7 +131,7 @@ interface PackageInterface /** * Returns the repository reference of this package, e.g. master, 1.0.0 or a commit hash for git * - * @return string The repository reference + * @return ?string The repository reference */ public function getSourceReference(); @@ -172,14 +172,14 @@ interface PackageInterface /** * Returns the reference of the distribution archive of this version, e.g. master, 1.0.0 or a commit hash for git * - * @return string + * @return ?string */ public function getDistReference(); /** * Returns the sha1 checksum for the distribution archive of this version * - * @return string + * @return ?string */ public function getDistSha1Checksum(); diff --git a/tests/Composer/Test/Downloader/FossilDownloaderTest.php b/tests/Composer/Test/Downloader/FossilDownloaderTest.php index 41f4ec17e..33920da27 100644 --- a/tests/Composer/Test/Downloader/FossilDownloaderTest.php +++ b/tests/Composer/Test/Downloader/FossilDownloaderTest.php @@ -132,7 +132,11 @@ class FossilDownloaderTest extends TestCase $processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedFossilCommand)) - ->will($this->returnValue(0)); + ->will($this->returnCallback(function ($cmd, &$output, $path) { + $output = ''; + + return 0; + })); $expectedFossilCommand = $this->getCmd("fossil pull && fossil up 'trunk'"); $processExecutor->expects($this->at(1)) ->method('execute') diff --git a/tests/Composer/Test/Downloader/GitDownloaderTest.php b/tests/Composer/Test/Downloader/GitDownloaderTest.php index 65b41a529..248ee8074 100644 --- a/tests/Composer/Test/Downloader/GitDownloaderTest.php +++ b/tests/Composer/Test/Downloader/GitDownloaderTest.php @@ -18,8 +18,6 @@ use Composer\Test\TestCase; use Composer\Util\Filesystem; use Composer\Util\Platform; use Composer\Test\Mock\ProcessExecutorMock; -use DateTime; -use Prophecy\Argument; class GitDownloaderTest extends TestCase { @@ -71,7 +69,7 @@ class GitDownloaderTest extends TestCase protected function getDownloaderMock($io = null, $config = null, $executor = null, $filesystem = null) { $io = $io ?: $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); - $executor = $executor ?: $this->getMockBuilder('Composer\Util\ProcessExecutor')->setMethods(array('execute'))->getMock(); + $executor = $executor ?: new ProcessExecutorMock; $filesystem = $filesystem ?: $this->getMockBuilder('Composer\Util\Filesystem')->getMock(); $config = $this->setupConfig($config); @@ -109,33 +107,21 @@ class GitDownloaderTest extends TestCase $packageMock->expects($this->any()) ->method('getPrettyVersion') ->will($this->returnValue('dev-master')); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->setMethods(array('execute'))->getMock(); - $expectedGitCommand = $this->winCompat("git clone --no-checkout -- 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer -- 'https://example.com/composer/composer' && git fetch composer && git remote set-url origin -- 'https://example.com/composer/composer' && git remote set-url composer -- 'https://example.com/composer/composer'"); - $processExecutor->expects($this->at(0)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand)) - ->will($this->returnValue(0)); + $process = new ProcessExecutorMock; + $process->expects(array( + $this->winCompat("git clone --no-checkout -- 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer -- 'https://example.com/composer/composer' && git fetch composer && git remote set-url origin -- 'https://example.com/composer/composer' && git remote set-url composer -- 'https://example.com/composer/composer'"), + $this->winCompat("git branch -r"), + $this->winCompat("(git checkout 'master' -- || git checkout -B 'master' 'composer/master' --) && git reset --hard '1234567890123456789012345678901234567890' --"), + ), true); - $processExecutor->expects($this->at(1)) - ->method('execute') - ->with($this->equalTo($this->winCompat("git branch -r")), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath'))) - ->will($this->returnCallback(function ($cmd, &$output) { - $output = ''; - - return 0; - })); - - $processExecutor->expects($this->at(2)) - ->method('execute') - ->with($this->equalTo($this->winCompat("(git checkout 'master' -- || git checkout -B 'master' 'composer/master' --) && git reset --hard '1234567890123456789012345678901234567890' --")), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath'))) - ->will($this->returnValue(0)); - - $downloader = $this->getDownloaderMock(null, null, $processExecutor); + $downloader = $this->getDownloaderMock(null, null, $process); $downloader->download($packageMock, 'composerPath'); $downloader->prepare('install', $packageMock, 'composerPath'); $downloader->install($packageMock, 'composerPath'); $downloader->cleanup('install', $packageMock, 'composerPath'); + + $process->assertComplete($this); } public function testDownloadWithCache() @@ -153,7 +139,6 @@ class GitDownloaderTest extends TestCase $packageMock->expects($this->any()) ->method('getPrettyVersion') ->will($this->returnValue('dev-master')); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->setMethods(array('execute'))->getMock(); $this->initGitVersion('2.17.0'); @@ -164,54 +149,24 @@ class GitDownloaderTest extends TestCase $filesystem = new \Composer\Util\Filesystem; $filesystem->removeDirectory($cachePath); - $expectedGitCommand = $this->winCompat(sprintf("git clone --mirror -- 'https://example.com/composer/composer' '%s'", $cachePath)); - $processExecutor->expects($this->at(0)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand)) - ->will($this->returnCallback(function () use ($cachePath) { - @mkdir($cachePath, 0777, true); + $process = new ProcessExecutorMock; + $process->expects(array( + array('cmd' => $this->winCompat(sprintf("git clone --mirror -- 'https://example.com/composer/composer' '%s'", $cachePath)), 'callback' => function () use ($cachePath) { @mkdir($cachePath, 0777, true); }), + array('cmd' => 'git rev-parse --git-dir', 'stdout' => '.'), + $this->winCompat('git rev-parse --quiet --verify \'1234567890123456789012345678901234567890^{commit}\''), + $this->winCompat(sprintf("git clone --no-checkout '%1\$s' 'composerPath' --dissociate --reference '%1\$s' && cd 'composerPath' && git remote set-url origin -- 'https://example.com/composer/composer' && git remote add composer -- 'https://example.com/composer/composer'", $cachePath)), + 'git branch -r', + $this->winCompat("(git checkout 'master' -- || git checkout -B 'master' 'composer/master' --) && git reset --hard '1234567890123456789012345678901234567890' --") + ), true); - return 0; - })); - $processExecutor->expects($this->at(1)) - ->method('execute') - ->with($this->equalTo('git rev-parse --git-dir'), $this->anything(), $this->equalTo($this->winCompat($cachePath))) - ->will($this->returnCallback(function ($command, &$output = null) { - $output = '.'; - - return 0; - })); - $processExecutor->expects($this->at(2)) - ->method('execute') - ->with($this->equalTo($this->winCompat('git rev-parse --quiet --verify \'1234567890123456789012345678901234567890^{commit}\'')), $this->equalTo(null), $this->equalTo($this->winCompat($cachePath))) - ->will($this->returnValue(0)); - - $expectedGitCommand = $this->winCompat(sprintf("git clone --no-checkout '%1\$s' 'composerPath' --dissociate --reference '%1\$s' && cd 'composerPath' && git remote set-url origin -- 'https://example.com/composer/composer' && git remote add composer -- 'https://example.com/composer/composer'", $cachePath)); - $processExecutor->expects($this->at(3)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand)) - ->will($this->returnValue(0)); - - $processExecutor->expects($this->at(4)) - ->method('execute') - ->with($this->equalTo($this->winCompat("git branch -r")), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath'))) - ->will($this->returnCallback(function ($cmd, &$output, $path) { - $output = ''; - - return 0; - })); - - $processExecutor->expects($this->at(5)) - ->method('execute') - ->with($this->equalTo($this->winCompat("(git checkout 'master' -- || git checkout -B 'master' 'composer/master' --) && git reset --hard '1234567890123456789012345678901234567890' --")), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath'))) - ->will($this->returnValue(0)); - - $downloader = $this->getDownloaderMock(null, $config, $processExecutor); + $downloader = $this->getDownloaderMock(null, $config, $process); $downloader->download($packageMock, 'composerPath'); $downloader->prepare('install', $packageMock, 'composerPath'); $downloader->install($packageMock, 'composerPath'); $downloader->cleanup('install', $packageMock, 'composerPath'); @rmdir($cachePath); + + $process->assertComplete($this); } public function testDownloadUsesVariousProtocolsAndSetsPushUrlForGithub() @@ -229,56 +184,28 @@ class GitDownloaderTest extends TestCase $packageMock->expects($this->any()) ->method('getPrettyVersion') ->will($this->returnValue('1.0.0')); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->setMethods(array('execute', 'getErrorOutput'))->getMock(); - $expectedGitCommand = $this->winCompat("git clone --no-checkout -- 'https://github.com/mirrors/composer' 'composerPath' && cd 'composerPath' && git remote add composer -- 'https://github.com/mirrors/composer' && git fetch composer && git remote set-url origin -- 'https://github.com/mirrors/composer' && git remote set-url composer -- 'https://github.com/mirrors/composer'"); - $processExecutor->expects($this->at(0)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand)) - ->will($this->returnValue(1)); + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => $this->winCompat("git clone --no-checkout -- 'https://github.com/mirrors/composer' 'composerPath' && cd 'composerPath' && git remote add composer -- 'https://github.com/mirrors/composer' && git fetch composer && git remote set-url origin -- 'https://github.com/mirrors/composer' && git remote set-url composer -- 'https://github.com/mirrors/composer'"), + 'return' => 1, + 'stderr' => 'Error1', + ), + $this->winCompat("git clone --no-checkout -- 'git@github.com:mirrors/composer' 'composerPath' && cd 'composerPath' && git remote add composer -- 'git@github.com:mirrors/composer' && git fetch composer && git remote set-url origin -- 'git@github.com:mirrors/composer' && git remote set-url composer -- 'git@github.com:mirrors/composer'"), + $this->winCompat("git remote set-url origin -- 'https://github.com/composer/composer'"), + $this->winCompat("git remote set-url --push origin -- 'git@github.com:composer/composer.git'"), + 'git branch -r', + $this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --"), + ), true); - $processExecutor->expects($this->at(1)) - ->method('getErrorOutput') - ->with() - ->will($this->returnValue('Error1')); - - $expectedGitCommand = $this->winCompat("git clone --no-checkout -- 'git@github.com:mirrors/composer' 'composerPath' && cd 'composerPath' && git remote add composer -- 'git@github.com:mirrors/composer' && git fetch composer && git remote set-url origin -- 'git@github.com:mirrors/composer' && git remote set-url composer -- 'git@github.com:mirrors/composer'"); - $processExecutor->expects($this->at(2)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand)) - ->will($this->returnValue(0)); - - $expectedGitCommand = $this->winCompat("git remote set-url origin -- 'https://github.com/composer/composer'"); - $processExecutor->expects($this->at(3)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath'))) - ->will($this->returnValue(0)); - - $expectedGitCommand = $this->winCompat("git remote set-url --push origin -- 'git@github.com:composer/composer.git'"); - $processExecutor->expects($this->at(4)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath'))) - ->will($this->returnValue(0)); - - $processExecutor->expects($this->at(5)) - ->method('execute') - ->with($this->equalTo('git branch -r')) - ->will($this->returnCallback(function ($cmd, &$output, $path) { - $output = ''; - - return 0; - })); - - $processExecutor->expects($this->at(6)) - ->method('execute') - ->with($this->equalTo($this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --")), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath'))) - ->will($this->returnValue(0)); - - $downloader = $this->getDownloaderMock(null, new Config(), $processExecutor); + $downloader = $this->getDownloaderMock(null, new Config(), $process); $downloader->download($packageMock, 'composerPath'); $downloader->prepare('install', $packageMock, 'composerPath'); $downloader->install($packageMock, 'composerPath'); $downloader->cleanup('install', $packageMock, 'composerPath'); + + $process->assertComplete($this); } public function pushUrlProvider() @@ -501,25 +428,35 @@ composer https://github.com/old/url (push) ->method('getVersion') ->will($this->returnValue('1.0.0.0')); - $process = $this->prophesize('Composer\Util\ProcessExecutor'); - $process->execute($this->winCompat('git --version'), Argument::cetera())->willReturn(0); - $process->execute($this->winCompat('git show-ref --head -d'), Argument::cetera())->willReturn(0); - $process->execute($this->winCompat('git status --porcelain --untracked-files=no'), Argument::cetera())->willReturn(0); - $process->execute($this->winCompat('git remote -v'), Argument::cetera())->willReturn(0); - $process->execute($this->winCompat('git branch -r'), Argument::cetera())->willReturn(0); - $process->execute($expectedGitUpdateCommand, null, $this->winCompat($this->workingDir))->willReturn(1)->shouldBeCalled(); - $process->execute($expectedGitUpdateCommand2, null, $this->winCompat($this->workingDir))->willReturn(1)->shouldBeCalled(); - $process->getErrorOutput()->willReturn(''); + $process = new ProcessExecutorMock; + $process->expects(array( + $this->winCompat('git show-ref --head -d'), + $this->winCompat('git status --porcelain --untracked-files=no'), + $this->winCompat('git remote -v'), + array( + 'cmd' => $expectedGitUpdateCommand, + 'return' => 1, + ), + array( + 'cmd' => $expectedGitUpdateCommand2, + 'return' => 1, + ), + $this->winCompat('git --version'), + $this->winCompat('git branch -r'), + ), true); $this->fs->ensureDirectoryExists($this->workingDir.'/.git'); // not using PHPUnit's expected exception because Prophecy exceptions extend from RuntimeException too so it is not safe try { - $downloader = $this->getDownloaderMock(null, new Config(), $process->reveal()); + $downloader = $this->getDownloaderMock(null, new Config(), $process); $downloader->download($packageMock, $this->workingDir, $packageMock); $downloader->prepare('update', $packageMock, $this->workingDir, $packageMock); $downloader->update($packageMock, $packageMock, $this->workingDir); $downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock); + + $process->assertComplete($this); + $this->fail('This test should throw'); } catch (\RuntimeException $e) { if ('RuntimeException' !== get_class($e)) { @@ -544,24 +481,38 @@ composer https://github.com/old/url (push) $packageMock->expects($this->any()) ->method('getSourceUrls') ->will($this->returnValue(array(Platform::isWindows() ? 'C:\\' : '/', 'https://github.com/composer/composer'))); + $packageMock->expects($this->any()) + ->method('getPrettyVersion') + ->will($this->returnValue('1.0.0')); - $process = $this->prophesize('Composer\Util\ProcessExecutor'); - $process->execute($this->winCompat('git --version'), Argument::cetera())->willReturn(0); - $process->execute($this->winCompat('git show-ref --head -d'), Argument::cetera())->willReturn(0); - $process->execute($this->winCompat('git status --porcelain --untracked-files=no'), Argument::cetera())->willReturn(0); - $process->execute($this->winCompat('git remote -v'), Argument::cetera())->willReturn(0); - $process->execute($this->winCompat('git branch -r'), Argument::cetera())->willReturn(0); - $process->execute($expectedFirstGitUpdateCommand, Argument::cetera())->willReturn(1)->shouldBeCalled(); - $process->execute($expectedSecondGitUpdateCommand, Argument::cetera())->willReturn(0)->shouldBeCalled(); - $process->execute($this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --"), null, $this->winCompat($this->workingDir))->willReturn(0)->shouldBeCalled(); - $process->getErrorOutput()->willReturn(''); + $process = new ProcessExecutorMock; + $process->expects(array( + $this->winCompat('git show-ref --head -d'), + $this->winCompat('git status --porcelain --untracked-files=no'), + $this->winCompat('git remote -v'), + array( + 'cmd' => $expectedFirstGitUpdateCommand, + 'return' => 1, + ), + $this->winCompat('git --version'), + $this->winCompat('git remote -v'), + array( + 'cmd' => $expectedSecondGitUpdateCommand, + 'return' => 0, + ), + $this->winCompat('git branch -r'), + $this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --"), + $this->winCompat('git remote -v'), + ), true); $this->fs->ensureDirectoryExists($this->workingDir.'/.git'); - $downloader = $this->getDownloaderMock(null, new Config(), $process->reveal()); + $downloader = $this->getDownloaderMock(null, new Config(), $process); $downloader->download($packageMock, $this->workingDir, $packageMock); $downloader->prepare('update', $packageMock, $this->workingDir, $packageMock); $downloader->update($packageMock, $packageMock, $this->workingDir); $downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock); + + $process->assertComplete($this); } public function testDowngradeShowsAppropriateMessage() @@ -590,14 +541,14 @@ composer https://github.com/old/url (push) $newPackage->expects($this->any()) ->method('getVersion') ->will($this->returnValue('1.0.0.0')); + $newPackage->expects($this->any()) + ->method('getPrettyVersion') + ->will($this->returnValue('1.0.0')); $newPackage->expects($this->any()) ->method('getFullPrettyVersion') ->will($this->returnValue('1.0.0')); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->setMethods(array('execute'))->getMock(); - $processExecutor->expects($this->any()) - ->method('execute') - ->will($this->returnValue(0)); + $process = new ProcessExecutorMock; $ioMock = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); $ioMock->expects($this->at(0)) @@ -605,7 +556,7 @@ composer https://github.com/old/url (push) ->with($this->stringContains('Downgrading')); $this->fs->ensureDirectoryExists($this->workingDir.'/.git'); - $downloader = $this->getDownloaderMock($ioMock, null, $processExecutor); + $downloader = $this->getDownloaderMock($ioMock, null, $process); $downloader->download($newPackage, $this->workingDir, $oldPackage); $downloader->prepare('update', $newPackage, $this->workingDir, $oldPackage); $downloader->update($oldPackage, $newPackage, $this->workingDir); @@ -635,11 +586,11 @@ composer https://github.com/old/url (push) $newPackage->expects($this->any()) ->method('getVersion') ->will($this->returnValue('dev-ref2')); + $newPackage->expects($this->any()) + ->method('getPrettyVersion') + ->will($this->returnValue('dev-ref2')); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->setMethods(array('execute'))->getMock(); - $processExecutor->expects($this->any()) - ->method('execute') - ->will($this->returnValue(0)); + $process = new ProcessExecutorMock; $ioMock = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); $ioMock->expects($this->at(0)) @@ -647,7 +598,7 @@ composer https://github.com/old/url (push) ->with($this->stringContains('Upgrading')); $this->fs->ensureDirectoryExists($this->workingDir.'/.git'); - $downloader = $this->getDownloaderMock($ioMock, null, $processExecutor); + $downloader = $this->getDownloaderMock($ioMock, null, $process); $downloader->download($newPackage, $this->workingDir, $oldPackage); $downloader->prepare('update', $newPackage, $this->workingDir, $oldPackage); $downloader->update($oldPackage, $newPackage, $this->workingDir); @@ -656,24 +607,29 @@ composer https://github.com/old/url (push) public function testRemove() { - $expectedGitResetCommand = $this->winCompat("cd 'composerPath' && git status --porcelain --untracked-files=no"); + $expectedGitResetCommand = $this->winCompat("git status --porcelain --untracked-files=no"); $packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock(); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->setMethods(array('execute'))->getMock(); - $processExecutor->expects($this->any()) - ->method('execute') - ->with($this->equalTo($expectedGitResetCommand)) - ->will($this->returnValue(0)); + $process = new ProcessExecutorMock; + $process->expects(array( + 'git show-ref --head -d', + $expectedGitResetCommand, + ), true); + + $this->fs->ensureDirectoryExists($this->workingDir.'/.git'); + $filesystem = $this->getMockBuilder('Composer\Util\Filesystem')->getMock(); $filesystem->expects($this->once()) ->method('removeDirectoryAsync') - ->with($this->equalTo('composerPath')) + ->with($this->equalTo($this->workingDir)) ->will($this->returnValue(\React\Promise\resolve(true))); - $downloader = $this->getDownloaderMock(null, null, $processExecutor, $filesystem); - $downloader->prepare('uninstall', $packageMock, 'composerPath'); - $downloader->remove($packageMock, 'composerPath'); - $downloader->cleanup('uninstall', $packageMock, 'composerPath'); + $downloader = $this->getDownloaderMock(null, null, $process, $filesystem); + $downloader->prepare('uninstall', $packageMock, $this->workingDir); + $downloader->remove($packageMock, $this->workingDir); + $downloader->cleanup('uninstall', $packageMock, $this->workingDir); + + $process->assertComplete($this); } public function testGetInstallationSource() diff --git a/tests/Composer/Test/Downloader/HgDownloaderTest.php b/tests/Composer/Test/Downloader/HgDownloaderTest.php index 7e606a607..e31262b1d 100644 --- a/tests/Composer/Test/Downloader/HgDownloaderTest.php +++ b/tests/Composer/Test/Downloader/HgDownloaderTest.php @@ -16,6 +16,7 @@ use Composer\Downloader\HgDownloader; use Composer\Test\TestCase; use Composer\Util\Filesystem; use Composer\Util\Platform; +use Composer\Test\Mock\ProcessExecutorMock; class HgDownloaderTest extends TestCase { @@ -39,7 +40,7 @@ class HgDownloaderTest extends TestCase { $io = $io ?: $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); $config = $config ?: $this->getMockBuilder('Composer\Config')->getMock(); - $executor = $executor ?: $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); + $executor = $executor ?: new ProcessExecutorMock; $filesystem = $filesystem ?: $this->getMockBuilder('Composer\Util\Filesystem')->getMock(); return new HgDownloader($io, $config, $executor, $filesystem); @@ -67,22 +68,17 @@ class HgDownloaderTest extends TestCase $packageMock->expects($this->once()) ->method('getSourceUrls') ->will($this->returnValue(array('https://mercurial.dev/l3l0/composer'))); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); - $expectedGitCommand = $this->getCmd('hg clone -- \'https://mercurial.dev/l3l0/composer\' \'composerPath\''); - $processExecutor->expects($this->at(0)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand)) - ->will($this->returnValue(0)); + $process = new ProcessExecutorMock; + $process->expects(array( + $this->getCmd('hg clone -- \'https://mercurial.dev/l3l0/composer\' \'composerPath\''), + $this->getCmd('hg up -- \'ref\''), + ), true); - $expectedGitCommand = $this->getCmd('hg up -- \'ref\''); - $processExecutor->expects($this->at(1)) - ->method('execute') - ->with($this->equalTo($expectedGitCommand)) - ->will($this->returnValue(0)); - - $downloader = $this->getDownloaderMock(null, null, $processExecutor); + $downloader = $this->getDownloaderMock(null, null, $process); $downloader->install($packageMock, 'composerPath'); + + $process->assertComplete($this); } public function testUpdateforPackageWithoutSourceReference() @@ -115,44 +111,44 @@ class HgDownloaderTest extends TestCase $packageMock->expects($this->any()) ->method('getSourceUrls') ->will($this->returnValue(array('https://github.com/l3l0/composer'))); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); - $expectedHgCommand = $this->getCmd("hg st"); - $processExecutor->expects($this->at(0)) - ->method('execute') - ->with($this->equalTo($expectedHgCommand)) - ->will($this->returnValue(0)); - $expectedHgCommand = $this->getCmd("hg pull -- 'https://github.com/l3l0/composer' && hg up -- 'ref'"); - $processExecutor->expects($this->at(1)) - ->method('execute') - ->with($this->equalTo($expectedHgCommand)) - ->will($this->returnValue(0)); + $process = new ProcessExecutorMock; + $process->expects(array( + $this->getCmd('hg st'), + $this->getCmd("hg pull -- 'https://github.com/l3l0/composer' && hg up -- 'ref'"), + ), true); - $downloader = $this->getDownloaderMock(null, null, $processExecutor); + $downloader = $this->getDownloaderMock(null, null, $process); $downloader->prepare('update', $packageMock, $this->workingDir, $packageMock); $downloader->update($packageMock, $packageMock, $this->workingDir); $downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock); + + $process->assertComplete($this); } public function testRemove() { - $expectedResetCommand = $this->getCmd('cd \'composerPath\' && hg st'); - + $fs = new Filesystem; + $fs->ensureDirectoryExists($this->workingDir.'/.hg'); $packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock(); - $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); - $processExecutor->expects($this->any()) - ->method('execute') - ->with($this->equalTo($expectedResetCommand)); + + $process = new ProcessExecutorMock; + $process->expects(array( + $this->getCmd('hg st'), + ), true); + $filesystem = $this->getMockBuilder('Composer\Util\Filesystem')->getMock(); $filesystem->expects($this->once()) ->method('removeDirectoryAsync') - ->with($this->equalTo('composerPath')) + ->with($this->equalTo($this->workingDir)) ->will($this->returnValue(\React\Promise\resolve(true))); - $downloader = $this->getDownloaderMock(null, null, $processExecutor, $filesystem); - $downloader->prepare('uninstall', $packageMock, 'composerPath'); - $downloader->remove($packageMock, 'composerPath'); - $downloader->cleanup('uninstall', $packageMock, 'composerPath'); + $downloader = $this->getDownloaderMock(null, null, $process, $filesystem); + $downloader->prepare('uninstall', $packageMock, $this->workingDir); + $downloader->remove($packageMock, $this->workingDir); + $downloader->cleanup('uninstall', $packageMock, $this->workingDir); + + $process->assertComplete($this); } public function testGetInstallationSource() diff --git a/tests/Composer/Test/Fixtures/installer/update-installed-reference.test b/tests/Composer/Test/Fixtures/installer/update-installed-reference.test index ae0b2d537..9f91322eb 100644 --- a/tests/Composer/Test/Fixtures/installer/update-installed-reference.test +++ b/tests/Composer/Test/Fixtures/installer/update-installed-reference.test @@ -28,4 +28,4 @@ Updating a dev package forcing it's reference should not do anything if the refe --RUN-- update --EXPECT-- -Upgrading a/a (dev-master def000 => dev-master ) +Upgrading a/a (dev-master def000 => dev-master) diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 3526db5c1..c4202511c 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -67,6 +67,21 @@ class InstallerTest extends TestCase ->setConstructorArgs(array($io)) ->getMock(); $config = $this->getMockBuilder('Composer\Config')->getMock(); + $config->expects($this->any()) + ->method('get') + ->will($this->returnCallback(function ($key) { + switch ($key) { + case 'vendor-dir': + return 'foo'; + case 'lock'; + case 'notify-on-install'; + return true; + case 'platform'; + return array(); + } + + throw new \UnexpectedValueException('Unknown key '.$key); + })); $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(); $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(); diff --git a/tests/Composer/Test/Mock/ProcessExecutorMock.php b/tests/Composer/Test/Mock/ProcessExecutorMock.php index 370e65147..1d1889f0f 100644 --- a/tests/Composer/Test/Mock/ProcessExecutorMock.php +++ b/tests/Composer/Test/Mock/ProcessExecutorMock.php @@ -15,6 +15,7 @@ namespace Composer\Test\Mock; use Composer\Util\ProcessExecutor; use Composer\Util\Platform; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\AssertionFailedError; use Symfony\Component\Process\Process; use React\Promise\Promise; @@ -29,16 +30,18 @@ class ProcessExecutorMock extends ProcessExecutor private $log = array(); /** - * @param array $expectations - * @param bool $strict set to true if you want to provide *all* expected commands, and not just a subset you are interested in testing - * @param array{return: int, stdout?: string, stderr?: string} $defaultHandler default command handler for undefined commands if not in strict mode + * @param array $expectations + * @param bool $strict set to true if you want to provide *all* expected commands, and not just a subset you are interested in testing + * @param array{return: int, stdout?: string, stderr?: string} $defaultHandler default command handler for undefined commands if not in strict mode */ public function expects(array $expectations, $strict = false, array $defaultHandler = array('return' => 0, 'stdout' => '', 'stderr' => '')) { - $default = array('return' => 0, 'stdout' => '', 'stderr' => ''); + $default = array('cmd' => '', 'return' => 0, 'stdout' => '', 'stderr' => '', 'callback' => null); $this->expectations = array_map(function ($expect) use ($default) { if (is_string($expect)) { $expect = array('cmd' => $expect); + } elseif ($diff = array_diff_key(array_merge($default, $expect), $default)) { + throw new \UnexpectedValueException('Unexpected keys in process execution step: '.implode(', ', array_keys($diff))); } return array_merge($default, $expect); @@ -53,7 +56,7 @@ class ProcessExecutorMock extends ProcessExecutor $expectations = array_map(function ($expect) { return $expect['cmd']; }, $this->expectations); - throw new \LogicException( + throw new AssertionFailedError( 'There are still '.count($this->expectations).' expected process calls which have not been consumed:'.PHP_EOL. implode(PHP_EOL, $expectations).PHP_EOL.PHP_EOL. 'Received calls:'.PHP_EOL.implode(PHP_EOL, $this->log) @@ -88,19 +91,25 @@ class ProcessExecutorMock extends ProcessExecutor $callback = is_callable($output) ? $output : array($this, 'outputHandler'); + $this->log[] = $command; + if ($this->expectations && $command === $this->expectations[0]['cmd']) { $expect = array_shift($this->expectations); $stdout = $expect['stdout']; $stderr = $expect['stderr']; $return = $expect['return']; + if (isset($expect['callback'])) { + call_user_func($expect['callback']); + } } elseif (!$this->strict) { $stdout = $this->defaultHandler['stdout']; $stderr = $this->defaultHandler['stderr']; $return = $this->defaultHandler['return']; } else { - throw new \LogicException( + throw new AssertionFailedError( 'Received unexpected command "'.$command.'" in "'.$cwd.'"'.PHP_EOL. - ($this->expectations ? 'Expected "'.$this->expectations[0]['cmd'].'" at this point.' : 'Expected no more calls at this point.') + ($this->expectations ? 'Expected "'.$this->expectations[0]['cmd'].'" at this point.' : 'Expected no more calls at this point.').PHP_EOL. + 'Received calls:'.PHP_EOL.implode(PHP_EOL, array_slice($this->log, 0, -1)) ); } @@ -115,8 +124,6 @@ class ProcessExecutorMock extends ProcessExecutor $output = $stdout; } - $this->log[] = $command; - $this->errorOutput = $stderr; return $return; diff --git a/tests/Composer/Test/Package/Version/VersionGuesserTest.php b/tests/Composer/Test/Package/Version/VersionGuesserTest.php index 8df182d66..d932f9223 100644 --- a/tests/Composer/Test/Package/Version/VersionGuesserTest.php +++ b/tests/Composer/Test/Package/Version/VersionGuesserTest.php @@ -18,6 +18,7 @@ use Composer\Semver\VersionParser; use Composer\Test\TestCase; use Composer\Util\Git as GitUtil; use Composer\Util\ProcessExecutor; +use Composer\Test\Mock\ProcessExecutorMock; class VersionGuesserTest extends TestCase { @@ -32,70 +33,28 @@ class VersionGuesserTest extends TestCase { $branch = 'default'; - $executor = $this->getMockBuilder('Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - $step = 0; + $process = new ProcessExecutorMock; + $process->expects(array( + array('cmd' => 'git branch -a --no-color --no-abbrev -v', 'return' => 128), + array('cmd' => 'git describe --exact-match --tags', 'return' => 128), + array('cmd' => 'git log --pretty="%H" -n1 HEAD'.GitUtil::getNoShowSignatureFlag($process), 'return' => 128), + array('cmd' => 'hg branch', 'return' => 0, 'stdout' => $branch), + array('cmd' => 'hg branches', 'return' => 0), + array('cmd' => 'hg bookmarks', 'return' => 0), + ), true); GitUtil::getVersion(new ProcessExecutor); - $executor - ->expects($this->at($step)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - - return 128; - }) - ; - - ++$step; - $executor - ->expects($this->at($step)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git describe --exact-match --tags', $command); - - return 128; - }) - ; - - ++$step; - $executor - ->expects($this->at($step)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $executor) { - $self->assertEquals('git log --pretty="%H" -n1 HEAD'.GitUtil::getNoShowSignatureFlag($executor), $command); - - return 128; - }) - ; - - ++$step; - $executor - ->expects($this->at($step)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $branch) { - $self->assertEquals('hg branch', $command); - $output = $branch; - - return 0; - }) - ; - $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionArray = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals("dev-".$branch, $versionArray['version']); $this->assertEquals("dev-".$branch, $versionArray['pretty_version']); $this->assertEmpty($versionArray['commit']); + + $process->assertComplete($this); } public function testGuessVersionReturnsData() @@ -103,29 +62,17 @@ class VersionGuesserTest extends TestCase $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; $anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* master $commitHash Commit message\n(no branch) $anotherCommitHash Commit message\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* master $commitHash Commit message\n(no branch) $anotherCommitHash Commit message\n" + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionArray = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals("dev-master", $versionArray['version']); @@ -133,6 +80,8 @@ class VersionGuesserTest extends TestCase $this->assertArrayNotHasKey('feature_version', $versionArray); $this->assertArrayNotHasKey('feature_pretty_version', $versionArray); $this->assertEquals($commitHash, $versionArray['commit']); + + $process->assertComplete($this); } public function testGuessVersionDoesNotSeeCustomDefaultBranchAsNonFeatureBranch() @@ -140,34 +89,24 @@ class VersionGuesserTest extends TestCase $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; $anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea'; - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - // Assumption here is that arbitrary would be the default branch - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = " arbitrary $commitHash Commit message\n* current $anotherCommitHash Another message\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + // Assumption here is that arbitrary would be the default branch + 'stdout' => " arbitrary $commitHash Commit message\n* current $anotherCommitHash Another message\n" + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionArray = $guesser->guessVersion(array('version' => 'self.version'), 'dummy/path'); $this->assertEquals("dev-current", $versionArray['version']); $this->assertEquals($anotherCommitHash, $versionArray['commit']); + + $process->assertComplete($this); } public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNaming() @@ -175,46 +114,29 @@ class VersionGuesserTest extends TestCase $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; $anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea'; - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = " arbitrary $commitHash Commit message\n* feature $anotherCommitHash Another message\n"; - - return 0; - }) - ; - - $executor - ->expects($this->at(1)) - ->method('execute') - ->willReturnCallback(function ($command, &$output, $path) use ($self, $anotherCommitHash) { - $self->assertEquals('git rev-list arbitrary..feature', $command); - $output = "$anotherCommitHash\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => " arbitrary $commitHash Commit message\n* feature $anotherCommitHash Another message\n" + ), + array( + 'cmd' => 'git rev-list arbitrary..feature', + 'stdout' => "$anotherCommitHash\n" + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionArray = $guesser->guessVersion(array('version' => 'self.version', 'non-feature-branches' => array('arbitrary')), 'dummy/path'); $this->assertEquals("dev-arbitrary", $versionArray['version']); $this->assertEquals($anotherCommitHash, $versionArray['commit']); $this->assertEquals("dev-feature", $versionArray['feature_version']); $this->assertEquals("dev-feature", $versionArray['feature_pretty_version']); + + $process->assertComplete($this); } public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingRegex() @@ -222,45 +144,29 @@ class VersionGuesserTest extends TestCase $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; $anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea'; - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = " latest-testing $commitHash Commit message\n* feature $anotherCommitHash Another message\n"; - - return 0; - }) - ; - $executor - ->expects($this->at(1)) - ->method('execute') - ->willReturnCallback(function ($command, &$output, $path) use ($self, $anotherCommitHash) { - $self->assertEquals('git rev-list latest-testing..feature', $command); - $output = "$anotherCommitHash\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => " latest-testing $commitHash Commit message\n* feature $anotherCommitHash Another message\n", + ), + array( + 'cmd' => 'git rev-list latest-testing..feature', + 'stdout' => "$anotherCommitHash\n", + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionArray = $guesser->guessVersion(array('version' => 'self.version', 'non-feature-branches' => array('latest-.*')), 'dummy/path'); $this->assertEquals("dev-latest-testing", $versionArray['version']); $this->assertEquals($anotherCommitHash, $versionArray['commit']); $this->assertEquals("dev-feature", $versionArray['feature_version']); $this->assertEquals("dev-feature", $versionArray['feature_pretty_version']); + + $process->assertComplete($this); } public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingWhenOnNonFeatureBranch() @@ -268,310 +174,209 @@ class VersionGuesserTest extends TestCase $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; $anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea'; - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* latest-testing $commitHash Commit message\n current $anotherCommitHash Another message\n master $anotherCommitHash Another message\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* latest-testing $commitHash Commit message\n current $anotherCommitHash Another message\n master $anotherCommitHash Another message\n", + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionArray = $guesser->guessVersion(array('version' => 'self.version', 'non-feature-branches' => array('latest-.*')), 'dummy/path'); $this->assertEquals("dev-latest-testing", $versionArray['version']); $this->assertEquals($commitHash, $versionArray['commit']); $this->assertArrayNotHasKey('feature_version', $versionArray); $this->assertArrayNotHasKey('feature_pretty_version', $versionArray); + + $process->assertComplete($this); } public function testDetachedHeadBecomesDevHash() { $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $commitHash) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* (no branch) $commitHash Commit message\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* (no branch) $commitHash Commit message\n", + ), + 'git describe --exact-match --tags', + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionData = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals("dev-$commitHash", $versionData['version']); + + $process->assertComplete($this); } public function testDetachedFetchHeadBecomesDevHashGit2() { $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock(); - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $commitHash) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* (HEAD detached at FETCH_HEAD) $commitHash Commit message\n"; - - return 0; - }); + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* (HEAD detached at FETCH_HEAD) $commitHash Commit message\n", + ), + 'git describe --exact-match --tags', + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionData = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals("dev-$commitHash", $versionData['version']); + + $process->assertComplete($this); } public function testDetachedCommitHeadBecomesDevHashGit2() { $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock(); - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self, $commitHash) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* (HEAD detached at 03a15d220) $commitHash Commit message\n"; - - return 0; - }); + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* (HEAD detached at 03a15d220) $commitHash Commit message\n", + ), + 'git describe --exact-match --tags', + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionData = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals("dev-$commitHash", $versionData['version']); + + $process->assertComplete($this); } public function testTagBecomesVersion() { - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* (HEAD detached at v2.0.5-alpha2) 433b98d4218c181bae01865901aac045585e8a1a Commit message\n"; - - return 0; - }) - ; - $executor - ->expects($this->at(1)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git describe --exact-match --tags', $command); - $output = "v2.0.5-alpha2"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* (HEAD detached at v2.0.5-alpha2) 433b98d4218c181bae01865901aac045585e8a1a Commit message\n", + ), + array( + 'cmd' => 'git describe --exact-match --tags', + 'stdout' => "v2.0.5-alpha2", + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionData = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals("2.0.5.0-alpha2", $versionData['version']); + + $process->assertComplete($this); } public function testTagBecomesPrettyVersion() { - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* (HEAD detached at 1.0.0) c006f0c12bbbf197b5c071ffb1c0e9812bb14a4d Commit message\n"; - - return 0; - }) - ; - $executor - ->expects($this->at(1)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git describe --exact-match --tags', $command); - $output = '1.0.0'; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* (HEAD detached at 1.0.0) c006f0c12bbbf197b5c071ffb1c0e9812bb14a4d Commit message\n", + ), + array( + 'cmd' => 'git describe --exact-match --tags', + 'stdout' => '1.0.0', + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionData = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals('1.0.0.0', $versionData['version']); $this->assertEquals('1.0.0', $versionData['pretty_version']); + + $process->assertComplete($this); } public function testInvalidTagBecomesVersion() { - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* foo 03a15d220da53c52eddd5f32ffca64a7b3801bea Commit message\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* foo 03a15d220da53c52eddd5f32ffca64a7b3801bea Commit message\n", + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionData = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals("dev-foo", $versionData['version']); + + $process->assertComplete($this); } public function testNumericBranchesShowNicely() { - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* 1.5 03a15d220da53c52eddd5f32ffca64a7b3801bea Commit message\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* 1.5 03a15d220da53c52eddd5f32ffca64a7b3801bea Commit message\n", + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionData = $guesser->guessVersion(array(), 'dummy/path'); $this->assertEquals("1.5.x-dev", $versionData['pretty_version']); $this->assertEquals("1.5.9999999.9999999-dev", $versionData['version']); + + $process->assertComplete($this); } public function testRemoteBranchesAreSelected() { - $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') - ->setMethods(array('execute')) - ->disableArgumentCloning() - ->disableOriginalConstructor() - ->getMock() - ; - - $self = $this; - - $executor - ->expects($this->at(0)) - ->method('execute') - ->willReturnCallback(function ($command, &$output) use ($self) { - $self->assertEquals('git branch -a --no-color --no-abbrev -v', $command); - $output = "* feature-branch 03a15d220da53c52eddd5f32ffca64a7b3801bea Commit message\n". - "remotes/origin/1.5 03a15d220da53c52eddd5f32ffca64a7b3801bea Commit message\n"; - - return 0; - }) - ; - - $executor - ->expects($this->at(1)) - ->method('execute') - ->willReturnCallback(function ($command, &$output, $path) use ($self) { - $self->assertEquals('git rev-list remotes/origin/1.5..feature-branch', $command); - $output = "\n"; - - return 0; - }) - ; + $process = new ProcessExecutorMock; + $process->expects(array( + array( + 'cmd' => 'git branch -a --no-color --no-abbrev -v', + 'stdout' => "* feature-branch 03a15d220da53c52eddd5f32ffca64a7b3801bea Commit message\n". + "remotes/origin/1.5 03a15d220da53c52eddd5f32ffca64a7b3801bea Commit message\n", + ), + array( + 'cmd' => 'git rev-list remotes/origin/1.5..feature-branch', + 'stdout' => "\n", + ), + ), true); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); - $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $guesser = new VersionGuesser($config, $process, new VersionParser()); $versionData = $guesser->guessVersion(array('version' => 'self.version'), 'dummy/path'); $this->assertEquals("1.5.x-dev", $versionData['pretty_version']); $this->assertEquals("1.5.9999999.9999999-dev", $versionData['version']); + + $process->assertComplete($this); } }