Files
Aislo/resources/tester/test_m02_labor_values.py
T
eomsangdonandClaude Opus 5.5 c704f18982 refactor(M02): 선택 입력 지움(39-7b G3) — 카드 · 자리 고르기 · inputs/ 연결 · 입력 목록 · 연결 · 알약 길 · 프로젝트 복사본 「입력연결」 · 시스템 층 inputs · 시험
- 넣을 값 카드(M02_Labor_Values)는 담은 로직 입력 전부를 보임(자리 「선택」 감싸기 없앰) · 이름 「넣을 값」
- 고르기 모달 면적산출 알약 = 복사본 일위대가 알약(가져온 때 그대로)
- 입력값.json · 고른자재.json · /calc 는 그대로 · storage 층 inputs/ 파일은 안 건드림(읽기만 끊음)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
2026-10-04 19:36:46 +09:00

102 lines
4.2 KiB
Python

"""일위대가 넣을 값(39-3) — 입력 목록 길 `GET /api/m02/logic-lib/inputs` · 값 셈(TS 모델).
못박는 것
- 입력 목록 = 키 차례 · 겹친 키 한 번 · 입력마다 자동값 · 없는 키는 「빠진로직」.
- 입력 목록 몸 한 벌(`M02_Labor_Inputs`) · 옛 선택 입력은 없앰(39-7b).
- 값 셈 = 칸 글 → 저장 값(빈 글 = 자동값 · 범위 = 수 · 고르기 = 원래 모양) · 범위 밖 ·
모르는 이름 버림(사라진 값 알림) · 줄 아래 작은 글 · 빈 값 수(자동값도 없는 입력만).
화면 TS 는 그 자리에서 트랜스파일해 node 로 돌림 · 정본은 읽기만.
"""
from __future__ import annotations
import json
import shutil
import subprocess
from pathlib import Path
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from common_util.common_util_auth import verify_session
from M02_MasterTemplete import M02_Labor_Inputs as labor_inputs
from M02_MasterTemplete import M02_MasterTemplete_Router_Combos as combos_router
ROOT = Path(__file__).resolve().parents[2]
A, B = "GF000222", "GF000221" # 찰쌓기 인력 · 장비
@pytest.fixture()
def client() -> TestClient:
app = FastAPI()
app.include_router(combos_router.router)
app.dependency_overrides[verify_session] = lambda: {"user_id": 42, "role": "USER"}
return TestClient(app)
def test_입력_목록은_키_차례_겹침_한_번_자동값_빠진_로직(client: TestClient) -> None:
res = client.get("/api/m02/logic-lib/inputs", params={"keys": f"{B},{A},{B},GF999999,"})
assert res.status_code == 200, res.text
got = res.json()
assert [x["로직"] for x in got["로직"]] == [B, A]
assert got["빠진로직"] == ["GF999999"]
one = got["로직"][1]
assert one["이름"] and one["결과단위"]
assert one["입력"] and all("자동값" in i and "이름" in i for i in one["입력"])
# 입력 목록 몸 한 벌(M02_Labor_Inputs)
assert got["로직"] == labor_inputs.logic_inputs([B, A])["로직"]
def test_빈_키는_빈_목록(client: TestClient) -> None:
got = client.get("/api/m02/logic-lib/inputs").json()
assert got == {"로직": [], "빠진로직": []}
SCRIPT = r"""
const fs = require("fs");
const path = require("path");
const ts = require(path.join(process.argv[1], "config", "node_modules", "typescript"));
const file = path.join(process.argv[1], "M02_MasterTemplete", "M02_Labor_Values_Model.ts");
const js = ts.transpileModule(fs.readFileSync(file, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
new Function("exports", "module", "require", js)(box.exports, box, require);
const m = box.exports;
const height = { 이름: "높이", 단위: "m", 범위: [0.5, 5], 자동값: 1.2 };
const kind = { 이름: "종류", 고르기: ["막돌", "견치돌"] };
const size = { 이름: "규격", 고르기: [25, 40] };
const area = { 이름: "지역" };
const inputs = [height, kind, size, area];
console.log(JSON.stringify({
stored: [
m.storedOf(height, ""), m.storedOf(height, "2.5"), m.storedOf(kind, "막돌"),
m.storedOf(size, "40"), m.storedOf(area, "서울"),
],
outside: [
m.isOutside(height, "9"), m.isOutside(height, "0.5"), m.isOutside(height, ""),
m.isOutside(height, "abc"), m.isOutside(area, "9"),
],
known: m.keepKnown(inputs, { 높이: 2, 종류: "", 없앤것: 3 }),
line: m.valueLine(inputs, { 높이: 2, 규격: 40 }),
lineEmpty: m.valueLine(inputs, {}),
}));
"""
def test_값_셈() -> None:
node = shutil.which("node")
if not node:
pytest.skip("node 없음")
out = subprocess.run(
[node, "-e", SCRIPT, str(ROOT)], capture_output=True, text=True, encoding="utf-8"
)
assert out.returncode == 0, out.stderr
got = json.loads(out.stdout)
assert got["stored"] == [None, 2.5, "막돌", 40, "서울"]
assert got["outside"] == [True, False, False, True, False]
assert got["known"] == {"kept": {"높이": 2}, "lost": ["없앤것"]}
assert got["line"] == {"text": "높이 2m · 규격 40", "empty": 2} # 종류 · 지역 = 자동값 없음
assert got["lineEmpty"] == {"text": "", "empty": 3} # 높이는 자동값이 있어 빈 값 아님