Files
houseplan-card/docs/reviews/CODE-REVIEW-211-r2.md
T
2026-08-19 22:05:42 +00:00

11 KiB
Raw Blame History

CODE-REVIEW-211-r2 — коррекция compatibility-смока после полного Linux CI

  • Issue: https://github.com/Matysh/houseplan-card/issues/211
  • ТЗ: docs/specs/211-device-icons-visual-parity.md (принято SPEC-REVIEW-211-r2, зелёный)
  • Предыдущий цикл: docs/reviews/CODE-REVIEW-211-r1.md — зелёный, реализация (4e82976, 270cf63) уже слита в dev до того, как полный Linux smoke вскрыл устаревшую проверку; поэтому временный S8-merged был гонкой двух событий, а не итоговым статусом (см. комментарии владельца в issue).
  • Диапазон этого цикла: origin/dev..HEAD = один коммит 4d1b62b — test: align locked marker smoke with design package · Issue: #211 · User-Visible: no
  • Цикл: r2/4

Скоуп проверки

Весь диапазон git diff origin/dev...HEAD — это 11 строк в одном файле, demo/smoke_cover_no_plate.mjs (7 добавлено, 4 удалено). Ничего в src/**, custom_components/**, конфиге, i18n или changelog не тронуто — класс B (гейт/тест), трейлер User-Visible: no соответствует. Изменение правит один устаревший compatibility-факт (lockedLockIsNeutral → lockedLockKeepsPackageFace) внутри смока, который сам по себе не входит в диапазон реализации #211, но проверяет побочный контракт («у замка есть рамка, замок не становится нейтральным»), задетый переходом на дизайн-пакет #179/#211.

Продуктовый код в этом цикле не проверяется повторно — он уже был предметом CODE-REVIEW-211-r1 (зелёный) и в этом диапазоне не менялся.

Как проверялось

Гейты — прогнаны

npx tsc --noEmit                                            → чисто
npm test                                                     → 939 pass, 0 fail, 0 skipped
npm run build                                                → OK
cmp dist/houseplan-card.js custom_components/.../houseplan-card.js → идентичны
cmp dist/houseplan-card.js demo/srv/assets/houseplan-card.js        → идентичны
node demo/smoke_cover_no_plate.mjs                            → все факты true, OK
node demo/smoke_device_icon_design.mjs                        → все факты true, OK (доп. проверка
    основного AC3-смока лежащей рядом поверхности; продукт не менялся с r1, но
    это самый дешёвый способ убедиться, что коррекция теста не разошлась с
    уже принятым CSS)

Проверка «тест умеет падать» (обязательная дисциплина, применена к

единственному изменённому предикату)

Правило .dev.lock-locked в src/styles.ts вернул временно к состоянию до основного фикса 4e82976 (background: var(--device-core-bg); color: #000, без theme-light/theme-dark расщепления — то есть ровно то поведение, которое проверял старый lockedLockIsNeutral), пересобрал dist и синхронизировал demo/srv/assets/houseplan-card.js (демо-сервер отдаёт именно эту копию, не dist/ напрямую — без этого шага мутация не была бы видна смоку). Результат:

"lockedLockKeepsPackageFace": false
FAILED (1): lockedLockKeepsPackageFace: expected true, got false

Все остальные факты смока остались зелёными — падение точечное, как и должно быть для правки одного предиката. После проверки src/styles.ts восстановлен из копии, npm run build прогнан повторно, dist синхронизирован обратно в demo/srv/assets и в custom_components/houseplan/frontend; git status — чистое дерево, диффа не осталось.

Дополнительно проверено чтением: новые ожидаемые значения (rgb(0, 0, 0)/rgb(255, 255, 255) для Light, rgb(37, 37, 37)/ rgb(255, 255, 255) для Dark) — это буквальный computed-style результат правил .dev.lock-locked, .dev.theme-light.lock-locked, .dev.theme-dark.lock-locked (src/styles.ts:2035-2048), которые сами уже были зафиксированы и приняты в CODE-REVIEW-211-r1 как соответствующие §7.3 ТЗ (Lock Light: core black / glyph white, Lock Dark: core #252525 / glyph white). --device-face-bg/--device-face-fg транслируются в background/color .device-core напрямую (src/styles.ts:1988-1989), так что тест меряет ровно то, что видит пользователь, а не побочный токен.

Оценка ветвления по теме в самом тесте

Смок не переключает hass.themes.darkMode, а демо-фикстура (demo/srv/demo.html) не задаёт его вовсе, поэтому device-face.ts:24 (hass.themes.darkMode ? 'theme-dark' : 'theme-light') в этом прогоне детерминированно даёт theme-light — веткой rgb(37, 37, 37) тест здесь фактически не исполняется. Это не дефект: тёмная ветка того же контракта (darkLockUsesWhiteGlyphAndDarkShell) уже отдельно и явно проверяется вычисляемым фактом в demo/smoke_device_icon_design.mjs и была подтверждена в r1 независимым before/after прогоном. Тернарное выражение здесь написано корректно и симметрично на случай, если смок когда-нибудь начнёт переключать тему, но не создаёт для этого дублирующего покрытия — фиксирую как наблюдение, не как находку.

Коммит и трейлеры

4d1b62b: Issue: #211, User-Visible: no — верно, диапазон не содержит изменений продукта, изменений в changelog не требуется.

Что проверено и корректно

  • Правка ограничена одним файлом гейта (demo/smoke_cover_no_plate.mjs), относится к предмету #211 (AC3, Lock state parity) и устраняет расхождение между устаревшим pre-#179 предположением теста («заблокированный замок — нейтральный, глиф всегда чёрный») и принятым дизайн-пакетом («core черный/ #252525, глиф всегда белый»).
  • Новый предикат lockedLockKeepsPackageFace измеряет именно тот CSS, который производит видимый пиксель (background/color на .device-core через --device-face-bg/--device-face-fg), не побочный токен.
  • Предикат доказанно умеет падать: воспроизведена красная линия на до-фиксовом правиле, падение точечное (1 из ~60 фактов файла), после восстановления кода все факты снова зелёные.
  • Остальные факты того же файла (cover plate/morph/valve/window/unlocked-lock) не задеты диапазоном и остались зелёными — регрессии в соседних, не относящихся к #211 проверках нет.
  • tsc, unit-suite и build чистые; три копии бандла идентичны после восстановления дерева.
  • Коммит несёт корректный Issue:/User-Visible: трейлер для class B.

Находки

Нет находок уровня High, Medium или Low. Единственное отмеченное выше наблюдение (тернарная dark-ветка предиката не исполняется в этом конкретном прогоне) не поднимаю как находку: поведение для Dark уже покрыто отдельным, явно исполняемым фактом в другом смоке, а сам тернар написан правильно и не вводит риск регрессии.

Чего не проверял и почему

  • Полный набор из 127 browser smokes — не запускал; диапазон правит один предикат в одном уже существующем файле, не относящийся к нему smoke не может быть задет текстовой правкой ассерта.
  • npm run golden:verify — не запускал; диапазон не меняет ни один файл, влияющий на рендер (только тестовый ассерт), видимый результат не может измениться.
  • python -m pytest tests_backend -q — не запускал; custom_components/**/*.py не тронут.
  • Performance-профили — не запускал; диапазон не касается DOM/CSS/JS продукта.
  • Полный Linux CI-прогон — не запускал локально; это гейт CI на выходе из код-ревью, а не задача рецензента. (Именно такой прогон и обнаружил устаревший факт, который правит этот коммит — второй такой же прогон на этом SHA пройдёт штатно через пайплайн после зелёного вердикта.)

Вердикт

Единственное изменение цикла — точечная и доказанная (падает на старом поведении, зелёное на новом) коррекция стороннего compatibility-теста, приводящая его в соответствие с уже принятым в r1 дизайн-контрактом #211/#179. Продуктовый код не менялся, регрессий нет, трейлеры корректны.

Зелёный.