Quelltext des aktuellen Standes
<?php
declare(strict_types=1);
/**
* Deckt ab, dass die Netzwerkplan-Spalten jede Instanz erreichen.
*
* `001_initial_schema.sql` gilt einer bestehenden Instanz als angewendet und
* läuft dort nie erneut. Eine Spalte, die ausschließlich dort angelegt wird,
* entsteht deshalb nur auf Neuinstallationen – auf allen übrigen fehlt sie
* dauerhaft, und jeder Zugriff darauf endet im internen Fehler. Nachgezogen
* wird so etwas über eine eigene, höher nummerierte Migration.
*/
return static function (): void {
$migrationsDir = __DIR__ . '/../database/migrations';
/** Inhalt aller Migrationen außer der Baseline. */
$ausserhalbBaseline = static function () use ($migrationsDir): string {
$text = '';
foreach ((array)glob($migrationsDir . '/*.sql') as $datei) {
if (str_starts_with(basename((string)$datei), '001_')) {
continue;
}
$text .= (string)file_get_contents((string)$datei);
}
return $text;
};
$spalten = ['drawio_xml', 'diagram_format', 'preview_svg'];
test('Die Netzwerkplan-Spalten werden ausserhalb der Baseline nachgezogen', function () use ($spalten, $ausserhalbBaseline) {
$text = $ausserhalbBaseline();
foreach ($spalten as $spalte) {
assertTrue(
preg_match('/ADD COLUMN\s+`?' . preg_quote($spalte, '/') . '`?/i', $text) === 1,
'Die Spalte "' . $spalte . '" entsteht nur in der Baseline und erreicht damit keine bestehende Instanz'
);
}
});
test('Jede Spalte steht in einer eigenen Anweisung', function () use ($migrationsDir) {
// Fasst eine Anweisung mehrere Spalten zusammen, verhindert eine
// bereits vorhandene Spalte das Anlegen der übrigen: der Duplicate-
// Fehler lässt die gesamte Anweisung scheitern.
$datei = $migrationsDir . '/244_netdiagram_drawio_columns.sql';
assertTrue(is_file($datei), 'Die nachziehende Migration fehlt');
$sql = (string)file_get_contents($datei);
foreach (explode("\n", $sql) as $zeile) {
$zeile = trim($zeile);
if (!str_starts_with(strtoupper($zeile), 'ALTER TABLE')) {
continue;
}
assertSame(1, substr_count(strtoupper($zeile), 'ADD COLUMN'),
'Diese Anweisung legt mehr als eine Spalte an: ' . $zeile);
}
});
test('Die Migration bleibt bei wiederholtem Lauf harmlos', function () use ($migrationsDir) {
$sql = strtoupper((string)file_get_contents($migrationsDir . '/244_netdiagram_drawio_columns.sql'));
// Ein zweiter Lauf darf keine Daten anfassen.
foreach (['TRUNCATE', 'DROP TABLE', 'DELETE FROM', 'AUTO_INCREMENT ='] as $verboten) {
assertFalse(str_contains($sql, $verboten), 'Die Migration enthält "' . $verboten . '"');
}
});
test('Code und Schema nennen dieselben Spalten', function () use ($spalten, $migrationsDir) {
$controller = (string)file_get_contents(__DIR__ . '/../src/Controllers/NetworkDiagramController.php');
$schema = '';
foreach ((array)glob($migrationsDir . '/*.sql') as $datei) {
$schema .= (string)file_get_contents((string)$datei);
}
foreach ($spalten as $spalte) {
assertTrue(str_contains($controller, $spalte), 'Der Controller nutzt "' . $spalte . '" nicht mehr');
assertTrue(str_contains($schema, '`' . $spalte . '`'), 'Die Spalte "' . $spalte . '" fehlt im Schema');
}
});
};