- cp949 에 없는 글자는 「?」 로 바꿔 씀(22MB 공사 저장 중 멈춤) - 기계경비 본문 Index(−3·−2·−1) 유지 - % 단위 수량은 소수로 써서 음수·큰 값도 되돌아옴 - 경쟁사 예제 estx 2건 저장값 대조·구버전 왕복 시험 추가 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
98 lines
4.2 KiB
Python
98 lines
4.2 KiB
Python
"""구버전 EST Plus(.est): 394 바이트 레코드 쓰기→읽기 왕복, 단가비교 자리, 짝짓기."""
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
from test_est_rea_parity import run
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
EST = ROOT / "tools/est-test"
|
|
|
|
|
|
def node(code):
|
|
out = subprocess.check_output(
|
|
["node", "-e", code], cwd=EST, text=True, encoding="utf-8"
|
|
)
|
|
return json.loads(out)
|
|
|
|
|
|
def test_extended_and_round_trip_of_sample():
|
|
result = node(
|
|
"""
|
|
const L=require('./legacy-estplus.cjs'),s=require('./sample.json');
|
|
const b=Buffer.alloc(10),xs=[0,1,-2.5,1234567.891,0.001,1e15].map(v=>(L.writeX(b,0,v),L.readX(b,0)));
|
|
const buf=L.write(s),p=L.read(buf,'t');
|
|
const same=(t,keys)=>s.tables[t].every((r,i)=>keys.every(k=>Math.abs((Number(r[k])||0)-(Number(p.tables[t][i][k])||0))<1e-6));
|
|
console.log(JSON.stringify({xs,
|
|
est:same('EstMainDat',['GN','TU','TC','NC','GC','JC','Level']),
|
|
head:same('HeadMainDat',['GN','TC','NC','GC','JC']),
|
|
cost:s.tables.CostMainDat.every((r,i)=>r.Index>0||(r.LineData||'')===(p.tables.CostMainDat[i].LineData||'')),
|
|
title:p.tables.CostTitleDat[0].Name,labor:p.tables.LaborcDat.length,
|
|
linked:p.tables.EstMainDat.find(r=>r.Name==='터파기').Code,auto:p.options.AutoCalc,
|
|
cmp:L.compare(buf,2)[0]}));
|
|
""")
|
|
assert result["xs"] == [0, 1, -2.5, 1234567.891, 0.001, 1e15]
|
|
assert result["est"] and result["head"] and result["cost"]
|
|
assert result["title"] == "터파기"
|
|
assert result["labor"] == 9
|
|
assert result["linked"] == "D0000000001"
|
|
assert result["auto"] is False
|
|
assert result["cmp"] == {"ONU": 66841, "OGU": 1336, "OJU": 0}
|
|
|
|
|
|
def test_pair_flags_sum_mismatch_in_order():
|
|
result = run(
|
|
"math",
|
|
"""(()=>{
|
|
const p=EstNative.empty();p.tables.HeadMainDat=[{Index:1,Code:'U1',Name:'a',NC:10,GC:5},{Index:0},
|
|
{Index:2,Code:'U2',Name:'b',NC:3}];
|
|
return EstEstPlus.pair(p,2,[{ONU:10,OGU:5,OJU:0},{ONU:4,OGU:0,OJU:0}]).map(r=>[r.Code,r.UsesCheck]);
|
|
})()""",
|
|
)
|
|
assert result == [["U1", False], ["U2", True]]
|
|
|
|
|
|
def test_percent_quantity_machine_index_and_non_cp949_text():
|
|
result = node(
|
|
"""
|
|
const L=require('./legacy-estplus.cjs');
|
|
const p={name:'t',options:{},tables:{EstMainDat:[],HeadMainDat:[{Index:1,Name:'a'},
|
|
{Index:0,LinkIndex:0,Name:'사용고재',Unite:'%',GN:-500},{Index:0,LinkIndex:0,Name:'공구손료',Unite:'%',GN:3},
|
|
{Index:0,LinkIndex:0,Name:'x'+String.fromCodePoint(0x1F600)+'y',GN:1}],
|
|
MachMainDat:[{Index:1,Name:'굴삭기',TC:10},{Index:-3,Selected:1,Name:'손료',GN:2,JC:5},{Index:-1,Selected:11,Name:'운전사',GN:1,NC:7}],
|
|
CostMainDat:[],LaborcDat:[],StuffcDat:[],SilJukDat:[],Wonga:[]}};
|
|
const b=L.read(L.write(p),'t');
|
|
console.log(JSON.stringify({gn:b.tables.HeadMainDat.slice(1,3).map(r=>r.GN),name:b.tables.HeadMainDat[3].Name,
|
|
mach:b.tables.MachMainDat.map(r=>[r.Index,r.Selected,r.TC])}));
|
|
""")
|
|
assert result["gn"] == [-500, 3]
|
|
assert result["name"] == "x?y"
|
|
assert result["mach"] == [[1, 0, 10], [-3, 1, 5], [-1, 11, 7]]
|
|
|
|
|
|
def test_competitor_examples_keep_stored_values_and_round_trip_to_legacy():
|
|
folder = ROOT / "resources/knowledge/original/경쟁사 프로그램/EST Plus 2/example"
|
|
files = sorted(folder.glob("*.estx"))
|
|
assert len(files) >= 2
|
|
for file in files:
|
|
parity = json.loads(
|
|
subprocess.check_output(
|
|
["node", str(ROOT / "resources/tester/helper_est_archive.cjs"), str(file)],
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=300,
|
|
)
|
|
)
|
|
assert parity["differences"] == [], file.name
|
|
result = node(
|
|
f"""
|
|
const L=require('./legacy-estplus.cjs'),{{importEstx}}=require('./import-estx.cjs');
|
|
const p=importEstx(require('fs').readFileSync({json.dumps(str(file))}),'x'),b=L.read(L.write(p),'t');
|
|
const diff=(t,ks)=>p.tables[t].filter((r,i)=>ks.some(k=>Math.abs((Number(r[k])||0)-(Number(b.tables[t][i][k])||0))>1e-6)).length;
|
|
console.log(JSON.stringify({{est:diff('EstMainDat',['GN','TC','NC','GC','JC']),head:diff('HeadMainDat',['GN','TC','NC','GC','JC']),
|
|
cmp:L.compare(L.write(p),2).length===p.tables.HeadMainDat.filter(r=>r.Index>0).length}}));
|
|
"""
|
|
)
|
|
assert result == {"est": 0, "head": 0, "cmp": True}, file.name
|