refactor: Divi-Reiter und divi-check in die Divi-Integration verschoben; CoreIndependenceTest prüft auch Cli, ChangeLog, Pods und die Wurzeldateien, erkennt Alias-Importe und kennt nur noch Plugin.php als Ausnahme
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d0d3488df8
commit
7f9a087b8b
@@ -10,27 +10,37 @@ use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
|
||||
/**
|
||||
* The generic core knows no Divi class: nothing below the CORE_PATHS imports or names a class of
|
||||
* LIT\MCP\Integrations\Divi. Divi plugs in through ports (AbilityGuard, ToolRefusal, BuilderDetector,
|
||||
* The generic core knows no Divi class: nothing below the CORE_PATHS and none of the CORE_ROOTS files imports or names
|
||||
* a class of LIT\MCP\Integrations\Divi. Divi plugs in through ports (AbilityGuard, ToolRefusal, BuilderDetector,
|
||||
* MediaUsageSource, EnvironmentComponent, ContentSchema's excluded post types) that Plugin.php – the composition
|
||||
* root, outside these paths – wires up. Divi's own names (et_* …) are DiviBoundaryTest's business, not this test's.
|
||||
* root, the one listed exception – wires up. Divi's own UI (settings tab, WP-CLI command) lives in
|
||||
* Integrations/Divi. Divi's own names (et_* …) are DiviBoundaryTest's business, not this test's.
|
||||
*/
|
||||
final class CoreIndependenceTest extends TestCase
|
||||
{
|
||||
/** Directories below src/ that must not use Divi classes. */
|
||||
/** Directories below src/ (scanned recursively) that must not use Divi classes. */
|
||||
private const CORE_PATHS = [
|
||||
'Abilities',
|
||||
'Integrations/Core',
|
||||
'Integrations/WordPress',
|
||||
'Integrations/Media',
|
||||
'Admin',
|
||||
'ChangeLog',
|
||||
'Cli',
|
||||
'Guides',
|
||||
'Integrations/Core',
|
||||
'Integrations/Media',
|
||||
'Integrations/Pods',
|
||||
'Integrations/WordPress',
|
||||
'Server',
|
||||
];
|
||||
|
||||
/** Files inside CORE_PATHS that may use Divi classes, each with its reason. */
|
||||
/** CORE_PATHS that may be absent: no generic WP-CLI command exists yet (Divi's lives in Integrations/Divi/Cli). */
|
||||
private const OPTIONAL_PATHS = ['Cli'];
|
||||
|
||||
/** Directories below src/ whose PHP files directly inside (not below) must not use Divi classes either. */
|
||||
private const CORE_ROOTS = ['', 'Integrations'];
|
||||
|
||||
/** Files of the scan that may use Divi classes, each with its reason. */
|
||||
private const EXCEPTIONS = [
|
||||
'Admin/DiviTab.php' => 'The settings tab "Divi" is Divi UI: release state, admin check and release/withdraw.',
|
||||
'Plugin.php' => 'Composition root: builds DiviIntegration and wires its ports (DiviFeatureGate) into the core.',
|
||||
];
|
||||
|
||||
public function testTheCoreUsesNoDiviClass(): void
|
||||
@@ -63,7 +73,7 @@ final class CoreIndependenceTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testTheScanFindsImportsQualifiedNamesGroupUsesAndClassStrings(): void
|
||||
public function testTheScanFindsImportsQualifiedNamesGroupUsesAliasesAndClassStrings(): void
|
||||
{
|
||||
$source = <<<'PHP'
|
||||
<?php
|
||||
@@ -72,11 +82,13 @@ final class CoreIndependenceTest extends TestCase
|
||||
$a = \LIT\MCP\Integrations\Divi\Schema\DiviModules::isAvailable();
|
||||
$b = 'LIT\\MCP\\Integrations\\Divi\\Design\\DesignSystemReader';
|
||||
$c = "LIT\\MCP\\Integrations\\Divi\\Library\\LibraryAccess";
|
||||
use LIT\MCP\Integrations\Divi as D;
|
||||
PHP;
|
||||
|
||||
self::assertSame(
|
||||
[
|
||||
'Divi\Pages\DiviPages',
|
||||
'LIT\MCP\Integrations\Divi',
|
||||
'LIT\MCP\Integrations\Divi\Design\DesignSystemReader',
|
||||
'LIT\MCP\Integrations\Divi\Library\LibraryAccess',
|
||||
'LIT\MCP\Integrations\Divi\Release\ReleaseGate',
|
||||
@@ -114,7 +126,8 @@ final class CoreIndependenceTest extends TestCase
|
||||
T_CONSTANT_ENCAPSED_STRING => ltrim(str_replace('\\\\', '\\', substr($token[1], 1, -1)), '\\'),
|
||||
default => '',
|
||||
};
|
||||
if (preg_match('/^(?:LIT\\\\MCP\\\\Integrations\\\\)?Divi\\\\[A-Za-z0-9_\\\\]+$/', $text) === 1) {
|
||||
$diviClass = '/^(?:LIT\\\\MCP\\\\Integrations\\\\)?Divi\\\\[A-Za-z0-9_\\\\]+$/';
|
||||
if (preg_match($diviClass, $text) === 1 || $text === 'LIT\\MCP\\Integrations\\Divi') {
|
||||
$names[] = $text;
|
||||
}
|
||||
}
|
||||
@@ -124,12 +137,44 @@ final class CoreIndependenceTest extends TestCase
|
||||
return $names;
|
||||
}
|
||||
|
||||
/** @return array<string, string> Path below src/ => absolute path of every PHP file in CORE_PATHS. */
|
||||
public function testEveryScannedPathExists(): void
|
||||
{
|
||||
$root = self::root();
|
||||
foreach ([...self::CORE_PATHS, ...self::CORE_ROOTS] as $directory) {
|
||||
if (! in_array($directory, self::OPTIONAL_PATHS, true)) {
|
||||
self::assertDirectoryExists($root . $directory, $directory . ' fehlt – Scan-Liste anpassen');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testTheDiviUiLivesInTheDiviIntegration(): void
|
||||
{
|
||||
$files = self::coreFiles();
|
||||
|
||||
self::assertArrayHasKey('Plugin.php', $files, 'root files are scanned');
|
||||
self::assertArrayHasKey('Integrations/IntegrationRegistry.php', $files, 'Integrations root files are scanned');
|
||||
self::assertArrayNotHasKey('Admin/DiviTab.php', $files, 'the Divi tab belongs to Integrations/Divi/Admin');
|
||||
self::assertFileExists(self::root() . 'Integrations/Divi/Admin/DiviTab.php');
|
||||
self::assertFileExists(self::root() . 'Integrations/Divi/Cli/DiviCheckCommand.php');
|
||||
}
|
||||
|
||||
private static function root(): string
|
||||
{
|
||||
return dirname(__DIR__, 3) . '/src/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string> Path below src/ => absolute path of every PHP file in CORE_PATHS (recursively) and
|
||||
* directly in CORE_ROOTS.
|
||||
*/
|
||||
private static function coreFiles(): array
|
||||
{
|
||||
$root = dirname(__DIR__, 3) . '/src/';
|
||||
$root = self::root();
|
||||
$files = [];
|
||||
foreach (self::CORE_PATHS as $directory) {
|
||||
if (! is_dir($root . $directory)) {
|
||||
continue; // Only an OPTIONAL_PATHS entry may be missing (testEveryScannedPathExists).
|
||||
}
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($root . $directory, FilesystemIterator::SKIP_DOTS)
|
||||
);
|
||||
@@ -139,6 +184,11 @@ final class CoreIndependenceTest extends TestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (self::CORE_ROOTS as $directory) {
|
||||
foreach (glob($root . ($directory === '' ? '' : $directory . '/') . '*.php') ?: [] as $path) {
|
||||
$files[substr($path, strlen($root))] = $path;
|
||||
}
|
||||
}
|
||||
ksort($files);
|
||||
|
||||
return $files;
|
||||
|
||||
Reference in New Issue
Block a user