Skip to content

Commit

Permalink
Create a IsMapped expression
Browse files Browse the repository at this point in the history
This will allow us to ensure that certain classes are always in a map.
This is useful, for example, to ensure that DTOs like commands and
events are always set in a map, so that a serializer knows how
to serialize/deserialize them.
  • Loading branch information
Herberto Graca committed Jul 27, 2023
1 parent 976c200 commit 3aee92f
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/Expression/ForClasses/IsMapped.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Arkitect\Expression\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Expression\Description;
use Arkitect\Expression\Expression;
use Arkitect\Rules\Violation;
use Arkitect\Rules\ViolationMessage;
use Arkitect\Rules\Violations;

final class IsMapped implements Expression
{
public const POSITIVE_DESCRIPTION = 'should exist in the list';

/** @var array */
private $list;

public function __construct(array $list)
{
$this->list = array_flip($list);
}

public function describe(ClassDescription $theClass, string $because): Description
{
return new Description(self::POSITIVE_DESCRIPTION, $because);
}

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
{
if (isset($this->list[$theClass->getFQCN()])) {
return;
}

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

$violations->add($violation);
}
}
46 changes: 46 additions & 0 deletions tests/Unit/Expressions/ForClasses/IsMappedTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Arkitect\Tests\Unit\Expressions\ForClasses;

use Arkitect\Analyzer\ClassDescriptionBuilder;
use Arkitect\Expression\ForClasses\IsMapped;
use Arkitect\Rules\Violations;
use PHPUnit\Framework\TestCase;

final class IsMappedTest extends TestCase
{
public function test_it_should_not_add_violation_if_fqcn_is_in_list(): void
{
$listedFqcn = 'App\SharedKernel\Component\MyClass';
$list = [
'a' => $listedFqcn,
'b' => 'App\SharedKernel\Component\MyOtherClass',
];
$expression = new IsMapped($list);
$classDescription = (new ClassDescriptionBuilder())->setClassName($listedFqcn)->build();

$violations = new Violations();
$expression->evaluate($classDescription, $violations, '');

self::assertEquals(0, $violations->count());
}

public function test_it_should_add_violation_if_fqcn_is_not_in_list(): void
{
$nonListedFqcn = 'App\SharedKernel\Component\MyClass';
$list = [
'a' => 'App\SharedKernel\Component\SomeClass',
'b' => 'App\SharedKernel\Component\MyOtherClass',
];
$expression = new IsMapped($list);
$classDescription = (new ClassDescriptionBuilder())->setClassName($nonListedFqcn)->build();

$violations = new Violations();
$expression->evaluate($classDescription, $violations, '');

self::assertEquals(1, $violations->count());
self::assertEquals(IsMapped::POSITIVE_DESCRIPTION, $expression->describe($classDescription, '')->toString());
}
}

0 comments on commit 3aee92f

Please sign in to comment.