1. Go to this page and download the library: Download structuraphp/structura library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
structuraphp / structura example snippets
return static function (StructuraConfig $config): void {
$config->archiRootNamespace(
'<MY_NAMESPACE>\Tests\Architecture', // namespace
'tests/Architecture', // test directory
);
};
use StructuraPhp\Structura\Asserts\ToExtendNothing;
use StructuraPhp\Structura\Attributes\TestDox;
use StructuraPhp\Structura\Expr;
use StructuraPhp\Structura\Testing\TestBuilder;
use Symfony\Component\Finder\Finder;
final class TestDto extends TestBuilder
{
#[TestDox('Asserts rules Dto architecture')]
public function testAssertArchitectureRules(): void
{
$this
->allClasses()
->fromDir(
'app/Dto',
fn(Finder $finder) => $finder->depth('== 0')
)
->that($this->conditionThat(...))
->except($this->exception(...))
->should($this->should(...));
}
private function that(Expr $expr): void
{
// The rules will only apply to classes (ignore traits, enums, interfaces, etc.)
$expr->toBeClasses();
}
private function exception(Except $except): void
{
// These classes will be ignored in the tests
$except
->byClassname(
className: [
FooDto::class,
BarDto::class,
],
expression: ToExtendNothing::class
);
}
private function should(Expr $expr): void
{
$expr
->toBeFinal()
->toBeReadonly()
->toHaveSuffix('Dto')
->toExtendsNothing()
->toHaveMethod('fromArray')
->toImplement(\JsonSerializable::class);
}
}
->fromDir(
'src/Dto',
static fn(Finder $finder): Finder => $finder->depth('== 0')
)
->fromRaw('
use ArrayAccess;
use Depend\Bap;
use Depend\Bar;
class Foo implements \Stringable {
public function __construct(ArrayAccess $arrayAccess) {}
public function __toString(): string {
return $this->arrayAccess['foo'] ?? throw new \Exception();
}
}')
[\Attribute(\Attribute::TARGET_CLASS_CONSTANT)] // OK
class Foo {
}
#[Custom] // KO
class Bar {
}
(new ReflectionClass(Bar::class))->getAttributes()[0]->newInstance();
// Fatal error: Uncaught Error: Attribute class "Custom" not found
// if Foo class implements ArrayAccess and (JsonSerializable or Countable)
$this
->allClasses()
->fromRaw(' class Foo implements ArrayAccess, JsonSerializable {}')
->should(fn(Expr $expr) => $expr
->toBeClasses()
->toImplement(ArrayAccess::class)
->or(fn(Expr $expr) => $expr
->toImplement(JsonSerializable::class)
->toImplement(Countable::class)
)
);
final readonly class CustomRule implements ExprInterface
{
public function __construct(
private string $message = '',
) {}
public function __toString(): string
{
return 'exemple'; // Name of the rule
}
public function assert(ClassDescription $class): bool
{
return true; // Must return false if the test fails
}
public function getViolation(ClassDescription $class): ViolationValueObject
{
return new ViolationValueObject(
'error message', // Console output
$this::class,
$class->lines,
$class->getFileBasename(),
$this->message,
);
}
}