fix(est-test): handle percent details and subtotals
This commit is contained in:
@@ -91,3 +91,54 @@ def test_jdl_special_machine_detail_is_fixed_only_when_amounts_match():
|
||||
assert "상세 산식 미변환" in result["before"][6]["Name"]
|
||||
assert any("특수 기계 상세" in warning for warning in result["warnings"])
|
||||
assert not result["errors"]
|
||||
|
||||
|
||||
def test_jdl_machine_percent_detail_round_trips_fixed_amounts():
|
||||
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')),blank=structuredClone(empty);
|
||||
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 files=new Map([['Global.ini',Buffer.from('[BASIC]')],['Main.txt',Buffer.from('0\\tSample\\t02\\x05\\r\\n')],
|
||||
['junit.txt',table('junit.txt',[{F_CODE:'J1',F_DES:'machine',F_MPRICE:5},{F_CODE:'J2',F_DES:'ambiguous',F_MPRICE:50}])],
|
||||
['jpart.txt',table('jpart.txt',[{F_CODE:'J1',F_SEQ:'1',F_DES:'percent',F_UNIT:'%',F_QQTY:10,F_MPRICE:50,F_SPROPER:'1'},
|
||||
{F_CODE:'J2',F_SEQ:'1',F_DES:'uncertain',F_UNIT:'%',F_QQTY:1,F_MPRICE:50}])]]);
|
||||
const p=j.read(a.pack(files),empty),before=structuredClone(p.tables.MachMainDat);p.options.AutoCalc=true;
|
||||
p.tables.MachMainDat[1].GC=6;const q=s.calculate(p),out=j.output(q),entries=a.unpack(out.bytes),back=j.read(out.bytes,blank);
|
||||
process.stdout.write(JSON.stringify({before,parts:j.parse('jpart.txt',entries.get('jpart.txt')),
|
||||
rows:back.tables.MachMainDat,errors:q.calculation.errors}));"""
|
||||
result = json.loads(
|
||||
subprocess.check_output(
|
||||
["node", "-e", script], input=json.dumps(project).encode(), cwd=ROOT
|
||||
)
|
||||
)
|
||||
assert result["before"][1]["GC"] == 5
|
||||
assert result["before"][1]["GN"] == 10
|
||||
assert result["before"][1]["JdlSourceQuantity"] == 10
|
||||
assert result["parts"][0]["F_UNIT"] == "%"
|
||||
assert result["parts"][0]["F_QQTY"] == 100
|
||||
assert result["rows"][1]["GC"] == 6
|
||||
assert "상세 산식 미변환" in result["before"][-1]["Name"]
|
||||
assert not result["errors"]
|
||||
|
||||
|
||||
def test_jdl_fixed_unit_percent_exports_a_consistent_quantity():
|
||||
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')),empty=structuredClone(p);p.name='percent';
|
||||
p.tables.HeadTitleDat=[{Code:'U',Name:'unit',GC:10,TC:10}];
|
||||
p.tables.HeadMainDat=[{Index:1,Code:'U'},
|
||||
{Index:0,Name:'fixed percent',Unite:'%',CalcIndex:1,JdlSummary:true,GC:10,TC:10}];
|
||||
p.tables.EstMainDat=[{Code:'U',Name:'unit',LinkIndex:103,GN:2,GU:10,GC:20,TC:20},{LinkIndex:54}];
|
||||
const out=j.output(p),files=a.unpack(out.bytes),parts=j.parse('unitpart.txt',files.get('unitpart.txt')),
|
||||
q=j.read(out.bytes,empty);
|
||||
process.stdout.write(JSON.stringify({part:parts[0],row:q.tables.HeadMainDat[1],total:q.tables.EstMainDat.at(-1).TC}));"""
|
||||
result = json.loads(
|
||||
subprocess.check_output(
|
||||
["node", "-e", script], input=json.dumps(project).encode(), cwd=ROOT
|
||||
)
|
||||
)
|
||||
assert result["part"]["F_UNIT"] == "%"
|
||||
assert result["part"]["F_QQTY"] == 100
|
||||
assert result["part"]["F_MPRICE"] == result["part"]["F_MCOST"] == 10
|
||||
assert result["row"]["GC"] == 10
|
||||
assert result["total"] == 20
|
||||
|
||||
@@ -49,6 +49,26 @@ def test_redundant_price_caption_keeps_quantity_and_source_updates():
|
||||
assert result["mismatch"]["errors"]
|
||||
|
||||
|
||||
def test_component_total_ignores_following_numeric_substitution():
|
||||
result = run(
|
||||
"math",
|
||||
"""(() => {
|
||||
const rows = [
|
||||
{Index:1, Code:'D1'},
|
||||
{Index:0, LineData:'LL = 5'},
|
||||
{Index:0, SCheck:-3, LineData:'100 = \\x12100\\x12'},
|
||||
{Index:0, SCheck:-3, LineData:'\\x1a경비 : 100\\x1a ÷ LL = 100 ÷ 5 = \\x1220\\x12'}
|
||||
];
|
||||
const first=EstText.calculate(rows);rows[1].LineData='LL = 4';rows[2].LineData='120 = \\x12100\\x12';
|
||||
return {first,changed:EstText.calculate(rows)};
|
||||
})()""",
|
||||
)
|
||||
assert result["first"]["errors"] == []
|
||||
assert result["first"]["rows"][3]["TC"] == 20
|
||||
assert result["changed"]["errors"] == []
|
||||
assert result["changed"]["rows"][3]["TC"] == 30
|
||||
|
||||
|
||||
def test_equals_in_description_is_not_a_formula_separator():
|
||||
result = run(
|
||||
"math",
|
||||
|
||||
Reference in New Issue
Block a user