Files
Aislo/resources/tester/test_m01_auto.py
T
eomsangdonandClaude Sonnet 5 a30890546c fix(M01): 빠진 원 단위 입력도 null 처럼 그 줄만 비움 (/calc · /text)
- mf.fill_empty — 화면이 안 보낸 가격 입력(단위에 원)을 null 로 채움 · Store.calc·text 에서 부름
- 시험 test_m01_auto.py 한 개 더 — 입력 둘 뺀 GF000056

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
2026-09-24 10:24:43 +09:00

127 lines
5.5 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.
"""M01 견본 입력(`GET /logic/auto`) · 값 빈 품목은 그 줄만 비움 — PLAN 3-2 · 계약 3-1 표.
자동값 = 고르기 목록 첫째 · 범위 최솟값 · 찾기 조건 값은 그 표 가장 낮은 줄 · 나누는 수 1 · 그 밖 0.
정본 폴더를 읽기만 함(쓰지 않음).
"""
from __future__ import annotations
from decimal import Decimal
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from M01_MasterData import M01_MasterData_Router as router_module
from M01_MasterData import M01_MasterData_Store as store
@pytest.fixture(scope="module")
def client() -> TestClient:
app = FastAPI()
app.include_router(router_module.router)
return TestClient(app)
def _auto(client: TestClient, key: str) -> dict:
got = client.get("/api/m01/logic/auto", params={"key": key})
assert got.status_code == 200, got.text
return got.json()["값"]
def _calc(client: TestClient, key: str) -> dict:
got = client.post("/api/m01/calc", json={"key": key, "inputs": _auto(client, key)}).json()
assert got["ok"] is True, got
return got
def test_고르기는_목록_첫째_범위는_최솟값(client) -> None:
got = _auto(client, "GF000160") # 12-4 합판거푸집
assert got["횟수"] == "1회사용시" and got["폼타이"] == "아님" and got["합판"] == "MT000018"
assert got["소형할증"] == 0 # 범위 [0, 30]
assert got["높이할증"] == 0 # 찾기·나누기에 안 쓰임
def test_찾기_조건_값은_표_가장_낮은_줄(client) -> None:
assert _auto(client, "GC000561")["층수층"] == 0 # 가장 낮은 줄 「6 미만」 — 아래 끝이 열림
assert _auto(client, "GC000559")["강재총사용량"] == 0 # 「60 미만」
# 두 표가 같은 입력을 씀 — 한 표는 6 부터 · 한 표는 15 부터 → 둘 다에 드는 가장 낮은 값
assert _auto(client, "GC000724")["규격"] == 15
def test_나누는_수는_1(client) -> None:
assert _auto(client, "GC000998")["수직고초과단계"] == 1
assert _auto(client, "GC000278")["두께"] == 1
def test_없는_로직은_404(client) -> None:
assert client.get("/api/m01/logic/auto", params={"key": "GF999999"}).status_code == 404
def test_견본_금액은_앞과_같음(client) -> None:
assert Decimal(str(_calc(client, "GF000160")["sums"]["계"])) == Decimal("117485.212")
assert Decimal(str(_calc(client, "GF000219")["sums"]["계"])) == Decimal("79279.668")
def test_후보_0_값_빈_품목은_그_줄만_비움(client) -> None:
got = _calc(client, "GC000027") # 가새(후보 0) · 발판(값 없음)
blank = {one["이름"]: one for one in got["lines"] if one.get("까닭")}
assert len(blank) == 2
for one in blank.values():
assert one["단가"] is None and one["금액"] is None
assert "후보 없음" in blank["가새 L1518-2개"]["까닭"]
assert "값 없음" in blank["발판 45×200×2000"]["까닭"]
rest = sum(Decimal(str(one["금액"])) for one in got["lines"] if one["금액"] is not None)
assert Decimal(str(got["sums"]["계"])) == rest > 0 # 빈 줄은 빼고 더함
def test_빈_줄을_부르는_덧줄도_비움(client) -> None:
got = _calc(client, "GF000185") # 레미콘 후보 0 → 레미콘 금액을 부르는 덧줄
blank = [one for one in got["lines"] if one.get("까닭")]
assert [one["이름"] for one in blank] == ["구체콘크리트(철근) 레미콘", "콘크리트다짐"]
assert "구체콘크리트(철근) 레미콘" in blank[1]["까닭"] and blank[1]["금액"] is None
def test_자동값으로_로직_전부_멈춤_0() -> None:
files, whole = store.loaded()
stuck = []
for data in files.values():
if data.get("그룹") != "로직":
continue
for row in data.get("줄") or []:
try:
store.cm.mf.run(whole, str(row["키"]), store.mau.values(whole, row))
except (store.cm.mf.FormulaError, ArithmeticError, KeyError, TypeError) as e:
stuck.append(f"{row['키']} {e}")
assert stuck == []
def test_원_단위_입력은_자동값_null(client) -> None:
got = _auto(client, "GF000056") # 체인톱가격(원) · 체인오일단가(원/ℓ)
assert got["체인톱가격"] is None and got["체인오일단가"] is None
assert got["소작업로"] == 0 # 원 아닌 수는 그대로 0
def test_빈_입력을_쓰는_줄만_비움(client) -> None:
got = _calc(client, "GF000056")
blank = {one["이름"]: one for one in got["lines"] if one.get("까닭")}
assert set(blank) == {"체인오일", "체인톱 손료"}
for one in blank.values():
assert one["단가"] is None and one["금액"] is None and "비어 있음" in one["까닭"]
rest = sum(Decimal(str(one["금액"])) for one in got["lines"] if one["금액"] is not None)
assert Decimal(str(got["sums"]["계"])) == rest > 0 # 빈 줄은 빼고 더함
assert got["sums"]["경비"] == 0
def test_빠진_원_입력도_null_처럼_줄만_비움(client) -> None:
given = {
k: v
for k, v in _auto(client, "GF000056").items()
if k not in ("체인톱가격", "체인오일단가")
}
for path in ("calc", "text"):
got = client.post(f"/api/m01/{path}", json={"key": "GF000056", "inputs": given}).json()
assert got["ok"] is True, (path, got)
lines = client.post("/api/m01/calc", json={"key": "GF000056", "inputs": given}).json()["lines"]
assert {o["이름"] for o in lines if o.get("까닭")} == {"체인오일", "체인톱 손료"}