Merge remote-tracking branch 'naderman/error-msgs'
commit
892cfdd57d
|
@ -163,4 +163,17 @@ class Pool
|
||||||
{
|
{
|
||||||
return ($literal > 0 ? '+' : '-') . $this->literalToPackage($literal);
|
return ($literal > 0 ? '+' : '-') . $this->literalToPackage($literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function literalToPrettyString($literal, $installedMap)
|
||||||
|
{
|
||||||
|
$package = $this->literalToPackage($literal);
|
||||||
|
|
||||||
|
if (isset($installedMap[$package->getId()])) {
|
||||||
|
$prefix = ($literal > 0 ? 'keep' : 'remove');
|
||||||
|
} else {
|
||||||
|
$prefix = ($literal > 0 ? 'install' : 'don\'t install');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $prefix.' '.$package->getPrettyString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,19 @@ namespace Composer\DependencyResolver;
|
||||||
*/
|
*/
|
||||||
class Problem
|
class Problem
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* A map containing the id of each rule part of this problem as a key
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $reasonSeen;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of reasons for the problem, each is a rule or a job and a rule
|
* A set of reasons for the problem, each is a rule or a job and a rule
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $reasons;
|
protected $reasons = array();
|
||||||
|
|
||||||
|
protected $section = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a rule as a reason
|
* Add a rule as a reason
|
||||||
|
@ -50,12 +58,16 @@ class Problem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A human readable textual representation of the problem's reasons
|
* A human readable textual representation of the problem's reasons
|
||||||
|
*
|
||||||
|
* @param array $installedMap A map of all installed packages
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function getPrettyString(array $installedMap = array())
|
||||||
{
|
{
|
||||||
if (count($this->reasons) === 1) {
|
$reasons = call_user_func_array('array_merge', array_reverse($this->reasons));
|
||||||
reset($this->reasons);
|
|
||||||
$reason = current($this->reasons);
|
if (count($reasons) === 1) {
|
||||||
|
reset($reasons);
|
||||||
|
$reason = current($reasons);
|
||||||
|
|
||||||
$rule = $reason['rule'];
|
$rule = $reason['rule'];
|
||||||
$job = $reason['job'];
|
$job = $reason['job'];
|
||||||
|
@ -73,9 +85,9 @@ class Problem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$messages = array("Problem caused by:");
|
$messages = array();
|
||||||
|
|
||||||
foreach ($this->reasons as $reason) {
|
foreach ($reasons as $reason) {
|
||||||
|
|
||||||
$rule = $reason['rule'];
|
$rule = $reason['rule'];
|
||||||
$job = $reason['job'];
|
$job = $reason['job'];
|
||||||
|
@ -84,12 +96,12 @@ class Problem
|
||||||
$messages[] = $this->jobToText($job);
|
$messages[] = $this->jobToText($job);
|
||||||
} elseif ($rule) {
|
} elseif ($rule) {
|
||||||
if ($rule instanceof Rule) {
|
if ($rule instanceof Rule) {
|
||||||
$messages[] = $rule->toHumanReadableString();
|
$messages[] = $rule->getPrettyString($installedMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode("\n\t\t\t- ", $messages);
|
return "\n - ".implode("\n - ", $messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,11 +112,17 @@ class Problem
|
||||||
*/
|
*/
|
||||||
protected function addReason($id, $reason)
|
protected function addReason($id, $reason)
|
||||||
{
|
{
|
||||||
if (!isset($this->reasons[$id])) {
|
if (!isset($this->reasonSeen[$id])) {
|
||||||
$this->reasons[$id] = $reason;
|
$this->reasonSeen[$id] = true;
|
||||||
|
$this->reasons[$this->section][] = $reason;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function nextSection()
|
||||||
|
{
|
||||||
|
$this->section++;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns a job into a human readable description
|
* Turns a job into a human readable description
|
||||||
*
|
*
|
||||||
|
@ -119,7 +137,7 @@ class Problem
|
||||||
return 'No package found to satisfy install request for '.$job['packageName'].$this->constraintToText($job['constraint']);
|
return 'No package found to satisfy install request for '.$job['packageName'].$this->constraintToText($job['constraint']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Installation request for '.$job['packageName'].$this->constraintToText($job['constraint']).': Satisfiable by ['.$this->getPackageList($job['packages']).'].';
|
return 'Installation request for '.$job['packageName'].$this->constraintToText($job['constraint']).' -> satisfiable by '.$this->getPackageList($job['packages']).'.';
|
||||||
case 'update':
|
case 'update':
|
||||||
return 'Update request for '.$job['packageName'].$this->constraintToText($job['constraint']).'.';
|
return 'Update request for '.$job['packageName'].$this->constraintToText($job['constraint']).'.';
|
||||||
case 'remove':
|
case 'remove':
|
||||||
|
@ -146,6 +164,6 @@ class Problem
|
||||||
*/
|
*/
|
||||||
protected function constraintToText($constraint)
|
protected function constraintToText($constraint)
|
||||||
{
|
{
|
||||||
return ($constraint) ? ' '.$constraint : '';
|
return ($constraint) ? ' '.$constraint->getPrettyString() : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,14 +147,14 @@ class Rule
|
||||||
return 1 === count($this->literals);
|
return 1 === count($this->literals);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toHumanReadableString()
|
public function getPrettyString(array $installedMap = array())
|
||||||
{
|
{
|
||||||
$ruleText = '';
|
$ruleText = '';
|
||||||
foreach ($this->literals as $i => $literal) {
|
foreach ($this->literals as $i => $literal) {
|
||||||
if ($i != 0) {
|
if ($i != 0) {
|
||||||
$ruleText .= '|';
|
$ruleText .= '|';
|
||||||
}
|
}
|
||||||
$ruleText .= $this->pool->literalToString($literal);
|
$ruleText .= $this->pool->literalToPrettyString($literal, $installedMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($this->reason) {
|
switch ($this->reason) {
|
||||||
|
@ -171,7 +171,7 @@ class Rule
|
||||||
$package1 = $this->pool->literalToPackage($this->literals[0]);
|
$package1 = $this->pool->literalToPackage($this->literals[0]);
|
||||||
$package2 = $this->pool->literalToPackage($this->literals[1]);
|
$package2 = $this->pool->literalToPackage($this->literals[1]);
|
||||||
|
|
||||||
return 'Package '.$package1->getPrettyString().' conflicts with '.$package2->getPrettyString().'"';
|
return $package1->getPrettyString().' conflicts with '.$package2->getPrettyString().'.';
|
||||||
|
|
||||||
case self::RULE_PACKAGE_REQUIRES:
|
case self::RULE_PACKAGE_REQUIRES:
|
||||||
$literals = $this->literals;
|
$literals = $this->literals;
|
||||||
|
@ -183,11 +183,15 @@ class Rule
|
||||||
$requires[] = $this->pool->literalToPackage($literal);
|
$requires[] = $this->pool->literalToPackage($literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
$text = 'Package "'.$sourcePackage.'" contains the rule '.$this->reasonData.'. ';
|
$text = $this->reasonData->getPrettyString($sourcePackage);
|
||||||
if ($requires) {
|
if ($requires) {
|
||||||
$text .= 'Any of these packages satisfy the dependency: '.implode(', ', $requires).'.';
|
$requireText = array();
|
||||||
|
foreach ($requires as $require) {
|
||||||
|
$requireText[] = $require->getPrettyString();
|
||||||
|
}
|
||||||
|
$text .= ' -> satisfiable by '.implode(', ', $requireText).'.';
|
||||||
} else {
|
} else {
|
||||||
$text .= 'No package satisfies this dependency.';
|
$text .= ' -> no matching package found.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $text;
|
return $text;
|
||||||
|
@ -197,11 +201,18 @@ class Rule
|
||||||
case self::RULE_INSTALLED_PACKAGE_OBSOLETES:
|
case self::RULE_INSTALLED_PACKAGE_OBSOLETES:
|
||||||
return $ruleText;
|
return $ruleText;
|
||||||
case self::RULE_PACKAGE_SAME_NAME:
|
case self::RULE_PACKAGE_SAME_NAME:
|
||||||
return $ruleText;
|
$text = "Can only install one of: ";
|
||||||
|
|
||||||
|
$packages = array();
|
||||||
|
foreach ($this->literals as $i => $literal) {
|
||||||
|
$packages[] = $this->pool->literalToPackage($literal)->getPrettyString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $text.implode(', ', $packages).'.';
|
||||||
case self::RULE_PACKAGE_IMPLICIT_OBSOLETES:
|
case self::RULE_PACKAGE_IMPLICIT_OBSOLETES:
|
||||||
return $ruleText;
|
return $ruleText;
|
||||||
case self::RULE_LEARNED:
|
case self::RULE_LEARNED:
|
||||||
return 'learned: '.$ruleText;
|
return 'Conclusion: '.$ruleText;
|
||||||
case self::RULE_PACKAGE_ALIAS:
|
case self::RULE_PACKAGE_ALIAS:
|
||||||
return $ruleText;
|
return $ruleText;
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ class RuleSetGenerator
|
||||||
foreach ($package->getRequires() as $link) {
|
foreach ($package->getRequires() as $link) {
|
||||||
$possibleRequires = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
|
$possibleRequires = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
|
||||||
|
|
||||||
$this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRequireRule($package, $possibleRequires, Rule::RULE_PACKAGE_REQUIRES, (string) $link));
|
$this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRequireRule($package, $possibleRequires, Rule::RULE_PACKAGE_REQUIRES, $link));
|
||||||
|
|
||||||
foreach ($possibleRequires as $require) {
|
foreach ($possibleRequires as $require) {
|
||||||
$workQueue->enqueue($require);
|
$workQueue->enqueue($require);
|
||||||
|
@ -168,7 +168,7 @@ class RuleSetGenerator
|
||||||
$possibleConflicts = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
|
$possibleConflicts = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
|
||||||
|
|
||||||
foreach ($possibleConflicts as $conflict) {
|
foreach ($possibleConflicts as $conflict) {
|
||||||
$this->addRule(RuleSet::TYPE_PACKAGE, $this->createConflictRule($package, $conflict, Rule::RULE_PACKAGE_CONFLICT, (string) $link));
|
$this->addRule(RuleSet::TYPE_PACKAGE, $this->createConflictRule($package, $conflict, Rule::RULE_PACKAGE_CONFLICT, $link));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ class RuleSetGenerator
|
||||||
|
|
||||||
if (!$this->obsoleteImpossibleForAlias($package, $provider)) {
|
if (!$this->obsoleteImpossibleForAlias($package, $provider)) {
|
||||||
$reason = ($isInstalled) ? Rule::RULE_INSTALLED_PACKAGE_OBSOLETES : Rule::RULE_PACKAGE_OBSOLETES;
|
$reason = ($isInstalled) ? Rule::RULE_INSTALLED_PACKAGE_OBSOLETES : Rule::RULE_PACKAGE_OBSOLETES;
|
||||||
$this->addRule(RuleSet::TYPE_PACKAGE, $this->createConflictRule($package, $provider, $reason, (string) $link));
|
$this->addRule(RuleSet::TYPE_PACKAGE, $this->createConflictRule($package, $provider, $reason, $link));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,10 +198,10 @@ class RuleSetGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($package instanceof AliasPackage) && $package->getAliasOf() === $provider) {
|
if (($package instanceof AliasPackage) && $package->getAliasOf() === $provider) {
|
||||||
$this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRequireRule($package, array($provider), Rule::RULE_PACKAGE_ALIAS, (string) $package));
|
$this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRequireRule($package, array($provider), Rule::RULE_PACKAGE_ALIAS, $package));
|
||||||
} elseif (!$this->obsoleteImpossibleForAlias($package, $provider)) {
|
} elseif (!$this->obsoleteImpossibleForAlias($package, $provider)) {
|
||||||
$reason = ($package->getName() == $provider->getName()) ? Rule::RULE_PACKAGE_SAME_NAME : Rule::RULE_PACKAGE_IMPLICIT_OBSOLETES;
|
$reason = ($package->getName() == $provider->getName()) ? Rule::RULE_PACKAGE_SAME_NAME : Rule::RULE_PACKAGE_IMPLICIT_OBSOLETES;
|
||||||
$this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createConflictRule($package, $provider, $reason, (string) $package));
|
$this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createConflictRule($package, $provider, $reason, $package));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ class Solver
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->problems) {
|
if ($this->problems) {
|
||||||
throw new SolverProblemsException($this->problems);
|
throw new SolverProblemsException($this->problems, $this->installedMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
$transaction = new Transaction($this->policy, $this->pool, $this->installedMap, $this->decisions);
|
$transaction = new Transaction($this->policy, $this->pool, $this->installedMap, $this->decisions);
|
||||||
|
@ -457,6 +457,7 @@ class Solver
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$problem->nextSection();
|
||||||
$problem->addRule($conflictRule);
|
$problem->addRule($conflictRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,23 +18,24 @@ namespace Composer\DependencyResolver;
|
||||||
class SolverProblemsException extends \RuntimeException
|
class SolverProblemsException extends \RuntimeException
|
||||||
{
|
{
|
||||||
protected $problems;
|
protected $problems;
|
||||||
|
protected $installedMap;
|
||||||
|
|
||||||
public function __construct(array $problems)
|
public function __construct(array $problems, array $installedMap)
|
||||||
{
|
{
|
||||||
$this->problems = $problems;
|
$this->problems = $problems;
|
||||||
|
$this->installedMap = $installedMap;
|
||||||
|
|
||||||
parent::__construct($this->createMessage());
|
parent::__construct($this->createMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createMessage()
|
protected function createMessage()
|
||||||
{
|
{
|
||||||
$messages = array();
|
$text = "\n";
|
||||||
|
foreach ($this->problems as $i => $problem) {
|
||||||
foreach ($this->problems as $problem) {
|
$text .= " Problem ".($i+1).$problem->getPrettyString($this->installedMap)."\n";
|
||||||
$messages[] = (string) $problem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "\n\tProblems:\n\t\t- ".implode("\n\t\t- ", $messages);
|
return $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProblems()
|
public function getProblems()
|
||||||
|
|
|
@ -203,7 +203,7 @@ abstract class BasePackage implements PackageInterface
|
||||||
|
|
||||||
public function getPrettyString()
|
public function getPrettyString()
|
||||||
{
|
{
|
||||||
return $this->getPrettyName().'-'.$this->getPrettyVersion();
|
return $this->getPrettyName().' '.$this->getPrettyVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __clone()
|
public function __clone()
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
namespace Composer\Package;
|
namespace Composer\Package;
|
||||||
|
|
||||||
use Composer\Package\LinkConstraint\LinkConstraintInterface;
|
use Composer\Package\LinkConstraint\LinkConstraintInterface;
|
||||||
|
use Composer\Package\PackageInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a link between two packages, represented by their names
|
* Represents a link between two packages, represented by their names
|
||||||
|
@ -71,4 +72,9 @@ class Link
|
||||||
{
|
{
|
||||||
return $this->source.' '.$this->description.' '.$this->target.' ('.$this->constraint.')';
|
return $this->source.' '.$this->description.' '.$this->target.' ('.$this->constraint.')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPrettyString(PackageInterface $sourcePackage)
|
||||||
|
{
|
||||||
|
return $sourcePackage->getPrettyString().' '.$this->description.' '.$this->target.' '.$this->constraint->getPrettyString().'';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,5 +20,7 @@ namespace Composer\Package\LinkConstraint;
|
||||||
interface LinkConstraintInterface
|
interface LinkConstraintInterface
|
||||||
{
|
{
|
||||||
public function matches(LinkConstraintInterface $provider);
|
public function matches(LinkConstraintInterface $provider);
|
||||||
|
public function setPrettyString($prettyString);
|
||||||
|
public function getPrettyString();
|
||||||
public function __toString();
|
public function __toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace Composer\Package\LinkConstraint;
|
||||||
class MultiConstraint implements LinkConstraintInterface
|
class MultiConstraint implements LinkConstraintInterface
|
||||||
{
|
{
|
||||||
protected $constraints;
|
protected $constraints;
|
||||||
|
protected $prettyString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets operator and version to compare a package with
|
* Sets operator and version to compare a package with
|
||||||
|
@ -42,6 +43,19 @@ class MultiConstraint implements LinkConstraintInterface
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setPrettyString($prettyString)
|
||||||
|
{
|
||||||
|
$this->prettyString = $prettyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrettyString()
|
||||||
|
{
|
||||||
|
if ($this->prettyString) {
|
||||||
|
return $this->prettyString;
|
||||||
|
}
|
||||||
|
return $this->__toString();
|
||||||
|
}
|
||||||
|
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
$constraints = array();
|
$constraints = array();
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace Composer\Package\LinkConstraint;
|
||||||
*/
|
*/
|
||||||
abstract class SpecificConstraint implements LinkConstraintInterface
|
abstract class SpecificConstraint implements LinkConstraintInterface
|
||||||
{
|
{
|
||||||
|
protected $prettyString;
|
||||||
|
|
||||||
public function matches(LinkConstraintInterface $provider)
|
public function matches(LinkConstraintInterface $provider)
|
||||||
{
|
{
|
||||||
if ($provider instanceof MultiConstraint) {
|
if ($provider instanceof MultiConstraint) {
|
||||||
|
@ -31,7 +33,21 @@ abstract class SpecificConstraint implements LinkConstraintInterface
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setPrettyString($prettyString)
|
||||||
|
{
|
||||||
|
$this->prettyString = $prettyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrettyString()
|
||||||
|
{
|
||||||
|
if ($this->prettyString) {
|
||||||
|
return $this->prettyString;
|
||||||
|
}
|
||||||
|
return $this->__toString();
|
||||||
|
}
|
||||||
|
|
||||||
// implementations must implement a method of this format:
|
// implementations must implement a method of this format:
|
||||||
// not declared abstract here because type hinting violates parameter coherence (TODO right word?)
|
// not declared abstract here because type hinting violates parameter coherence (TODO right word?)
|
||||||
// public function matchSpecific(<SpecificConstraintType> $provider);
|
// public function matchSpecific(<SpecificConstraintType> $provider);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,8 @@ class VersionParser
|
||||||
*/
|
*/
|
||||||
public function parseConstraints($constraints)
|
public function parseConstraints($constraints)
|
||||||
{
|
{
|
||||||
|
$prettyConstraint = $constraints;
|
||||||
|
|
||||||
if (preg_match('{^([^,\s]*?)@('.implode('|', array_keys(BasePackage::$stabilities)).')$}i', $constraints, $match)) {
|
if (preg_match('{^([^,\s]*?)@('.implode('|', array_keys(BasePackage::$stabilities)).')$}i', $constraints, $match)) {
|
||||||
$constraints = empty($match[1]) ? '*' : $match[1];
|
$constraints = empty($match[1]) ? '*' : $match[1];
|
||||||
}
|
}
|
||||||
|
@ -184,10 +186,13 @@ class VersionParser
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 === count($constraintObjects)) {
|
if (1 === count($constraintObjects)) {
|
||||||
return $constraintObjects[0];
|
$constraint = $constraintObjects[0];
|
||||||
|
} else {
|
||||||
|
$constraint = new MultiConstraint($constraintObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MultiConstraint($constraintObjects);
|
$constraint->setPrettyString($prettyConstraint);
|
||||||
|
return $constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseConstraint($constraint)
|
private function parseConstraint($constraint)
|
||||||
|
|
|
@ -66,7 +66,7 @@ class SolverTest extends TestCase
|
||||||
$this->repo->addPackage($this->getPackage('A', '1.0'));
|
$this->repo->addPackage($this->getPackage('A', '1.0'));
|
||||||
$this->reposComplete();
|
$this->reposComplete();
|
||||||
|
|
||||||
$this->request->install('B', $this->getVersionConstraint('=', '1'));
|
$this->request->install('B', $this->getVersionConstraint('==', '1'));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$transaction = $this->solver->solve($this->request);
|
$transaction = $this->solver->solve($this->request);
|
||||||
|
@ -74,7 +74,7 @@ class SolverTest extends TestCase
|
||||||
} catch (SolverProblemsException $e) {
|
} catch (SolverProblemsException $e) {
|
||||||
$problems = $e->getProblems();
|
$problems = $e->getProblems();
|
||||||
$this->assertEquals(1, count($problems));
|
$this->assertEquals(1, count($problems));
|
||||||
$this->assertEquals('The requested package b == 1.0.0.0 could not be found.', (string) $problems[0]);
|
$this->assertEquals('The requested package b == 1 could not be found.', $problems[0]->getPrettyString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +641,13 @@ class SolverTest extends TestCase
|
||||||
} catch (SolverProblemsException $e) {
|
} catch (SolverProblemsException $e) {
|
||||||
$problems = $e->getProblems();
|
$problems = $e->getProblems();
|
||||||
$this->assertEquals(1, count($problems));
|
$this->assertEquals(1, count($problems));
|
||||||
// TODO assert problem properties
|
|
||||||
|
$msg = "\n";
|
||||||
|
$msg .= " Problem 1\n";
|
||||||
|
$msg .= " - Installation request for a -> satisfiable by A 1.0.\n";
|
||||||
|
$msg .= " - B 1.0 conflicts with A 1.0.\n";
|
||||||
|
$msg .= " - Installation request for b -> satisfiable by B 1.0.\n";
|
||||||
|
$this->assertEquals($msg, $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,6 +671,56 @@ class SolverTest extends TestCase
|
||||||
$problems = $e->getProblems();
|
$problems = $e->getProblems();
|
||||||
$this->assertEquals(1, count($problems));
|
$this->assertEquals(1, count($problems));
|
||||||
// TODO assert problem properties
|
// TODO assert problem properties
|
||||||
|
|
||||||
|
$msg = "\n";
|
||||||
|
$msg .= " Problem 1\n";
|
||||||
|
$msg .= " - Installation request for a -> satisfiable by A 1.0.\n";
|
||||||
|
$msg .= " - A 1.0 requires b >= 2.0 -> no matching package found.\n";
|
||||||
|
$this->assertEquals($msg, $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRequireMismatchException()
|
||||||
|
{
|
||||||
|
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
|
||||||
|
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
|
||||||
|
$this->repo->addPackage($packageB2 = $this->getPackage('B', '0.9'));
|
||||||
|
$this->repo->addPackage($packageC = $this->getPackage('C', '1.0'));
|
||||||
|
$this->repo->addPackage($packageD = $this->getPackage('D', '1.0'));
|
||||||
|
|
||||||
|
$packageA->setRequires(array(
|
||||||
|
new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires'),
|
||||||
|
));
|
||||||
|
$packageB->setRequires(array(
|
||||||
|
new Link('B', 'C', $this->getVersionConstraint('>=', '1.0'), 'requires'),
|
||||||
|
));
|
||||||
|
$packageC->setRequires(array(
|
||||||
|
new Link('C', 'D', $this->getVersionConstraint('>=', '1.0'), 'requires'),
|
||||||
|
));
|
||||||
|
$packageD->setRequires(array(
|
||||||
|
new Link('D', 'B', $this->getVersionConstraint('<', '1.0'), 'requires'),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->reposComplete();
|
||||||
|
|
||||||
|
$this->request->install('A');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$transaction = $this->solver->solve($this->request);
|
||||||
|
$this->fail('Unsolvable conflict did not result in exception.');
|
||||||
|
} catch (SolverProblemsException $e) {
|
||||||
|
$problems = $e->getProblems();
|
||||||
|
$this->assertEquals(1, count($problems));
|
||||||
|
|
||||||
|
$msg = "\n";
|
||||||
|
$msg .= " Problem 1\n";
|
||||||
|
$msg .= " - C 1.0 requires d >= 1.0 -> satisfiable by D 1.0.\n";
|
||||||
|
$msg .= " - D 1.0 requires b < 1.0 -> satisfiable by B 0.9.\n";
|
||||||
|
$msg .= " - B 1.0 requires c >= 1.0 -> satisfiable by C 1.0.\n";
|
||||||
|
$msg .= " - Can only install one of: B 0.9, B 1.0.\n";
|
||||||
|
$msg .= " - A 1.0 requires b >= 1.0 -> satisfiable by B 1.0.\n";
|
||||||
|
$msg .= " - Installation request for a -> satisfiable by A 1.0.\n";
|
||||||
|
$this->assertEquals($msg, $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,14 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
protected function getVersionConstraint($operator, $version)
|
protected function getVersionConstraint($operator, $version)
|
||||||
{
|
{
|
||||||
return new VersionConstraint(
|
$constraint = new VersionConstraint(
|
||||||
$operator,
|
$operator,
|
||||||
self::getVersionParser()->normalize($version)
|
self::getVersionParser()->normalize($version)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$constraint->setPrettyString($operator.' '.$version);
|
||||||
|
|
||||||
|
return $constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPackage($name, $version)
|
protected function getPackage($name, $version)
|
||||||
|
|
Loading…
Reference in New Issue