Merge branch 'main_laptop_1' of C:/Program_coding/임도설계 및 견적자동화 프로그램 개발 into sub_laptop_3
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀
|
||||
"""795-1 SK 로직 사본 — 저장 때 M01 닫힌 묶음을 찍고 셈은 사본으로(임시 storage · M01 은 메모리 덮개).
|
||||
|
||||
① M01 로직 줄 바꿔도 사본 SK 금액 그대로 ② 노임 바꿔도 [단가 갱신] 전엔 그대로 · 누르면 따라감
|
||||
③ [재생성] 뒤 고친 칸 다시 얹힘 · 못 얹은 칸 알림 ④ M01 새 판 배지 ⑤ 지워진 키 = 마지막 값
|
||||
⑥ 옛 SK(사본 없음) = 옛 길 · 지문 그대로 ⑦ 가져온 식 SK 같은 규칙.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from M01_MasterData import M01_MasterData_Store as m01
|
||||
from M02_MasterTemplete import M02_Labor_Doc as labor
|
||||
from M02_MasterTemplete import M02_Labor_Ref as refs
|
||||
from M02_MasterTemplete import M02_Library_Same as same
|
||||
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
||||
from M02_MasterTemplete import M02_Sangeun_Calc as calc
|
||||
from M02_MasterTemplete import M02_Sangeun_Copy as skc
|
||||
from M02_MasterTemplete import M02_Sangeun_Imported as imp
|
||||
from resources.tester.test_m02_labor_ref import world # noqa: F401 — 같은 임시 층
|
||||
|
||||
PCT = "GC001109" # 원/㎡ · 인력 둘 + 「노무비 * 3 / 100」
|
||||
MAN = "LB000002" # 보통인부
|
||||
|
||||
|
||||
def _live():
|
||||
return m01.loaded()[1]
|
||||
|
||||
|
||||
def _fake(monkeypatch, rows=(), drop=()):
|
||||
"""M01 바꿈 흉내 — 지금 색인 위에 바뀐 줄 · 지운 키(정본 파일 안 고침)."""
|
||||
files, live = m01.loaded()
|
||||
fake = skc.Copy(live, [copy.deepcopy(r) for r in rows])
|
||||
for key in drop:
|
||||
skc.Copy._own(fake.index, live.index, key[:2]).pop(key, None)
|
||||
monkeypatch.setattr(m01, "loaded", lambda: (files, fake))
|
||||
return fake
|
||||
|
||||
|
||||
def _sk(folder, **doc):
|
||||
with store.at(folder):
|
||||
body = {"이름": "sub2임시 사본", "단위": "㎡", "더한줄": [], **doc}
|
||||
return refs.create("sangeun", body)["이름"]
|
||||
|
||||
|
||||
def _doc(folder, key):
|
||||
with store.at(folder):
|
||||
return store.read("sangeun", key)["문서"]
|
||||
|
||||
|
||||
def _save(folder, key, doc):
|
||||
with store.at(folder):
|
||||
store.write("sangeun", key, store.read("sangeun", key)["판"], doc)
|
||||
|
||||
|
||||
def _calc(folder, doc):
|
||||
with store.at(folder):
|
||||
return calc.calc_doc(doc, None, False)
|
||||
|
||||
|
||||
def _sum(folder, key):
|
||||
return _calc(folder, _doc(folder, key))["기준"]["계"]
|
||||
|
||||
|
||||
def _cids(folder, key):
|
||||
return [x["cid"] for x in _calc(folder, _doc(folder, key))["줄"]]
|
||||
|
||||
|
||||
def _changed(row, at=0):
|
||||
row = copy.deepcopy(row)
|
||||
row["호표"][at]["수량"] = f"({row['호표'][at]['수량']}) * 2"
|
||||
return row
|
||||
|
||||
|
||||
def test_copy_stamped_and_logic_change_kept(world, monkeypatch):
|
||||
"""① · ④ 저장 때 사본(로직 · 단가 갈래) · M01 로직 바꿔도 금액 그대로 · 배지만."""
|
||||
me = world["personal"]
|
||||
key = _sk(me, 바탕={"로직": PCT})
|
||||
got = _doc(me, key)["사본"]
|
||||
assert PCT in {r["키"] for r in got["로직"]}
|
||||
assert got["단가"] and all(r["키"][:2] in skc.RES for r in got["단가"])
|
||||
assert not any(r["키"][:2] in skc.RES for r in got["로직"])
|
||||
first = _calc(me, _doc(me, key))
|
||||
assert first["사본"]["M01새판"] is False and first["사본"]["지운키"] == []
|
||||
was = first["기준"]["계"]
|
||||
plain = labor.run_line(_live(), PCT, {})["기준"]["계"]
|
||||
_fake(monkeypatch, [_changed(_live().logic(PCT))])
|
||||
assert labor.run_line(m01.loaded()[1], PCT, {})["기준"]["계"] != plain # M01 셈은 바뀜
|
||||
now = _calc(me, _doc(me, key))
|
||||
assert now["기준"]["계"] == was
|
||||
assert now["사본"]["M01새판"] is True
|
||||
|
||||
|
||||
def test_price_refresh_only_on_press(world, monkeypatch):
|
||||
"""② 노임 바꿈 → 그대로 · [단가 갱신] 미리 셈 · 저장 = 새 SK 와 같은 값 · 바뀐자원."""
|
||||
me = world["personal"]
|
||||
key = _sk(me, 바탕={"로직": PCT})
|
||||
was = _sum(me, key)
|
||||
lb = _cids(me, key)[0].split(":")[1].split("#")[0]
|
||||
row = copy.deepcopy(_live().get(lb))
|
||||
row["값"] = row["값"] * 2
|
||||
_fake(monkeypatch, [row])
|
||||
assert _sum(me, key) == was # 누르기 전 = 단가 기준 시점 값
|
||||
fresh = _sum(me, _sk(me, 바탕={"로직": PCT})) # 지금 M01 로 새로 찍은 SK
|
||||
assert fresh != was
|
||||
with store.at(me):
|
||||
got = skc.preview(_doc(me, key), skc.PRICE)
|
||||
assert got["전"]["계"] == was and got["후"]["계"] == fresh
|
||||
assert [x["키"] for x in got["바뀐자원"]] == [lb]
|
||||
assert got["문서"][skc.JOB] == skc.PRICE
|
||||
_save(me, key, got["문서"]) # [저장] = 서버가 할일 적용
|
||||
saved = _doc(me, key)
|
||||
assert skc.JOB not in saved and _sum(me, key) == fresh
|
||||
assert saved["사본"]["단가시점"] >= saved["사본"]["시점"]
|
||||
|
||||
|
||||
def test_regen_reapplies_covers(world, monkeypatch):
|
||||
"""③ [재생성] — 덮개 · 까닭 새 사본에 다시 얹힘 · 없어진 줄 덮개 = 못얹은 · 배지 꺼짐."""
|
||||
me = world["personal"]
|
||||
probe = _sk(me, 바탕={"로직": PCT})
|
||||
one, two = _cids(me, probe)[:2]
|
||||
covers = {one: {"qty": 0.5}, two: {"qty": 0.7}}
|
||||
key = _sk(me, 바탕={"로직": PCT}, 덮개=covers, 까닭={one: "현장 실측"})
|
||||
row = copy.deepcopy(_live().logic(PCT))
|
||||
row["호표"] = [x for n, x in enumerate(row["호표"]) if n != 1] # 둘째 줄 없앤 새 판
|
||||
_fake(monkeypatch, [row])
|
||||
with store.at(me):
|
||||
got = skc.preview(_doc(me, key), skc.REGEN)
|
||||
assert [x["cid"] for x in got["못얹은"]] == [two]
|
||||
assert got["전"]["계"] != got["후"]["계"]
|
||||
_save(me, key, got["문서"])
|
||||
doc = _doc(me, key)
|
||||
assert doc["덮개"][one]["qty"] == 0.5 and doc["까닭"][one] == "현장 실측"
|
||||
now = _calc(me, doc)
|
||||
assert now["줄"][0]["덮개"] == ["qty"]
|
||||
assert now["사본"]["M01새판"] is False
|
||||
assert now["기준"]["계"] == got["후"]["계"]
|
||||
|
||||
|
||||
def test_deleted_keys_keep_last_value(world, monkeypatch):
|
||||
"""⑤ 사본이 부르는 M01 키(바탕 로직 · 노임)가 지워져도 마지막 값 · 지운키 표지."""
|
||||
me = world["personal"]
|
||||
key = _sk(me, 바탕={"로직": PCT})
|
||||
was = _sum(me, key)
|
||||
lb = _cids(me, key)[0].split(":")[1].split("#")[0]
|
||||
_fake(monkeypatch, drop=[PCT, lb])
|
||||
with pytest.raises(Exception):
|
||||
m01.loaded()[1].logic(PCT)
|
||||
now = _calc(me, _doc(me, key))
|
||||
assert now["기준"]["계"] == was
|
||||
assert {PCT, lb} <= set(now["사본"]["지운키"])
|
||||
with store.at(me):
|
||||
got = skc.preview(_doc(me, key), skc.PRICE)
|
||||
assert {"키": lb, "이름": got["바뀐자원"][0]["이름"], "지워짐": True} in got["바뀐자원"]
|
||||
assert got["후"]["계"] == was
|
||||
|
||||
|
||||
def test_old_sk_without_copy_old_path(world, monkeypatch):
|
||||
"""⑥ 사본 없는 옛 SK = M01 지금 값(옛 길) · 같은 내용 지문 = 새 사본 SK 와 같음."""
|
||||
me = world["personal"]
|
||||
key = _sk(me, 바탕={"로직": PCT})
|
||||
path = me / "sangeun" / f"{key}.json"
|
||||
raw = json.loads(path.read_bytes())
|
||||
old = {k: v for k, v in raw.items() if k != "사본"}
|
||||
path.write_text(json.dumps(old, ensure_ascii=False), encoding="utf-8")
|
||||
fresh = _sk(me, 바탕={"로직": PCT})
|
||||
assert _sum(me, key) == _sum(me, fresh)
|
||||
assert "사본" not in _calc(me, _doc(me, key))
|
||||
with store.at(me):
|
||||
assert same.Same().finger("sangeun", old) == same.Same().finger("sangeun", _doc(me, fresh))
|
||||
_fake(monkeypatch, [_changed(_live().logic(PCT))])
|
||||
moved = labor.run_line(m01.loaded()[1], PCT, {})["기준"]["계"]
|
||||
assert _sum(me, key) == pytest.approx(moved, abs=1) # 옛 길 = 따라감
|
||||
assert _sum(me, fresh) != _sum(me, key) # 사본 SK = 그대로
|
||||
with store.at(me): # 판 다른 두 SK = 지문 다름(오판 막음)
|
||||
assert same.Same().finger("sangeun", _doc(me, key)) != same.Same().finger(
|
||||
"sangeun", _doc(me, fresh)
|
||||
)
|
||||
|
||||
|
||||
def _imported_row():
|
||||
man = {"종류": "인력", "이름": "보통인부", "단위": "인", "수량": "0.5", "비목": "노무비"}
|
||||
mat = {"종류": "재료", "이름": "각재", "단위": "㎥", "수량": "0.01", "비목": "재료비"}
|
||||
return {
|
||||
"이름": "sub2임시 가져온",
|
||||
"결과단위": "원/㎡",
|
||||
"호표": [{**man, "단가": 165545, "이음": MAN}, {**mat, "단가": 500661}],
|
||||
}
|
||||
|
||||
|
||||
def test_imported_same_rule(world, monkeypatch):
|
||||
"""⑦ 가져온 식 SK(단가기준 우리) — 이음 노임 바꿔도 그대로 · [단가 갱신] 뒤 따라감."""
|
||||
me = world["personal"]
|
||||
with store.at(me):
|
||||
key = imp.create(_imported_row(), None, "sub2임시 가져온")["이름"]
|
||||
doc = _doc(me, key)
|
||||
assert MAN in {r["키"] for r in doc["사본"]["단가"]}
|
||||
with store.at(me):
|
||||
ours = imp.to_price(doc, "우리")["문서"]
|
||||
_save(me, key, ours)
|
||||
was = _sum(me, key)
|
||||
row = copy.deepcopy(_live().get(MAN))
|
||||
row["값"] = row["값"] * 2
|
||||
_fake(monkeypatch, [row])
|
||||
assert _sum(me, key) == was
|
||||
with store.at(me):
|
||||
got = skc.preview(_doc(me, key), skc.PRICE)
|
||||
assert [x["키"] for x in got["바뀐자원"]] == [MAN]
|
||||
assert got["후"]["노무비"] == pytest.approx(got["전"]["노무비"] * 2, abs=1)
|
||||
@@ -0,0 +1,186 @@
|
||||
# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀
|
||||
"""795-2 일위대가 · 사전조합(SC) 로직 사본 — 임시 storage · M01 은 메모리 덮개(정본 안 고침).
|
||||
|
||||
① 저장 때 사본 · M01 로직 바꿔도 일위대가 · SC 금액 그대로 · 배지 ② 노임 바꿔도 [단가 갱신] 전엔
|
||||
그대로 · 누르면 따라감 ③ [재생성] 뒤 줄 덮개 다시 얹힘 · 못 얹은 칸 알림 ④ 층 복사 · 열 복사 =
|
||||
사본 그대로 ⑤ TS 짝(Labor_Calc.ts settle) 같은 금액 ⑥ 사본 없는 옛 문서 = 옛 길.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from M01_MasterData import M01_MasterData_Store as m01
|
||||
from M02_MasterTemplete import M02_Labor_Copy as lc
|
||||
from M02_MasterTemplete import M02_Labor_Doc as labor
|
||||
from M02_MasterTemplete import M02_Labor_Ref as refs
|
||||
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
||||
from M02_MasterTemplete import M02_Sangeun_Copy as skc
|
||||
from resources.tester.test_795_1_sk_copy import _changed, _fake, _live
|
||||
from resources.tester.test_m02_labor_calc_mirror import _same, _ts
|
||||
from resources.tester.test_m02_labor_ref import world # noqa: F401 — 같은 임시 층
|
||||
|
||||
PCT = "GC001109" # 원/㎡ · 인력 둘(LB000036 · LB000002) + 「노무비 * 3 / 100」
|
||||
LB = "LB000036"
|
||||
COVER = {"덮개": {f"labor:{LB}#0": {"qty": 0.5}}}
|
||||
COL = "sub2임시"
|
||||
|
||||
|
||||
def _sc(folder, lines):
|
||||
with store.at(folder):
|
||||
body = {"이름": "sub2임시 조합", "단위": "㎡", "담은로직": lines}
|
||||
return refs.create("precombo", body)["이름"]
|
||||
|
||||
|
||||
def _read(folder, kind, key):
|
||||
with store.at(folder):
|
||||
return store.read(kind, key)["문서"]
|
||||
|
||||
|
||||
def _write(folder, kind, key, doc):
|
||||
with store.at(folder):
|
||||
have = (
|
||||
store.read(kind, key)["판"] if (store.root() / kind / f"{key}.json").is_file() else ""
|
||||
)
|
||||
store.write(kind, key, have, doc)
|
||||
|
||||
|
||||
def _labor(folder, lines):
|
||||
_write(folder, "labor", COL, {"열": COL, "담은로직": lines, "자재": []})
|
||||
return _read(folder, "labor", COL)
|
||||
|
||||
|
||||
def _calc(folder, key, doc=None):
|
||||
"""화면 셈 길(`Labor_Router._calc`) — 열 = 일위대가 열 · SC 키."""
|
||||
with store.at(folder):
|
||||
kind = "precombo" if key.startswith("SC-") else "labor"
|
||||
got = labor.clean({**(doc or store.read(kind, key)["문서"]), "열": key})
|
||||
return lc.mark(labor.calc(got, {}), lc.settle(got))
|
||||
|
||||
|
||||
def _unit(folder, key):
|
||||
"""SC 1 단위 값(쓰는 쪽 `Expand` · 안 줄 수량 1)."""
|
||||
ref = {"층": "personal", "주인": "7/42", "키": key}
|
||||
with store.at(folder):
|
||||
lines = refs.read_ref(ref)["담은로직"]
|
||||
given = {f"{refs.ref_id(ref)}#{i}": 1 for i in range(len(lines))}
|
||||
return refs.Expand(m01.loaded()[1], given=given)(ref)["기준"]["계"]
|
||||
|
||||
|
||||
def _double(key):
|
||||
row = copy.deepcopy(_live().get(key))
|
||||
row["값"] = row["값"] * 2
|
||||
return row
|
||||
|
||||
|
||||
def test_copy_stamped_logic_change_kept(world, monkeypatch):
|
||||
"""① 일위대가 · SC 저장 때 사본 · M01 로직 바꿔도 금액 그대로 · M01 새 판 배지."""
|
||||
me = world["personal"]
|
||||
sc = _sc(me, [{"로직": PCT, "수량": {"손": 1}}])
|
||||
doc = _labor(me, [{"로직": PCT, "수량": {"손": 2}}])
|
||||
for got in (doc, _read(me, "precombo", sc)):
|
||||
assert PCT in {r["키"] for r in got["사본"]["로직"]}
|
||||
assert LB in {r["키"] for r in got["사본"]["단가"]}
|
||||
was = (_calc(me, COL)["반영합"]["계"], _calc(me, sc)["기준합"]["계"], _unit(me, sc))
|
||||
assert _calc(me, COL)["사본"]["M01새판"] is False
|
||||
_fake(monkeypatch, [_changed(_live().logic(PCT))])
|
||||
assert labor.run_line(m01.loaded()[1], PCT, {})["기준"]["계"] != was[2] # M01 셈은 바뀜
|
||||
now = (_calc(me, COL)["반영합"]["계"], _calc(me, sc)["기준합"]["계"], _unit(me, sc))
|
||||
assert now == was
|
||||
assert _calc(me, COL)["사본"]["M01새판"] is True
|
||||
assert labor.server(_read(me, "labor", COL))["계산값"]["반영합"]["계"] == was[0] # 다시 저장
|
||||
|
||||
|
||||
def test_price_refresh_only_on_press(world, monkeypatch):
|
||||
"""② 노임 바꿈 → 그대로 · [단가 갱신] 미리 셈 = 새로 찍은 문서 값 · [저장] 때 적용."""
|
||||
me = world["personal"]
|
||||
sc = _sc(me, [{"로직": PCT, "수량": {"손": 1}}])
|
||||
was = _calc(me, sc)["기준합"]["계"]
|
||||
_fake(monkeypatch, [_double(LB)])
|
||||
assert _calc(me, sc)["기준합"]["계"] == was and _unit(me, sc) == was
|
||||
fresh = _calc(me, _sc(me, [{"로직": PCT, "수량": {"손": 1}}]))["기준합"]["계"]
|
||||
assert fresh != was
|
||||
with store.at(me):
|
||||
got = lc.preview(labor.clean({**_read(me, "precombo", sc), "열": sc}), lc.PRICE)
|
||||
assert got["전"]["기준합"]["계"] == was and got["후"]["기준합"]["계"] == fresh
|
||||
assert [x["키"] for x in got["바뀐자원"]] == [LB]
|
||||
_write(me, "precombo", sc, {**_read(me, "precombo", sc), lc.JOB: got["doc"][lc.JOB]})
|
||||
saved = _read(me, "precombo", sc)
|
||||
assert lc.JOB not in saved and _unit(me, sc) == fresh
|
||||
assert _calc(me, sc)["사본"]["단가새값"] is False
|
||||
|
||||
|
||||
def test_regen_reapplies_line_cover(world, monkeypatch):
|
||||
"""③ [재생성] — 줄 덮개(cid) 새 사본에 다시 얹힘 · 없어진 줄 덮개 = 못얹은 · 배지 꺼짐."""
|
||||
me = world["personal"]
|
||||
two = {"덮개": {f"labor:{LB}#0": {"qty": 0.5}, "labor:LB000002#0": {"qty": 0.7}}}
|
||||
_labor(me, [{"로직": PCT, "수량": {"손": 1}, "패치": two}])
|
||||
row = copy.deepcopy(_live().logic(PCT))
|
||||
row["호표"] = [x for n, x in enumerate(row["호표"]) if n != 1] # 둘째 줄 없앤 새 판
|
||||
_fake(monkeypatch, [row])
|
||||
assert not _calc(me, COL)["줄"][0].get("짝잃음") # 사본 = 옛 판 그대로
|
||||
with store.at(me):
|
||||
got = lc.preview(labor.clean(_read(me, "labor", COL)), lc.REGEN)
|
||||
assert [x["cid"] for x in got["못얹은"]] == ["labor:LB000002#0"]
|
||||
assert got["전"]["기준합"]["계"] != got["후"]["기준합"]["계"]
|
||||
_write(me, "labor", COL, got["doc"])
|
||||
doc = _read(me, "labor", COL)
|
||||
assert doc["담은로직"][0]["패치"]["덮개"][f"labor:{LB}#0"] == {"qty": 0.5}
|
||||
now = _calc(me, COL)
|
||||
assert now["사본"]["M01새판"] is False and now["기준합"]["계"] == got["후"]["기준합"]["계"]
|
||||
|
||||
|
||||
def test_layer_and_column_copy_keep_copy(world, monkeypatch):
|
||||
"""④ 층 사이 복사(회사 → 개인) · 열 복사 = 원본 사본 그대로(지금 M01 로 다시 안 찍음)."""
|
||||
co, me = world["company"], world["personal"]
|
||||
src = _sc(co, [{"로직": PCT, "수량": {"손": 1}, "패치": COVER}])
|
||||
first = _read(co, "precombo", src)["사본"]
|
||||
old = _labor(me, [{"로직": PCT, "수량": {"손": 2}}])["사본"] # 받는 열 = 옛 M01 사본
|
||||
_fake(monkeypatch, [_double(LB), _changed(_live().logic(PCT))])
|
||||
ref = {"층": "company", "주인": "7", "키": src}
|
||||
with store.at(me):
|
||||
got = refs.create(
|
||||
"precombo", refs.carry(refs.origin_mark(refs.read_ref(ref), ref), ("company", "7"))
|
||||
)
|
||||
mine = _read(me, "precombo", got["이름"])["사본"]
|
||||
assert (mine["판"], mine["단가판"]) == (first["판"], first["단가판"])
|
||||
_write(me, "labor", "sub2임시2", {"열": "sub2임시2", "담은로직": [{"로직": PCT}], "자재": []})
|
||||
other = _read(me, "labor", "sub2임시2")["사본"] # 원본 열 = 바뀐 M01 사본
|
||||
assert other["판"] != old["판"]
|
||||
with store.at(me): # 열 복사(copy_from) = 받은 사본 먼저
|
||||
store.copy_from("labor", COL, "sub2임시2")
|
||||
assert _read(me, "labor", COL)["사본"]["판"] == other["판"]
|
||||
|
||||
|
||||
def test_ts_mirror_same_amount(world, monkeypatch):
|
||||
"""⑤ 사본 셈 답 → TS 짝 settle 같은 답 · M01 바뀐 뒤에도 같은 금액."""
|
||||
me = world["personal"]
|
||||
doc = _labor(me, [{"로직": PCT, "수량": None}])
|
||||
with store.at(me):
|
||||
before = labor.calc(labor.clean(doc), {})
|
||||
_fake(monkeypatch, [_double(LB), _changed(_live().logic(PCT))])
|
||||
with store.at(me):
|
||||
clean = labor.clean(_read(me, "labor", COL))
|
||||
answer = labor.calc(clean, {})
|
||||
assert answer["기준합"] == before["기준합"]
|
||||
key = answer["줄"][0]["알약"]
|
||||
for values in ({}, {key: 3}):
|
||||
_same(labor.settle(answer, clean, values), _ts(answer, clean, values))
|
||||
|
||||
|
||||
def test_old_doc_without_copy_old_path(world, monkeypatch):
|
||||
"""⑥ 사본 없는 옛 일위대가 = 셈은 지금 M01(옛 길) · 다시 저장하면 그때 사본."""
|
||||
me = world["personal"]
|
||||
_labor(me, [{"로직": PCT, "수량": {"손": 1}}])
|
||||
path = me / "labor" / f"{COL}.json"
|
||||
raw = {k: v for k, v in json.loads(path.read_bytes()).items() if k != "사본"}
|
||||
path.write_text(json.dumps(raw, ensure_ascii=False), encoding="utf-8")
|
||||
assert "사본" not in _calc(me, COL)
|
||||
_fake(monkeypatch, [_double(LB)])
|
||||
moved = labor.run_line(m01.loaded()[1], PCT, {})["기준"]["계"]
|
||||
assert _calc(me, COL)["기준합"]["계"] == pytest.approx(moved, abs=1)
|
||||
with store.at(me):
|
||||
assert skc.has(labor.server(raw))
|
||||
@@ -0,0 +1,101 @@
|
||||
# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀
|
||||
"""795-3 옛 SK · SC · 일위대가 → 로직 사본 옮기기 — 임시 storage 에서만.
|
||||
|
||||
① 보기만 = 안 씀 · 전후 같음 ② 쓰기 = 사본 칸만 더함 · 다른 칸 그대로 · 금액 같음 · 백업 · 되돌림
|
||||
③ 전후 다르면 안 씀(목록) ④ 프로젝트 층 일위대가 = 세기 · 대조만.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
from M02_MasterTemplete import M02_Copy_Migrate as mig
|
||||
from M02_MasterTemplete import M02_Labor_Copy as lc
|
||||
from M02_MasterTemplete import M02_Labor_Ref as refs
|
||||
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
||||
from M02_MasterTemplete import M02_Sangeun_Copy as skc
|
||||
from M02_MasterTemplete import M02_Template_Layers as layers
|
||||
from resources.tester.test_795_1_sk_copy import _fake, _live
|
||||
from resources.tester.test_m02_labor_ref import world # noqa: F401 — 같은 임시 층
|
||||
|
||||
PCT, LB = "GC001109", "LB000036"
|
||||
LINE = {"로직": PCT, "수량": {"손": 1}}
|
||||
|
||||
|
||||
def _old(path):
|
||||
"""사본 칸 뗀 옛 문서로 되씀 → 옛 내용."""
|
||||
raw = {k: v for k, v in json.loads(path.read_bytes()).items() if k != skc.KEY}
|
||||
path.write_text(json.dumps(raw, ensure_ascii=False), encoding="utf-8")
|
||||
return raw
|
||||
|
||||
|
||||
def _make(me):
|
||||
with store.at(me):
|
||||
sk = refs.create(
|
||||
"sangeun", {"이름": "sub2임시", "단위": "㎡", "바탕": {"로직": PCT}, "더한줄": []}
|
||||
)["이름"]
|
||||
sc = refs.create("precombo", {"이름": "sub2임시", "단위": "㎡", "담은로직": [LINE]})["이름"]
|
||||
store.write("labor", "sub2임시", "", {"열": "sub2임시", "담은로직": [LINE], "자재": []})
|
||||
paths = [me / "sangeun" / f"{sk}.json", me / "precombo" / f"{sc}.json"]
|
||||
paths.append(me / "labor" / "sub2임시.json")
|
||||
return {p: _old(p) for p in paths}
|
||||
|
||||
|
||||
def _mine(rows, olds):
|
||||
keys = {p.stem for p in olds}
|
||||
return {r["키"]: r for r in rows if r["어디"].startswith("개인") and r["키"] in keys}
|
||||
|
||||
|
||||
def test_dry_then_apply_then_restore(world, tmp_path):
|
||||
"""① · ② 보기만 → 쓰기(사본만 더함 · 금액 같음) → 되돌림 = 처음 파일."""
|
||||
olds = _make(world["personal"])
|
||||
rows = _mine(mig.migrate(), olds)
|
||||
assert {r["상태"] for r in rows.values()} == {"같음"} and len(rows) == 3
|
||||
assert not any(r["씀"] for r in rows.values())
|
||||
assert all(json.loads(p.read_bytes()) == raw for p, raw in olds.items())
|
||||
back = tmp_path / "back"
|
||||
rows = _mine(mig.migrate(True, back), olds)
|
||||
assert all(r["씀"] for r in rows.values())
|
||||
for path, raw in olds.items():
|
||||
now = json.loads(path.read_bytes())
|
||||
assert skc.has(now) and {k: v for k, v in now.items() if k != skc.KEY} == raw
|
||||
again = _mine(mig.migrate(), olds) # 다시 돌림 = 이미 있음
|
||||
assert {r["상태"] for r in again.values()} == {"있음"}
|
||||
assert {r["전"]["계"] for r in rows.values() if r["종류"] == "sangeun"} == {
|
||||
r["후"]["계"] for r in rows.values() if r["종류"] == "sangeun"
|
||||
}
|
||||
mig.restore(back)
|
||||
assert all(json.loads(p.read_bytes()) == raw for p, raw in olds.items())
|
||||
|
||||
|
||||
def test_different_amount_not_written(world, monkeypatch, tmp_path):
|
||||
"""③ 찍은 사본 금액이 지금과 다르면(노임 다른 판) 안 씀 · 까닭."""
|
||||
olds = _make(world["personal"])
|
||||
real = lc.stamp
|
||||
|
||||
def stale(doc): # 노임 두 배 판으로 찍힌 사본 흉내
|
||||
with monkeypatch.context() as m:
|
||||
row = copy.deepcopy(_live().get(LB))
|
||||
row["값"] = row["값"] * 2
|
||||
_fake(m, [row])
|
||||
return real(doc)
|
||||
|
||||
monkeypatch.setattr(lc, "stamp", stale)
|
||||
rows = _mine(mig.migrate(True, tmp_path / "back"), olds)
|
||||
bad = [r for r in rows.values() if r["종류"] != "sangeun"]
|
||||
assert {r["상태"] for r in bad} == {"다름"} and not any(r["씀"] for r in bad)
|
||||
assert all(not skc.has(json.loads(p.read_bytes())) for p in olds if p.parent.name != "sangeun")
|
||||
|
||||
|
||||
def test_project_labor_count_only(world, tmp_path):
|
||||
"""④ 프로젝트 층 일위대가 = 대조만 · 안 씀."""
|
||||
folder = layers.storage_root() / "7" / "42" / "p1" / "templates" / "labor"
|
||||
folder.mkdir(parents=True)
|
||||
path = folder / "x.json"
|
||||
raw = {"열": "x", "담은로직": [LINE], "자재": []}
|
||||
path.write_text(json.dumps(raw, ensure_ascii=False), encoding="utf-8")
|
||||
rows = [r for r in mig.migrate(True, tmp_path / "back") if r["어디"].startswith("프로젝트")]
|
||||
assert [(r["키"], r["상태"], r["씀"]) for r in rows] == [("x", "같음", False)]
|
||||
assert json.loads(path.read_bytes()) == raw
|
||||
assert mig.table(rows) == {"프로젝트 labor": {"같음": 1}}
|
||||
Reference in New Issue
Block a user