diff --git a/src/Composer/Package/LinkConstraint/VersionConstraint.php b/src/Composer/Package/LinkConstraint/VersionConstraint.php index 0bf928047..c7cf62ff2 100644 --- a/src/Composer/Package/LinkConstraint/VersionConstraint.php +++ b/src/Composer/Package/LinkConstraint/VersionConstraint.php @@ -36,9 +36,32 @@ class VersionConstraint extends SpecificConstraint $this->version = $version; } + /** + * + * @param VersionConstraint $provider + */ public function matchSpecific(VersionConstraint $provider) { - return version_compare($provider->version, $this->version, $this->operator); + $noEqualOp = str_replace('=', '', $this->operator); + $providerNoEqualOp = str_replace('=', '', $provider->operator); + + // an example for the condition is <= 2.0 & < 1.0 + // these kinds of comparisons always have a solution + if ($this->operator != '==' && $noEqualOp == $providerNoEqualOp) { + return true; + } + + if (version_compare($provider->version, $this->version, $this->operator)) { + // special case, e.g. require >= 1.0 and provide < 1.0 + // 1.0 >= 1.0 but 1.0 is outside of the provided interval + if ($provider->version == $this->version && $provider->operator == $providerNoEqualOp && $this->operator != $noEqualOp) { + return false; + } + + return true; + } + + return false; } public function __toString() diff --git a/tests/Composer/Test/Package/LinkConstraint/VersionConstraintTest.php b/tests/Composer/Test/Package/LinkConstraint/VersionConstraintTest.php new file mode 100644 index 000000000..0aa9052be --- /dev/null +++ b/tests/Composer/Test/Package/LinkConstraint/VersionConstraintTest.php @@ -0,0 +1,69 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Package; + +use Composer\Package\LinkConstraint\VersionConstraint; + +class VersionConstraintTest extends \PHPUnit_Framework_TestCase +{ + static public function successfulVersionMatches() + { + return array( + // require provide + array('==', '1', '==', '1'), + array('>=', '1', '>=', '2'), + array('>=', '2', '>=', '1'), + array('>=', '2', '>', '1'), + array('<=', '2', '>=', '1'), + array('>=', '1', '<=', '2'), + array('==', '2', '>=', '2'), + ); + } + + /** + * @dataProvider successfulVersionMatches + */ + public function testVersionMatchSucceeds($requireOperator, $requireVersion, $provideOperator, $provideVersion) + { + $versionRequire = new VersionConstraint($requireOperator, $requireVersion); + $versionProvide = new VersionConstraint($provideOperator, $provideVersion); + + $this->assertTrue($versionRequire->matches($versionProvide)); + } + + static public function failingVersionMatches() + { + return array( + // require provide + array('==', '1', '==', '2'), + array('>=', '2', '<=', '1'), + array('>=', '2', '<', '2'), + array('<=', '2', '>', '2'), + array('>', '2', '<=', '2'), + array('<=', '1', '>=', '2'), + array('>=', '2', '<=', '1'), + array('==', '2', '<', '2'), + ); + } + + /** + * @dataProvider failingVersionMatches + */ + public function testVersionMatchFails($requireOperator, $requireVersion, $provideOperator, $provideVersion) + { + $versionRequire = new VersionConstraint($requireOperator, $requireVersion); + $versionProvide = new VersionConstraint($provideOperator, $provideVersion); + + $this->assertFalse($versionRequire->matches($versionProvide)); + } +}