zapretgui/tests/test_updater_install_runtime_architecture.py
loop-uh 6360b4fb99
All checks were successful
Zapret source guards / validate (push) Successful in 10s
Windows-сборка / Dev Dev 21.1.7.71 опубликован
Закрытие программы: прощальный экран с медоедом и лёгкой строкой, окно плавно гаснет
После «Закрыть только GUI» окно просто пропадало, а после «Закрыть и
остановить DPI» стояло как было, пока останавливался обход; уборка при
выходе шла при видимом окне, и оно на это время замирало.

Теперь между командой и исчезновением окна поверх него проступает экран
(ui/exit_screen.py): медоед, заголовок, который прямо говорит, что происходит
(«Окно закрывается», «Останавливаем обход», «Обход остановлен»), и лёгкая
строка под ним. Строка берётся из общего набора шуток ui/fun_phrases (блоки
exit_keep, exit_idle, exit_stopping, exit_stopped); пока блока нет —
простая запасная фраза. Затем прозрачность окна плавно уходит в ноль, и
только после этого программа закрывается: уборка идёт при невидимом окне.

Экран показывает единственный владелец выхода — ApplicationLifecycle, через
window_port.begin_exit_screen. Это украшение, а не шаг выхода: если окна нет
на экране или экран не удалось показать, программа закрывается сразу; если
остановка обхода не сообщила о себе за 20 секунд, экран убирается. Выход
ради установки обновления (farewell=False) и завершение сеанса Windows идут
без экрана.

Проверено на настоящей сборке на win10 (нажатие кнопок окна «Закрыть
приложение» через средства доступности): окно отвечает всё время показа
(самая долгая заминка 42 мс), прозрачность уходит 255 → 0 без скачка, окно
исчезает сразу после.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 02:25:03 +03:00

29 lines
1.2 KiB
Python

from __future__ import annotations
"""Устройство установки: страница только показывает, работой владеют сервисы."""
import inspect
import unittest
from updater.download import service as install_service
from updater.ui import page
class UpdaterInstallArchitectureTest(unittest.TestCase):
def test_page_owns_no_download_dpi_or_installer_work(self) -> None:
source = inspect.getsource(page)
for forbidden in ("shutdown_sync", "restart(", "start_supervised_installation", "download_artifact", "QThread"):
self.assertNotIn(forbidden, source)
def test_installer_success_requests_exit_on_main_thread(self) -> None:
source = inspect.getsource(install_service.UpdateInstallService._on_task_done)
self.assertIn("QTimer.singleShot", source)
# Без прощального экрана: программа закрывается не по команде человека.
self.assertIn("request_exit(stop_dpi=False, farewell=False)", source)
self.assertNotIn("os._exit", inspect.getsource(install_service))
if __name__ == "__main__":
unittest.main()