2026-08-12 15:45:29 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
2026-08-13 11:25:08 +02:00
|
|
|
namespace Tests\Architecture;
|
|
|
|
|
|
2026-08-14 11:33:29 +02:00
|
|
|
/** @return array<int, string> */
|
|
|
|
|
function enumsIn(string $namespace): array
|
|
|
|
|
{
|
|
|
|
|
$dir = dirname(__DIR__, 2) . '/src/' . str_replace('\\', '/', $namespace);
|
|
|
|
|
$enums = [];
|
|
|
|
|
if (! is_dir($dir)) {
|
|
|
|
|
return $enums;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)) as $file) {
|
|
|
|
|
$class = $namespace . str_replace([$dir, '.php', '/'], ['', '', '\\'], $file->getPathname());
|
|
|
|
|
if ($file->isFile() && enum_exists($class)) {
|
|
|
|
|
$enums[] = $class;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $enums;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-12 15:45:29 +02:00
|
|
|
describe('Application Architecture Rules', function (): void {
|
|
|
|
|
arch('Application layer does not depend on Presentation, Infra, or App')
|
|
|
|
|
->expect('Application')
|
|
|
|
|
->not->toUse([
|
|
|
|
|
'Presentation',
|
|
|
|
|
'Infra',
|
|
|
|
|
'Infrastructure',
|
|
|
|
|
'App',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
arch('Application layer does not depend on Illuminate framework')
|
|
|
|
|
->expect('Application')
|
|
|
|
|
->not->toUse('Illuminate');
|
|
|
|
|
|
|
|
|
|
arch('Application layer uses strict types')
|
|
|
|
|
->expect('Application')
|
|
|
|
|
->toUseStrictTypes();
|
|
|
|
|
|
|
|
|
|
arch('Application Usecase classes are final and readonly')
|
|
|
|
|
->expect('Application\Usecase')
|
2026-08-14 11:33:29 +02:00
|
|
|
->classes()
|
2026-08-12 15:45:29 +02:00
|
|
|
->toBeReadonly()
|
2026-08-14 11:33:29 +02:00
|
|
|
->toBeFinal()
|
|
|
|
|
->ignoring(enumsIn('Application\Usecase'));
|
2026-08-12 17:01:09 +02:00
|
|
|
|
|
|
|
|
arch('Application layer must not contain Presenters')
|
|
|
|
|
->expect('Application')
|
|
|
|
|
->classes()
|
|
|
|
|
->not->toHaveSuffix('Presenter');
|
|
|
|
|
|
|
|
|
|
arch('Application layer must not contain Views')
|
|
|
|
|
->expect('Application')
|
|
|
|
|
->classes()
|
|
|
|
|
->not->toHaveSuffix('View');
|
2026-08-12 15:45:29 +02:00
|
|
|
});
|