Files
Aislo/resources/tester/test_800_2_equation_layout.py
T
eomsangdonandClaude Opus 5.5 58a3e039b3 feat(813-2): 보조 문서 부품 표지 73 · 작업량당 기계경비 6 지움 · 단가산출 목록에서 뺌 · 기계 → 부품 길
- 표지 = 수식 문서 머리 · 옛 로직 줄 칸 「부품」 — 기계경비식 9 · 작업량 틀 60(기종 = 기계표 상세구분 · 규격 열쇠) · 계수식 4 · 변환기가 옮김 · 틀 문서 9 장
- 지움 = 작업량당 기계경비 6(GC001145 · 1148 · 1151 · 1156 · 1159 · 1166 · 부르는 곳 0 · 요구 734-4 · 735-4) — 수식 문서 · 옛 로직 · 키대장 폐기 칸 · 빌더 · 변수표
- 이름 꼬리 4 = 원문 제목(지게운반 · 인력운반(기계설비) · 벽돌운반 · 수중펌프 설치 및 해체) · 키 폐기 0
- 서버 = `M01_MasterData_Parts` — M01 `/logics` · M02 `/logic-lib/logics` 목록에서 부품 뺌(1,440) · 키로 열기 · 부르기 그대로 · `/m01/parts`(기종 계산식 · 틀 · 계수식) · `/m02/logic-lib/machine-parts` · 연결 찾기 과녁에서 부품 뺌(1,444 → 1,435 · 판정 코드 그대로)
- 금액 전후 = 문서 1,513 · 셈 9,626(기본 + 옵션 표본) 모두 같음 · 791_1 지문 남은 1,513 같음 → 지문 다시 뜸 · 802_2 변환 대조 1,513 · 목록 xlsx 다시 씀(요약 수)
- 낡은 시험 = 1,519 · 1,518 기대 → 1,513 · GC001148 견본 → 같은 꼴 GF000089 토사깍기(기계)(블록 Q 39.293 · 합계 2,190) · 지운 6 을 셈하던 줄 걷음 · 목록 수 1,440 · 묶음 328 · 부르는 수 507
- 새 지킴 시험 test_813_2_parts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 20:49:52 +09:00

128 lines
5.4 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 ("GF000089", "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")
assert "ORDER" in sum_ts and "ui-eq__grp" in sum_ts # 가 · 나 · 다 묶음
assert "o.after?.(line)" in line_ts # 블록 식 줄 바로 아래
assert "block-key" not in line_ts # 줄 곁 DB 열쇠 글 없음
assert "ui-eq__solve" not in line_ts and "ui-eq__step" not in line_ts # 풀이 · 줄 번호 걷음