- 서버: inputs · combo_logics · _num 몸을 M02_Labor_Inputs.py 로(logic_inputs = 로직 키들 입력 + 자동값) · M02_MasterTemplete_Inputs.py 는 그것을 부름 - 길: GET /api/m02/logic-lib/inputs?keys= (로그인 · 일위대가 입력 모달용) - 화면: 값 카드(createInputsValueCard) · 값 함수 → M02_Labor_Values.ts · M02_Labor_Values_Model.ts · 값 칸 하나(createValueControl)를 떼어 값 카드와 입력 모달이 같이 씀 · CSS 도 옮김 - 옛 자리(M02_MasterTemplete_Inputs.ts · _Inputs_Model.ts)는 새 파일을 다시 내보냄 — B05 고르기 모달 그대로 - 시험: 새 test_m02_labor_values.py · 옮긴 자리 따라 test_item_picker_detail · test_m02_card_shell · helper_m02_inputs 고침 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
102 lines
4.2 KiB
Python
102 lines
4.2 KiB
Python
"""일위대가 넣을 값(39-3) — 입력 목록 길 `GET /api/m02/logic-lib/inputs` · 값 셈(TS 모델).
|
|
|
|
못박는 것
|
|
- 입력 목록 = 키 차례 · 겹친 키 한 번 · 입력마다 자동값 · 없는 키는 「빠진로직」.
|
|
- 옛 선택 입력 길(`M02_MasterTemplete_Inputs.inputs`)과 몸 한 벌(`M02_Labor_Inputs`).
|
|
- 값 셈 = 칸 글 → 저장 값(빈 글 = 자동값 · 범위 = 수 · 고르기 = 원래 모양) · 범위 밖 ·
|
|
모르는 이름 버림(사라진 값 알림) · 줄 아래 작은 글 · 빈 값 수(자동값도 없는 입력만).
|
|
화면 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["입력"])
|
|
# 옛 선택 입력 목록과 같은 몸
|
|
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} # 높이는 자동값이 있어 빈 값 아님
|