Files
Aislo/resources/tester/test_800_2_equation_layout.py
T
eomsangdonandClaude Opus 5.5 2732cf0f41 merge(800): sub2 800-1 변수 기호 기본값 · sub3 800-2~4 수식 영역 / 정의 영역 합침
- master_equation.export: 기호 씌움(msym.apply) 먼저 → 정의(view.definitions)는 기호 씌운 줄로 · _clean 마지막
- test_800_2: 800-1 기호로 중간 · 표 찾기가 다른 기호 = 다른 정의(옛 「한 줄로 합침」 기대 낡음)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 17:17:13 +09:00

131 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""PLAN 800-2 · 800-3 — 수식 탭 변수 정의 영역 · 바로 고침 · 새 기호 연결 (서버 몫 · 임시 쓰기 없음)."""
import json
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
sys.path[:0] = [str(ROOT), str(ROOT / "resources/master_data/scripts")]
from M01_MasterData import M01_MasterData_Equation as eq # noqa: E402
from M01_MasterData import M01_MasterData_Store as store # noqa: E402
KEY = "GC000211"
OFF = {"폼타이": "아님", "측압": "3t/㎡"}
ON = {"폼타이": "사용", "측압": "4t/㎡"}
def _defs(inputs):
return eq.read(KEY, inputs)["수식"]["정의"]
def _text(defs):
return json.dumps(defs, ensure_ascii=False)
def test_defs_merge_and_clean():
defs = _defs(OFF)
signs = [(d["기호"], d["위"], d["아래"]) for d in defs]
assert len(signs) == len(set(signs)), "같은 변수는 한 번만"
assert not re.search(r"[A-Z]{2}\d{6}", _text(defs)), "DB 열쇠 글 0"
assert all(
set(d) <= {"열쇠", "기호", "위", "아래", "이름", "갈래", "연결", "고침", "안씀"}
for d in defs
)
by = {
(d["이름"], d["갈래"]): d for d in defs
} # 800-1 기호가 생겨 중간 · 표 찾기는 다른 기호 = 다른 정의
sign = lambda d: (d["기호"], d["위"], d["아래"])
assert sign(by[("보통인부", "중간")]) != sign(by[("보통인부", "찾기")])
assert by[("사용횟수", "입력")]["연결"] == ["입력 — 옵션에서 고름"]
def test_unpicked_branches_hidden():
off, on = _text(_defs(OFF)), _text(_defs(ON))
for col in ("4t/㎡", "5t/㎡", "6t/㎡", "폼타이 소요량"):
assert col not in off
assert "칸 4t/㎡" in on and "칸 3t/㎡" not in on and "칸 5t/㎡" not in on
assert "측압" in on and "측압" not in off # 폼타이 아님이면 측압 갈래도 안 탐
def test_live_edit_preview_changes_total():
spot = {"할일": "식", "자리": "호표:0", "식": "형틀목공 × 2"}
got = eq.preview(KEY, [spot], OFF)
assert got["되나"] and got["후"]["계"] > got["전"]["계"]
def test_unknown_symbol_asks_link_then_links():
spot = {"할일": "식", "자리": "호표:0", "식": "형틀목공 × 2 + Z"}
got = eq.preview(KEY, [spot], OFF)
assert not got["되나"] and "모르는 기호 「Z」" in got["까닭"][0]
for link in (
{"갈래": "상수", "값": "0"},
{"갈래": "입력", "기본값": "0"},
{"갈래": "표", "표": "QC000431", "칸": "형틀목공", "조건": {"유형": "유형"}},
{"갈래": "요소", "요소": "LB000007"},
):
add = {"할일": "연결", "열쇠": "Z", "이름": "새값", **link}
got = eq.preview(KEY, [add, spot], OFF)
assert got["되나"], (link, got["까닭"])
assert any(d["기호"] == "Z" for d in got["수식"]["정의"])
def test_link_bad_input_blocked():
bad = [
{"갈래": "표", "표": "QC000431", "칸": "없는칸", "조건": {"유형": "유형"}},
{"갈래": "표", "표": "QC000431", "칸": "형틀목공", "조건": {}},
{"갈래": "요소", "요소": "GC000211"},
{"갈래": "상수", "값": "abc"},
]
for link in bad:
got = eq.preview(KEY, [{"할일": "연결", "열쇠": "Z", **link}], OFF)
assert not got["되나"], link
def test_drop_guard_and_unused_input():
got = eq.preview(KEY, [{"할일": "지움", "열쇠": "사용횟수"}], OFF)
assert not got["되나"] and "쓰는 곳" in got["까닭"][0]
add = {"할일": "연결", "열쇠": "Y", "갈래": "입력"}
got = eq.preview(KEY, [add], OFF)
unused = [d for d in got["수식"]["정의"] if d["기호"] == "Y"]
assert unused and unused[0].get("안씀")
assert eq.preview(KEY, [add, {"할일": "지움", "열쇠": "Y"}], OFF)["되나"]
def test_candidates():
whole = store.loaded()[1]
got = eq.links({"갈래": "표", "검색": "합판거푸집 폼타이", "분류": ""})
assert got["후보"] and "조건" in got["후보"][0]
assert eq.links({"갈래": "요소", "검색": "형틀목공", "분류": "인력"})["후보"]
assert eq.links({"갈래": "로직", "검색": "합판거푸집", "분류": ""})["후보"]
assert whole is not None
def test_groups_add_up_to_total():
"""800-4 — 묶음(블록 · 자원 · 덧줄) 소계 합 + 끝수 = 합계(비목마다) · 한 묶음 소계 = 노 + 재 + 경."""
for key in ("GC001148", "GC000211"):
eqn = eq.read(key, {})["수식"]
sub, total = eqn["소계"], eqn["합계"]
for k in ("노무비", "재료비", "경비"):
got = sum(float(r[k]) for r in sub["줄"]) + float(sub["끝수"][k])
assert abs(got - float(total[k])) < 1e-6, (key, k)
assert all(
abs(float(r["계"]) - sum(float(r[k]) for k in ("노무비", "재료비", "경비"))) < 1e-6
for r in sub["줄"]
)
def test_screen_source_groups_and_inline_edit():
ui = ROOT / "ui_template"
sum_ts = (ui / "ui_template_equation_sum.ts").read_text(encoding="utf-8")
line_ts = (ui / "ui_template_equation_line.ts").read_text(encoding="utf-8")
page = (ROOT / "M01_MasterData/M01_MasterData_UI_LogicLab_Equation.ts").read_text(
encoding="utf-8"
)
assert "ORDER" in sum_ts and "ui-eq__grp" in sum_ts # 가 · 나 · 다 묶음
assert "o.after?.(line)" in line_ts and "after:" in page # 블록 식 줄 바로 아래
assert "block-key" not in line_ts # 줄 곁 DB 열쇠 글 없음
assert "ui-eq__solve" not in line_ts and "ui-eq__step" not in line_ts # 풀이 · 줄 번호 걷음