Merge remote-tracking branch 'origin/dev' into sub_desktop_1
This commit is contained in:
@@ -24,9 +24,34 @@ SOURCE = PROJECT_ROOT / "Z01_MasterData" / "Z01_MasterData_UI_Cells.ts"
|
||||
_RUNNER = """
|
||||
import { writeFileSync } from "node:fs";
|
||||
import {
|
||||
cellText, clampPage, columnTitle, latestOnly, pageCount, rowCells, shownColumns,
|
||||
cellInfo, cellText, clampPage, columnTitle, latestOnly, pageCount, parseCellInput, rowCells,
|
||||
shownColumns,
|
||||
} from "./Z01_MasterData_UI_Cells.js";
|
||||
|
||||
// 기초단가 — 표 수준 editable·locked·formula · 줄 수준 @id·@overrides·@formula (2026-09-15 브레인)
|
||||
const meta = {
|
||||
editable: ["daily_wage_krw"],
|
||||
locked: { hourly_krw: "계산으로 나옴" },
|
||||
formula: { hourly_krw: "기계경비 = 손료 + 연료 + 노무" },
|
||||
};
|
||||
const machineRow = {
|
||||
"@id": "M-001",
|
||||
daily_wage_krw: 300000,
|
||||
hourly_krw: 12340,
|
||||
"@overrides": { daily_wage_krw: { original: 250000, value: 300000 } },
|
||||
"@formula": { hourly_krw: "12,340 = 8,200 + 2,140 + 2,000" },
|
||||
};
|
||||
// 판정은 서버 state 만 — edited · source_changed · orphan (화면이 original≠current 로 따로 안 셈)
|
||||
const withState = (state, current) => ({
|
||||
"@id": "M-002",
|
||||
daily_wage_krw: 300000,
|
||||
"@overrides": { daily_wage_krw: { original: 250000, value: 300000, current, state } },
|
||||
});
|
||||
// 값은 같아도 서버가 바뀜이라 하면 바뀜 · 값이 달라도 서버가 edited 라 하면 edited
|
||||
const changedRow = withState("source_changed", 250000);
|
||||
const sameRow = withState("edited", 270000);
|
||||
const orphanRow = withState("orphan", undefined);
|
||||
|
||||
const wait = (ms, value, fail) =>
|
||||
new Promise((ok, no) => setTimeout(() => (fail ? no(new Error(value)) : ok(value)), ms));
|
||||
const fetchLatest = latestOnly(wait);
|
||||
@@ -62,6 +87,21 @@ writeFileSync(process.argv[2], JSON.stringify({
|
||||
race: race.map((v) => v ?? null),
|
||||
raceError: raceError.map((v) => v ?? null),
|
||||
latestError,
|
||||
info: [
|
||||
cellInfo(meta, machineRow, "daily_wage_krw"),
|
||||
cellInfo(meta, machineRow, "hourly_krw"),
|
||||
cellInfo({}, { name: "x" }, "name"),
|
||||
cellInfo(meta, changedRow, "daily_wage_krw"),
|
||||
cellInfo(meta, sameRow, "daily_wage_krw"),
|
||||
cellInfo(meta, orphanRow, "daily_wage_krw"),
|
||||
],
|
||||
parsed: [
|
||||
parseCellInput("12,340", 100),
|
||||
parseCellInput("abc", 100),
|
||||
parseCellInput("", 100),
|
||||
parseCellInput("보통인부2", "보통인부"),
|
||||
parseCellInput("3.5", null),
|
||||
].map((v) => (v === undefined ? "invalid" : v)),
|
||||
}));
|
||||
"""
|
||||
|
||||
@@ -109,3 +149,27 @@ def test_칸_글자와_숨김_열(tmp_path: Path) -> None:
|
||||
assert got["race"] == [None, "new"]
|
||||
assert got["raceError"] == [None, "new"]
|
||||
assert got["latestError"] == "thrown boom"
|
||||
# 고칠 수 있는 칸 · 고쳐짐이면 원래 값 · 못 고치는 칸은 까닭과 식 · 줄마다 값 넣은 식
|
||||
wage, hourly, plain, changed, same, orphan = got["info"]
|
||||
# state 가 안 온 고친 칸은 화면이 때우지 않고 「missing」으로 드러냄(서버 버그)
|
||||
assert wage == {
|
||||
"editable": True,
|
||||
"reason": None,
|
||||
"overridden": True,
|
||||
"original": 250000,
|
||||
"state": "missing",
|
||||
"rule": None,
|
||||
"filled": None,
|
||||
}
|
||||
# 원본이 바뀐 고친 칸 — 고친 값은 그대로 쓰되 또렷이 알림 · 지금 원본 값을 곁들임(브레인)
|
||||
assert changed["state"] == "source_changed" and changed["current"] == 250000
|
||||
assert same["state"] == "edited" and "current" not in same
|
||||
assert orphan["state"] == "orphan"
|
||||
assert hourly["state"] is None and plain["state"] is None
|
||||
assert hourly["editable"] is False and hourly["reason"] == "계산으로 나옴"
|
||||
assert hourly["overridden"] is False and "original" not in hourly
|
||||
assert hourly["rule"] == "기계경비 = 손료 + 연료 + 노무"
|
||||
assert hourly["filled"] == "12,340 = 8,200 + 2,140 + 2,000"
|
||||
assert plain["editable"] is False and plain["reason"] is None and plain["rule"] is None
|
||||
# 수 칸은 쉼표를 떼고 수로 · 못 읽으면 저장 안 함 · 글자 칸은 글자 그대로 · 빈 칸에 수를 적으면 수
|
||||
assert got["parsed"] == [12340, "invalid", "invalid", "보통인부2", 3.5]
|
||||
|
||||
Reference in New Issue
Block a user