"""자막 배경 상자(padding)와 위치 조정 모드.""" from __future__ import annotations import os import pytest pytest.importorskip("PySide6") os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") from PySide6.QtCore import QPoint, QRect # noqa: E402 from PySide6.QtWidgets import QApplication # noqa: E402 from livesub.config import OverlayConfig, SubtitleStyle # noqa: E402 from livesub.ui.overlay import SubtitleOverlay, _content_box # noqa: E402 WINDOW = QRect(0, 0, 1000, 400) @pytest.fixture(scope="session") def qapp(): app = QApplication.instance() or QApplication([]) yield app # --- 배경 상자 ------------------------------------------------------------- def test_배경은_글자를_감싼다(): """창 전체가 아니라 글자 크기에 맞춰야 여백이 곧 배경 크기가 된다.""" box = _content_box(WINDOW, text_w=300, text_h=60, pad=18, align="center") assert box.width() == 300 + 18 * 2 assert box.height() == 60 + 18 * 2 assert box.width() < WINDOW.width() def test_여백을_키우면_배경이_커진다(): small = _content_box(WINDOW, 300, 60, pad=8, align="center") large = _content_box(WINDOW, 300, 60, pad=40, align="center") assert large.width() - small.width() == (40 - 8) * 2 assert large.height() - small.height() == (40 - 8) * 2 def test_배경은_창_밖으로_넘지_않는다(): box = _content_box(WINDOW, text_w=5000, text_h=5000, pad=40, align="center") assert box.width() == WINDOW.width() assert box.height() == WINDOW.height() @pytest.mark.parametrize( ("align", "expected_left"), [("left", 0), ("center", (1000 - 336) // 2), ("right", 1000 - 336)], ) def test_정렬에_따라_상자가_붙는_쪽이_달라진다(align, expected_left): box = _content_box(WINDOW, text_w=300, text_h=60, pad=18, align=align) assert box.width() == 336 assert abs(box.x() - expected_left) <= 1 def test_기본_여백이_설정에_있다(): assert SubtitleStyle().padding > 0 # --- 위치 조정 모드 -------------------------------------------------------- @pytest.fixture def overlay(qapp): cfg = OverlayConfig() cfg.visible = False widget = SubtitleOverlay(SubtitleStyle(), cfg) yield widget widget.close() def test_기본은_잠겨_있어_움직이지_않는다(overlay): """게임 중에 자막을 실수로 끌고 다니는 사고를 막는 기본값이다.""" assert OverlayConfig().locked is True assert overlay.edit_mode is False assert overlay._interactive is False def test_위치_조정을_켜면_잡을_수_있다(overlay): overlay.set_edit_mode(True) assert overlay.edit_mode is True assert overlay._interactive is True # 클릭 통과가 켜져 있으면 마우스가 창을 그냥 지나가 잡을 수가 없다. from PySide6.QtCore import Qt assert not overlay.testAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents) overlay.set_edit_mode(False) assert overlay._interactive is False def test_모서리를_집었는지_알아본다(overlay): overlay.setGeometry(0, 0, 600, 200) assert overlay._corner_at(QPoint(2, 2)) == "topleft" assert overlay._corner_at(QPoint(598, 2)) == "topright" assert overlay._corner_at(QPoint(2, 198)) == "bottomleft" assert overlay._corner_at(QPoint(598, 198)) == "bottomright" # 가운데는 이동용이지 크기 조절이 아니다 assert overlay._corner_at(QPoint(300, 100)) == "" def test_크기를_키우면_글자도_같이_커진다(overlay): overlay.set_edit_mode(True) overlay.setGeometry(100, 100, 600, 200) overlay.style_cfg.font_size = 40 overlay._resize_corner = "bottomright" overlay._resize_geo = QRect(overlay.geometry()) overlay._resize_mouse = QPoint(700, 300) overlay._resize_font = 40 overlay._resize_to(QPoint(700, 500)) # 높이 200 -> 400 assert overlay.height() == 400 assert overlay.style_cfg.font_size == 80 def test_반대쪽_모서리는_제자리에_있는다(overlay): """왼쪽 위를 끌면 오른쪽 아래는 움직이지 않아야 한다.""" overlay.set_edit_mode(True) overlay.setGeometry(200, 200, 600, 200) start = QRect(overlay.geometry()) overlay._resize_corner = "topleft" overlay._resize_geo = start overlay._resize_mouse = QPoint(200, 200) overlay._resize_font = overlay.style_cfg.font_size overlay._resize_to(QPoint(300, 250)) assert overlay.geometry().right() == start.right() assert overlay.geometry().bottom() == start.bottom() assert overlay.geometry().x() == 300 def test_최소_크기_아래로는_줄지_않는다(overlay): overlay.set_edit_mode(True) overlay.setGeometry(0, 0, 600, 200) overlay._resize_corner = "bottomright" overlay._resize_geo = QRect(overlay.geometry()) overlay._resize_mouse = QPoint(600, 200) overlay._resize_font = overlay.style_cfg.font_size overlay._resize_to(QPoint(-5000, -5000)) assert overlay.width() >= overlay.minimumWidth() assert overlay.height() >= overlay.minimumHeight()