Files
Aislo/resources/tester/test_572_hopyo_same.py
T
eomsangdonandClaude Opus 5.5 42de907aa2 feat(733-1b): 불러오기 단가산출 같은 내용 SK 씀 · 위 층 같은 것 알림 · 결과 화면 꼬리표
- M02_Hopyo_Sangeun — Maker.write 가 이 층 같은 내용 SK(M02_Library_Same 지문)가 있으면 새로 안 만들고 그것을 씀 · 이름 = 먼저 만든 것 · 뒤 출처 = 본뜬.또[그 블록 본뜬 + 이름] · made 가 또 읽음 · origin_of = 출처마다 갈래 · 못옮김 · 놓음
- 다른 출처가 쓰는 SK 내용은 안 바꿈 — 고른 기초 · 잇기로 바뀌면 떼어 냄(앞 출처면 뒤 출처에게 넘겨줌) · 혼자 쓰던 SK 만 제자리 덮음
- 응답 같은것씀 [{번, 키}] · 위층같음 [{번, 층, 주인, 키}](회사 · 마스터 · 알림만)
- M02_Hopyo_SkLink — 못옮김 · 갈래를 그 블록 출처에서 읽음(같은 내용이라도 엑셀마다 못옮김이 다름 · 금액 지킴)
- 불러오기 ② 단가산출 표 갈래 칸 꼬리표 「같은 것 씀」 · 「위 층에 같은 것 — 연결 권함」 · 요약 글에 수
- 새 시험 test_572_hopyo_same.py — 바이트만 다른 사본 새 SK 0 · 위 층 알림 · 출처마다 못옮김 · 떼어 냄 · 넘겨줌
- 낡은 시험 고침: test_718_1(만든 SK 수 = 만듦 수 가정 → 같은 내용 SK 한 벌이라 문서 수 + 같은것씀 = 만듦) · test_729(_sk_docs 가 본뜬 키만 봄 → 또 출처도 블록에 매김)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 14:14:42 +09:00

115 lines
5.7 KiB
Python

