- 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>
115 lines
5.7 KiB
Python
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
|