Files

68 lines
3.3 KiB
Python

from pathlib import Path
from lxml import etree
from test_est_rea_parity import run
ROOT = Path(__file__).resolve().parents[2]
SCHEMA = next((ROOT / "resources/knowledge").rglob("조달청_공사원가호환규정.xsd"))
def test_c3r_export_validates_against_the_supplied_schema_and_preserves_prices():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.name='C3R test';p.options.SourceRefresh=false;
p.tables.StuffcDat=[{PkID:1,Code:'M1',Name:'material',TC:100,GC:100}];
p.tables.LaborcDat=[{PkID:1,Code:'L1',Name:'labor',TC:50,NC:50}];
p.tables.EstMainDat=[{PkID:1,Code:'M1',LinkIndex:5,Name:'material',GN:2,GU:100},{PkID:2,Code:'L1',LinkIndex:6,Name:'labor',GN:3,NU:50},{PkID:3,LinkIndex:54}];
p.tables.Wonga=[{Gubun:'G',Name:'material',BaseField:'GC'}, {Gubun:'N',Name:'labor',BaseField:'NC'},{Gubun:'T',Name:'total',VSusic:'G+N'}];
return EstC3r.output(EstNative.calculate(p),{company:'test',kind:'토목공사',date:'2026-11-06'});
})()""",
)
schema = etree.XMLSchema(etree.parse(str(SCHEMA)))
root = etree.fromstring(result["xml"].encode("utf-8"))
assert schema.validate(root), str(schema.error_log)
assert root.findtext(".//세부공종/재료비") == "200"
assert root.findtext(".//세부공종/수량") == "2"
assert root.findtext(".//작성정보/파일검증여부") == "false"
assert result["warnings"] == []
def test_xml_excluded_rows_do_not_inflate_group_totals_and_invalid_codes_are_rejected():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.name='test';p.tables.StuffcDat=[{Code:'M1',Name:'material',TC:100}];p.tables.EstMainDat=[
{Code:'M1',Name:'normal',LinkIndex:5,GN:2,GU:100,GC:200,TC:200},
{Code:'X1',Name:'excluded',GN:1,GC:999,TC:999,CalcIndex:3},{LinkIndex:54}];
const meta={company:'test',kind:'토목공사',date:'2026-11-06'};
const result=EstC3r.output(p,meta);let blocked=false;
p.tables.EstMainDat[0].Code='bad code';try{EstC3r.output(p,meta)}catch{blocked=true}
return {...result,blocked};
})()""",
)
root = etree.fromstring(result["xml"].encode("utf-8"))
assert root.findtext(".//내역서/재료비") == "200"
assert root.findall(".//세부공종")[1].findtext("계산제외") == "true"
assert result["blocked"]
def test_xml_keeps_parent_and_child_groups_instead_of_dropping_empty_parent_headers():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.name='test';p.tables.EstMainDat=[
{Code:'ROOT',Name:'parent',Level:3,GC:200,TC:200},
{Code:'CHILD',Name:'child',Level:1,GC:200,TC:200},
{Code:'FIX',Name:'fixed',GN:1,GC:200,TC:200,CalcIndex:1},{LinkIndex:54}];
return EstC3r.output(p,{company:'test',kind:'토목공사',date:'2026-11-06'});
})()""",
)
root = etree.fromstring(result["xml"].encode("utf-8"))
schema = etree.XMLSchema(etree.parse(str(SCHEMA)))
assert schema.validate(root), str(schema.error_log)
groups = root.findall(".//내역서")
assert [group.findtext("내역서번호") for group in groups] == ["01", "0101"]
assert [group.findtext("재료비") for group in groups] == ["200", "200"]
assert len(groups[0].findall("세부공종")) == 0
assert len(groups[1].findall("세부공종")) == 1