feat(z01): 기초단가 다섯을 한 표로 모으는 이름표 · 줄 열쇠·null 판정
- `merged_tables` 다섯(노임·자재·유가·제비율·기계) — 열 62. **값은 안 옮김**, 열 이름·단위·숨김과 `editable`(고칠 수 있나)만 담음. 계산값 넷은 기계에만 있고 `editable: false` - `machine_cost_chain` 다섯 걸음 — 손료(취득가×1,000×손료계수) · 연료(연료량×유가×(1+잡재료)) · 조종원(일 노임÷8×제수당) · 암 할증 · 시간당 기계경비. **밑값 11 / 계산값 4** 를 가름 · 기계가 유가·노임 표를 물어 갱신 차례가 갈림을 적음 - `merge_findings` 네 갈래 — 이름 다른 같은 열 2 · 한쪽에만 있는 열 4 · 단위·축 어긋남 4 · 부딪힘 2 - `row_keys` 다섯 판정(브레인 ①) — 자재 `item_code`·기계 `machine_code` 는 전수 겹침 0 으로 **있음** · 노임은 두 코드 공간이라 `출처+직종코드` 로 묶어야 함 · 유가·제비율은 **줄 열쇠 없음**(지어내지 않음) - `null_is_real` 여섯(브레인 ②) — ⭐ 노임 일 노임이 **30 줄에 아예 없음**(미조사가 제값) · 기계 운전경비에 **명시 null 12** · 되돌리기 null 과 뜻이 겹치는 자리를 규칙과 함께 적음 - 시험 36건(8건 늘) — 계산값이 기계 밖으로 새거나 줄 열쇠·null 판정이 빠지면 빨강 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFCnEYNH4tsS2MbHvzBhZk
This commit is contained in:
@@ -447,3 +447,94 @@ def test_미결은_미판정으로_표시된다(labels):
|
||||
column = labels["synthetic_tables"]["@values"]["columns"][3]
|
||||
assert column["key"] == "@undecided"
|
||||
assert column["name_ko"] == "미판정"
|
||||
|
||||
|
||||
MERGED_KEYS = ("labor", "material", "oil", "rates", "machine")
|
||||
|
||||
|
||||
def test_기초단가_다섯이_다_있다(labels):
|
||||
merged = {m["key"]: m for m in labels["merged_tables"]}
|
||||
assert tuple(merged) == MERGED_KEYS
|
||||
for entry in merged.values():
|
||||
assert entry["name_ko"].strip()
|
||||
assert entry["summary"].strip()
|
||||
assert entry["columns"], entry["key"]
|
||||
assert entry["sources"], entry["key"]
|
||||
|
||||
|
||||
def test_합친_표의_열마다_이름과_고칠수있나가_있다(labels):
|
||||
bad = []
|
||||
for entry in labels["merged_tables"]:
|
||||
for column in entry["columns"]:
|
||||
if not column["name_ko"].strip():
|
||||
bad.append(f"{entry['key']}/{column['key']} — 이름 없음")
|
||||
if not isinstance(column.get("editable"), bool):
|
||||
bad.append(f"{entry['key']}/{column['key']} — editable 없음")
|
||||
assert not bad, bad
|
||||
|
||||
|
||||
def test_계산값은_기계에만_있고_못_고친다(labels):
|
||||
"""⭐ 밑값만 고칠 수 있다 — 계산값을 손으로 고치면 밑값과 어긋나 되짚을 수 없다."""
|
||||
derived = {
|
||||
entry["key"]: [c["key"] for c in entry["columns"] if not c["editable"]]
|
||||
for entry in labels["merged_tables"]
|
||||
}
|
||||
assert derived["machine"] == [
|
||||
"hourly_loss_krw",
|
||||
"hourly_fuel_krw",
|
||||
"hourly_operator_krw",
|
||||
"hourly_total_krw",
|
||||
]
|
||||
for key in ("labor", "material", "oil", "rates"):
|
||||
assert derived[key] == [], f"{key} 에 계산값이 생겼다"
|
||||
|
||||
|
||||
def test_기계_계산_사슬이_다섯_걸음으로_적혀_있다(labels):
|
||||
chain = labels["machine_cost_chain"]
|
||||
assert len(chain["steps"]) == 5
|
||||
for step in chain["steps"]:
|
||||
assert step["step"].strip() and step["formula"].strip()
|
||||
assert "밑값" in chain["editable_rule"] and "계산값" in chain["editable_rule"]
|
||||
# 기계는 유가·노임 표를 문다 — 갱신 차례가 여기서 갈린다.
|
||||
assert "유가" in chain["cross_table"] and "노임" in chain["cross_table"]
|
||||
|
||||
|
||||
def test_열_맞대기_어긋남이_네_갈래로_적혀_있다(labels):
|
||||
findings = labels["merge_findings"]
|
||||
assert set(findings) == {
|
||||
"renamed_same_column",
|
||||
"one_side_only",
|
||||
"unit_or_axis_mismatch",
|
||||
"collision",
|
||||
}
|
||||
assert all(findings[k] for k in findings)
|
||||
|
||||
|
||||
def test_줄_열쇠가_다섯_다_판정돼_있다(labels):
|
||||
"""덮개가 원본 줄을 붙드는 끈 — 없는 자료는 「없음」으로 내고 지어내지 않는다."""
|
||||
keys = {r["table"]: r for r in labels["row_keys"]}
|
||||
assert set(keys) == set(MERGED_KEYS)
|
||||
for entry in keys.values():
|
||||
assert entry["verdict"].strip() and entry["key"] and entry["checked"].strip()
|
||||
assert keys["material"]["key"] == ["item_code"]
|
||||
assert keys["machine"]["key"] == ["machine_code"]
|
||||
# 한 칸으로는 안 되는 둘 — 묶어야 한다.
|
||||
assert len(keys["labor"]["key"]) > 1
|
||||
assert keys["oil"]["verdict"].startswith("없음")
|
||||
assert keys["rates"]["verdict"].startswith("없음")
|
||||
|
||||
|
||||
def test_null_이_제값인_열이_적혀_있다(labels):
|
||||
"""되돌리기 null 과 원본의 「값 없음」이 겹치는 자리 — 겹치면 미조사가 값 지움으로 바뀐다."""
|
||||
block = labels["null_is_real"]
|
||||
assert block["columns"]
|
||||
for row in block["columns"]:
|
||||
assert row["table"] in MERGED_KEYS
|
||||
assert row["column"].strip() and row["why"].strip()
|
||||
assert isinstance(row["rows"], int)
|
||||
# 가장 위험한 자리 — 노임 일 노임이 없는 줄(미조사)
|
||||
wage = [
|
||||
r for r in block["columns"] if r["table"] == "labor" and "daily_wage_krw" in r["column"]
|
||||
]
|
||||
assert wage and wage[0]["rows"] == 30
|
||||
assert "되돌리기" in block["rule"]
|
||||
|
||||
Reference in New Issue
Block a user