Files
Aislo/resources/tester/test_183_3_b09_applied_pick.py
T
eomsangdonandClaude Opus 5.5 a2619cbc40 test(841-2): B09 시험 실패 가름 — 낡은 틀 · 낡은 기대 고침(코드 흠 0)
㉠ 시험 틀 낡음 — 공용 원화 꼴(751-2 common_util_money.ts formatMoney · formatPrice)로 옮겨진 뒤 TS 를 import 떼고 이어 돌리는 틀에 그 함수가 없음
- test_184_3 money_ts()(함수 속에 넣어 이름 겹침 0) · 145-4 · 166-1 · 183-3 · 185-1 · 239-1(184-3 틀) · 261-2 가 같이 붙임
㉠ 기대 글 낡음
- 155-5 · 157-1: 801-5 M01 단위 표기(「mm」 → 「㎜」 · 찾기 값 「20 sec」)
- 243-1: 719-4 산근 계산서 표(제 표 · 두 번 눌러 고침)가 표 목록에 빠짐 → 더하고 editOnDouble 지킴
- 246-2: 공용 메뉴 「▾」 = 요구 551 여럿 고르기 단추 꼬리(다른 기능) → 옛 아코디언 표지만 봄
- 311: B05 「노선 추천」 칸 626-1 걷음 → 접힘 기대에서 뺌
㉡ 걷은 기능 시험 · ㉢ 코드 흠 — 없음
- B09 이름 든 51 파일 + 위 다섯 + 717-4 · 721 = 315 통과 · 실패 0(717-4 · 721 = sub1 고침 받은 판 통과) · 719-1 · 796-2e = sub4 몫이라 안 만짐

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-15 17:07:22 +09:00

118 lines
5.0 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.
"""183-3 자재단가대비표 적용 단가 — 칸 누름 고르기 메뉴 · 고른 출처 칸 강조 · 기본 최저.
- 공용 표 `cellClass` 옵션(칸 class · 안 주면 같은 글) — Node 로 `renderDataTableHtml`
- 고르기 항목 `appliedChoices`(값 있는 출처 · 견적 · 최저(자동) · ✓ 표시) — Node 로 함수만 떼어 돌림
- 배선: 수기 적용 칸 · 출처 칸 돌림 없앰 · Shell 이 cellClass · choices 를 넘김 · B09 메뉴 한 벌
셈 · 저장(pick › applied › 최저)은 그대로(test_144 · test_166_4).
"""
import json
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
TS = ROOT / "config" / "node_modules" / "typescript"
def _src(rel: str) -> str:
return (ROOT / rel).read_text(encoding="utf-8")
def _node(script: str):
out = subprocess.run(
["node", "-e", script], capture_output=True, text=True, encoding="utf-8", timeout=60
)
assert out.returncode == 0, out.stderr
return json.loads(out.stdout)
from test_184_3_b09_bill_menu import money_ts # noqa: E402 — 공용 원화 꼴 틀
PRELUDE = f"""
const fs = require("fs");
const ts = require({json.dumps(str(TS))});
const js = (code) => ts.transpileModule(code, {{
compilerOptions: {{ module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }},
}}).outputText;
"""
def test_공용_표_cellClass_칸_class_안_주면_같은_글():
table = json.dumps(str(ROOT / "ui_template" / "ui_template_data_table.ts"))
got = _node(
PRELUDE
+ f"""
const box = {{ exports: {{}} }};
new Function("exports", "module", "require", js(fs.readFileSync({table}, "utf8")))(
box.exports, box, (p) => (p.endsWith(".css") ? {{}} : require(p)));
const m = box.exports;
const o = {{ columns: [{{ key: "a", label: "A" }}, {{ key: "b", label: "B" }}],
rows: [{{ a: 1, b: 2 }}, {{ a: 3, b: 4 }}] }};
const marked = m.renderDataTableHtml({{ ...o,
cellClass: (i, k) => (i === 0 && k === "b" ? "is-picked" : null) }});
console.log(JSON.stringify({{
plain: m.renderDataTableHtml(o),
none: m.renderDataTableHtml({{ ...o, cellClass: () => null }}),
count: marked.split("is-picked").length - 1,
row0: marked.split("<tbody>")[1].split("</tr>")[0],
}}));
"""
)
assert got["plain"] == got["none"]
assert got["count"] == 1 and '<td class="is-picked">2</td>' in got["row0"]
def test_고르기_항목_값_있는_출처_견적_최저_자동():
base = _src("B09_Estimation/B09_Estimation_UI_Tabs_Base.ts")
start = base.index("function appliedChoices")
body = base[start : base.index("\n}\n", start) + 3]
sources = _src("B09_Estimation/B09_Estimation_Calc_Base.ts")
at = sources.index("export const SOURCES")
line = sources[at : sources.index(";", at) + 1] + "\n"
got = _node(
PRELUDE
+ f"""
const appliedChoices = new Function(js({json.dumps(money_ts() + line.replace("export ", "") + body)}) + "; return appliedChoices;")();
const r = {{ prices: {{ 관급: null, 물가정보: 1200, 물가자료: 0, 유통물가: 1000, 견적: 1500 }},
lowest_from: "유통물가", applied_from: "유통물가", pick: null }};
const seen = [];
const items = appliedChoices(r, (s) => seen.push(s));
items.forEach((x) => Array.isArray(x) && x[1]());
const pick = {{ ...r, applied_from: "견적", pick: "견적" }};
console.log(JSON.stringify({{
labels: items.map((x) => (Array.isArray(x) ? x[0] : x)),
seen,
picked: appliedChoices(pick, () => 0).map((x) => (Array.isArray(x) ? x[0] : x)),
}}));
"""
)
assert got["labels"] == [
"물가정보 1,200",
"✓ 유통물가 1,000 · 최저",
"견적 1,500",
"-",
"✓ 최저(자동)",
]
assert got["seen"] == ["물가정보", "유통물가", "견적", None]
assert got["picked"][2] == "✓ 견적 1,500" and got["picked"][-1] == "최저(자동)"
def test_배선_수기_적용_칸_출처_돌림_없앰():
base = _src("B09_Estimation/B09_Estimation_UI_Tabs_Base.ts")
compare = base[base.index("export const buildCompare") : base.index("function usesOf")]
assert 'editable: (_i, key) => key === "p:견적",' in compare
assert "nextPick" not in base and 'key === "applied_from"' not in compare
assert 'key === `p:${rows[i]?.applied_from}` ? "is-picked"' in compare
assert (
'key === "applied" && rows[i] ? chooseApplied(rows[i]) : null' in compare
) # 257-3 메뉴 둘 공용
assert "delete cell.applied" in compare
shell = _src("B09_Estimation/B09_Estimation_UI_Shell.ts")
builders = _src("B09_Estimation/B09_Estimation_UI_Builders.ts") # 303-2 옵션 짜기
assert "cellClass: spec.cellClass," in builders and "...tableOptionsOf(spec, tab)," in shell
assert "openMenuAt(box.left, box.bottom, items)" in shell
edit = _src("B09_Estimation/B09_Estimation_UI_Tabs_Bill_Edit.ts")
assert "export function openMenuAt(" in edit and "const ctxMenu = sharedMenu();" in edit
css = _src("B09_Estimation/B09_Estimation_UI_Page.css")
assert "td.is-picked" in css and "var(--color-success)" in css # 257-3 초록 테두리