Files
netslim-core/tests/Architecture/SupportGovernanceTest.php
2026-03-20 22:13:41 +01:00

91 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Architecture;
use Tests\Architecture\Support\ArchitectureTestCase;
final class SupportGovernanceTest extends ArchitectureTestCase
{
/** @var list<string> */
private const APPROVED_SUPPORT_TOP_LEVEL_ENTRIES = [
'Exception',
'Util',
];
/** @var list<string> */
private const APPROVED_SUPPORT_FILES = [
'Exception/NotFoundException.php',
'Util/DateParser.php',
'Util/SlugHelper.php',
];
public function testSupportUsesOnlyApprovedTopLevelEntries(): void
{
$supportPath = $this->projectPath('src/Kernel/Support');
self::assertDirectoryExists($supportPath);
$entries = array_values(array_filter(scandir($supportPath) ?: [], static fn (string $entry): bool => !in_array($entry, ['.', '..'], true)));
sort($entries);
self::assertSame(
self::APPROVED_SUPPORT_TOP_LEVEL_ENTRIES,
$entries,
'Kernel/Support is frozen by default: only explicitly approved subdirectories may exist.',
);
}
public function testSupportContainsOnlyExplicitlyApprovedFiles(): void
{
$supportPath = $this->projectPath('src/Kernel/Support');
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($supportPath, \FilesystemIterator::SKIP_DOTS),
);
$files = [];
foreach ($iterator as $fileInfo) {
if (!$fileInfo->isFile() || $fileInfo->getExtension() !== 'php') {
continue;
}
$files[] = substr($fileInfo->getPathname(), strlen($supportPath) + 1);
}
sort($files);
self::assertSame(
self::APPROVED_SUPPORT_FILES,
$files,
'Any new file under Kernel/Support must be a deliberate architectural decision: update the allow list, tests and documentation together.',
);
}
public function testSupportStaysIndependentFromFeatureModulesAndFrameworks(): void
{
$this->assertFilesDoNotReferenceFragments(
$this->phpFilesUnder('src/Kernel/Support'),
array_merge(
self::APPLICATION_NAMESPACES,
self::INFRASTRUCTURE_NAMESPACES,
self::UI_NAMESPACES,
self::FRAMEWORK_NAMESPACE_FRAGMENTS,
self::HTTP_MESSAGE_DEPENDENCIES,
),
'Kernel/Support must stay pure, transverse and framework-agnostic',
);
}
public function testSupportClassesAreFinal(): void
{
foreach ($this->phpFilesUnder('src/Kernel/Support') as $file) {
$code = $this->normalizedCode($file);
self::assertTrue(
str_contains($code, 'finalclass'),
$this->fileRuleMessage('Kernel/Support classes must be final to avoid becoming extension points by accident', $file),
);
}
}
}