62 lines
3.1 KiB
Python
62 lines
3.1 KiB
Python
"""EST 테스트 앱 단가 도구(원본 중복 항목 정리 · 단가정의 엑셀 · 할증/낙찰/복원 · 항목선택계산 SUM 줄)."""
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
from test_est_rea_parity import run
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def run_js(code: str):
|
|
runner = f"""
|
|
const fs = require('fs'), vm = require('vm');
|
|
const ctx = vm.createContext({{ structuredClone }});
|
|
vm.runInContext(fs.readFileSync('tools/est-test/native-price-tools.js', 'utf8'), ctx);
|
|
process.stdout.write(JSON.stringify(vm.runInContext({json.dumps(code)}, ctx)));
|
|
"""
|
|
return json.loads(subprocess.check_output(["node", "-e", runner], cwd=ROOT).decode("utf-8"))
|
|
|
|
|
|
def test_price_tools_rules():
|
|
out = run_js(
|
|
r"""(() => {
|
|
const P = EstPriceTools;
|
|
const same = P.samecheck([{ Name: '철 근', Size: 'D10', Unite: 'ton', TC: 5 }, { Name: '철근', Size: 'D10', Unite: 'ton', TC: 9 },
|
|
{ Name: '철근|', Size: 'D10', Unite: 'ton', TC: 9 }, { Name: '모래', TC: 1 }]);
|
|
const g = P.gungu([{ Code: 'C1', Index: 3, Name: '포장', Size: 't=5', Unite: 'm2', EXPLEAN: '포함: 재료\n제외: 운반' }, { Code: 'C2', Name: '빈' }]);
|
|
const rows = [{ Name: 'a', TC: 100 }, { Name: 'b', TC: 200, OTC: 210 }, { Name: '', TC: 0 }];
|
|
const n = P.setRate(rows, [], 'NachalRatio', 88);
|
|
const one = [{ Name: 'x', TC: 1 }, { Name: 'y', TC: 2 }]; P.setRate(one, [1], 'Ratio', 5);
|
|
const r = { Name: '', Size: '', LinkIndex: 0 };
|
|
P.sumRow('HeadMainDat', r, { name: '기구손료', size: '', rate: 2, base: 2, target: 3, picked: [1, 3] });
|
|
const errs = [];
|
|
for (const [row, o] of [[{ Index: 1 }, {}], [{}, { base: 0, target: 2, picked: [1] }], [{}, { base: 1, target: 1, picked: [] }],
|
|
[{}, { base: 1, target: 1, picked: [1, 2, 3, 4, 5, 6] }]])
|
|
try { P.sumRow('HeadMainDat', row, { name: '', size: '', rate: 1, ...o }); } catch (e) { errs.push(e.message.slice(0, 8)); }
|
|
return { same: [same.removed, same.rows.map((x) => [x.Name, x.TC])], g, n, rows: rows.map((x) => [x.NachalRatio ?? null, x.OTC ?? null]),
|
|
one: one.map((x) => x.Ratio ?? null), r: [r.Code, r.LinkIndex, r.GN, r.Biul, r.Unite], errs };
|
|
})()"""
|
|
)
|
|
assert out["same"] == [2, [["철근|", 9], ["모래", 1]]]
|
|
assert out["g"] == [["C1", "3. 포장 (t=5) [m2]"], ["", "포함: 재료"], ["", "제외: 운반"], ["", ""]]
|
|
assert out["n"] == 3
|
|
assert out["rows"] == [[88, 100], [88, 210], [None, None]]
|
|
assert out["one"] == [5, 5]
|
|
assert out["r"] == ["A0103", 62, 2, 0.02, "%"]
|
|
assert out["errs"] == ["현재 라인에는 ", "비목별항목은 비", "더할항목의 색인", "더할항목의 색인"]
|
|
|
|
|
|
def test_sum_row_code_numbers_select_groups():
|
|
result = run(
|
|
"math",
|
|
"""(()=>{
|
|
const rows=[{Index:1,Code:'H'},{Code:'a',GN:1,NC:100,NU:100,SKind:1},{Code:'b',GN:1,NC:50,NU:50,SKind:3},
|
|
{Code:'c',GN:1,NC:7,NU:7,SKind:2},{Code:'A0103',LinkIndex:62,GN:10,OCheck:2,SCheck:2}];
|
|
const out=EstRows.head(rows,{HeadDigits:0});
|
|
return out.rows?out.rows[4].NC:out[4].NC;
|
|
})()""",
|
|
)
|
|
assert result == 15
|