fix(sheet): 마스터 딱지는 식 먼저 · 식 줄은 열 이름 · 머리 글 안 잘리는 최소 폭 · 쪽 나눔 시험 (M02 브레인 확인)
- 식 있는 열 = 계산 · 바인딩만 = 설계값(펼침이면 값마다 열) · 손 = 손 입력 - 식 줄은 [열id] 대신 머리 글 이름 · 같은 종류는 짧게 · 풍선은 긴 이름 + id 식 · 변수도 이름 - 열 폭 최소 = 머리 글 · 단위 폭(캔버스로 잼) · 들어갈 것 · 식 줄은 세 줄로 자르고 풍선에 전문 · 머리 칸도 풍선 - 쪽 나눔을 pagePlan 으로 떼어 시험 test_sheet_pages.py(줄 120 → 쪽 3 · 합계 마지막 쪽만) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tjoit7rxvpLMM7cafeVTo1
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""표 쪽 나눔 — `ui_template_sheet_ops.ts` `pagePlan` 을 Node 로 바로 돌려 봄.
|
||||
|
||||
격자(`_render`)가 쪽을 이 계획대로 그림.
|
||||
|
||||
줄 120 문서 → project 쪽 3(50 · 50 · 20) · 쪽마다 머리(격자가 쪽마다 thead) · 합계는 마지막 쪽만 ·
|
||||
「전구간」 줄은 맨 위 · master 는 한 쪽.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
OPS = ROOT / "ui_template" / "sheet" / "ui_template_sheet_ops.ts"
|
||||
|
||||
pytestmark = pytest.mark.skipif(shutil.which("node") is None, reason="node 가 없음")
|
||||
|
||||
SCRIPT = """
|
||||
const { pagePlan } = await import(process.argv[1]);
|
||||
const doc = JSON.parse(process.argv[2]);
|
||||
const out = {};
|
||||
for (const mode of ["project", "master"]) {
|
||||
out[mode] = pagePlan(doc, mode).map((p) => ({
|
||||
ids: p.rows.map((r) => r.id), first: p.first, totals: p.totals,
|
||||
}));
|
||||
}
|
||||
console.log(JSON.stringify(out));
|
||||
"""
|
||||
|
||||
|
||||
def _plan(doc: dict) -> dict:
|
||||
result = subprocess.run(
|
||||
[
|
||||
"node",
|
||||
"--experimental-strip-types",
|
||||
"--no-warnings",
|
||||
"--input-type=module",
|
||||
"-e",
|
||||
SCRIPT,
|
||||
OPS.as_uri(),
|
||||
json.dumps(doc, ensure_ascii=False),
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
timeout=60,
|
||||
)
|
||||
assert result.returncode == 0, result.stderr
|
||||
return json.loads(result.stdout)
|
||||
|
||||
|
||||
def _doc(n: int, **head) -> dict:
|
||||
rows = [{"id": f"p{i}", "값": {}} for i in range(1, n)]
|
||||
rows.insert(7, {"id": "all", "값": {}, "고정": "전구간"}) # 문서 가운데 있어도 맨 위로
|
||||
return {"양식": "시험", "종류": "표", "판": 1, "열": [], "줄": rows, **head}
|
||||
|
||||
|
||||
def test_120_rows_make_three_pages_totals_last():
|
||||
plan = _plan(_doc(120))["project"]
|
||||
assert [len(p["ids"]) for p in plan] == [50, 50, 20]
|
||||
assert [p["first"] for p in plan] == [1, 51, 101]
|
||||
assert [p["totals"] for p in plan] == [False, False, True]
|
||||
assert plan[0]["ids"][0] == "all"
|
||||
assert sum((p["ids"] for p in plan), []).count("all") == 1
|
||||
|
||||
|
||||
def test_page_rows_from_doc_and_master_single_page():
|
||||
got = _plan(_doc(55, 쪽줄=20))
|
||||
assert [len(p["ids"]) for p in got["project"]] == [20, 20, 15]
|
||||
assert [len(p["ids"]) for p in got["master"]] == [55]
|
||||
assert got["master"][0]["totals"] is True
|
||||
|
||||
|
||||
def test_empty_doc_still_one_page_with_totals():
|
||||
plan = _plan({"양식": "시험", "종류": "표", "판": 1, "열": [], "줄": []})["project"]
|
||||
assert plan == [{"ids": [], "first": 1, "totals": True}]
|
||||
Reference in New Issue
Block a user