Skip to content

Commit 5cb4c9c

Browse files
author
Herberto Graca
committed
Create a Not expression
This will reduce the amount of expressions needed and allow for complex expressions (within an OR or an AND) to be negated.
1 parent 976c200 commit 5cb4c9c

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

src/Expression/ForClasses/Not.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Arkitect\Expression\ForClasses;
6+
7+
use Arkitect\Analyzer\ClassDescription;
8+
use Arkitect\Expression\Description;
9+
use Arkitect\Expression\Expression;
10+
use Arkitect\Rules\Violation;
11+
use Arkitect\Rules\ViolationMessage;
12+
use Arkitect\Rules\Violations;
13+
14+
final class Not implements Expression
15+
{
16+
/** @var Expression */
17+
private $expression;
18+
19+
public function __construct(Expression $expression)
20+
{
21+
$this->expression = $expression;
22+
}
23+
24+
public function describe(ClassDescription $theClass, string $because): Description
25+
{
26+
return new Description('must NOT (' . $this->expression->describe($theClass, '')->toString() . ')', $because);
27+
}
28+
29+
public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
30+
{
31+
$newViolations = new Violations();
32+
$this->expression->evaluate($theClass, $newViolations, $because);
33+
if (0 !== $newViolations->count()) {
34+
return;
35+
}
36+
37+
$violations->add(Violation::create(
38+
$theClass->getFQCN(),
39+
ViolationMessage::selfExplanatory($this->describe($theClass, $because))
40+
));
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Arkitect\Tests\Unit\Expressions\ForClasses;
6+
7+
use Arkitect\Analyzer\ClassDescription;
8+
use Arkitect\Analyzer\FullyQualifiedClassName;
9+
use Arkitect\Expression\ForClasses\IsInterface;
10+
use Arkitect\Expression\ForClasses\Not;
11+
use Arkitect\Rules\Violations;
12+
use PHPUnit\Framework\TestCase;
13+
14+
class NotTest extends TestCase
15+
{
16+
public function test_it_should_return_violation_error(): void
17+
{
18+
$isNotInterface = new Not(new IsInterface());
19+
$classDescription = new ClassDescription(
20+
FullyQualifiedClassName::fromString('HappyIsland'),
21+
[],
22+
[],
23+
null,
24+
false,
25+
false,
26+
true,
27+
false,
28+
false
29+
);
30+
$because = 'we want to add this rule for our software';
31+
$violationError = $isNotInterface->describe($classDescription, $because)->toString();
32+
33+
$violations = new Violations();
34+
$isNotInterface->evaluate($classDescription, $violations, $because);
35+
self::assertNotEquals(0, $violations->count());
36+
37+
$this->assertEquals('must NOT (HappyIsland should be an interface) because we want to add this rule for our software', $violationError);
38+
}
39+
40+
public function test_it_should_return_true_if_is_not_interface(): void
41+
{
42+
$isNotInterface = new Not(new IsInterface());
43+
$classDescription = new ClassDescription(
44+
FullyQualifiedClassName::fromString('HappyIsland'),
45+
[],
46+
[],
47+
null,
48+
false,
49+
false,
50+
false,
51+
false,
52+
false
53+
);
54+
$because = 'we want to add this rule for our software';
55+
$violations = new Violations();
56+
$isNotInterface->evaluate($classDescription, $violations, $because);
57+
self::assertEquals(0, $violations->count());
58+
}
59+
}

0 commit comments

Comments
 (0)