Skip to content

Commit

Permalink
Fix MultiConstrain optimization with version overlap
Browse files Browse the repository at this point in the history
  • Loading branch information
jderusse committed Nov 12, 2020
1 parent bcf1cc7 commit 2977d5b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 80 deletions.
32 changes: 27 additions & 5 deletions src/Constraint/MultiConstraint.php
Expand Up @@ -237,8 +237,6 @@ private static function optimizeConstraints(array $constraints, $conjunctive)
&& $left->conjunctive
&& $right instanceof self
&& $right->conjunctive
&& \count($left->constraints) === 2
&& \count($right->constraints) === 2
&& ($left0 = (string) $left->constraints[0])
&& $left0[0] === '>' && $left0[1] === '='
&& ($left1 = (string) $left->constraints[1])
Expand All @@ -249,6 +247,29 @@ private static function optimizeConstraints(array $constraints, $conjunctive)
&& $right1[0] === '<'
&& substr($left1, 2) === substr($right0, 3)
) {
for ($j = 2, $m = count($right->constraints); $j < $m; $j++) {
$c = (string)$right->constraints[$j];
switch ($c[0]) {
case '!':
case '<':
case '=':
break;
default:
continue 3;
}
}
for ($j = 2, $m = count($left->constraints); $j < $m; $j++) {
$c = (string)$left->constraints[$j];
switch ($c[0]) {
case '!':
case '>':
case '=':
break;
default:
continue 3;
}
}

$optimized = true;
$left = new MultiConstraint(
array_merge(
Expand All @@ -260,10 +281,11 @@ private static function optimizeConstraints(array $constraints, $conjunctive)
\array_slice($right->constraints, 2)
),
true);
} else {
$mergedConstraints[] = $left;
$left = $right;
continue;
}

$mergedConstraints[] = $left;
$left = $right;
}
if ($optimized) {
$mergedConstraints[] = $left;
Expand Down
93 changes: 18 additions & 75 deletions tests/Constraint/MultiConstraintTest.php
Expand Up @@ -312,7 +312,7 @@ public function multiConstraintOptimizations()
true // conjunctive
),
),
'Test does not collapse when one side is more complex' => array(
'Test does not collapse when one side changes the bounds' => array(
'~2.5.9 || ~2.6, >=2.6.2',
new MultiConstraint(
array(
Expand All @@ -335,96 +335,39 @@ public function multiConstraintOptimizations()
false
)
),
'Test does not collapse multiple contiguous with other constraint but collapses the end' => array(
'Test collapses multiple contiguous with other constraint' => array(
'^1.0 || ^2.0 !=2.0.1 || ^3.0 || ^4.0',
new MultiConstraint(
array(
new MultiConstraint(
array(
new Constraint('>=', '1.0.0.0-dev'),
new Constraint('<', '2.0.0.0-dev'),
),
true // conjunctive
),
new MultiConstraint(
array(
new Constraint('>=', '2.0.0.0-dev'),
new Constraint('<', '3.0.0.0-dev'),
new Constraint('!=', '2.0.1.0'),
),
true // conjunctive
),
new MultiConstraint(
array(
new Constraint('>=', '3.0.0.0-dev'),
new Constraint('<', '5.0.0.0-dev'),
),
true // conjunctive
),
new Constraint('>=', '1.0.0.0-dev'),
new Constraint('<', '5.0.0.0-dev'),
new Constraint('!=', '2.0.1.0'),
),
false
true
)
),
'Test does not collapse multiple contiguous with multiple other constraint' => array(
'Test collapses multiple contiguous with multiple other constraint' => array(
'^1.0 != 1.0.1 || ^2.0 !=2.0.1 || ^3.0 || ^4.0 != 4.0.1',
new MultiConstraint(
array(
new MultiConstraint(
array(
new Constraint('>=', '1.0.0.0-dev'),
new Constraint('<', '2.0.0.0-dev'),
new Constraint('!=', '1.0.1.0'),
),
true // conjunctive
),
new MultiConstraint(
array(
new Constraint('>=', '2.0.0.0-dev'),
new Constraint('<', '3.0.0.0-dev'),
new Constraint('!=', '2.0.1.0'),
),
true // conjunctive
),
new MultiConstraint(
array(
new Constraint('>=', '3.0.0.0-dev'),
new Constraint('<', '4.0.0.0-dev'),
),
true // conjunctive
),
new MultiConstraint(
array(
new Constraint('>=', '4.0.0.0-dev'),
new Constraint('<', '5.0.0.0-dev'),
new Constraint('!=', '4.0.1.0'),
),
true // conjunctive
),
new Constraint('>=', '1.0.0.0-dev'),
new Constraint('<', '5.0.0.0-dev'),
new Constraint('!=', '1.0.1.0'),
new Constraint('!=', '2.0.1.0'),
new Constraint('!=', '4.0.1.0'),
),
false
true
)
),
'Test does not collapse if contiguous range and other constraints also apply' => array(
'Test collapse if contiguous range and other constraints also apply' => array(
'~0.1 || ~1.0 !=1.0.1',
new MultiConstraint(
array(
new MultiConstraint(
array(
new Constraint('>=', '0.1.0.0-dev'),
new Constraint('<', '1.0.0.0-dev'),
),
true // conjunctive
),
new MultiConstraint(
array(
new Constraint('>=', '1.0.0.0-dev'),
new Constraint('<', '2.0.0.0-dev'),
new Constraint('!=', '1.0.1.0'),
),
true // conjunctive
),
new Constraint('>=', '0.1.0.0-dev'),
new Constraint('<', '2.0.0.0-dev'),
new Constraint('!=', '1.0.1.0'),
),
false
true // conjunctive
)
),
'Parse caret constraints must not collapse if non contiguous range' => array(
Expand Down

0 comments on commit 2977d5b

Please sign in to comment.