- createDataTable — 묶음 머리 여러 줄 · 머리 · 앞 열 · 합계 줄 고정 스크롤 - 숫자 오른쪽 맞춤 · 고정폭 숫자 · 천 단위 쉼표 · 열마다 소수 자리 · 빈 값 「—」 - 줄 번갈아 색 · 올린 줄 강조 · 테마 토큰만 · 보이는 줄 근처만 그림(1,000줄 64~118ms) - 견본(머리 3줄 · 30열 · 66줄 · 합계) 시험 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
88 lines
3.0 KiB
Python
88 lines
3.0 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""공용 표 양식(PLAN 70-1) 회귀검증 — 묶음 머리 · 고정 열 · 숫자 꼴 · 빈 값 · 합계 · 1,000줄.
|
||
|
||
Node 헬퍼(`helper_ui_data_table.cjs`)가 `ui_template/ui_template_data_table.ts` 를 트랜스파일해
|
||
견본(`fixture_data_table_sample.js` · 머리 3줄 · 30열 · 66줄)으로 HTML 을 만들고, 여기서 판정함.
|
||
"""
|
||
|
||
import json
|
||
import os
|
||
import subprocess
|
||
|
||
import pytest
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
|
||
|
||
@pytest.fixture(scope="module")
|
||
def r():
|
||
proc = subprocess.run(
|
||
["node", os.path.join(HERE, "helper_ui_data_table.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["cols"] == 30
|
||
assert r["headRows"] == 3
|
||
assert r["bodyRows"] == 66
|
||
|
||
|
||
def test_묶음_머리_합침(r):
|
||
first = r["firstHeadRow"]
|
||
# 측점 · 거리 · 유용토 등 묶음 없는 열은 머리 3줄을 세로로 차지
|
||
assert 'rowspan="3" class="is-frozen is-edge" style="left:0px" title="측점">측점</th>' in first
|
||
assert first.count('rowspan="3"') == 5 # 측점 거리 유용토 차인토량 누가토량
|
||
assert 'colspan="13">절토</th>' in first # 토사 · 연암 · 측구파기 토사 · 암 각 3 + 보정량계
|
||
assert 'colspan="4">면고르기</th>' in first
|
||
assert 'colspan="2">노면정리</th>' in first
|
||
second = r["secondHeadRow"]
|
||
assert 'colspan="3">토사</th>' in second and 'colspan="3">연암</th>' in second
|
||
assert 'rowspan="2" data-num="" title="보정량계"' in second # 한 단 묶음은 머리 2줄
|
||
|
||
|
||
def test_고정_열과_숫자_칸(r):
|
||
row = r["firstBodyRow"]
|
||
assert row.startswith('<tr><td class="is-frozen is-edge" style="left:0px">120</td>')
|
||
assert r["frozenCells"] == 66
|
||
assert '<td data-num="">0</td>' in row # 거리 0 은 빈 값 아님
|
||
|
||
|
||
def test_숫자_꼴(r):
|
||
f = r["fmt"]
|
||
assert f["thousands"] == "1,234,567.89"
|
||
assert f["neg"] == "-97.90"
|
||
assert f["zero"] == "0.00"
|
||
assert f["nul"] == f["undef"] == f["blank"] == f["nan"] == "—"
|
||
assert f["text"] == "120+18" and f["textNum"] == "5"
|
||
|
||
|
||
def test_합계_줄(r):
|
||
assert r["foot"].startswith('<tr><td class="is-frozen is-edge" style="left:0px">합계</td>')
|
||
assert "is-empty" in r["foot"] # 누가토량 합계는 비움
|
||
assert r["noTotal"] is False
|
||
|
||
|
||
def test_글_새지_않음(r):
|
||
assert "<b>" in r["escaped"] and "a&<" in r["escaped"]
|
||
|
||
|
||
def test_천_줄_빠름(r):
|
||
assert r["bigRows"] == 1000
|
||
assert r["bigMs"] < 300
|
||
|
||
|
||
def test_보이는_줄만_그림(r):
|
||
w = r["win"]
|
||
assert w["n"] == 62 # 위 빈 줄 + 60줄 + 아래 빈 줄
|
||
assert 'style="height:1525px"><td colspan="30">' in w["top"] # 61줄 × 25
|
||
assert w["second"].startswith(
|
||
'<tr class="is-alt">'
|
||
) # 61 번째(홀수) 줄 — 번갈아 색은 전체 줄 번호로
|
||
assert 'style="height:21975px"' in w["bottom"] # (1000 - 121) × 25
|