# -*- coding: utf-8 -*- """PLAN 199-1 — B08 표 칸 최대 높이 = 브라우저 창 아래 끝까지. Node 헬퍼(`helper_ui_fill_viewport.cjs`)가 `ui_template_data_table.ts` 의 창 끝까지 셈을 가짜 DOM 에서 돌리고, 여기서 옵션 · 셈 · 창 크기 바뀜 · 합계 줄 고정 · B08 적용을 판정함. """ import json import os import re import subprocess import pytest HERE = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.normpath(os.path.join(HERE, "..", "..")) def _read(*parts: str) -> str: with open(os.path.join(ROOT, *parts), encoding="utf-8") as f: return f.read() @pytest.fixture(scope="module") def r(): proc = subprocess.run( ["node", os.path.join(HERE, "helper_ui_fill_viewport.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=60, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_최대_높이_창_기준_셈(r): assert r["clamp"] == 900 - 200 - 68 assert r["small"] == 120 # 아주 작은 창에서도 머리 + 몇 줄은 남김 assert r["below"] == r["belowExpected"] == 80 # 뒤 형제 + 윗대 아래 여백 def test_붙은_뒤에_셈(r): assert r["beforeAttach"] is None # 문서에 붙기 전엔 안 건드림 assert r["observed"] # 칸 + 문서 본문(body) 둘 다 관찰 assert r["first"] == f"{900 - 200 - 80}px" # 620 assert r["fits"] >= 1 def test_창_크기_바뀌면_다시_셈(r): assert r["afterResize"] == f"{600 - 200 - 80}px" # 320 def test_스크롤_위치와_무관(r): assert r["afterScroll"] == r["afterResize"] def test_아래_요소가_늘면_그만큼_줄어듦(r): assert r["afterNoteGrow"] == f"{600 - 200 - 140}px" # 260 def test_칸이_떨어지면_창_청취_해제(r): assert r["listenersAfterDetach"] == 0 def test_공용_표_옵션과_연결(): ts = _read("ui_template", "ui_template_data_table.ts") assert re.search(r"fillViewport\?: boolean", ts) assert re.search(r"if \(opts\.fillViewport\) fillViewport\(root, \(\) => draw\(false\)\)", ts) def test_합계_줄_고정_그대로(): css = _read("ui_template", "ui_template_data_table.css") assert re.search(r"tfoot[^{]*\{[^}]*position:\s*sticky[^}]*bottom:\s*0", css, re.S) assert "max-height: calc(100dvh - 260px)" in css # 옵션 안 준 표의 기본값은 그대로 @pytest.mark.parametrize( "name, count", [ ("B08_Quantity_UI_Summary.ts", 1), ("B08_Quantity_UI_Earthwork.ts", 1), ("B08_Quantity_UI_Earthwork_Sheets.ts", 2), ("B08_Quantity_UI_Material.ts", 1), ], ) def test_B08_표_모두_적용(name, count): src = _read("B08_Quantity", name) assert src.count("fillViewport: true") == count == src.count("createDataTable({")