113 lines
3.7 KiB
PHP
113 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Architecture;
|
|
|
|
use Tests\Architecture\Support\ArchitectureTestCase;
|
|
|
|
final class ModuleBoundaryGovernanceTest extends ArchitectureTestCase
|
|
{
|
|
public function testKernelDoesNotImportFeatureModules(): void
|
|
{
|
|
$violations = [];
|
|
$featurePrefixes = [
|
|
'Netig\\Netslim\\Identity\\',
|
|
'Netig\\Netslim\\Settings\\',
|
|
'Netig\\Netslim\\AuditLog\\',
|
|
'Netig\\Netslim\\Notifications\\',
|
|
'Netig\\Netslim\\Taxonomy\\',
|
|
'Netig\\Netslim\\Media\\',
|
|
];
|
|
|
|
foreach ($this->phpFilesUnder('src/Kernel') as $file) {
|
|
foreach ($this->importedClasses($file) as $import) {
|
|
$importsFeatureModule = false;
|
|
foreach ($featurePrefixes as $prefix) {
|
|
if (str_starts_with($import, $prefix)) {
|
|
$importsFeatureModule = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$importsFeatureModule) {
|
|
continue;
|
|
}
|
|
|
|
$violations[] = $this->relativePath($file) . ' -> ' . $import;
|
|
}
|
|
}
|
|
|
|
$this->assertNoArchitectureViolations(
|
|
$violations,
|
|
'Kernel must not import feature modules directly',
|
|
);
|
|
}
|
|
|
|
public function testApplicationDomainAndInfrastructureUseOnlyApprovedCrossModuleContracts(): void
|
|
{
|
|
$violations = [];
|
|
$allowedExternalImports = [
|
|
'Identity' => [],
|
|
'Settings' => [],
|
|
'AuditLog' => [],
|
|
'Notifications' => [],
|
|
'Taxonomy' => [],
|
|
'Media' => [],
|
|
];
|
|
|
|
foreach (self::FEATURE_MODULES as $module) {
|
|
$directories = [
|
|
$this->projectPath('src/' . $module . '/Application'),
|
|
$this->projectPath('src/' . $module . '/Domain'),
|
|
$this->projectPath('src/' . $module . '/Infrastructure'),
|
|
];
|
|
|
|
foreach ($directories as $directory) {
|
|
if (!is_dir($directory)) {
|
|
continue;
|
|
}
|
|
|
|
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory));
|
|
foreach ($iterator as $fileInfo) {
|
|
if (!$fileInfo->isFile() || $fileInfo->getExtension() !== 'php') {
|
|
continue;
|
|
}
|
|
|
|
$file = $fileInfo->getPathname();
|
|
$imports = $this->importedClasses($file);
|
|
|
|
foreach ($imports as $import) {
|
|
if (!str_starts_with($import, 'Netig\\Netslim\\')) {
|
|
continue;
|
|
}
|
|
|
|
if (str_starts_with($import, 'Netig\\Netslim\\Kernel\\') || str_starts_with($import, 'Netig\\Netslim\\' . $module . '\\')) {
|
|
continue;
|
|
}
|
|
|
|
$isAllowed = false;
|
|
foreach ($allowedExternalImports[$module] as $allowedPrefix) {
|
|
if (str_starts_with($import, $allowedPrefix)) {
|
|
$isAllowed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($isAllowed) {
|
|
continue;
|
|
}
|
|
|
|
$violations[] = $this->relativePath($file) . ' -> ' . $import;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->assertNoArchitectureViolations(
|
|
$violations,
|
|
'Application, Domain and Infrastructure layers must only cross module boundaries through approved public contracts',
|
|
);
|
|
}
|
|
}
|