"""불러오기 [단가산출 만들기] 같은 내용 SK 씀(PLAN 733-1b · 요구서_572 3장 2).
북부청 임도(실물)를 임시 층에 → 같은 파일 안 같은 내용 SK 한 벌 · 바이트만 다른 사본 다시 = 새 SK 0 ·
뒤 출처 = `본뜬.또` · 다시 = 그대로 · 위 층(회사) 같은 것 = `위층같음` 알림 ·
출처마다 못옮김 · 다른 출처가 쓰는 SK 내용은 안 바꿈(떼어 냄 · 넘겨줌).
"""
import io
import json
import zipfile
from M02_MasterTemplete import M02_Hopyo_Fit as fit
from M02_MasterTemplete import M02_Hopyo_Sangeun as sangeun
from M02_MasterTemplete import M02_Library_Same as same
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete import M02_Template_Layers as layers
from resources.tester.test_572_library_same import _put
from resources.tester.test_m02_hopyo_excel import NORTH, URL, _post, client # noqa: F401
def _rezip(data: bytes) -> bytes:
"""내용 같고 바이트 다른 사본 — xlsx = 다시 묶음 · xls = 끝에 빈 칸 한 벌(512 바이트)."""
if not zipfile.is_zipfile(io.BytesIO(data)):
return data + bytes(512)
src, buf = zipfile.ZipFile(io.BytesIO(data)), io.BytesIO()
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED, compresslevel=1) as z:
for info in src.infolist():
z.writestr(
zipfile.ZipInfo(info.filename, (2026, 1, 1, 0, 0, 0)), src.read(info.filename)
)
return buf.getvalue()
def _sks(folder) -> dict[str, dict]:
paths = sorted((folder / "sangeun").glob("SK-*.json"))
return {p.stem: json.loads(p.read_bytes()) for p in paths}
def _make(client, folder, data, name):
res = _post(client, data=data, name=name)
assert res.status_code == 200, res.text
key = res.json()["키"]
fit.run_job(folder, key)
got = client.post(f"{URL.format('personal')}/{key}/sangeun")
assert got.status_code == 200, got.text
return key, got.json()
def test_불러오기_같은내용_SK_씀_바이트만_다른_사본_새_SK_0(client):
folder = layers.personal_dir(7, 42)
data = NORTH.read_bytes()
hp1, one = _make(client, folder, data, NORTH.name)
docs = _sks(folder)
fingers = [same.finger("sangeun", d) for d in docs.values()]
assert len(fingers) == len(set(fingers)) # 같은 내용 SK 한 벌
assert one["같은것씀"] and len(docs) + len(one["같은것씀"]) == len(one["만듦"])
assert one["위층같음"] == []
shared = docs[one["같은것씀"][0]["키"]]
assert [x["키"].split(" ")[0] for x in shared["본뜬"]["또"]] == [hp1]
again = client.post(f"{URL.format('personal')}/{hp1}/sangeun").json()
assert again["만듦"] == [] and again["그대로"] == len(one["만듦"])
# 위 층(회사)에 같은 것 = 알림만
firm = layers.company_dir(7)
first = next(iter(docs))
_put(firm, "sangeun", "SK-000001", docs[first])
# 바이트만 다른 사본 = 새 HP · 새 SK 0 · 뒤 출처 = 본뜬.또
hp2, two = _make(client, folder, _rezip(data), "사본_" + NORTH.name)
assert hp2 != hp1 and _sks(folder).keys() == docs.keys()
assert len(two["만듦"]) == len(one["만듦"]) == len(two["같은것씀"])
assert {"층": "company", "주인": "7", "키": "SK-000001"} in [
{k: x[k] for k in ("층", "주인", "키")} for x in two["위층같음"]
]
also = {x["키"].split(" ")[0] for d in _sks(folder).values() for x in d["본뜬"].get("또", [])}
assert also == {hp1, hp2}
again = client.post(f"{URL.format('personal')}/{hp2}/sangeun").json()
assert again["만듦"] == [] and again["그대로"] == len(one["만듦"])
def _maker(hp: str) -> sangeun.Maker:
"""블록 하나짜리 만들기(파일 · 맞춤셈 없이) — 쓰기 규칙만 봄."""
m = object.__new__(sangeun.Maker)
m.first, m.blocks = {1: {"이름": "줄", "단위": "㎥"}}, {1: {"이름": "블록"}}
m.hp, m.sure = {"키": hp, "파일": f"{hp}.xls"}, {"원본": ["personal", "7/42"]}
m.same, m.reused, m.above = same.Same(), [], []
return m
def _plan(code: str, lost: list) -> dict:
keep = {"갈래": "기초", "엑셀품": {}, "못옮김": lost, "바탕": {"로직": code}, "입력값": {}}
return {**keep, "자재표시": {}, "덮개": {}, "더한줄": [], "뺀줄": []}
def test_같은내용_SK_출처마다_못옮김_떼어냄_넘겨줌(client):
folder, at = layers.personal_dir(7, 42), ("personal", "7/42")
one, two = _maker("HP-000001"), _maker("HP-000002")
with store.at(folder):
key = one.write(1, _plan("GF000113", []), None)
assert two.write(1, _plan("GF000113", [{"id": "x"}]), None) == key # 같은 것 씀
assert two.reused == [{"번": 1, "키": key}]
doc = _sks(folder)[key]
assert sangeun.origin_of(doc, "HP-000002 단산1", at)["못옮김"] == [{"id": "x"}]
assert sangeun.origin_of(doc, "HP-000001 단산1", at)["못옮김"] == []
assert sangeun.made(folder, "HP-000002", at) == {"HP-000002 단산1": key}
# 뒤 출처가 바탕을 바꿈 = 떼어 냄 · 남의 SK 내용 그대로
moved = _maker("HP-000002").write(1, _plan("GF000114", []), key)
assert moved != key and "또" not in _sks(folder)[key]["본뜬"]
assert _sks(folder)[key]["바탕"]["로직"] == "GF000113"
# 앞 출처가 바탕을 바꿈 = 뒤 출처에게 넘겨줌
assert _maker("HP-000003").write(1, _plan("GF000113", []), None) == key
back = _maker("HP-000001").write(1, _plan("GF000114", []), key)
assert back == moved # 바꾼 내용 = 이미 있는 같은 것
left = _sks(folder)[key]
assert left["바탕"]["로직"] == "GF000113" and left["본뜬"]["키"] == "HP-000003 단산1"
assert "또" not in left["본뜬"] and len(_sks(folder)) == 2