Merge remote-tracking branch 'origin/dev' into sub_laptop_5
This commit is contained in:
@@ -154,7 +154,7 @@ def test_사본_없는_시설_알림_응답에_사본(root):
|
||||
out = _run(root)
|
||||
# 100(유출 흙막이) · 200 · 300 · 400 · 500(기본 날개벽 잇기) · 600 · 개거 700 = 7곳
|
||||
assert not any("wing" in c["id"] for c in out["columns"])
|
||||
assert "조합 사본 없는 시설 7곳 — 「미연결」 줄을 눌러 조합 연결" in out["notes"]
|
||||
assert "조합 사본 없는 시설 7곳 — 노랑 램프 줄을 눌러 조합 연결" in out["notes"]
|
||||
assert not any("관 연장 없음" in n for n in out["notes"])
|
||||
assert set(out["linked"]) == {"pipe@100.0", "pipe@500.0__gford"}
|
||||
|
||||
@@ -187,7 +187,7 @@ def test_화면_조합_이름_구조물도는_사본에서():
|
||||
ui = (ROOT / "B08_Quantity/B08_Quantity_UI_Summary.ts").read_text(encoding="utf-8")
|
||||
assert "loadPickerRows" not in ui # 층 목록 GET 안 씀
|
||||
assert "linkedOnly(" in ui
|
||||
assert "unlinkedAt(" in ui and "B08_Quantity_Summary_Unlinked" in ui # 154-1 미연결 줄
|
||||
assert "unlinkedAt(" in ui and "B08_Quantity_Summary_LampTip" in ui # 154-1 · 198-1 미연결 램프
|
||||
drawing = (ROOT / "B08_Quantity/B08_Quantity_UI_Drawing.ts").read_text(encoding="utf-8")
|
||||
assert "readTemplate" not in drawing # 층 폴백 없음
|
||||
assert "B08_Quantity_Sheets_NoCopy" in drawing
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""160-2 B08 구조물 집계표 「미지정」 — 측점 옆 열 글 · 같은 조합 열 칸 표기(화면만).
|
||||
"""160-2 B08 구조물 집계표 빈 조합 칸 글(198-1 부터 미연결 램프 호버 글 · 「미지정」 열 · 칸 표기는 지움).
|
||||
|
||||
`B08_Quantity_Summary_Data.ts` 를 `common_util_summary_item.ts` 와 이어 붙여 node 로 돌림(61-1 시험과 같은 꼴).
|
||||
"""
|
||||
@@ -47,31 +47,23 @@ FACILITIES = [
|
||||
]
|
||||
|
||||
|
||||
def test_미지정_글과_조합_칸():
|
||||
def test_빈_조합_칸_글():
|
||||
out = _run(
|
||||
f"\nconst f = {json.dumps(FACILITIES, ensure_ascii=False)};"
|
||||
"\nconst at = (s) => unlinkedAt(f, s);"
|
||||
"\nconsole.log(JSON.stringify({"
|
||||
" t100: unassignedText(at(100), '본체'), t160: unassignedText(at(160), '본체'),"
|
||||
" t0: unassignedText(at(0), '본체'),"
|
||||
" c100: [...unassignedCombos(at(100))], c160: [...unassignedCombos(at(160))] }));"
|
||||
" t0: unassignedText(at(0), '본체') }));"
|
||||
)
|
||||
assert out["t100"] == "배관: 본체 · 관 / 세월교: 유출 구조"
|
||||
assert out["t160"] == "BOX" and out["t0"] == ""
|
||||
assert out["c100"] == ["system||SS2"] # 연결된 칸 · 고른 조합 없는 칸은 뺌
|
||||
assert out["c160"] == []
|
||||
|
||||
|
||||
def test_화면_연결():
|
||||
summary = (ROOT / "B08_Quantity/B08_Quantity_UI_Summary.ts").read_text(encoding="utf-8")
|
||||
assert (
|
||||
'unassignedText(at, L("B08_Quantity_Link_Body"))' in summary
|
||||
'unassignedText(unlinkedAt(unlinked, station), L("B08_Quantity_Link_Body"))' in summary
|
||||
) # 칸 이름 = 모달과 같은 규칙
|
||||
assert (
|
||||
'key: "unassigned", label: missingHead' in summary
|
||||
and "frozen: hasMissing ? 2 : 1" in summary
|
||||
)
|
||||
assert "...markOf(here[i])," in summary and "filter((id) => comboIds.has(id))" in summary
|
||||
assert '${L("B08_Quantity_Summary_Unlinked")}' in summary # 「· 미연결」 측점 표기 그대로
|
||||
assert 'key: "unassigned"' not in summary and "unassignedCombos" not in summary # 198-1
|
||||
locale = (ROOT / "ui_template/ui_template_locale_b4.ts").read_text(encoding="utf-8")
|
||||
assert 'B08_Quantity_Summary_Unassigned: ["미지정", "Unassigned"]' in locale
|
||||
assert "B08_Quantity_Summary_Unassigned" not in locale
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
"""198-1 B08 구조물 집계표 — 미연결 = 측점 칸 왼쪽 램프 하나 · 「미지정」 열 지움.
|
||||
|
||||
- 칸 class: 화면 소스의 `cellClass` 를 떼어 공용 표 `renderDataTableHtml` 로 그림(Node) — 미연결 줄 측점 칸만 램프
|
||||
- 호버 글: 화면 소스의 호버 함수를 떼어 가짜 칸으로 부름 — 「구조물 조합 미연결 — 빈 칸 이름」 · 연결 줄은 없음
|
||||
- CSS: 램프 = 경고 노랑 토큰(177-1) · 밝음 · 어두움 둘 다
|
||||
- 줄 값 = 측점 + 서버 값뿐(「미지정」 · 「· 미연결」 글 없음 → 수량 · 합계 그대로)
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
TS = ROOT / "config" / "node_modules" / "typescript"
|
||||
UI = (ROOT / "B08_Quantity" / "B08_Quantity_UI_Summary.ts").read_text(encoding="utf-8")
|
||||
|
||||
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 _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)
|
||||
|
||||
|
||||
def _lamp_class() -> str:
|
||||
m = re.search(r'const LAMP_CLASS = "([^"]+)";', UI)
|
||||
assert m
|
||||
return m.group(1)
|
||||
|
||||
|
||||
def test_미연결_줄_측점_칸만_램프():
|
||||
cell = re.search(r"cellClass: (\(i, key\) => .*?),\n", UI)
|
||||
assert cell
|
||||
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 LAMP_CLASS = {json.dumps(_lamp_class())};
|
||||
const missing = ["", "BOX", ""];
|
||||
const cellClass = {cell.group(1)};
|
||||
const html = box.exports.renderDataTableHtml({{
|
||||
columns: [{{ key: "station", label: "측점" }}, {{ key: "c1", label: "조합" }}],
|
||||
rows: [{{ station: "0+000" }}, {{ station: "0+020" }}, {{ station: "0+040", c1: 1 }}],
|
||||
frozen: 1, empty: "", cellClass }});
|
||||
const rows = html.split("<tbody>")[1].split("</tr>");
|
||||
console.log(JSON.stringify({{
|
||||
count: html.split(LAMP_CLASS).length - 1,
|
||||
row1: rows[1],
|
||||
row0: rows[0],
|
||||
}}));
|
||||
"""
|
||||
)
|
||||
assert got["count"] == 1
|
||||
assert f'<td class="is-frozen is-edge {_lamp_class()}"' in got["row1"] # 측점 칸(첫 칸)
|
||||
assert _lamp_class() not in got["row0"]
|
||||
|
||||
|
||||
def test_호버_글_까닭_한_줄():
|
||||
hover = re.search(
|
||||
r"attachHoverInfo\(\n\s*table\.root,\n\s*(\(cell\) => \{.*?\n\s*\}),\n", UI, re.S
|
||||
)
|
||||
assert hover
|
||||
got = _node(
|
||||
PRELUDE
|
||||
+ f"""
|
||||
const L = (k) => ({{ B08_Quantity_Summary_LampTip: "구조물 조합 미연결" }})[k];
|
||||
const missing = ["", "배관: 본체 · 관 / 세월교: 유출 구조"];
|
||||
const text = eval(js("(" + {json.dumps(hover.group(1))} + ")"));
|
||||
const cell = (i) => ({{ closest: () => ({{ dataset: {{ i: String(i) }} }}) }});
|
||||
console.log(JSON.stringify([text(cell(1)), text(cell(0)) || null]));
|
||||
"""
|
||||
)
|
||||
assert got == ["구조물 조합 미연결 — 배관: 본체 · 관 / 세월교: 유출 구조", None]
|
||||
assert 'import { attachHoverInfo } from "@ui/ui_template_hover_info";' in UI
|
||||
assert "`td.${LAMP_CLASS}`," in UI # 램프 칸에만
|
||||
locale = (ROOT / "ui_template" / "ui_template_locale_b4.ts").read_text(encoding="utf-8")
|
||||
assert 'B08_Quantity_Summary_LampTip: ["구조물 조합 미연결",' in locale
|
||||
|
||||
|
||||
def test_미지정_열_없음_줄_값_그대로():
|
||||
assert 'key: "unassigned"' not in UI and "B08_Quantity_Summary_Unassigned" not in UI
|
||||
assert 'L("B08_Quantity_Summary_Unlinked")' not in UI # 측점 「· 미연결」 글 지움
|
||||
assert "frozen: 1," in UI
|
||||
rows = re.search(r"rows: stations\.map\(\(station, i\) => \(\{(.*?)\}\)\),", UI, re.S)
|
||||
assert rows and [s.strip() for s in rows.group(1).strip().split("\n")] == [
|
||||
"station: labels[i],",
|
||||
"...values.get(stationKey(station)),",
|
||||
]
|
||||
|
||||
|
||||
def test_램프_경고_노랑_토큰():
|
||||
css = (ROOT / "B08_Quantity" / "B08_Quantity_UI_Page.css").read_text(encoding="utf-8")
|
||||
m = re.search(
|
||||
r'\[data-b08-summary="table"\] td\.' + re.escape(_lamp_class()) + r"::before\s*\{([^}]*)\}",
|
||||
css,
|
||||
)
|
||||
assert m
|
||||
assert re.search(r"background:\s*var\(--color-warning\)", m.group(1))
|
||||
assert "border-radius: 50%" in m.group(1)
|
||||
theme = (ROOT / "ui_template" / "ui_template_theme.css").read_text(encoding="utf-8")
|
||||
assert len(re.findall(r"--color-warning:\s*#", theme)) >= 2 # 밝음 · 어두움
|
||||
@@ -96,5 +96,5 @@ def test_집계표는_공용_표():
|
||||
# PLAN 70-2 — 공용 많은 자료 표 · 측점 열 고정 · 칸은 빈칸(「—」 아님)
|
||||
ui = (ROOT / "B08_Quantity" / "B08_Quantity_UI_Summary.ts").read_text(encoding="utf-8")
|
||||
assert "createDataTable(" in ui and "@ui/ui_template_data_table" in ui
|
||||
assert "frozen: hasMissing ? 2 : 1" in ui and 'empty: ""' in ui and "onRowClick" in ui
|
||||
assert "frozen: 1," in ui and 'empty: ""' in ui and "onRowClick" in ui
|
||||
assert 'document.createElement("table")' not in ui
|
||||
|
||||
Reference in New Issue
Block a user