Get rid of Literal object / literal id mix, use literals only to save memory
parent
9ffe0d13f5
commit
451bab1c2c
|
@ -50,44 +50,44 @@ class DefaultPolicy implements PolicyInterface
|
|||
|
||||
public function selectPreferedPackages(Pool $pool, array $installedMap, array $literals)
|
||||
{
|
||||
$packages = $this->groupLiteralsByNamePreferInstalled($installedMap, $literals);
|
||||
$packages = $this->groupLiteralsByNamePreferInstalled($pool,$installedMap, $literals);
|
||||
|
||||
foreach ($packages as &$literals) {
|
||||
$policy = $this;
|
||||
usort($literals, function ($a, $b) use ($policy, $pool, $installedMap) {
|
||||
return $policy->compareByPriorityPreferInstalled($pool, $installedMap, $a->getPackage(), $b->getPackage(), true);
|
||||
return $policy->compareByPriorityPreferInstalled($pool, $installedMap, $pool->literalToPackage($a), $pool->literalToPackage($b), true);
|
||||
});
|
||||
}
|
||||
|
||||
foreach ($packages as &$literals) {
|
||||
$literals = $this->pruneToBestVersion($literals);
|
||||
$literals = $this->pruneToBestVersion($pool, $literals);
|
||||
|
||||
$literals = $this->pruneToHighestPriorityOrInstalled($pool, $installedMap, $literals);
|
||||
|
||||
$literals = $this->pruneRemoteAliases($literals);
|
||||
$literals = $this->pruneRemoteAliases($pool, $literals);
|
||||
}
|
||||
|
||||
$selected = call_user_func_array('array_merge', $packages);
|
||||
|
||||
// now sort the result across all packages to respect replaces across packages
|
||||
usort($selected, function ($a, $b) use ($policy, $pool, $installedMap) {
|
||||
return $policy->compareByPriorityPreferInstalled($pool, $installedMap, $a->getPackage(), $b->getPackage());
|
||||
return $policy->compareByPriorityPreferInstalled($pool, $installedMap, $pool->literalToPackage($a), $pool->literalToPackage($b));
|
||||
});
|
||||
|
||||
return $selected;
|
||||
}
|
||||
|
||||
protected function groupLiteralsByNamePreferInstalled(array $installedMap, $literals)
|
||||
protected function groupLiteralsByNamePreferInstalled(Pool $pool, array $installedMap, $literals)
|
||||
{
|
||||
$packages = array();
|
||||
foreach ($literals as $literal) {
|
||||
$packageName = $literal->getPackage()->getName();
|
||||
$packageName = $pool->literalToPackage($literal)->getName();
|
||||
|
||||
if (!isset($packages[$packageName])) {
|
||||
$packages[$packageName] = array();
|
||||
}
|
||||
|
||||
if (isset($installedMap[$literal->getPackageId()])) {
|
||||
if (isset($installedMap[abs($literal)])) {
|
||||
array_unshift($packages[$packageName], $literal);
|
||||
} else {
|
||||
$packages[$packageName][] = $literal;
|
||||
|
@ -165,19 +165,21 @@ class DefaultPolicy implements PolicyInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
protected function pruneToBestVersion($literals)
|
||||
protected function pruneToBestVersion(Pool $pool, $literals)
|
||||
{
|
||||
$bestLiterals = array($literals[0]);
|
||||
$bestPackage = $literals[0]->getPackage();
|
||||
$bestPackage = $pool->literalToPackage($literals[0]);
|
||||
foreach ($literals as $i => $literal) {
|
||||
if (0 === $i) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->versionCompare($literal->getPackage(), $bestPackage, '>')) {
|
||||
$bestPackage = $literal->getPackage();
|
||||
$package = $pool->literalToPackage($literal);
|
||||
|
||||
if ($this->versionCompare($package, $bestPackage, '>')) {
|
||||
$bestPackage = $package;
|
||||
$bestLiterals = array($literal);
|
||||
} else if ($this->versionCompare($literal->getPackage(), $bestPackage, '==')) {
|
||||
} else if ($this->versionCompare($package, $bestPackage, '==')) {
|
||||
$bestLiterals[] = $literal;
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +217,7 @@ class DefaultPolicy implements PolicyInterface
|
|||
$priority = null;
|
||||
|
||||
foreach ($literals as $literal) {
|
||||
$package = $literal->getPackage();
|
||||
$package = $pool->literalToPackage($literal);
|
||||
|
||||
if (isset($installedMap[$package->getId()])) {
|
||||
$selected[] = $literal;
|
||||
|
@ -241,12 +243,12 @@ class DefaultPolicy implements PolicyInterface
|
|||
*
|
||||
* If no package is a local alias, nothing happens
|
||||
*/
|
||||
protected function pruneRemoteAliases(array $literals)
|
||||
protected function pruneRemoteAliases(Pool $pool, array $literals)
|
||||
{
|
||||
$hasLocalAlias = false;
|
||||
|
||||
foreach ($literals as $literal) {
|
||||
$package = $literal->getPackage();
|
||||
$package = $pool->literalToPackage($literal);
|
||||
|
||||
if ($package instanceof AliasPackage && $package->isRootPackageAlias()) {
|
||||
$hasLocalAlias = true;
|
||||
|
@ -260,7 +262,7 @@ class DefaultPolicy implements PolicyInterface
|
|||
|
||||
$selected = array();
|
||||
foreach ($literals as $literal) {
|
||||
$package = $literal->getPackage();
|
||||
$package = $pool->literalToPackage($literal);
|
||||
|
||||
if ($package instanceof AliasPackage && $package->isRootPackageAlias()) {
|
||||
$selected[] = $literal;
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
<?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\DependencyResolver;
|
||||
|
||||
use Composer\Package\PackageInterface;
|
||||
|
||||
/**
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
*/
|
||||
class Literal
|
||||
{
|
||||
protected $package;
|
||||
protected $wanted;
|
||||
protected $id;
|
||||
|
||||
public function __construct(PackageInterface $package, $wanted)
|
||||
{
|
||||
$this->package = $package;
|
||||
$this->wanted = $wanted;
|
||||
$this->id = ($this->wanted ? '' : '-') . $this->package->getId();
|
||||
}
|
||||
|
||||
public function isWanted()
|
||||
{
|
||||
return $this->wanted;
|
||||
}
|
||||
|
||||
public function getPackage()
|
||||
{
|
||||
return $this->package;
|
||||
}
|
||||
|
||||
public function getPackageId()
|
||||
{
|
||||
return $this->package->getId();
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return ($this->wanted ? '+' : '-') . $this->getPackage();
|
||||
}
|
||||
|
||||
public function inverted()
|
||||
{
|
||||
return new Literal($this->getPackage(), !$this->isWanted());
|
||||
}
|
||||
|
||||
public function equals(Literal $b)
|
||||
{
|
||||
return $this->id === $b->id;
|
||||
}
|
||||
}
|
|
@ -151,4 +151,15 @@ class Pool
|
|||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function literalToPackage($literal)
|
||||
{
|
||||
$packageId = abs($literal);
|
||||
return $this->packageById($packageId);
|
||||
}
|
||||
|
||||
public function literalToString($literal)
|
||||
{
|
||||
return ($literal > 0 ? '+' : '-') . $this->literalToPackage($literal);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ class Rule
|
|||
const RULE_LEARNED = 12;
|
||||
const RULE_PACKAGE_ALIAS = 13;
|
||||
|
||||
protected $pool;
|
||||
|
||||
protected $disabled;
|
||||
protected $literals;
|
||||
protected $type;
|
||||
|
@ -37,18 +39,14 @@ class Rule
|
|||
|
||||
protected $job;
|
||||
|
||||
public $watch1;
|
||||
public $watch2;
|
||||
|
||||
public $next1;
|
||||
public $next2;
|
||||
|
||||
public $ruleHash;
|
||||
|
||||
public function __construct(array $literals, $reason, $reasonData, $job = null)
|
||||
public function __construct(Pool $pool, array $literals, $reason, $reasonData, $job = null)
|
||||
{
|
||||
$this->pool = $pool;
|
||||
|
||||
// sort all packages ascending by id
|
||||
usort($literals, array($this, 'compareLiteralsById'));
|
||||
sort($literals);
|
||||
|
||||
$this->literals = $literals;
|
||||
$this->reason = $reason;
|
||||
|
@ -59,14 +57,9 @@ class Rule
|
|||
|
||||
$this->job = $job;
|
||||
|
||||
$this->watch1 = (count($this->literals) > 0) ? $literals[0]->getId() : 0;
|
||||
$this->watch2 = (count($this->literals) > 1) ? $literals[1]->getId() : 0;
|
||||
|
||||
$this->type = -1;
|
||||
|
||||
$this->ruleHash = substr(md5(implode(',', array_map(function ($l) {
|
||||
return $l->getId();
|
||||
}, $this->literals))), 0, 5);
|
||||
$this->ruleHash = substr(md5(implode(',', $this->literals)), 0, 5);
|
||||
}
|
||||
|
||||
public function getHash()
|
||||
|
@ -108,7 +101,7 @@ class Rule
|
|||
}
|
||||
|
||||
for ($i = 0, $n = count($this->literals); $i < $n; $i++) {
|
||||
if ($this->literals[$i]->getId() !== $rule->literals[$i]->getId()) {
|
||||
if ($this->literals[$i] !== $rule->literals[$i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -166,24 +159,6 @@ class Rule
|
|||
return 1 === count($this->literals);
|
||||
}
|
||||
|
||||
public function getNext(Literal $literal)
|
||||
{
|
||||
if ($this->watch1 == $literal->getId()) {
|
||||
return $this->next1;
|
||||
} else {
|
||||
return $this->next2;
|
||||
}
|
||||
}
|
||||
|
||||
public function getOtherWatch(Literal $literal)
|
||||
{
|
||||
if ($this->watch1 == $literal->getId()) {
|
||||
return $this->watch2;
|
||||
} else {
|
||||
return $this->watch1;
|
||||
}
|
||||
}
|
||||
|
||||
public function toHumanReadableString()
|
||||
{
|
||||
$ruleText = '';
|
||||
|
@ -191,7 +166,7 @@ class Rule
|
|||
if ($i != 0) {
|
||||
$ruleText .= '|';
|
||||
}
|
||||
$ruleText .= $literal;
|
||||
$ruleText .= $this->pool->literalToString($literal);
|
||||
}
|
||||
|
||||
switch ($this->reason) {
|
||||
|
@ -205,18 +180,18 @@ class Rule
|
|||
return "Remove command rule ($ruleText)";
|
||||
|
||||
case self::RULE_PACKAGE_CONFLICT:
|
||||
$package1 = $this->literals[0]->getPackage();
|
||||
$package2 = $this->literals[1]->getPackage();
|
||||
$package1 = $this->pool->literalToPackage($this->literals[0]);
|
||||
$package2 = $this->pool->literalToPackage($this->literals[1]);
|
||||
return 'Package "'.$package1.'" conflicts with "'.$package2.'"';
|
||||
|
||||
case self::RULE_PACKAGE_REQUIRES:
|
||||
$literals = $this->literals;
|
||||
$sourceLiteral = array_shift($literals);
|
||||
$sourcePackage = $sourceLiteral->getPackage();
|
||||
$sourcePackage = $this->pool->literalToPackage($sourceLiteral);
|
||||
|
||||
$requires = array();
|
||||
foreach ($literals as $literal) {
|
||||
$requires[] = $literal->getPackage();
|
||||
$requires[] = $this->pool->literalToPackage($literal);
|
||||
}
|
||||
|
||||
$text = 'Package "'.$sourcePackage.'" contains the rule '.$this->reasonData.'. ';
|
||||
|
@ -255,26 +230,11 @@ class Rule
|
|||
if ($i != 0) {
|
||||
$result .= '|';
|
||||
}
|
||||
$result .= $literal;
|
||||
$result .= $this->pool->literalToString($literal);
|
||||
}
|
||||
|
||||
$result .= ')';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison function for sorting literals by their id
|
||||
*
|
||||
* @param Literal $a
|
||||
* @param Literal $b
|
||||
* @return int 0 if the literals are equal, 1 if b is larger than a, -1 else
|
||||
*/
|
||||
private function compareLiteralsById(Literal $a, Literal $b)
|
||||
{
|
||||
if ($a->getId() === $b->getId()) {
|
||||
return 0;
|
||||
}
|
||||
return $a->getId() < $b->getId() ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,34 +50,17 @@ class RuleSetGenerator
|
|||
*/
|
||||
protected function createRequireRule(PackageInterface $package, array $providers, $reason, $reasonData = null)
|
||||
{
|
||||
$literals = array(new Literal($package, false));
|
||||
$literals = array(-$package->getId());
|
||||
|
||||
foreach ($providers as $provider) {
|
||||
// self fulfilling rule?
|
||||
if ($provider === $package) {
|
||||
return null;
|
||||
}
|
||||
$literals[] = new Literal($provider, true);
|
||||
$literals[] = $provider->getId();
|
||||
}
|
||||
|
||||
return new Rule($literals, $reason, $reasonData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new rule for installing a package
|
||||
*
|
||||
* The rule is simply (A) for a package A to be installed.
|
||||
*
|
||||
* @param PackageInterface $package The package to be installed
|
||||
* @param int $reason A RULE_* constant describing the
|
||||
* reason for generating this rule
|
||||
* @param mixed $reasonData Any data, e.g. the package name, that
|
||||
* goes with the reason
|
||||
* @return Rule The generated rule
|
||||
*/
|
||||
protected function createInstallRule(PackageInterface $package, $reason, $reasonData = null)
|
||||
{
|
||||
return new Rule(new Literal($package, true));
|
||||
return new Rule($this->pool, $literals, $reason, $reasonData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,10 +79,10 @@ class RuleSetGenerator
|
|||
{
|
||||
$literals = array();
|
||||
foreach ($packages as $package) {
|
||||
$literals[] = new Literal($package, true);
|
||||
$literals[] = $package->getId();
|
||||
}
|
||||
|
||||
return new Rule($literals, $reason, $job['packageName'], $job);
|
||||
return new Rule($this->pool, $literals, $reason, $job['packageName'], $job);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +98,7 @@ class RuleSetGenerator
|
|||
*/
|
||||
protected function createRemoveRule(PackageInterface $package, $reason, $job)
|
||||
{
|
||||
return new Rule(array(new Literal($package, false)), $reason, $job['packageName'], $job);
|
||||
return new Rule($this->pool, array(-$package->getId()), $reason, $job['packageName'], $job);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,7 +122,7 @@ class RuleSetGenerator
|
|||
return null;
|
||||
}
|
||||
|
||||
return new Rule(array(new Literal($issuer, false), new Literal($provider, false)), $reason, $reasonData);
|
||||
return new Rule($this->pool, array(-$issuer->getId(), -$provider->getId()), $reason, $reasonData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,33 +38,31 @@ class RuleWatchGraph
|
|||
}
|
||||
}
|
||||
|
||||
public function contains($literalId)
|
||||
public function contains($literal)
|
||||
{
|
||||
return isset($this->watches[$literalId]);
|
||||
return isset($this->watches[$literal]);
|
||||
}
|
||||
|
||||
public function walkLiteral($literalId, $level, $skipCallback, $conflictCallback, $decideCallback)
|
||||
public function walkLiteral($literal, $level, $skipCallback, $conflictCallback, $decideCallback)
|
||||
{
|
||||
if (!isset($this->watches[$literalId])) {
|
||||
if (!isset($this->watches[$literal])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->watches[$literalId]->rewind();
|
||||
while ($this->watches[$literalId]->valid()) {
|
||||
$node = $this->watches[$literalId]->current();
|
||||
$otherWatch = $node->getOtherWatch($literalId);
|
||||
$this->watches[$literal]->rewind();
|
||||
while ($this->watches[$literal]->valid()) {
|
||||
$node = $this->watches[$literal]->current();
|
||||
$otherWatch = $node->getOtherWatch($literal);
|
||||
|
||||
if (!$node->getRule()->isDisabled() && !call_user_func($skipCallback, $otherWatch)) {
|
||||
$ruleLiterals = $node->getRule()->getLiterals();
|
||||
|
||||
foreach ($ruleLiterals as $ruleLiteral) {
|
||||
$ruleLiteralId = $ruleLiteral->getId();
|
||||
if ($literal !== $ruleLiteral &&
|
||||
$otherWatch !== $ruleLiteral &&
|
||||
!call_user_func($conflictCallback, $ruleLiteral)) {
|
||||
|
||||
if ($literalId !== $ruleLiteralId &&
|
||||
$otherWatch !== $ruleLiteralId &&
|
||||
!call_user_func($conflictCallback, $ruleLiteralId)) {
|
||||
|
||||
$this->moveWatch($literalId, $ruleLiteralId, $node);
|
||||
$this->moveWatch($literal, $ruleLiteral, $node);
|
||||
|
||||
continue 2;
|
||||
}
|
||||
|
@ -77,7 +75,7 @@ class RuleWatchGraph
|
|||
call_user_func($decideCallback, $otherWatch, $level, $node->getRule());
|
||||
}
|
||||
|
||||
$this->watches[$literalId]->next();
|
||||
$this->watches[$literal]->next();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -28,8 +28,8 @@ class RuleWatchNode
|
|||
|
||||
$literals = $rule->getLiterals();
|
||||
|
||||
$this->watch1 = (count($literals) > 0) ? $literals[0]->getId() : 0;
|
||||
$this->watch2 = (count($literals) > 1) ? $literals[1]->getId() : 0;
|
||||
$this->watch1 = (count($literals) > 0) ? $literals[0] : 0;
|
||||
$this->watch2 = (count($literals) > 1) ? $literals[1] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,10 +47,10 @@ class RuleWatchNode
|
|||
$watchLevel = 0;
|
||||
|
||||
foreach ($literals as $literal) {
|
||||
$level = abs($decisionMap[$literal->getPackageId()]);
|
||||
$level = abs($decisionMap[abs($literal)]);
|
||||
|
||||
if ($level > $watchLevel) {
|
||||
$this->rule->watch2 = $literal->getId();
|
||||
$this->rule->watch2 = $literal;
|
||||
$watchLevel = $level;
|
||||
}
|
||||
}
|
||||
|
@ -61,9 +61,9 @@ class RuleWatchNode
|
|||
return $this->rule;
|
||||
}
|
||||
|
||||
public function getOtherWatch($literalId)
|
||||
public function getOtherWatch($literal)
|
||||
{
|
||||
if ($this->watch1 == $literalId) {
|
||||
if ($this->watch1 == $literal) {
|
||||
return $this->watch2;
|
||||
} else {
|
||||
return $this->watch1;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
namespace Composer\DependencyResolver;
|
||||
|
||||
use Composer\Repository\RepositoryInterface;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\DependencyResolver\Operation;
|
||||
|
||||
|
@ -51,10 +50,10 @@ class Solver
|
|||
$this->ruleSetGenerator = new RuleSetGenerator($policy, $pool);
|
||||
}
|
||||
|
||||
private function findDecisionRule(PackageInterface $package)
|
||||
private function findDecisionRule($packageId)
|
||||
{
|
||||
foreach ($this->decisionQueue as $i => $literal) {
|
||||
if ($package === $literal->getPackage()) {
|
||||
if ($packageId === abs($literal)) {
|
||||
return $this->decisionQueueWhy[$i];
|
||||
}
|
||||
}
|
||||
|
@ -77,10 +76,8 @@ class Solver
|
|||
$literals = $rule->getLiterals();
|
||||
$literal = $literals[0];
|
||||
|
||||
if (!$this->decided($literal->getPackage())) {
|
||||
$this->decisionQueue[] = $literal;
|
||||
$this->decisionQueueWhy[] = $rule;
|
||||
$this->addDecision($literal, 1);
|
||||
if (!$this->decided(abs($literal))) {
|
||||
$this->decide($literal, 1, $rule);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -94,7 +91,7 @@ class Solver
|
|||
continue;
|
||||
}
|
||||
|
||||
$conflict = $this->findDecisionRule($literal->getPackage());
|
||||
$conflict = $this->findDecisionRule(abs($literal));
|
||||
|
||||
if ($conflict && RuleSet::TYPE_PACKAGE === $conflict->getType()) {
|
||||
|
||||
|
@ -122,7 +119,7 @@ class Solver
|
|||
$assertRuleLiterals = $assertRule->getLiterals();
|
||||
$assertRuleLiteral = $assertRuleLiterals[0];
|
||||
|
||||
if ($literal->getPackageId() !== $assertRuleLiteral->getPackageId()) {
|
||||
if (abs($literal) !== abs($assertRuleLiteral)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -136,7 +133,7 @@ class Solver
|
|||
$decisionLiteral = array_pop($this->decisionQueue);
|
||||
array_pop($this->decisionQueueWhy);
|
||||
unset($this->decisionQueueFree[count($this->decisionQueue)]);
|
||||
$this->decisionMap[$decisionLiteral->getPackageId()] = 0;
|
||||
$this->decisionMap[abs($decisionLiteral)] = 0;
|
||||
}
|
||||
$ruleIndex = -1;
|
||||
}
|
||||
|
@ -149,10 +146,8 @@ class Solver
|
|||
$literals = $rule->getLiterals();
|
||||
$literal = $literals[0];
|
||||
|
||||
if ($this->decisionMap[$literal->getPackageId()] == 0) {
|
||||
$this->decisionQueue[] = $literal;
|
||||
$this->decisionQueueWhy[] = $rule;
|
||||
$this->addDecision($literal, 1);
|
||||
if ($this->decisionMap[abs($literal)] == 0) {
|
||||
$this->decide($literal, 1, $rule);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -191,7 +186,7 @@ class Solver
|
|||
case 'install':
|
||||
if (!$job['packages']) {
|
||||
$problem = new Problem();
|
||||
$problem->addRule(new Rule(array(), null, null, $job));
|
||||
$problem->addRule(new Rule($this->pool, array(), null, null, $job));
|
||||
$this->problems[] = $problem;
|
||||
}
|
||||
break;
|
||||
|
@ -237,24 +232,20 @@ class Solver
|
|||
return new Literal($package, $id > 0);
|
||||
}
|
||||
|
||||
protected function addDecision(Literal $l, $level)
|
||||
protected function addDecision($literal, $level)
|
||||
{
|
||||
$this->addDecisionId($l->getId(), $level);
|
||||
}
|
||||
|
||||
protected function addDecisionId($literalId, $level)
|
||||
{
|
||||
$packageId = abs($literalId);
|
||||
$packageId = abs($literal);
|
||||
|
||||
$previousDecision = $this->decisionMap[$packageId];
|
||||
if ($previousDecision != 0) {
|
||||
$literal = $this->literalFromId($literalId);
|
||||
$literalString = $this->pool->literalToString($literal);
|
||||
$package = $this->pool->literalToPackage($literal);
|
||||
throw new SolverBugException(
|
||||
"Trying to decide $literal on level $level, even though ".$literal->getPackage()." was previously decided as ".(int) $previousDecision."."
|
||||
"Trying to decide $literalString on level $level, even though $package was previously decided as ".(int) $previousDecision."."
|
||||
);
|
||||
}
|
||||
|
||||
if ($literalId > 0) {
|
||||
if ($literal > 0) {
|
||||
$this->decisionMap[$packageId] = $level;
|
||||
} else {
|
||||
$this->decisionMap[$packageId] = -$level;
|
||||
|
@ -263,67 +254,49 @@ class Solver
|
|||
|
||||
public function decide($literal, $level, $why)
|
||||
{
|
||||
$this->addDecisionId($literal, $level);
|
||||
$this->decisionQueue[] = $this->literalFromId($literal);
|
||||
$this->addDecision($literal, $level);
|
||||
$this->decisionQueue[] = $literal;
|
||||
$this->decisionQueueWhy[] = $why;
|
||||
}
|
||||
|
||||
protected function decisionsContain(Literal $l)
|
||||
public function decisionsContain($literal)
|
||||
{
|
||||
$packageId = abs($literal);
|
||||
return (
|
||||
$this->decisionMap[$l->getPackageId()] > 0 && $l->isWanted() ||
|
||||
$this->decisionMap[$l->getPackageId()] < 0 && !$l->isWanted()
|
||||
$this->decisionMap[$packageId] > 0 && $literal > 0 ||
|
||||
$this->decisionMap[$packageId] < 0 && $literal < 0
|
||||
);
|
||||
}
|
||||
|
||||
public function decisionsContainId($literalId)
|
||||
protected function decisionsSatisfy($literal)
|
||||
{
|
||||
$packageId = abs($literalId);
|
||||
$packageId = abs($literal);
|
||||
return (
|
||||
$this->decisionMap[$packageId] > 0 && $literalId > 0 ||
|
||||
$this->decisionMap[$packageId] < 0 && $literalId < 0
|
||||
$literal > 0 && $this->decisionMap[$packageId] > 0 ||
|
||||
$literal < 0 && $this->decisionMap[$packageId] < 0
|
||||
);
|
||||
}
|
||||
|
||||
protected function decisionsSatisfy(Literal $l)
|
||||
{
|
||||
return ($l->isWanted() && $this->decisionMap[$l->getPackageId()] > 0) ||
|
||||
(!$l->isWanted() && $this->decisionMap[$l->getPackageId()] < 0);
|
||||
}
|
||||
|
||||
protected function decisionsConflict(Literal $l)
|
||||
public function decisionsConflict($literal)
|
||||
{
|
||||
$packageId = abs($literal);
|
||||
return (
|
||||
$this->decisionMap[$l->getPackageId()] > 0 && !$l->isWanted() ||
|
||||
$this->decisionMap[$l->getPackageId()] < 0 && $l->isWanted()
|
||||
($this->decisionMap[$packageId] > 0 && $literal < 0) ||
|
||||
($this->decisionMap[$packageId] < 0 && $literal > 0)
|
||||
);
|
||||
}
|
||||
|
||||
public function decisionsConflictId($literalId)
|
||||
protected function decided($packageId)
|
||||
{
|
||||
$packageId = abs($literalId);
|
||||
return (
|
||||
($this->decisionMap[$packageId] > 0 && $literalId < 0) ||
|
||||
($this->decisionMap[$packageId] < 0 && $literalId > 0)
|
||||
);
|
||||
return $this->decisionMap[$packageId] != 0;
|
||||
}
|
||||
|
||||
protected function decided(PackageInterface $p)
|
||||
protected function undecided($packageId)
|
||||
{
|
||||
return $this->decisionMap[$p->getId()] != 0;
|
||||
return $this->decisionMap[$packageId] == 0;
|
||||
}
|
||||
|
||||
protected function undecided(PackageInterface $p)
|
||||
{
|
||||
return $this->decisionMap[$p->getId()] == 0;
|
||||
}
|
||||
|
||||
protected function decidedInstall(PackageInterface $p) {
|
||||
return $this->decisionMap[$p->getId()] > 0;
|
||||
}
|
||||
|
||||
protected function decidedRemove(PackageInterface $p) {
|
||||
return $this->decisionMap[$p->getId()] < 0;
|
||||
protected function decidedInstall($packageId) {
|
||||
return $this->decisionMap[$packageId] > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -341,15 +314,15 @@ class Solver
|
|||
// A was decided => (-A|B) now requires B to be true, so we look for
|
||||
// rules which are fulfilled by -A, rather than A.
|
||||
|
||||
$literal = $this->decisionQueue[$this->propagateIndex]->inverted();
|
||||
$literal = -$this->decisionQueue[$this->propagateIndex];
|
||||
|
||||
$this->propagateIndex++;
|
||||
|
||||
$conflict = $this->watchGraph->walkLiteral(
|
||||
$literal->getId(),
|
||||
$literal,
|
||||
$level,
|
||||
array($this, 'decisionsContainId'),
|
||||
array($this, 'decisionsConflictId'),
|
||||
array($this, 'decisionsContain'),
|
||||
array($this, 'decisionsConflict'),
|
||||
array($this, 'decide')
|
||||
);
|
||||
|
||||
|
@ -369,17 +342,17 @@ class Solver
|
|||
while (!empty($this->decisionQueue)) {
|
||||
$literal = $this->decisionQueue[count($this->decisionQueue) - 1];
|
||||
|
||||
if (!$this->decisionMap[$literal->getPackageId()]) {
|
||||
if (!$this->decisionMap[abs($literal)]) {
|
||||
break;
|
||||
}
|
||||
|
||||
$decisionLevel = abs($this->decisionMap[$literal->getPackageId()]);
|
||||
$decisionLevel = abs($this->decisionMap[abs($literal)]);
|
||||
|
||||
if ($decisionLevel <= $level) {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->decisionMap[$literal->getPackageId()] = 0;
|
||||
$this->decisionMap[abs($literal)] = 0;
|
||||
array_pop($this->decisionQueue);
|
||||
array_pop($this->decisionQueueWhy);
|
||||
|
||||
|
@ -412,13 +385,11 @@ class Solver
|
|||
* returns the new solver level or 0 if unsolvable
|
||||
*
|
||||
*/
|
||||
private function setPropagateLearn($level, Literal $literal, $disableRules, Rule $rule)
|
||||
private function setPropagateLearn($level, $literal, $disableRules, Rule $rule)
|
||||
{
|
||||
$level++;
|
||||
|
||||
$this->addDecision($literal, $level);
|
||||
$this->decisionQueue[] = $literal;
|
||||
$this->decisionQueueWhy[] = $rule;
|
||||
$this->decide($literal, $level, $rule);
|
||||
$this->decisionQueueFree[count($this->decisionQueueWhy) - 1] = true;
|
||||
|
||||
while (true) {
|
||||
|
@ -457,9 +428,7 @@ class Solver
|
|||
$ruleNode->watch2OnHighest($this->decisionMap);
|
||||
$this->watchGraph->insert($ruleNode);
|
||||
|
||||
$this->addDecision($learnLiteral, $level);
|
||||
$this->decisionQueue[] = $learnLiteral;
|
||||
$this->decisionQueueWhy[] = $newRule;
|
||||
$this->decide($learnLiteral, $level, $newRule);
|
||||
}
|
||||
|
||||
return $level;
|
||||
|
@ -502,12 +471,12 @@ class Solver
|
|||
continue;
|
||||
}
|
||||
|
||||
if (isset($seen[$literal->getPackageId()])) {
|
||||
if (isset($seen[abs($literal)])) {
|
||||
continue;
|
||||
}
|
||||
$seen[$literal->getPackageId()] = true;
|
||||
$seen[abs($literal)] = true;
|
||||
|
||||
$l = abs($this->decisionMap[$literal->getPackageId()]);
|
||||
$l = abs($this->decisionMap[abs($literal)]);
|
||||
|
||||
if (1 === $l) {
|
||||
$l1num++;
|
||||
|
@ -543,15 +512,15 @@ class Solver
|
|||
|
||||
$literal = $this->decisionQueue[$decisionId];
|
||||
|
||||
if (isset($seen[$literal->getPackageId()])) {
|
||||
if (isset($seen[abs($literal)])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unset($seen[$literal->getPackageId()]);
|
||||
unset($seen[abs($literal)]);
|
||||
|
||||
if ($num && 0 === --$num) {
|
||||
$learnedLiterals[0] = $this->literalFromId(-$literal->getPackageId());
|
||||
$learnedLiterals[0] = -abs($literal);
|
||||
|
||||
if (!$l1num) {
|
||||
break 2;
|
||||
|
@ -559,7 +528,7 @@ class Solver
|
|||
|
||||
foreach ($learnedLiterals as $i => $learnedLiteral) {
|
||||
if ($i !== 0) {
|
||||
unset($seen[$literal->getPackageId()]);
|
||||
unset($seen[abs($learnedLiteral)]);
|
||||
}
|
||||
}
|
||||
// only level 1 marks left
|
||||
|
@ -579,7 +548,7 @@ class Solver
|
|||
);
|
||||
}
|
||||
|
||||
$newRule = new Rule($learnedLiterals, Rule::RULE_LEARNED, $why);
|
||||
$newRule = new Rule($this->pool, $learnedLiterals, Rule::RULE_LEARNED, $why);
|
||||
|
||||
return array($learnedLiterals[0], $ruleLevel, $newRule, $why);
|
||||
}
|
||||
|
@ -626,18 +595,12 @@ class Solver
|
|||
$seen = array();
|
||||
$literals = $conflictRule->getLiterals();
|
||||
|
||||
/* unnecessary because unlike rule.d, watch2 == 2nd literal, unless watch2 changed
|
||||
if (sizeof($literals) == 2) {
|
||||
$literals[1] = $this->literalFromId($conflictRule->watch2);
|
||||
}
|
||||
*/
|
||||
|
||||
foreach ($literals as $literal) {
|
||||
// skip the one true literal
|
||||
if ($this->decisionsSatisfy($literal)) {
|
||||
continue;
|
||||
}
|
||||
$seen[$literal->getPackageId()] = true;
|
||||
$seen[abs($literal)] = true;
|
||||
}
|
||||
|
||||
$decisionId = count($this->decisionQueue);
|
||||
|
@ -648,7 +611,7 @@ class Solver
|
|||
$literal = $this->decisionQueue[$decisionId];
|
||||
|
||||
// skip literals that are not in this rule
|
||||
if (!isset($seen[$literal->getPackageId()])) {
|
||||
if (!isset($seen[abs($literal)])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -658,18 +621,13 @@ class Solver
|
|||
$this->analyzeUnsolvableRule($problem, $why, $lastWeakWhy);
|
||||
|
||||
$literals = $why->getLiterals();
|
||||
/* unnecessary because unlike rule.d, watch2 == 2nd literal, unless watch2 changed
|
||||
if (sizeof($literals) == 2) {
|
||||
$literals[1] = $this->literalFromId($why->watch2);
|
||||
}
|
||||
*/
|
||||
|
||||
foreach ($literals as $literal) {
|
||||
// skip the one true literal
|
||||
if ($this->decisionsSatisfy($literal)) {
|
||||
continue;
|
||||
}
|
||||
$seen[$literal->getPackageId()] = true;
|
||||
$seen[abs($literal)] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,7 +671,7 @@ class Solver
|
|||
private function resetSolver()
|
||||
{
|
||||
while ($literal = array_pop($this->decisionQueue)) {
|
||||
$this->decisionMap[$literal->getPackageId()] = 0;
|
||||
$this->decisionMap[abs($literal)] = 0;
|
||||
}
|
||||
|
||||
$this->decisionQueueWhy = array();
|
||||
|
@ -812,9 +770,9 @@ class Solver
|
|||
if (count($this->installed) != count($this->updateMap)) {
|
||||
$prunedQueue = array();
|
||||
foreach ($decisionQueue as $literal) {
|
||||
if (isset($this->installedMap[$literal->getPackageId()])) {
|
||||
if (isset($this->installedMap[abs($literal)])) {
|
||||
$prunedQueue[] = $literal;
|
||||
if (isset($this->updateMap[$literal->getPackageId()])) {
|
||||
if (isset($this->updateMap[abs($literal)])) {
|
||||
$prunedQueue = $decisionQueue;
|
||||
break;
|
||||
}
|
||||
|
@ -873,15 +831,15 @@ class Solver
|
|||
// just need to decide on the positive literals
|
||||
//
|
||||
foreach ($literals as $literal) {
|
||||
if (!$literal->isWanted()) {
|
||||
if (!$this->decidedInstall($literal->getPackage())) {
|
||||
if ($literal <= 0) {
|
||||
if (!$this->decidedInstall(abs($literal))) {
|
||||
continue 2; // next rule
|
||||
}
|
||||
} else {
|
||||
if ($this->decidedInstall($literal->getPackage())) {
|
||||
if ($this->decidedInstall(abs($literal))) {
|
||||
continue 2; // next rule
|
||||
}
|
||||
if ($this->undecided($literal->getPackage())) {
|
||||
if ($this->undecided(abs($literal))) {
|
||||
$decisionQueue[] = $literal;
|
||||
}
|
||||
}
|
||||
|
@ -919,7 +877,7 @@ class Solver
|
|||
list($literals, $level) = $this->branches[$i];
|
||||
|
||||
foreach ($literals as $offset => $literal) {
|
||||
if ($literal && $literal->isWanted() && $this->decisionMap[$literal->getPackageId()] > $level + 1) {
|
||||
if ($literal && $literal > 0 && $this->decisionMap[abs($literal)] > $level + 1) {
|
||||
$lastLiteral = $literal;
|
||||
$lastBranchIndex = $i;
|
||||
$lastBranchOffset = $offset;
|
||||
|
|
|
@ -43,35 +43,35 @@ class Transaction
|
|||
$installMeansUpdateMap = array();
|
||||
|
||||
foreach ($this->decisionQueue as $i => $literal) {
|
||||
$package = $literal->getPackage();
|
||||
$package = $this->pool->literalToPackage($literal);
|
||||
|
||||
// !wanted & installed
|
||||
if (!$literal->isWanted() && isset($this->installedMap[$package->getId()])) {
|
||||
if ($literal <= 0 && isset($this->installedMap[$package->getId()])) {
|
||||
$updates = $this->policy->findUpdatePackages($this->pool, $this->installedMap, $package);
|
||||
|
||||
$literals = array(new Literal($package, true));
|
||||
$literals = array($package->getId());
|
||||
|
||||
foreach ($updates as $update) {
|
||||
$literals[] = new Literal($update, true);
|
||||
$literals[] = $update->getId();
|
||||
}
|
||||
|
||||
foreach ($literals as $updateLiteral) {
|
||||
if (!$updateLiteral->equals($literal)) {
|
||||
$installMeansUpdateMap[$updateLiteral->getPackageId()] = $package;
|
||||
if ($updateLiteral !== $literal) {
|
||||
$installMeansUpdateMap[abs($updateLiteral)] = $package;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->decisionQueue as $i => $literal) {
|
||||
$package = $literal->getPackage();
|
||||
$package = $this->pool->literalToPackage($literal);
|
||||
|
||||
// wanted & installed || !wanted & !installed
|
||||
if ($literal->isWanted() == (isset($this->installedMap[$package->getId()]))) {
|
||||
if (($literal > 0) == (isset($this->installedMap[$package->getId()]))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($literal->isWanted()) {
|
||||
if ($literal > 0) {
|
||||
if ($package instanceof AliasPackage) {
|
||||
$transaction[] = new Operation\MarkAliasInstalledOperation(
|
||||
$package, $this->decisionQueueWhy[$i]
|
||||
|
@ -79,16 +79,16 @@ class Transaction
|
|||
continue;
|
||||
}
|
||||
|
||||
if (isset($installMeansUpdateMap[$literal->getPackageId()])) {
|
||||
if (isset($installMeansUpdateMap[abs($literal)])) {
|
||||
|
||||
$source = $installMeansUpdateMap[$literal->getPackageId()];
|
||||
$source = $installMeansUpdateMap[abs($literal)];
|
||||
|
||||
$transaction[] = new Operation\UpdateOperation(
|
||||
$source, $package, $this->decisionQueueWhy[$i]
|
||||
);
|
||||
|
||||
// avoid updates to one package from multiple origins
|
||||
unset($installMeansUpdateMap[$literal->getPackageId()]);
|
||||
unset($installMeansUpdateMap[abs($literal)]);
|
||||
$ignoreRemove[$source->getId()] = true;
|
||||
} else {
|
||||
$transaction[] = new Operation\InstallOperation(
|
||||
|
|
|
@ -16,7 +16,6 @@ use Composer\Repository\ArrayRepository;
|
|||
use Composer\Repository\RepositoryInterface;
|
||||
use Composer\DependencyResolver\DefaultPolicy;
|
||||
use Composer\DependencyResolver\Pool;
|
||||
use Composer\DependencyResolver\Literal;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
|
@ -44,8 +43,8 @@ class DefaultPolicyTest extends TestCase
|
|||
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
|
||||
$this->pool->addRepository($this->repo);
|
||||
|
||||
$literals = array(new Literal($packageA, true));
|
||||
$expected = array(new Literal($packageA, true));
|
||||
$literals = array($packageA->getId());
|
||||
$expected = array($packageA->getId());
|
||||
|
||||
$selected = $this->policy->selectPreferedPackages($this->pool, array(), $literals);
|
||||
|
||||
|
@ -58,8 +57,8 @@ class DefaultPolicyTest extends TestCase
|
|||
$this->repo->addPackage($packageA2 = $this->getPackage('A', '2.0'));
|
||||
$this->pool->addRepository($this->repo);
|
||||
|
||||
$literals = array(new Literal($packageA1, true), new Literal($packageA2, true));
|
||||
$expected = array(new Literal($packageA2, true));
|
||||
$literals = array($packageA1->getId(), $packageA2->getId());
|
||||
$expected = array($packageA2->getId());
|
||||
|
||||
$selected = $this->policy->selectPreferedPackages($this->pool, array(), $literals);
|
||||
|
||||
|
@ -73,8 +72,8 @@ class DefaultPolicyTest extends TestCase
|
|||
$this->pool->addRepository($this->repoInstalled);
|
||||
$this->pool->addRepository($this->repo);
|
||||
|
||||
$literals = array(new Literal($packageA, true), new Literal($packageAInstalled, true));
|
||||
$expected = array(new Literal($packageA, true));
|
||||
$literals = array($packageA->getId(), $packageAInstalled->getId());
|
||||
$expected = array($packageA->getId());
|
||||
|
||||
$selected = $this->policy->selectPreferedPackages($this->pool, $this->mapFromRepo($this->repoInstalled), $literals);
|
||||
|
||||
|
@ -92,8 +91,8 @@ class DefaultPolicyTest extends TestCase
|
|||
$this->pool->addRepository($this->repoImportant);
|
||||
$this->pool->addRepository($this->repo);
|
||||
|
||||
$literals = array(new Literal($packageA, true), new Literal($packageAImportant, true));
|
||||
$expected = array(new Literal($packageAImportant, true));
|
||||
$literals = array($packageA->getId(), $packageAImportant->getId());
|
||||
$expected = array($packageAImportant->getId());
|
||||
|
||||
$selected = $this->policy->selectPreferedPackages($this->pool, array(), $literals);
|
||||
|
||||
|
@ -119,10 +118,10 @@ class DefaultPolicyTest extends TestCase
|
|||
$packages = $this->pool->whatProvides('a', new VersionConstraint('=', '2.1.9999999.9999999-dev'));
|
||||
$literals = array();
|
||||
foreach ($packages as $package) {
|
||||
$literals[] = new Literal($package, true);
|
||||
$literals[] = $package->getId();
|
||||
}
|
||||
|
||||
$expected = array(new Literal($packageAAliasImportant, true));
|
||||
$expected = array($packageAAliasImportant->getId());
|
||||
|
||||
$selected = $this->policy->selectPreferedPackages($this->pool, array(), $literals);
|
||||
|
||||
|
@ -139,7 +138,7 @@ class DefaultPolicyTest extends TestCase
|
|||
|
||||
$this->pool->addRepository($this->repo);
|
||||
|
||||
$literals = array(new Literal($packageA, true), new Literal($packageB, true));
|
||||
$literals = array($packageA->getId(), $packageB->getId());
|
||||
$expected = $literals;
|
||||
|
||||
$selected = $this->policy->selectPreferedPackages($this->pool, array(), $literals);
|
||||
|
@ -157,8 +156,8 @@ class DefaultPolicyTest extends TestCase
|
|||
|
||||
$this->pool->addRepository($this->repo);
|
||||
|
||||
$literals = array(new Literal($packageA, true), new Literal($packageB, true));
|
||||
$expected = array(new Literal($packageA, true), new Literal($packageB, true));
|
||||
$literals = array($packageA->getId(), $packageB->getId());
|
||||
$expected = $literals;
|
||||
|
||||
$selected = $this->policy->selectPreferedPackages($this->pool, array(), $literals);
|
||||
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
<?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\DependencyResolver;
|
||||
|
||||
use Composer\DependencyResolver\Literal;
|
||||
use Composer\Test\TestCase;
|
||||
|
||||
class LiteralTest extends TestCase
|
||||
{
|
||||
protected $package;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->package = $this->getPackage('foo', '1');
|
||||
$this->package->setId(12);
|
||||
}
|
||||
|
||||
public function testLiteralWanted()
|
||||
{
|
||||
$literal = new Literal($this->package, true);
|
||||
|
||||
$this->assertEquals(12, $literal->getId());
|
||||
$this->assertEquals('+'.(string) $this->package, (string) $literal);
|
||||
}
|
||||
|
||||
public function testLiteralUnwanted()
|
||||
{
|
||||
$literal = new Literal($this->package, false);
|
||||
|
||||
$this->assertEquals(-12, $literal->getId());
|
||||
$this->assertEquals('-'.(string) $this->package, (string) $literal);
|
||||
}
|
||||
|
||||
public function testLiteralInverted()
|
||||
{
|
||||
$literal = new Literal($this->package, false);
|
||||
|
||||
$inverted = $literal->inverted();
|
||||
|
||||
$this->assertInstanceOf('\Composer\DependencyResolver\Literal', $inverted);
|
||||
$this->assertTrue($inverted->isWanted());
|
||||
$this->assertSame($this->package, $inverted->getPackage());
|
||||
$this->assertFalse($literal->equals($inverted));
|
||||
|
||||
$doubleInverted = $inverted->inverted();
|
||||
|
||||
$this->assertInstanceOf('\Composer\DependencyResolver\Literal', $doubleInverted);
|
||||
$this->assertFalse($doubleInverted->isWanted());
|
||||
$this->assertSame($this->package, $doubleInverted->getPackage());
|
||||
|
||||
$this->assertTrue($literal->equals($doubleInverted));
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ namespace Composer\Test\DependencyResolver;
|
|||
use Composer\DependencyResolver\Rule;
|
||||
use Composer\DependencyResolver\RuleSet;
|
||||
use Composer\DependencyResolver\RuleSetIterator;
|
||||
use Composer\DependencyResolver\Pool;
|
||||
|
||||
class ResultSetIteratorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
@ -22,13 +23,15 @@ class ResultSetIteratorTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->pool = new Pool;
|
||||
|
||||
$this->rules = array(
|
||||
RuleSet::TYPE_JOB => array(
|
||||
new Rule(array(), 'job1', null),
|
||||
new Rule(array(), 'job2', null),
|
||||
new Rule($this->pool, array(), 'job1', null),
|
||||
new Rule($this->pool, array(), 'job2', null),
|
||||
),
|
||||
RuleSet::TYPE_LEARNED => array(
|
||||
new Rule(array(), 'update1', null),
|
||||
new Rule($this->pool, array(), 'update1', null),
|
||||
),
|
||||
RuleSet::TYPE_PACKAGE => array(),
|
||||
);
|
||||
|
|
|
@ -14,21 +14,29 @@ namespace Composer\Test\DependencyResolver;
|
|||
|
||||
use Composer\DependencyResolver\Rule;
|
||||
use Composer\DependencyResolver\RuleSet;
|
||||
use Composer\DependencyResolver\Literal;
|
||||
use Composer\DependencyResolver\Pool;
|
||||
use Composer\Repository\ArrayRepository;
|
||||
use Composer\Test\TestCase;
|
||||
|
||||
class RuleSetTest extends TestCase
|
||||
{
|
||||
protected $pool;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->pool = new Pool;
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$rules = array(
|
||||
RuleSet::TYPE_PACKAGE => array(),
|
||||
RuleSet::TYPE_JOB => array(
|
||||
new Rule(array(), 'job1', null),
|
||||
new Rule(array(), 'job2', null),
|
||||
new Rule($this->pool, array(), 'job1', null),
|
||||
new Rule($this->pool, array(), 'job2', null),
|
||||
),
|
||||
RuleSet::TYPE_LEARNED => array(
|
||||
new Rule(array(), 'update1', null),
|
||||
new Rule($this->pool, array(), 'update1', null),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -48,15 +56,15 @@ class RuleSetTest extends TestCase
|
|||
{
|
||||
$ruleSet = new RuleSet;
|
||||
|
||||
$ruleSet->add(new Rule(array(), 'job1', null), 7);
|
||||
$ruleSet->add(new Rule($this->pool, array(), 'job1', null), 7);
|
||||
}
|
||||
|
||||
public function testCount()
|
||||
{
|
||||
$ruleSet = new RuleSet;
|
||||
|
||||
$ruleSet->add(new Rule(array(), 'job1', null), RuleSet::TYPE_JOB);
|
||||
$ruleSet->add(new Rule(array(), 'job2', null), RuleSet::TYPE_JOB);
|
||||
$ruleSet->add(new Rule($this->pool, array(), 'job1', null), RuleSet::TYPE_JOB);
|
||||
$ruleSet->add(new Rule($this->pool, array(), 'job2', null), RuleSet::TYPE_JOB);
|
||||
|
||||
$this->assertEquals(2, $ruleSet->count());
|
||||
}
|
||||
|
@ -65,7 +73,7 @@ class RuleSetTest extends TestCase
|
|||
{
|
||||
$ruleSet = new RuleSet;
|
||||
|
||||
$rule = new Rule(array(), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(), 'job1', null);
|
||||
$ruleSet->add($rule, RuleSet::TYPE_JOB);
|
||||
|
||||
$this->assertSame($rule, $ruleSet->ruleById(0));
|
||||
|
@ -75,8 +83,8 @@ class RuleSetTest extends TestCase
|
|||
{
|
||||
$ruleSet = new RuleSet;
|
||||
|
||||
$rule1 = new Rule(array(), 'job1', null);
|
||||
$rule2 = new Rule(array(), 'job1', null);
|
||||
$rule1 = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(), 'job1', null);
|
||||
$ruleSet->add($rule1, RuleSet::TYPE_JOB);
|
||||
$ruleSet->add($rule2, RuleSet::TYPE_LEARNED);
|
||||
|
||||
|
@ -90,8 +98,8 @@ class RuleSetTest extends TestCase
|
|||
public function testGetIteratorFor()
|
||||
{
|
||||
$ruleSet = new RuleSet;
|
||||
$rule1 = new Rule(array(), 'job1', null);
|
||||
$rule2 = new Rule(array(), 'job1', null);
|
||||
$rule1 = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(), 'job1', null);
|
||||
|
||||
$ruleSet->add($rule1, RuleSet::TYPE_JOB);
|
||||
$ruleSet->add($rule2, RuleSet::TYPE_LEARNED);
|
||||
|
@ -104,8 +112,8 @@ class RuleSetTest extends TestCase
|
|||
public function testGetIteratorWithout()
|
||||
{
|
||||
$ruleSet = new RuleSet;
|
||||
$rule1 = new Rule(array(), 'job1', null);
|
||||
$rule2 = new Rule(array(), 'job1', null);
|
||||
$rule1 = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(), 'job1', null);
|
||||
|
||||
$ruleSet->add($rule1, RuleSet::TYPE_JOB);
|
||||
$ruleSet->add($rule2, RuleSet::TYPE_LEARNED);
|
||||
|
@ -149,9 +157,13 @@ class RuleSetTest extends TestCase
|
|||
|
||||
public function testToString()
|
||||
{
|
||||
$repo = new ArrayRepository;
|
||||
$repo->addPackage($p = $this->getPackage('foo', '2.1'));
|
||||
$this->pool->addRepository($repo);
|
||||
|
||||
$ruleSet = new RuleSet;
|
||||
$literal = new Literal($this->getPackage('foo', '2.1'), true);
|
||||
$rule = new Rule(array($literal), 'job1', null);
|
||||
$literal = $p->getId();
|
||||
$rule = new Rule($this->pool, array($literal), 'job1', null);
|
||||
|
||||
$ruleSet->add($rule, RuleSet::TYPE_JOB);
|
||||
|
||||
|
|
|
@ -13,14 +13,22 @@
|
|||
namespace Composer\Test\DependencyResolver;
|
||||
|
||||
use Composer\DependencyResolver\Rule;
|
||||
use Composer\DependencyResolver\Literal;
|
||||
use Composer\DependencyResolver\Pool;
|
||||
use Composer\Repository\ArrayRepository;
|
||||
use Composer\Test\TestCase;
|
||||
|
||||
class RuleTest extends TestCase
|
||||
{
|
||||
protected $pool;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->pool = new Pool;
|
||||
}
|
||||
|
||||
public function testGetHash()
|
||||
{
|
||||
$rule = new Rule(array(), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule->ruleHash = '123';
|
||||
|
||||
$this->assertEquals('123', $rule->getHash());
|
||||
|
@ -28,7 +36,7 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testSetAndGetId()
|
||||
{
|
||||
$rule = new Rule(array(), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule->setId(666);
|
||||
|
||||
$this->assertEquals(666, $rule->getId());
|
||||
|
@ -36,10 +44,10 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testEqualsForRulesWithDifferentHashes()
|
||||
{
|
||||
$rule = new Rule(array(), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule->ruleHash = '123';
|
||||
|
||||
$rule2 = new Rule(array(), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule2->ruleHash = '321';
|
||||
|
||||
$this->assertFalse($rule->equals($rule2));
|
||||
|
@ -47,18 +55,10 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testEqualsForRulesWithDifferentLiterals()
|
||||
{
|
||||
$literal = $this->getLiteralMock();
|
||||
$literal->expects($this->any())
|
||||
->method('getId')
|
||||
->will($this->returnValue(1));
|
||||
$rule = new Rule(array($literal), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(1), 'job1', null);
|
||||
$rule->ruleHash = '123';
|
||||
|
||||
$literal = $this->getLiteralMock();
|
||||
$literal->expects($this->any())
|
||||
->method('getId')
|
||||
->will($this->returnValue(12));
|
||||
$rule2 = new Rule(array($literal), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(12), 'job1', null);
|
||||
$rule2->ruleHash = '123';
|
||||
|
||||
$this->assertFalse($rule->equals($rule2));
|
||||
|
@ -66,18 +66,9 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testEqualsForRulesWithDifferLiteralsQuantity()
|
||||
{
|
||||
$literal = $this->getLiteralMock();
|
||||
$literal->expects($this->any())
|
||||
->method('getId')
|
||||
->will($this->returnValue(1));
|
||||
$literal2 = $this->getLiteralMock();
|
||||
$literal2->expects($this->any())
|
||||
->method('getId')
|
||||
->will($this->returnValue(12));
|
||||
|
||||
$rule = new Rule(array($literal, $literal2), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(1, 12), 'job1', null);
|
||||
$rule->ruleHash = '123';
|
||||
$rule2 = new Rule(array($literal), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(1), 'job1', null);
|
||||
$rule2->ruleHash = '123';
|
||||
|
||||
$this->assertFalse($rule->equals($rule2));
|
||||
|
@ -85,24 +76,15 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testEqualsForRulesWithThisSameLiterals()
|
||||
{
|
||||
$literal = $this->getLiteralMock();
|
||||
$literal->expects($this->any())
|
||||
->method('getId')
|
||||
->will($this->returnValue(1));
|
||||
$literal2 = $this->getLiteralMock();
|
||||
$literal2->expects($this->any())
|
||||
->method('getId')
|
||||
->will($this->returnValue(12));
|
||||
|
||||
$rule = new Rule(array($literal, $literal2), 'job1', null);
|
||||
$rule2 = new Rule(array($literal, $literal2), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(1, 12), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(1, 12), 'job1', null);
|
||||
|
||||
$this->assertTrue($rule->equals($rule2));
|
||||
}
|
||||
|
||||
public function testSetAndGetType()
|
||||
{
|
||||
$rule = new Rule(array(), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule->setType('someType');
|
||||
|
||||
$this->assertEquals('someType', $rule->getType());
|
||||
|
@ -110,7 +92,7 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testEnable()
|
||||
{
|
||||
$rule = new Rule(array(), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule->disable();
|
||||
$rule->enable();
|
||||
|
||||
|
@ -120,7 +102,7 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testDisable()
|
||||
{
|
||||
$rule = new Rule(array(), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule->enable();
|
||||
$rule->disable();
|
||||
|
||||
|
@ -130,10 +112,10 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testSetWeak()
|
||||
{
|
||||
$rule = new Rule(array(), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule->setWeak(true);
|
||||
|
||||
$rule2 = new Rule(array(), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(), 'job1', null);
|
||||
$rule2->setWeak(false);
|
||||
|
||||
$this->assertTrue($rule->isWeak());
|
||||
|
@ -142,10 +124,8 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testIsAssertions()
|
||||
{
|
||||
$literal = $this->getLiteralMock();
|
||||
$literal2 = $this->getLiteralMock();
|
||||
$rule = new Rule(array($literal, $literal2), 'job1', null);
|
||||
$rule2 = new Rule(array($literal), 'job1', null);
|
||||
$rule = new Rule($this->pool, array(1, 12), 'job1', null);
|
||||
$rule2 = new Rule($this->pool, array(1), 'job1', null);
|
||||
|
||||
$this->assertFalse($rule->isAssertion());
|
||||
$this->assertTrue($rule2->isAssertion());
|
||||
|
@ -153,18 +133,13 @@ class RuleTest extends TestCase
|
|||
|
||||
public function testToString()
|
||||
{
|
||||
$literal = new Literal($this->getPackage('foo', '2.1'), true);
|
||||
$literal2 = new Literal($this->getPackage('baz', '1.1'), false);
|
||||
$repo = new ArrayRepository;
|
||||
$repo->addPackage($p1 = $this->getPackage('foo', '2.1'));
|
||||
$repo->addPackage($p2 = $this->getPackage('baz', '1.1'));
|
||||
$this->pool->addRepository($repo);
|
||||
|
||||
$rule = new Rule(array($literal, $literal2), 'job1', null);
|
||||
$rule = new Rule($this->pool, array($p1->getId(), -$p2->getId()), 'job1', null);
|
||||
|
||||
$this->assertEquals('(-baz-1.1.0.0|+foo-2.1.0.0)', $rule->__toString());
|
||||
}
|
||||
|
||||
private function getLiteralMock()
|
||||
{
|
||||
return $this->getMockBuilder('Composer\DependencyResolver\Literal')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue