mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Шаг 0 эпика #591. Видимых изменений нет — это подготовка: оба ядра стояли в трёх строках от жёсткого потолка, а разметка диалогов была крупнейшей перемещаемой частью редакторского рантайма. Перенос механический и проверяемый. Тела всех четырёх методов уехали побайтово: тип `this` объявлен параметром функции, поэтому ни одна строка разметки, ни один обработчик и ни один якорь мутанта не переписаны, а в классе остались однострочные делегаты. Сверка при подготовке коммита: 43 617, 16 795, 10 590 и 6 719 символов совпали посимвольно с оригиналом. src/editors/marker-dialog.ts диалог устройства на плане src/editors/space-settings-dialog.ts диалог пространства src/editors/general-settings-dialog.ts общие настройки src/editors/room-settings-dialog.ts настройки комнаты Имена файлов пространства и комнаты уточнены против ТЗ: рядом уже живёт `src/space-dialog.ts` с логикой того же диалога, и два `space-dialog.ts` в одном дереве путали бы обоих — и человека, и grep. Попутно из рантайма уехали два словаря ярлыков режима отображения (их единственный потребитель — диалог устройства) и границы шага сетки: последние теперь объявлены в модуле, который рисует поле, а кламп записи импортирует их оттуда. Направление импорта то же, что у самой функции рисования, цикла нет. `_radarSetup` стал публичным: диалог устройства обращается к контроллеру из своего модуля, а остальной класс и так живёт на `public _x`. Потолок ядра опущен 14100 → 12810 — ровно на 1290 вынесенных строк, запас над фактом прежний. Незафиксированный выигрыш ядро отыграло бы первой же правкой. Сборщик логического исходника для контрактных тестов (`test/houseplan-source.mjs`) научен подставлять тело вынесенной функции вместо делегата: шесть тестов, читающих разметку, продолжают видеть ровно то же, что и до переноса, — иначе их пришлось бы переучивать на новые пути в тот самый момент, когда они должны доказать, что перенос ничего не изменил. Issue: #592 User-Visible: no
55 lines
2.9 KiB
JavaScript
55 lines
2.9 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { readFileSync } from 'node:fs';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
/**
|
|
* Граница вынесенных диалогов (#592).
|
|
*
|
|
* Разметка четырёх диалогов настроек уехала из ядра редактора в отдельные
|
|
* модули, и ценность этого шага держится ровно на одном: модуль **рисует**, а
|
|
* состояние остаётся на хосте. Стоит одному черновику переехать в модуль — и
|
|
* следующий шаг эпика #591 будет переписывать не разметку, а владение
|
|
* состоянием, то есть окажется совсем другой задачей, чем заявлено.
|
|
*
|
|
* Тест смотрит на исходники, а не на поведение, потому что нарушение здесь
|
|
* невидимо в рантайме: диалог продолжит работать и с собственным состоянием —
|
|
* ровно до первого второго потребителя.
|
|
*/
|
|
|
|
const ROOT = fileURLToPath(new URL('../', import.meta.url));
|
|
const MODULES = [
|
|
'src/editors/marker-dialog.ts',
|
|
'src/editors/space-settings-dialog.ts',
|
|
'src/editors/general-settings-dialog.ts',
|
|
'src/editors/room-settings-dialog.ts',
|
|
];
|
|
const DRAFTS = ['_markerDialog', '_spaceDialog', '_settingsDialog', '_roomDialog'];
|
|
|
|
const source = (file) => readFileSync(new URL(file, new URL(ROOT, 'file:')), 'utf8');
|
|
|
|
test('#592 вынесенные диалоги не заводят собственного состояния', () => {
|
|
for (const file of MODULES) {
|
|
const text = source(file);
|
|
assert.ok(!/@state\(/.test(text), `${file}: реактивное состояние в модуле разметки`);
|
|
assert.ok(!/\bclass\s+[A-Za-z]/.test(text), `${file}: модуль разметки завёл класс`);
|
|
for (const draft of DRAFTS) {
|
|
const own = new RegExp(`(let|const|var)\\s+${draft}\\b|^\\s*${draft}\\s*[:=]`, 'm');
|
|
assert.ok(!own.test(text), `${file}: черновик ${draft} объявлен в модуле, а не на хосте`);
|
|
}
|
|
}
|
|
});
|
|
|
|
test('#592 диалоги остаются в ленивом редакторском графе', () => {
|
|
const runtime = source('src/houseplan-editor-runtime.ts');
|
|
for (const file of MODULES) {
|
|
const name = file.replace('src/', './').replace('.ts', '');
|
|
assert.ok(runtime.includes(`from '${name}'`), `${file}: не импортирован редакторским рантаймом`);
|
|
}
|
|
const card = source('src/houseplan-card.ts');
|
|
for (const file of MODULES) {
|
|
const name = file.replace('src/', './').replace('.ts', '');
|
|
assert.ok(!card.includes(name), `${file}: попал в синхронный граф карточки`);
|
|
}
|
|
});
|