From 050439a0d3557287c5b41fdf00d137cbb580d834 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 1 Jul 2012 18:27:16 +0200 Subject: [PATCH 1/4] Add support for defining assertions on expected lock files to integration tests --- tests/Composer/Test/InstallerTest.php | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 0dfff7b0b..87e6fef52 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -123,7 +123,7 @@ class InstallerTest extends TestCase /** * @dataProvider getIntegrationTests */ - public function testIntegration($file, $message, $condition, $composerConfig, $lock, $installed, $installedDev, $run, $expect) + public function testIntegration($file, $message, $condition, $composerConfig, $lock, $installed, $installedDev, $run, $expectLock, $expect) { if ($condition) { eval('$res = '.$condition.';'); @@ -170,6 +170,17 @@ class InstallerTest extends TestCase ->method('exists') ->will($this->returnValue(true)); + if ($expectLock) { + $actualLock = array(); + $lockJsonMock->expects($this->atLeastOnce()) + ->method('write') + ->will($this->returnCallback(function ($hash, $options) use (&$actualLock) { + // need to do assertion outside of mock for nice phpunit output + // so store value temporarily in reference for later assetion + $actualLock = $hash; + })); + } + $locker = new Locker($lockJsonMock, $repositoryManager, $composer->getInstallationManager(), md5(json_encode($composerConfig))); $composer->setLocker($locker); @@ -208,6 +219,11 @@ class InstallerTest extends TestCase fseek($appOutput, 0); $this->assertEquals(0, $result, $output . stream_get_contents($appOutput)); + if ($expectLock) { + unset($actualLock['hash']); + $this->assertEquals($expectLock, $actualLock); + } + $installationManager = $composer->getInstallationManager(); $this->assertSame($expect, implode("\n", $installationManager->getTrace())); } @@ -233,12 +249,14 @@ class InstallerTest extends TestCase (?:--INSTALLED--\s*(?P'.$content.'))?\s* (?:--INSTALLED:DEV--\s*(?P'.$content.'))?\s* --RUN--\s*(?P.*?)\s* + (?:--EXPECT-LOCK--\s*(?P'.$content.'))?\s* --EXPECT--\s*(?P.*?)\s* $}xs'; $installed = array(); $installedDev = array(); $lock = array(); + $expectLock = array(); if (preg_match($pattern, $test, $match)) { try { @@ -258,6 +276,9 @@ class InstallerTest extends TestCase $installedDev = JsonFile::parseJson($match['installedDev']); } $run = $match['run']; + if (!empty($match['expectLock'])) { + $expectLock = JsonFile::parseJson($match['expectLock']); + } $expect = $match['expect']; } catch (\Exception $e) { die(sprintf('Test "%s" is not valid: '.$e->getMessage(), str_replace($fixturesDir.'/', '', $file))); @@ -266,7 +287,7 @@ class InstallerTest extends TestCase die(sprintf('Test "%s" is not valid, did not match the expected format.', str_replace($fixturesDir.'/', '', $file))); } - $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $composer, $lock, $installed, $installedDev, $run, $expect); + $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $composer, $lock, $installed, $installedDev, $run, $expectLock, $expect); } return $tests; From 3c7fbe92642faec1e70eba52188e446c66a52388 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 1 Jul 2012 18:28:33 +0200 Subject: [PATCH 2/4] Add a test which verifies that aliases do not get duplicated on update --- .../Fixtures/installer/update-alias-lock.test | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/Composer/Test/Fixtures/installer/update-alias-lock.test diff --git a/tests/Composer/Test/Fixtures/installer/update-alias-lock.test b/tests/Composer/Test/Fixtures/installer/update-alias-lock.test new file mode 100644 index 000000000..cc69f17d1 --- /dev/null +++ b/tests/Composer/Test/Fixtures/installer/update-alias-lock.test @@ -0,0 +1,55 @@ +--TEST-- +Update aliased package to non-aliased version +--COMPOSER-- +{ + "repositories": [ + { + "type": "package", + "package": [ + { + "name": "a/a", "version": "dev-master", + "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, + "source": { "reference": "master", "type": "git", "url": "" } + } + ] + } + ], + "require": { + "a/a": "1.*" + }, + "minimum-stability": "stable" +} +--LOCK-- +{ + "packages": [ + { "package": "a/a", "version": "dev-master", "source-reference": "1234" }, + { "package": "a/a", "version": "dev-master", "alias-pretty-version": "1.0.x-dev", "alias-version": "1.0.9999999.9999999-dev" } + ], + "packages-dev": null, + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [] +} +--INSTALLED-- +[ + { + "name": "a/a", "version": "dev-master", + "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, + "source": { "reference": "1234", "type": "git", "url": "" } + } +] +--RUN-- +update +--EXPECT-LOCK-- +{ + "packages": [ + { "package": "a/a", "version": "dev-master", "alias-pretty-version": "1.0.x-dev", "alias-version": "1.0.9999999.9999999-dev" }, + { "package": "a/a", "version": "dev-master", "source-reference": "master" } + ], + "packages-dev": null, + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [] +} +--EXPECT-- +Updating a/a (dev-master 1234) to a/a (dev-master master) \ No newline at end of file From 9346d4a501edaa9eb1217fafd08944d197ea37c9 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 1 Jul 2012 18:41:58 +0200 Subject: [PATCH 3/4] Make the InstallationManagerMock behave like the real class on alias install --- tests/Composer/Test/Mock/InstallationManagerMock.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/Composer/Test/Mock/InstallationManagerMock.php b/tests/Composer/Test/Mock/InstallationManagerMock.php index 4bccc63f8..b643df728 100644 --- a/tests/Composer/Test/Mock/InstallationManagerMock.php +++ b/tests/Composer/Test/Mock/InstallationManagerMock.php @@ -56,9 +56,14 @@ class InstallationManagerMock extends InstallationManager public function markAliasInstalled(RepositoryInterface $repo, MarkAliasInstalledOperation $operation) { - $this->installed[] = $operation->getPackage(); + $package = $operation->getPackage(); + + $this->installed[] = $package; $this->trace[] = (string) $operation; - $repo->addPackage(clone $operation->getPackage()); + + if (!$repo->hasPackage($package)) { + $repo->addPackage($package); + } } public function markAliasUninstalled(RepositoryInterface $repo, MarkAliasUninstalledOperation $operation) From 4eb5f737186db59d075f1d56361ea0722629d914 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 1 Jul 2012 18:50:46 +0200 Subject: [PATCH 4/4] Only create alias package in repositories on the fly if necessary, fixes #793 --- src/Composer/Repository/ArrayRepository.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Composer/Repository/ArrayRepository.php b/src/Composer/Repository/ArrayRepository.php index d19584b7e..590fc3009 100644 --- a/src/Composer/Repository/ArrayRepository.php +++ b/src/Composer/Repository/ArrayRepository.php @@ -105,7 +105,10 @@ class ArrayRepository implements RepositoryInterface // create alias package on the fly if needed if ($package->getAlias()) { - $this->addPackage($this->createAliasPackage($package)); + $alias = $this->createAliasPackage($package); + if (!$this->hasPackage($alias)) { + $this->addPackage($alias); + } } }