Skip to content

Commit

Permalink
Merge pull request #383 from simivar/feature/is-not-interface
Browse files Browse the repository at this point in the history
Add IsInterface and IsNotInterface
  • Loading branch information
fain182 authored Apr 26, 2023
2 parents 9d11ff7 + 92e1721 commit f06eeb6
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 0 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,15 @@ $rules = Rule::allClasses()
->because('we want to be sure that aggregates are final classes');
```

### Is interface

```php
$rules = Rule::allClasses()
->that(new ResideInOneOfTheseNamespaces('App\Interfaces'))
->should(new IsInterface())
->because('we want to be sure that all interfaces are in one directory');
```

### Is not abstract

```php
Expand Down Expand Up @@ -278,6 +287,15 @@ $rules = Rule::allClasses()
->because('we want to be sure that our adapters are not final classes');
```

### Is not interface

```php
$rules = Rule::allClasses()
->that(new ResideInOneOfTheseNamespaces('Tests\Integration'))
->should(new IsNotInterface())
->because('we want to be sure that we do not have interfaces in tests');
```

### Not depends on a namespace

```php
Expand Down
34 changes: 34 additions & 0 deletions src/Expression/ForClasses/IsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?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;

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

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
{
if ($theClass->isInterface()) {
return;
}

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

$violations->add($violation);
}
}
34 changes: 34 additions & 0 deletions src/Expression/ForClasses/IsNotInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?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;

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

public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void
{
if (!$theClass->isInterface()) {
return;
}

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

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

declare(strict_types=1);

namespace Arkitect\Tests\Unit\Expressions\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Analyzer\FullyQualifiedClassName;
use Arkitect\Expression\ForClasses\IsInterface;
use Arkitect\Rules\Violations;
use PHPUnit\Framework\TestCase;

class IsInterfaceTest extends TestCase
{
public function test_it_should_return_violation_error(): void
{
$isFinal = new IsInterface();
$classDescription = new ClassDescription(
FullyQualifiedClassName::fromString('HappyIsland'),
[],
[],
null,
false,
false,
false,
false,
false
);
$because = 'we want to add this rule for our software';
$violationError = $isFinal->describe($classDescription, $because)->toString();

$violations = new Violations();
$isFinal->evaluate($classDescription, $violations, $because);
self::assertNotEquals(0, $violations->count());

$this->assertEquals('HappyIsland should be an interface because we want to add this rule for our software', $violationError);
}

public function test_it_should_return_true_if_is_interface(): void
{
$isFinal = new IsInterface();
$classDescription = new ClassDescription(
FullyQualifiedClassName::fromString('HappyIsland'),
[],
[],
null,
false,
false,
true,
false,
false
);
$because = 'we want to add this rule for our software';
$violations = new Violations();
$isFinal->evaluate($classDescription, $violations, $because);
self::assertEquals(0, $violations->count());
}
}
58 changes: 58 additions & 0 deletions tests/Unit/Expressions/ForClasses/IsNotInterfaceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Arkitect\Tests\Unit\Expressions\ForClasses;

use Arkitect\Analyzer\ClassDescription;
use Arkitect\Analyzer\FullyQualifiedClassName;
use Arkitect\Expression\ForClasses\IsNotInterface;
use Arkitect\Rules\Violations;
use PHPUnit\Framework\TestCase;

class IsNotInterfaceTest extends TestCase
{
public function test_it_should_return_violation_error(): void
{
$isFinal = new IsNotInterface();
$classDescription = new ClassDescription(
FullyQualifiedClassName::fromString('HappyIsland'),
[],
[],
null,
false,
false,
true,
false,
false
);
$because = 'we want to add this rule for our software';
$violationError = $isFinal->describe($classDescription, $because)->toString();

$violations = new Violations();
$isFinal->evaluate($classDescription, $violations, $because);
self::assertNotEquals(0, $violations->count());

$this->assertEquals('HappyIsland should not be an interface because we want to add this rule for our software', $violationError);
}

public function test_it_should_return_true_if_is_not_interface(): void
{
$isFinal = new IsNotInterface();
$classDescription = new ClassDescription(
FullyQualifiedClassName::fromString('HappyIsland'),
[],
[],
null,
false,
false,
false,
false,
false
);
$because = 'we want to add this rule for our software';
$violations = new Violations();
$isFinal->evaluate($classDescription, $violations, $because);
self::assertEquals(0, $violations->count());
}
}

0 comments on commit f06eeb6

Please sign in to comment.