expect("App\Cast") ->toHaveSuffix('Cast'); arch('adapters repositories have Repository suffix') ->expect("App\Adapters\Repositories") ->toHaveSuffix('Repository'); arch('dtos have Dto suffix') ->expect("App\Dtos") ->toHaveSuffix('Dto'); arch('exceptions have Exception suffix') ->expect("App\Exceptions") ->toHaveSuffix('Exception') ->ignoring([ GlobalHandler::class, ]); arch('controllers have Controller suffix') ->expect("App\Http\Controllers") ->toHaveSuffix('Controller'); arch('requests have Request suffix') ->expect("App\Http\Requests") ->toHaveSuffix('Request'); arch('resources have Resource suffix') ->expect("App\Http\Resources") ->toHaveSuffix('Resource'); arch('policies have Policy suffix') ->expect("App\Policies") ->toHaveSuffix('Policy'); arch('providers have Provider suffix') ->expect("App\Providers") ->toHaveSuffix('Provider'); arch('services have Service suffix') ->expect("App\Services") ->toHaveSuffix('Service') ->ignoring([ ArcadiaEmployee::class, EmployeeSyncServiceResult::class, ]); arch('queries have Query, QueryInput or QueryOutput suffix', function (): void { $path = __DIR__ . '/../../app/Queries'; $files = (new Finder())->files()->in($path)->name('*.php'); foreach ($files as $file) { $className = $file->getBasename('.php'); expect( str_ends_with($className, 'Query') || str_ends_with($className, 'QueryInput') || str_ends_with($className, 'QueryOutput') )->toBeTrue("{$className} must have suffix Query, QueryInput or QueryOutput"); } }); }); describe('naming conventions in domain', function (): void { arch('dtos have Dto suffix') ->expect("Domain\Dto") ->toHaveSuffix('Dto'); arch('exceptions have Exception suffix') ->expect("Domain\Exceptions") ->toHaveSuffix('Exception'); arch('policies have Policy suffix') ->expect("Domain\Policies") ->toHaveSuffix('Policy'); arch('port directories have Directory suffix') ->expect("Domain\Ports\Directories") ->toHaveSuffix('Directory'); arch('port repositories have Repository suffix') ->expect("Domain\Ports\Repositories") ->toHaveSuffix('Repository'); arch('domain services have Service suffix') ->expect("Domain\Services") ->toHaveSuffix('Service'); }); describe('naming conventions in infrastructure', function (): void { arch('adapters implement an interface from their domain ports', function (string $folder, string $infraNs, string $domainNs): void { $path = __DIR__ . '/../../infra/' . $folder; $files = (new Finder())->files()->in($path)->name('*.php'); foreach ($files as $file) { $className = $infraNs . '\\' . $file->getFilenameWithoutExtension(); $interfaces = (new \ReflectionClass($className))->getInterfaceNames(); $hasDomainPort = ! empty(array_filter( $interfaces, fn ($interface) => str_starts_with($interface, $domainNs) )); expect($hasDomainPort) ->toBeTrue(message: "La classe {$className} n'implémente aucune interface de {$domainNs}."); } })->with([ 'Directories' => ['Adapters/Directories', 'Infrastructure\Adapters\Directories', 'Domain\Ports\Directories\\'], 'Repositories' => ['Adapters/Repositories', 'Infrastructure\Adapters\Repositories', 'Domain\Ports\Repositories\\'], 'Services' => ['Adapters/Services', 'Infrastructure\Adapters\Services', 'Domain\Ports\Services\\'], ]); });