bffca85399
Канон знал 82 таблицы и 995 столбцов, а база — 121 и 1470: не описаны были рекламный модуль, телеграм-рассылки и весь отдел продаж. Главное, что выяснилось по дороге: db/schema.sql не документ, а исполняемый файл — миграция 0001_01_01_000000_load_initial_schema заливает его целиком первым шагом сборки. Перенести туда DDL модулей нельзя: те же таблицы создают дельта-миграции, их 77 и 49 из них без стражей. Сборка с нуля падала дважды. Поэтому канон разбит на два файла: schema.sql исполняется, новый schema_modules.sql только описывает. Проверено не глазами: - сборка с нуля 148 из 148 DONE; - столбцы 1470 против 1470, ноль расхождений по имени, типу, длине и NULL; - все четыре счётчика расхождений инструмента — ноль; - schema.sql отдельно исполняется без единой ошибки, ограничения 495=495, политики 64=64; - статанализ 0. Инструмент сверки усилен: считал только одну сторону и потому не видел переименования jivo_chat_id в chat_id — старое имя жило в каноне месяц. Теперь обе стороны, канон из нескольких файлов, понимание RENAME/DROP COLUMN и DROP TABLE. Починен разбор переносов строки внутри определения столбца. Сторож SchemaDeltaTest дополнен: файл модулей обязан быть на месте и описывать 39 таблиц, а тело schema.sql их не содержать. Принят вырезанием. Найдено и НЕ исправлено, нужно решение владельца: задвоенный указатель на deals и пять политик без NULLIF в миграциях. Оба помечены в тексте канона. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
47 lines
2.9 KiB
PHP
47 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
/**
|
|
* Сторож против пересборки тестовой БД ПОСРЕДИ прогона.
|
|
*
|
|
* Laravel заворачивает каждый тест в «черновую» транзакцию, а в конце проверяет, что
|
|
* соединение в ней осталось. Если тест черновик закрыл сам, Laravel сбрасывает свой
|
|
* признак «БД собрана» (RefreshDatabase.php, строки 158-160) и следующий тест
|
|
* пересобирает базу целиком — посреди прогона, снося её под всеми остальными. Отсюда
|
|
* и «прогон рвётся через раз», и «таблица X не существует» за сотни шагов от причины.
|
|
*
|
|
* Tests\TestCase взводит признак на каждом тесте, поэтому пересборки не происходит.
|
|
*
|
|
* ПРИЁМКА ВЫРЕЗАНИЕМ: убрать строку `RefreshDatabaseState::$migrated = true;` из
|
|
* TestCase::setUpTraits() — второй тест этого файла обязан УПАСТЬ (метки не будет,
|
|
* потому что базу пересоберут между тестами). Вернуть строку — снова зелёный.
|
|
*/
|
|
it('ловушка: тест закрывает черновую транзакцию и оставляет метку в БД', function () {
|
|
// Именно так ведёт себя боевой код со своими DB::transaction/SET LOCAL —
|
|
// здесь мы воспроизводим это нарочно и в чистом виде.
|
|
DB::commit();
|
|
|
|
DB::statement('DROP TABLE IF EXISTS proverka_peresborki');
|
|
DB::statement('CREATE TABLE proverka_peresborki (x int)');
|
|
|
|
expect(Schema::hasTable('proverka_peresborki'))->toBeTrue();
|
|
});
|
|
|
|
it('метка на месте — значит пересборки посреди прогона не было', function () {
|
|
expect(Schema::hasTable('proverka_peresborki'))->toBeTrue();
|
|
|
|
// Снимаем метку НАСОВСЕМ. Без этого DROP уезжает в черновую транзакцию, откат
|
|
// её возвращает — и метка остаётся в базе после всего прогона: сторож чистоты
|
|
// (tools/storozh-chistoty-bazy.mjs) видел ровно эту одну лишнюю таблицу.
|
|
// Приём тот же, что в первом тесте: сначала закрыть черновик, потом писать.
|
|
DB::commit();
|
|
DB::statement('DROP TABLE IF EXISTS proverka_peresborki');
|
|
});
|