"""157-2 B09 단가산출근거 탭 보기 둘 · 157-3 산근 규격 칸 「이름 규격」. - 157-2 보기 B(호표별 카드) = 보기 A(표) 줄 그대로 호표마다 묶음 — 같은 값 · 같은 차례(171-3 공용 묶음 카드로 갈음) - 단추 = 보기 바꿈(글 「박스보기」 ↔ 「표로 보기」 · 181-2) · 기억 못 읽음 · 모르는 값 = 카드(171-3 컨테이너 기본) - 157-3 규격 = 기계 · 직종 원문번호 → 「이름 규격」(M02 85-1 도우미) · 번호는 풍선(tip) """ import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from B09_Estimation.B09_Estimation_Sangeun import spec_text # noqa: E402 from resources.tester.helper_b09_group_cards import COMMON, GROUPS, TABS, run # noqa: E402 B09 = ROOT / "B09_Estimation" def _node(js_body): return run([COMMON, TABS, "B09_Estimation/B09_Estimation_UI_Tabs_Sangeun.ts", GROUPS], js_body) def _block(key, no, spec="", spec_raw=""): return { "key": key, "no": no, "name": f"산근{no}", "unit": "m3", "spec": spec, "spec_raw": spec_raw, "head": [f"산근{no} / m3", "산림품셈 적용"], "lines": [ {"kind": "labor", "name": "보통인부", "ref": {"tab": "labor", "key": "LB2"}, "why": None, "labor": 2979.8, "material": 0.0, "expense": 0.0, "text": ["보통인부 : 165,545 * 0.018 = 2,979.8 (긴 함수 " +"가" * 200 + ")"]}, {"kind": "machine", "name": "굴착기", "ref": {"tab": "machine", "key": "EQ1"}, "why": None, "labor": 3899.0, "material": 538.6, "expense": 912.8, "text": ["굴착기 노무비", "굴착기 재료비", "굴착기 경비"]}, ], "labor": 6878, "material": 538, "expense": 912, "sum": 8328, "why": None, "foot": "계 : 8,328", } # fmt: skip SHEETS = {"sg": [_block("SG:A", 1), _block("SG:B", 2)]} def test_157_2_두_보기_같은_값(): out = _node( f"\nconst t = buildSg({{ sheets: {json.dumps(SHEETS, ensure_ascii=False)} }});" "\nconst cards = tabGroups('sg', t);" "\nconst ats = cards.flatMap((c) => [c.at, ...c.lines.map((l) => l.at), c.foot.at]);" "\nconsole.log(JSON.stringify({ n: t.rows.length, keys: cards.map((c) => c.key), ats," " sums: cards.flatMap((c) => c.lines.map((l) => [l.sum, t.rows[l.at].sum]))," " heads: cards.map((c) => [c.no, c.name, c.unit, c.sum])," " links: cards.map((c) => c.lines.map((l) => (l.link ? t.link(l.at, 'kind').key : null))) }));" ) assert out["keys"] == ["SG:A", "SG:B"] assert out["ats"] == list(range(out["n"])) # 카드 줄 = 표 줄 번호 그대로 · 같은 차례 assert all(a == b for a, b in out["sums"]) assert out["heads"] == [["제 1 호표", "산근1", "m3", 8328], ["제 2 호표", "산근2", "m3", 8328]] # 머리 줄 1 · 노무 1 · 중기 3 — 줄 누름 이동은 표와 같은 link assert out["links"][0] == [None, "LB2", "EQ1", "EQ1", "EQ1"] def test_157_2_단추_바꿈(): out = _node("\nconsole.log(JSON.stringify([viewLabel('table'), viewLabel('cards')]));") assert out == ["호표보기", "박스보기"] # 304-1 단추 글 = 그 보기 이름 def test_157_2_기억_실패_때_카드(): out = _node( "\nconst a = [readGroupView(null), readGroupView({ sg: 'x' }), readGroupView({ dg: 'table' })," " readGroupView({ sg: 'table' }), readGroupView('table'), readGroupView('x')," " readGroupView({ dg: 'cards', sg: 'table' })];" "\nconsole.log(JSON.stringify(a));" ) # 304-1 한 값 · 옛 탭별 값 = dg 먼저 · 없으면 다른 탭 · 모르는 값 = 카드 assert out == ["cards", "cards", "table", "table", "table", "cards", "cards"] def test_157_2_화면_잇기(): shell = (B09 / "B09_Estimation_UI_Shell.ts").read_text("utf-8") assert "isGroupTab(tab)" in shell and "renderGroupPanel(" in shell assert not ( B09 / "B09_Estimation_UI_Tabs_Sangeun_Cards.ts" ).exists() # 171-2 공용 양식으로 갈음 css = (ROOT / "ui_template" / "ui_template_group_cards.css").read_text("utf-8") assert "white-space: pre-wrap" in css # 긴 산출내역 글 = 카드 안 줄바꿈 class _Whole: numbers = { "EQ": {"0201-0070": {"이름": "굴착기(무한궤도)", "규격": "0.6㎥"}}, "LB": {"1001": {"이름": "보통인부"}}, } def test_157_3_규격_이름_규격(): given = {"기계": "0201-0070", "직종": "1001", "규격": 150, "모름": "9999-9999"} shown, raw = spec_text(_Whole(), given) assert shown == "기계=굴착기(무한궤도) 0.6㎥, 직종=보통인부, 규격=150, 모름=9999-9999" assert raw == "기계=0201-0070, 직종=1001, 규격=150, 모름=9999-9999" def test_157_3_번호는_풍선(): block = _block("SG:A", 1, "기계=굴착기(무한궤도) 0.6㎥", "기계=0201-0070") plain = _block("SG:B", 2, "규격=150", "규격=150") listing = [{k: b[k] for k in ("key", "no", "name", "spec", "spec_raw", "unit")} for b in (block, plain)] # fmt: skip sg_json = json.dumps([block, plain], ensure_ascii=False) ls_json = json.dumps(listing, ensure_ascii=False) out = _node( f"\nconst sg = buildSg({{ sheets: {{ sg: {sg_json} }} }});" f"\nconst ls = buildSgList({{ sheets: {{ sg_list: {ls_json} }} }});" "\nconst heads = sg.rows.map((r, i) => [r, i])" ".filter(([r]) => !String(r.key).includes('|'));" "\nconsole.log(JSON.stringify({" " sg: heads.map(([r, i]) => [r.note, sg.tip(i, 'note') ?? null])," " ls: [0, 1].map((i) => [ls.rows[i].spec, ls.tip(i, 'spec') ?? null])," " other: ls.tip(0, 'name') ?? null }));" ) assert out["sg"] == [ ["기계=굴착기(무한궤도) 0.6㎥", "원문번호 기계=0201-0070"], ["규격=150", None], ] assert out["ls"] == [ ["기계=굴착기(무한궤도) 0.6㎥", "원문번호 기계=0201-0070"], ["규격=150", None], ] assert out["other"] is None