Skip to content

Commit

Permalink
Fix phparkitect#126 improve error messages including classname when p…
Browse files Browse the repository at this point in the history
…ossible

Added ViolationDescription, as input for a Violation
Added a description to the ViolationDescription
 - Only for Expressions where it made sense
  • Loading branch information
annervisser committed Aug 16, 2022
1 parent c76a3cf commit b791c37
Show file tree
Hide file tree
Showing 29 changed files with 197 additions and 100 deletions.
2 changes: 1 addition & 1 deletion src/Expression/Expression.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface Expression
* Returns a human readable description of the expression
* $theClass can be used to add contextual information.
*/
public function describe(ClassDescription $theClass, string $because): Description;
public function describe(ClassDescription $theClass, string $because): ExpressionDescription;

/**
* Evaluates the expression for the class passed as parameter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Arkitect\Expression;

class Description
class ExpressionDescription
{
/** @var string */
private $description;
Expand Down
12 changes: 8 additions & 4 deletions src/Expression/ForClasses/DependsOnlyOnTheseNamespaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

use Arkitect\Analyzer\ClassDependency;
use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

Expand All @@ -21,11 +22,11 @@ public function __construct(string ...$namespace)
$this->namespaces = $namespace;
}

public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
$desc = implode(', ', $this->namespaces);

return new Description("should depend only on classes in one of these namespaces: $desc", $because);
return new ExpressionDescription("should depend only on classes in one of these namespaces: $desc", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -44,7 +45,10 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str
if (!$dependency->matchesOneOf(...$this->namespaces)) {
$violation = Violation::createWithErrorLine(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString(),
ViolationDescription::withDescription(
$this->describe($theClass, $because),
"depends on {$dependency->getFQCN()->toString()}"
),
$dependency->getLine()
);

Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/DocBlockContains.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

Expand All @@ -20,17 +21,17 @@ public function __construct(string $docBlock)
$this->docBlock = $docBlock;
}

public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("should have a doc block that contains {$this->docBlock}", $because);
return new ExpressionDescription("should have a doc block that contains {$this->docBlock}", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
{
if (!$theClass->containsDocBlock($this->docBlock)) {
$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);
$violations->add($violation);
}
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/DocBlockNotContains.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

Expand All @@ -20,17 +21,17 @@ public function __construct(string $docBlock)
$this->docBlock = $docBlock;
}

public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("should not have a doc block that contains {$this->docBlock}", $because);
return new ExpressionDescription("should not have a doc block that contains {$this->docBlock}", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
{
if ($theClass->containsDocBlock($this->docBlock)) {
$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);
$violations->add($violation);
}
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/Extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

Expand All @@ -20,9 +21,9 @@ public function __construct(string $className)
$this->className = $className;
}

public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("should extend {$this->className}", $because);
return new ExpressionDescription("should extend {$this->className}", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -35,7 +36,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str

$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);

$violations->add($violation);
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/HaveAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

Expand All @@ -19,9 +20,9 @@ public function __construct(string $attribute)
$this->attribute = $attribute;
}

public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("should have the attribute {$this->attribute}", $because);
return new ExpressionDescription("should have the attribute {$this->attribute}", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -33,7 +34,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str
$violations->add(
Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
)
);
}
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/HaveNameMatching.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Analyzer\FullyQualifiedClassName;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

Expand All @@ -21,9 +22,9 @@ public function __construct(string $name)
$this->name = $name;
}

public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("should have a name that matches {$this->name}", $because);
return new ExpressionDescription("should have a name that matches {$this->name}", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -32,7 +33,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str
if (!$fqcn->classMatches($this->name)) {
$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);
$violations->add($violation);
}
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/Implement.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Analyzer\FullyQualifiedClassName;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

Expand All @@ -21,9 +22,9 @@ public function __construct(string $interface)
$this->interface = $interface;
}

public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("should implement {$this->interface}", $because);
return new ExpressionDescription("should implement {$this->interface}", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -37,7 +38,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str
if (0 === \count(array_filter($interfaces, $implements))) {
$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);
$violations->add($violation);
}
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/IsAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

class IsAbstract implements Expression
{
public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("{$theClass->getName()} should be abstract", $because);
return new ExpressionDescription("{$theClass->getName()} should be abstract", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -25,7 +26,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str

$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);

$violations->add($violation);
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/IsFinal.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

class IsFinal implements Expression
{
public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("{$theClass->getName()} should be final", $because);
return new ExpressionDescription("{$theClass->getName()} should be final", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -25,7 +26,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str

$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);

$violations->add($violation);
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/IsNotAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

class IsNotAbstract implements Expression
{
public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("{$theClass->getName()} should not be abstract", $because);
return new ExpressionDescription("{$theClass->getName()} should not be abstract", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -25,7 +26,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str

$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);

$violations->add($violation);
Expand Down
9 changes: 5 additions & 4 deletions src/Expression/ForClasses/IsNotFinal.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Expression\ExpressionDescription;
use Arkitect\Expression\ViolationDescription;
use Arkitect\Rules\Violation;
use Arkitect\Rules\Violations;

class IsNotFinal implements Expression
{
public function describe(ClassDescription $theClass, string $because): Description
public function describe(ClassDescription $theClass, string $because): ExpressionDescription
{
return new Description("{$theClass->getName()} should not be final", $because);
return new ExpressionDescription("{$theClass->getName()} should not be final", $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
Expand All @@ -25,7 +26,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str

$violation = Violation::create(
$theClass->getFQCN(),
$this->describe($theClass, $because)->toString()
ViolationDescription::selfExplanatory($this->describe($theClass, $because))
);

$violations->add($violation);
Expand Down
Loading

0 comments on commit b791c37

Please sign in to comment.