expect('App\Http\Controllers') ->not->toUse('Domain\Entities'); arch('No Domain Entities are used in Policies') ->expect('App\Policies') ->not->toUse('Domain\Entities'); arch('App Repositories implement App\Contracts\Repository') ->expect('App\Repositories') ->toImplement('App\Contracts\Repository'); arch('App Directories implement App\Contracts\Directory') ->expect('App\Directories') ->toImplement('App\Contracts\Directory'); arch('App DTOs are final readonly classes') ->expect('App\Dto') ->classes() ->toBeFinal() ->toBeReadonly(); arch('App Actions implement App\Contracts\Action and Inputs implement ActionInput', function (): void { $path = __DIR__ . '/../../app/Actions'; $files = (new Finder())->files()->in($path)->name('*.php'); foreach ($files as $file) { $subPath = $file->getRelativePathname(); $className = 'App\\Actions\\' . str_replace(['/', '.php'], ['\\', ''], $subPath); $reflection = new \ReflectionClass($className); if (str_ends_with($className, 'Input')) { expect($reflection->implementsInterface(ActionInput::class)) ->toBeTrue("{$className} must implement App\Contracts\ActionInput"); } elseif (str_ends_with($className, 'Output')) { if ($reflection->isEnum()) { expect($reflection->isEnum())->toBeTrue(); } else { expect($reflection->isFinal()) ->toBeTrue("{$className} must be final"); expect($reflection->isReadOnly()) ->toBeTrue("{$className} must be readonly"); } } else { expect($reflection->implementsInterface(Action::class)) ->toBeTrue("{$className} must implement App\Contracts\Action"); } } }); arch('App Queries implement App\Contracts\Query and Inputs implement QueryInput', function (): void { $path = __DIR__ . '/../../app/Queries'; $files = (new Finder())->files()->in($path)->name('*.php'); foreach ($files as $file) { $subPath = $file->getRelativePathname(); $className = 'App\\Queries\\' . str_replace(['/', '.php'], ['\\', ''], $subPath); $reflection = new \ReflectionClass($className); if (str_ends_with($className, 'Input')) { expect($reflection->implementsInterface(QueryInput::class)) ->toBeTrue("{$className} must implement App\Contracts\QueryInput"); } elseif (str_ends_with($className, 'Output')) { expect($reflection->isFinal() && $reflection->isReadOnly()) ->toBeTrue("{$className} must be final readonly"); } else { expect($reflection->implementsInterface(Query::class)) ->toBeTrue("{$className} must implement App\Contracts\Query"); } } }); });