Files
Aislo/resources/tester/test_est_native_export.py
T

84 lines
4.1 KiB
Python

import json
import struct
import subprocess
import zipfile
import pytest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
def test_recalculation_and_native_export_keep_original_title_identities_when_sample_exists():
sample = Path("C:/Dasansoft/Est Plus 2/Data/ProjectData/sample.estx")
if not sample.exists():
pytest.skip("installed EST sample unavailable")
script = """const fs=require('fs'),m=require('./tools/est-test/import-estx.cjs'),e=require('./tools/est-test/export-estx.cjs'),s=require('./tools/est-test/server.cjs');
const bytes=fs.readFileSync(process.argv[1]),p=m.importEstx(bytes),q=s.calculate(p);
const ids=['HeadTitleDat','CostTitleDat','MachTitleDat'].every(key=>p.tables[key].every((r,i)=>r.PkID===q.tables[key][i].PkID));
const row=q.tables.EstMainDat.find(r=>r.GN&&r.TC);row.GN+=1;
const edited=s.calculate(q),out=e.exportEstx(edited),again=m.importEstx(out),original=m.unzip(bytes),files=m.unzip(out);
const indexes=[...original].filter(([name])=>name.endsWith('.idx')).every(([name,value])=>value.equals(files.get(name)));
process.stdout.write(JSON.stringify({ids,indexes,gn:again.tables.EstMainDat.find(r=>r.PkID===row.PkID).GN,expected:row.GN}));"""
result = json.loads(
subprocess.check_output(["node", "-e", script, str(sample)], cwd=ROOT).decode("utf-8")
)
assert result["ids"] and result["indexes"]
assert result["gn"] == result["expected"]
def fixture(path):
fields = [
("PkID", 2, 4),
("Code", 1, 16),
("Name", 1, 32),
("GN", 7, 8),
("GU", 7, 8),
("TC", 7, 8),
]
stride = 25 + sum(width + 1 for _, _, width in fields)
data = bytearray(512 + 768 * len(fields) + stride)
data[8:24] = bytes.fromhex("068abe8e592364cb403d71d2e3bc64d0")
struct.pack_into("<IHH", data, 41, 1, stride, len(fields))
start = 512 + 768 * len(fields)
offset = 25
for i, (name, kind, width) in enumerate(fields):
at = 512 + i * 768
data[at + 2] = len(name)
data[at + 3 : at + 3 + len(name)] = name.encode("ascii")
data[at + 164] = kind
struct.pack_into("<H", data, at + 169, width)
struct.pack_into("<I", data, at + 172, offset)
data[start + offset] = 1
payload = start + offset + 1
if name == "PkID":
struct.pack_into("<i", data, payload, 1)
elif name in ["Code", "Name"]:
text = ("A" if name == "Code" else "원본").encode("cp949")
data[payload : payload + len(text)] = text
else:
struct.pack_into("<d", data, payload, {"GN": 2, "GU": 100, "TC": 200}[name])
offset += width + 1
with zipfile.ZipFile(path, "w", compression=zipfile.ZIP_DEFLATED) as archive:
archive.writestr("EstMainDat.dat", data)
archive.writestr("EstMainDat.idx", b"opaque index must remain unchanged")
archive.writestr("CadMainDat.blb", b"original drawing payload")
def test_estx_patches_values_and_preserves_indexes_drawings_and_rejects_structural_changes(
tmp_path,
):
source = tmp_path / "native.estx"
fixture(source)
script = """const fs=require('fs'),m=require('./tools/est-test/import-estx.cjs'),e=require('./tools/est-test/export-estx.cjs');
const b=fs.readFileSync(process.argv[1]),p=m.importEstx(b),same=e.exportEstx(p).equals(b);
p.tables.EstMainDat[0].GN=3;p.tables.EstMainDat[0].TC=300;p.tables.EstMainDat[0].Name='변경';
const next=e.exportEstx(p),q=m.importEstx(next),old=m.unzip(b),now=m.unzip(next);
let blocked=false;p.tables.EstMainDat[0].Code='B';try{e.exportEstx(p)}catch{blocked=true}
process.stdout.write(JSON.stringify({same,row:q.tables.EstMainDat[0],blocked,index:old.get('estmaindat.idx').equals(now.get('estmaindat.idx')),drawing:old.get('cadmaindat.blb').equals(now.get('cadmaindat.blb'))}));"""
result = json.loads(
subprocess.check_output(["node", "-e", script, str(source)], cwd=ROOT).decode("utf-8")
)
assert result["same"] and result["blocked"] and result["index"] and result["drawing"]
assert result["row"]["Name"] == "변경"
assert result["row"]["GN"] == 3 and result["row"]["TC"] == 300