Преглед изворни кода

Correct version contraint matching and add tests for various cases

Nils Adermann пре 14 година
родитељ
комит
d5dd86cd75

+ 24 - 1
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()

+ 69 - 0
tests/Composer/Test/Package/LinkConstraint/VersionConstraintTest.php

@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * 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));
+    }
+}