- 새 M02_Doc_Match(서버 단독) — 후보(결과단위 · 노임 키 · 재료 · 기계 · 품셈 절 번호) · 옵션 풀이(줄 수량 · 단가가 의존하는 선택 · 입력 변수만 돌려 좁힘 · 글 근거 값 유지) · 줄 대조(같음 · 단가 차이 · 단위 환산 · 기계 규격 · 비목 · 율 값 · 율 줄 · 공구손료 유무 · 줄 없음 · 끝수 · 옵션 글) · 판정 확정(다른 항 0 · 원 단위 같음) / 근접 / 없음(가까운 후보 보이기만)
- 새 M02_Doc_MatchSk — 찾기 = SK 가져온.원본.연결후보 적음 · 바꾸기 = 서버가 다시 찾아 확정만 같은 키에 M01 사본 SK(바탕 · 입력값 = 찾은 옵션) · 원래 몸 = 가져온보관 · 되돌리기 · 근접 · 없음 409
- 길 POST /api/m02/layers/{층}/sangeun/{키}/match {할일 찾기 · 바꾸기 · 되돌리기}(층 쓰기)
- M02_Sangeun_Imported clean — 가져온보관 칸 받음 · M02_Doc_Import 형제 SK 가 우리 기초 사본이면 그 수식 문서로 셈(연결 안 끊김)
- 화면 — 원문 패널 「어디서 왔나」 카드 맨 위 판정 띠(띠 알림 부품) · 확정 = [우리 기초 사본으로 바꾸기] · 근접 · 없음 = 단추 없음 + 다른 항 자세히 · 안 찾음 = [우리 기초와 연결 찾기] · 바꾼 SK = [가져온 식으로 되돌리기] · 저장 안 한 고침 있으면 막음 · 끝나면 SK 다시 엶(새 판)
- 시험 test_810_4_match(판정 셋 · 요구 704 파형강관 Φ800 = GF000179 근접 · 단위 환산 × 6 · 기계 규격 · 율 줄 · 옵션 풀이 · 줄 대조 · 바꾸기 = M01 사본 셈 · 되돌리기 · 근접 409 · 형제 사본 · 전수 S8104_ALL) · helper_810_4_sweep
- 낡은 시험 글 대조 고침 — 717_2b(View 다시 엶 mount) · 750_2(createSangeunSide(opt.match)) · 807_1(원문 패널에 SK 문서 넘김)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
94 lines
4.7 KiB
Python
94 lines
4.7 KiB
Python
"""750-2 화면 — 수식 · 단가산출 상세가 SK 셈 답 하나로(바탕 M01 로직 따로 셈 길 걷음 · 799-2 시험 계산 보기는 걷음) · 재료 고름 = 문서 `고름` ·
|
|
읽는 식 줄 = cid 로 이음 · 옵션 바꿈 = SK 셈 한 번(원문 대조는 서버 test_750_1)."""
|
|
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def _ts(rel: str) -> str:
|
|
return (ROOT / rel).read_text("utf-8")
|
|
|
|
|
|
def test_detail_uses_only_sk_answer():
|
|
ts = _ts("M02_MasterTemplete/M02_MasterTemplete_Sangeun_Detail.ts")
|
|
assert "text = got.글" in ts and "answer: async" not in ts and "buildCalc" not in ts
|
|
assert "onText" not in ts and "onLines" not in ts # 바탕 `/calc` · `/text` 부름 걷음
|
|
assert "dropText" not in ts and "baseCovers" not in ts and "applyCovers" not in ts
|
|
assert "calcSangeun(scope, plain, values, false)" in ts # 바탕 원값 셈 = 보기 덧칸 없이
|
|
assert "doc.고름 = " in ts and "pickMat" in ts # 재료 고름 = SK 문서 고름
|
|
|
|
|
|
def test_text_lines_joined_by_cid():
|
|
ho = _ts("M01_MasterData/M01_MasterData_UI_LogicLab_Ho.ts")
|
|
assert "ctx.cids && line.cid" in ho and "pickMat" in ho
|
|
api = _ts("M01_MasterData/M01_MasterData_UI_Logic_Api.ts")
|
|
assert "cid?: string" in api and "나눔?: number" in api
|
|
|
|
|
|
def test_calc_drive_is_screenless_and_m02_has_no_calc_hook():
|
|
ts = _ts("M01_MasterData/M01_MasterData_UI_Logic_Calc.ts")
|
|
assert "ctx.answer" not in ts and "CalcShown" not in ts # 799-2 M02 시험 계산 길 걷음
|
|
drive = _ts("M01_MasterData/M01_MasterData_UI_Logic_Drive.ts")
|
|
assert "runCalc(body)" in drive and "document." not in drive # 셈 구동 = 화면 없이
|
|
|
|
|
|
def test_752_1_source_panel_only_on_sangeun_screen():
|
|
"""752-1 원문 패널 — 단가산출 화면만 켬 · 일위대가 줄 모달 안 상세는 끔 · 기초마다 탭 · 좁은 폭 접힘."""
|
|
side = _ts("M02_MasterTemplete/M02_MasterTemplete_Sangeun_Side.ts")
|
|
assert "/m02/logic-lib/source" in side and "createSidePanels" in side
|
|
assert "OPEN_FROM" in side and "createSegment" in side
|
|
assert "source: true" in _ts("M02_MasterTemplete/M02_MasterTemplete_Sangeun_View.ts")
|
|
assert "source" not in _ts("M02_MasterTemplete/M02_MasterTemplete_Labor_RowSk.ts")
|
|
detail = _ts("M02_MasterTemplete/M02_MasterTemplete_Sangeun_Detail.ts")
|
|
assert "opt.source ? createSangeunSide(opt.match)" in detail and "side?.set(" in detail
|
|
|
|
|
|
def test_753_2_option_off_flag_reaches_sheet_and_views():
|
|
"""753-2 옵션으로 빠진 줄 — SK 줄 `옵션꺼짐` → 표 줄 `off` → 계산서 줄 `옵션꺼짐`(공용 계산서 · 상세 ·
|
|
텍스트 수식 · 시험 계산이 안 그림) · 소계 · 금액은 그대로."""
|
|
import json
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
if shutil.which("node") is None:
|
|
pytest.skip("node 가 없음")
|
|
m02 = ROOT / "M02_MasterTemplete"
|
|
strip = lambda p: re.sub(r"^import .*$", "", p.read_text("utf-8"), flags=re.M) # noqa: E731
|
|
src = "\n".join(
|
|
[
|
|
strip(m02 / "logic" / "M02_Born_Tag.ts"),
|
|
strip(m02 / "logic" / "M02_Sangeun_Undo.ts"),
|
|
# 751-3 모델이 가져오는 B09 `rounddown`(import 줄을 빼므로 같은 식을 둠)
|
|
"const rounddown = (v, p = 0) => { const s = 10 ** p; "
|
|
"const a = Math.floor(Math.abs(v) * s + 1e-7) / s; return v < 0 ? -a : a; };",
|
|
strip(m02 / "logic" / "M02_Sangeun_Cover_Model.ts"),
|
|
"""
|
|
const line = (cid, 이름, 수량, 금액, 꺼짐) => ({ cid, 이름, 단위: "개", 수량, 단가: 100, 금액,
|
|
비목: { 재료비: 금액 }, 묶음: "재료", ...(꺼짐 ? { 옵션꺼짐: true } : {}) });
|
|
const ans = { 기준: null, 짝잃음: [], 바탕판: "x", 정체: ["material:A#0", "material:B#0"],
|
|
줄: [line("material:A#0", "폼타이 12.7", 0, 0, true), line("material:B#0", "합판", 1, 100, false)] };
|
|
const rows = rowsOf(ans, null, {});
|
|
console.log(JSON.stringify({ off: rows.map((r) => r.off) }));
|
|
""",
|
|
]
|
|
)
|
|
out = subprocess.run(
|
|
["node", "--experimental-strip-types", "--no-warnings",
|
|
"--input-type=module-typescript", "-e", src],
|
|
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
|
) # fmt: skip
|
|
assert out.returncode == 0, out.stderr
|
|
got = json.loads(out.stdout)
|
|
assert got["off"] == [True, False]
|
|
sheet = (ROOT / "A00_Common" / "calc_sheet.ts").read_text("utf-8")
|
|
assert "b.줄.filter(shown)" in sheet and "g.줄.filter(shown)" in sheet
|
|
ho = (ROOT / "M01_MasterData" / "M01_MasterData_UI_LogicLab_Ho.ts").read_text("utf-8")
|
|
assert "옵션꺼짐" in ho
|
|
assert "옵션꺼짐" in (ROOT / "M01_MasterData" / "M01_MasterData_UI_Logic_Calc.ts").read_text(
|
|
"utf-8"
|
|
)
|