114 lines
6.8 KiB
Python
114 lines
6.8 KiB
Python
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
from test_est_rea_parity import run
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def test_jdl_basic_tables_use_native_separators_encoding_and_preserve_direct_money():
|
|
p = run(
|
|
"math",
|
|
"""(()=>{
|
|
const p=EstNative.empty();p.name='JDL test';p.options.SourceRefresh=false;
|
|
p.tables.StuffcDat=[{PkID:1,Code:'M',Name:'material',InputTC:100,ValueIndex:4}];
|
|
p.tables.EstMainDat=[{PkID:1,Code:'M',Name:'material',LinkIndex:5,GN:10,GU:100},
|
|
{PkID:2,Code:'FIX',Name:'fixed',GN:0,GC:80,TC:80,CalcIndex:1},
|
|
{PkID:3,Code:'SKIP',Name:'excluded',GN:1,GC:999,TC:999,CalcIndex:3},{PkID:4,LinkIndex:54}];
|
|
p.tables.Wonga=[{Gubun:'G',Name:'material',BaseField:'GC'},{Gubun:'T',Name:'total',VSusic:'G'}];
|
|
return EstNative.calculate(p);
|
|
})()""",
|
|
)
|
|
script = """const fs=require('fs'),j=require('./tools/est-test/jdl.cjs'),a=require('./tools/est-test/archive.cjs');
|
|
const p=JSON.parse(fs.readFileSync(0,'utf8')),empty=structuredClone(p);for(const name of Object.keys(empty.tables))empty.tables[name]=[];
|
|
const out=j.output(p),files=a.unpack(out.bytes),next=j.read(out.bytes,empty);
|
|
const raw=files.get('mainpart.txt');
|
|
process.stdout.write(JSON.stringify({next,files:[...files.keys()],tabs:raw.includes(9),terminator:raw.includes(5),warnings:out.warnings}));"""
|
|
result = json.loads(
|
|
subprocess.check_output(
|
|
["node", "-e", script],
|
|
input=json.dumps(p, ensure_ascii=False).encode("utf-8"),
|
|
cwd=ROOT,
|
|
).decode("utf-8")
|
|
)
|
|
assert result["tabs"] and result["terminator"]
|
|
assert {"Global.ini", "Main.txt", "mainpart.txt", "CostAccount.txt"}.issubset(result["files"])
|
|
assert result["next"]["tables"]["EstMainDat"][-1]["TC"] == 1080
|
|
assert result["next"]["tables"]["Wonga"][-1]["Cost"] == 1080
|
|
assert result["next"]["options"]["AutoCalc"] is False
|
|
assert result["warnings"]
|
|
|
|
|
|
def test_unchanged_import_preserves_original_jdl_and_edited_work_is_not_silently_discarded():
|
|
project = run("math", "EstNative.empty()")
|
|
script = """const fs=require('fs'),j=require('./tools/est-test/jdl.cjs'),a=require('./tools/est-test/archive.cjs'),s=require('./tools/est-test/server.cjs');
|
|
const empty=JSON.parse(fs.readFileSync(0,'utf8'));
|
|
const original=a.pack(new Map([['Global.ini',Buffer.from('[BASIC]\\r\\n')],
|
|
['Main.txt',Buffer.from('0\\tExample\\t02\\x05\\r\\n')],['extension.bin',Buffer.from([1,2,3,4])]]));
|
|
const p=j.markOriginal(s.calculate(j.read(original,empty)));p.id='0123456789abcdef01234567';
|
|
const unchanged=j.output(s.calculate(structuredClone(p)));
|
|
p.name='Changed';const changed=j.output(s.calculate(p)),files=a.unpack(changed.bytes);
|
|
process.stdout.write(JSON.stringify({unchanged:original.equals(unchanged.bytes),changed:!original.equals(changed.bytes),
|
|
name:files.get('Main.txt').toString().includes('Changed'),warning:changed.warnings.length>0}));"""
|
|
result = json.loads(
|
|
subprocess.check_output(
|
|
["node", "-e", script],
|
|
input=json.dumps(project, ensure_ascii=False).encode("utf-8"),
|
|
cwd=ROOT,
|
|
).decode("utf-8")
|
|
)
|
|
assert result == {"unchanged": True, "changed": True, "name": True, "warning": True}
|
|
|
|
|
|
def test_basic_jdl_unit_price_parts_import_with_recorded_costs_and_warn_for_special_parts():
|
|
project = run("math", "EstNative.empty()")
|
|
script = """const fs=require('fs'),j=require('./tools/est-test/jdl.cjs'),a=require('./tools/est-test/archive.cjs'),schema=require('./tools/est-test/jdl-schema.json'),s=require('./tools/est-test/server.cjs');
|
|
const empty=JSON.parse(fs.readFileSync(0,'utf8'));
|
|
const table=(name,rows)=>Buffer.from(rows.map(r=>schema[name].map(f=>r[f.name]??(f.kind===6?'0':'')).join('\\t')+'\\x05\\r\\n').join(''));
|
|
const common={F_CODE:'U1',F_CODE1:'M1',F_DES:'material',F_QQTY:2,F_MPRICE:100,F_MCOST:200,F_LOADBM:'T',F_SAVEBM:'T',F_SPROPER:'0',F_KWAN:'0',F_CLASS:'0'};
|
|
const files=new Map([['Global.ini',Buffer.from('[BASIC]')],['Main.txt',Buffer.from('0\\tSample\\t02\\x05\\r\\n')],
|
|
['m.txt',table('m.txt',[{F_CODE:'M1',F_DES:'material',F_MPRICE:100}])],
|
|
['unit.txt',table('unit.txt',[{F_CODE:'U1',F_DES:'unit',F_MPRICE:200}])],
|
|
['unitpart.txt',table('unitpart.txt',[{...common,F_SEQ:'1'},{...common,F_SEQ:'2',F_SPROPER:'1'}])]]);
|
|
const out=s.calculate(j.read(a.pack(files),empty));process.stdout.write(JSON.stringify({rows:out.tables.HeadMainDat,warnings:out.importWarnings}));"""
|
|
result = json.loads(
|
|
subprocess.check_output(
|
|
["node", "-e", script],
|
|
input=json.dumps(project, ensure_ascii=False).encode("utf-8"),
|
|
cwd=ROOT,
|
|
).decode("utf-8")
|
|
)
|
|
header, detail = result["rows"]
|
|
assert header["Index"] == 1 and header["TC"] == 200
|
|
assert detail["LinkIndex"] == 5 and detail["GN"] == 2 and detail["GC"] == 200
|
|
assert any("특수 구성" in warning for warning in result["warnings"])
|
|
|
|
|
|
def test_basic_jdl_unit_price_parts_export_and_reimport():
|
|
project = run("math", "EstNative.empty()")
|
|
script = """const fs=require('fs'),j=require('./tools/est-test/jdl.cjs'),a=require('./tools/est-test/archive.cjs');
|
|
const p=JSON.parse(fs.readFileSync(0,'utf8'));p.name='unit';
|
|
p.tables.StuffcDat=[{Code:'M1',Name:'material',TC:100}];
|
|
p.tables.HeadTitleDat=[{Code:'U1',Name:'unit',GC:200,NC:0,JC:0,SC:0}];
|
|
p.tables.HeadMainDat=[{Index:1,Code:'U1',Name:'unit',GC:200,TC:200},
|
|
{Index:0,Code:'M1',Name:'material',LinkIndex:5,GN:2,GU:100,GC:200,TC:200}];
|
|
p.tables.EstMainDat=[{Code:'U1',Name:'unit',LinkIndex:103,GN:1,GU:200,GC:200,TC:200},{LinkIndex:54}];
|
|
const out=j.output(p),files=a.unpack(out.bytes),empty=structuredClone(p);for(const k of Object.keys(empty.tables))empty.tables[k]=[];
|
|
const q=j.read(out.bytes,empty);p.tables.HeadMainDat[1].CalcIndex=1;
|
|
const special=j.output(p),specialFiles=a.unpack(special.bytes);
|
|
process.stdout.write(JSON.stringify({unit:j.parse('unit.txt',files.get('unit.txt')),
|
|
parts:j.parse('unitpart.txt',files.get('unitpart.txt')),rows:q.tables.HeadMainDat,main:q.tables.EstMainDat,
|
|
specialUnits:j.parse('unit.txt',specialFiles.get('unit.txt')).length,specialWarnings:special.warnings.length}));"""
|
|
result = json.loads(
|
|
subprocess.check_output(
|
|
["node", "-e", script],
|
|
input=json.dumps(project, ensure_ascii=False).encode("utf-8"),
|
|
cwd=ROOT,
|
|
).decode("utf-8")
|
|
)
|
|
assert len(result["unit"]) == len(result["parts"]) == 1
|
|
assert result["parts"][0]["F_QQTY"] == 2 and result["parts"][0]["F_MCOST"] == 200
|
|
assert result["rows"][1]["LinkIndex"] == 5 and result["rows"][1]["GC"] == 200
|
|
assert result["main"][1]["LinkIndex"] == 103
|
|
assert result["specialUnits"] == 0 and result["specialWarnings"] > 0
|