feat: admin check steps with throwaway write test and reports
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\Divi\Release;
|
||||
|
||||
use Closure;
|
||||
use LIT\MCP\Integrations\Divi\BlockTree\Block;
|
||||
use LIT\MCP\Integrations\Divi\BlockTree\Parser;
|
||||
use LIT\MCP\Integrations\Divi\BlockTree\Serializer;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Spec §6.2 step 3: a builder-made Divi 5 page (reference-page.html, from the converted fixture) parses and
|
||||
* serializes byte-identically, and WordPress' parse_blocks() sees the same block names and nesting as the plugin's
|
||||
* parser. Nothing is written. Not final so CompatibilityCheck can be tested with a mock.
|
||||
*/
|
||||
class FormatCheck
|
||||
{
|
||||
public const REFERENCE = __DIR__ . '/reference-page.html';
|
||||
|
||||
/** @param (Closure(string): array<int, mixed>)|null $wpBlocks null = parse_blocks(). */
|
||||
public function __construct(private ?string $file = null, private ?Closure $wpBlocks = null)
|
||||
{
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
public function problems(): array
|
||||
{
|
||||
$file = $this->file ?? self::REFERENCE;
|
||||
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- local plugin file.
|
||||
$content = is_file($file) ? file_get_contents($file) : false;
|
||||
if (! is_string($content) || $content === '') {
|
||||
return ['Der Referenzinhalt der Prüfung fehlt im Plugin.'];
|
||||
}
|
||||
|
||||
$document = (new Parser())->parse($content);
|
||||
$problems = [];
|
||||
if (Serializer::document($document) !== $content) {
|
||||
$problems[] = 'Parser und Serializer geben den Referenzinhalt nicht byte-gleich zurück.';
|
||||
}
|
||||
$wordPress = ($this->wpBlocks ?? static fn (string $markup): array => parse_blocks($markup))($content);
|
||||
if (self::structure($document->children()) !== self::wpStructure($wordPress)) {
|
||||
$problems[] = 'WordPress liest eine andere Blockstruktur als LIT MCP.';
|
||||
}
|
||||
|
||||
return $problems;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<Block> $blocks
|
||||
* @return list<array{0: string, 1: list<mixed>}>
|
||||
*/
|
||||
private static function structure(array $blocks): array
|
||||
{
|
||||
return array_map(
|
||||
static fn (Block $block): array => [$block->name(), self::structure($block->children())],
|
||||
$blocks
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, mixed> $blocks parse_blocks() result; freeform parts (blockName null) are left out.
|
||||
* @return list<array{0: string, 1: list<mixed>}>
|
||||
*/
|
||||
private static function wpStructure(array $blocks): array
|
||||
{
|
||||
$structure = [];
|
||||
foreach ($blocks as $block) {
|
||||
if (is_array($block) && is_string($block['blockName'] ?? null)) {
|
||||
$inner = is_array($block['innerBlocks'] ?? null) ? $block['innerBlocks'] : [];
|
||||
$structure[] = [$block['blockName'], self::wpStructure($inner)];
|
||||
}
|
||||
}
|
||||
|
||||
return $structure;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user