* php ../../v2-platform/tools/conformance-check/check.php * * Prüft Spec-Konformität (siehe v2-modules/_spec/delivery-format.md § Konformitäts-Check). * Schreibt tests/conformance-report.json + farbige Console-Ausgabe. * * Exit-Code: 0 = LIEFERBEREIT, 1 = Fehler vorhanden. * * PHASE 1 (heute): PHP-Checks (Manifest, Files, i18n, Migrations, admin-fields, CSS-Hex) * PHASE 2 (später): Browser-Checks (axe-core, Telemetry-Events, Keyboard) via Playwright/Headless */ declare(strict_types=1); require_once __DIR__ . '/lib/report.php'; require_once __DIR__ . '/lib/check-manifest.php'; require_once __DIR__ . '/lib/check-files.php'; require_once __DIR__ . '/lib/check-i18n.php'; require_once __DIR__ . '/lib/check-migrations.php'; require_once __DIR__ . '/lib/check-admin-fields.php'; require_once __DIR__ . '/lib/check-css.php'; require_once __DIR__ . '/lib/check-shared-assets.php'; // === Argumente / Modul-Pfad === $moduleDir = realpath(getcwd()); if (!$moduleDir) { fwrite(STDERR, "Fehler: aktuelles Verzeichnis nicht auflösbar.\n"); exit(1); } // Manifest muss vorhanden sein, sonst Abbruch $manifestPath = "$moduleDir/manifest.json"; if (!file_exists($manifestPath)) { fwrite(STDERR, "Fehler: manifest.json nicht gefunden in $moduleDir\n"); fwrite(STDERR, "Bist du im richtigen Modul-Ordner? Aufruf:\n"); fwrite(STDERR, " cd v2-modules/ && php ../../v2-platform/tools/conformance-check/check.php\n"); exit(1); } $manifestRaw = file_get_contents($manifestPath); $manifest = json_decode($manifestRaw, true); if (!is_array($manifest)) { fwrite(STDERR, "Fehler: manifest.json ist kein valides JSON.\n"); exit(1); } $slug = $manifest['slug'] ?? '(unbekannt)'; $version = $manifest['version'] ?? '(unbekannt)'; $report = new Report($slug, $version); $report->info("=== GeoGraSim V2-Konformitäts-Check ==="); $report->info("Modul: $slug @ $version"); $report->info("Pfad: $moduleDir"); $report->info("Spec: " . ($manifest['specVersion'] ?? '?')); $report->info(""); // === Checks ausführen === $checks = [ ['Manifest-Schema', fn() => check_manifest($manifest, $report)], ['Pflicht-Files', fn() => check_files($moduleDir, $manifest, $report)], ['i18n (Standard+Easy)', fn() => check_i18n($moduleDir, $manifest, $report)], ['DB-Migrations', fn() => check_migrations($moduleDir, $manifest, $report)], ['admin-fields.json', fn() => check_admin_fields($moduleDir, $manifest, $report)], ['CSS-Hex-Hardcodes', fn() => check_css($moduleDir, $slug, $report)], ['Shared-Assets-Pool', fn() => check_shared_assets($moduleDir, $manifest, $report)], ]; foreach ($checks as [$name, $fn]) { $report->info("--- $name ---"); try { $fn(); } catch (Throwable $e) { $report->fail("Check '$name' crashed: " . $e->getMessage()); } $report->info(""); } // === Phase-2-Hinweis (Browser-Checks) === $report->info("--- Phase-2-Checks (heute übersprungen) ---"); $report->note("axe-core A11y-Audit: braucht Playwright/Headless-Chrome"); $report->note("Telemetry-Event-Test (5+ Heartbeats, alle Milestones, 1 Result): manuell mit tests/mock-platform.html prüfen"); $report->note("Keyboard-Navigation-Test: manuell prüfen (Tab durchschalten, Enter aktiviert, Esc schließt)"); $report->note("High-Contrast / Reduced-Motion-Render: manuell prüfen"); $report->info(""); // === Report schreiben + Exit === $report->info("=== Zusammenfassung ==="); $summary = $report->summary(); $report->info("✓ Passed: {$summary['passed']}"); $report->info("✗ Failed: {$summary['failed']}"); $report->info("⚠ Warning: {$summary['warning']}"); // JSON-Report $reportDir = "$moduleDir/tests"; if (!is_dir($reportDir)) @mkdir($reportDir, 0775, true); $reportPath = "$reportDir/conformance-report.json"; file_put_contents($reportPath, json_encode($report->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); $report->info(""); $report->info("Report geschrieben: $reportPath"); if ($summary['failed'] > 0) { $report->info(""); $report->error("STATUS: NICHT LIEFERBEREIT — bitte Fehler oben beheben."); exit(1); } $report->info(""); $report->ok("STATUS: LIEFERBEREIT (Phase-1-Checks). Browser-Checks Phase 2 noch manuell."); exit(0);