Files
Aislo/resources/tester/test_est_jungsang.py
T
eomsangdonandClaude Opus 5.5 8c3a3d4267 feat(est-test): 정산원가계산서 작성과 당초금액 초기화
- 원본 처리 근거대로 당초금액 복사, 도급액 고정 연결 해제, (감)/(증) 차액 행
- 작성/해제 토글과 원가 화면 당초금액·정산금액 열, 재계산마다 차액 갱신

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 19:29:23 +09:00

88 lines
3.5 KiB
Python

"""EST 테스트 앱 정산원가계산서(원본 당초금액 초기화·정산원가계산서 작성/해제)."""
import json
import re
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
FILES = [
"native-math.js",
"native-formula.js",
"native-machine.js",
"native-rows.js",
"native-text.js",
"native-quantity.cjs",
"native-wonga.js",
"native-jungsang.js",
"native-engine.js",
"native-row-match.js",
"native-escalation.js",
"native-progress.js",
"native-business.js",
"native-review.js",
"native-resources.js",
"native-schedule.js",
"native-model.js",
"native-verify.js",
]
def run_js(code: str):
runner = f"""
const fs = require('fs'), vm = require('vm');
const ctx = vm.createContext({{ structuredClone, console }});
for (const f of {json.dumps(FILES)})
vm.runInContext(fs.readFileSync('tools/est-test/' + f, 'utf8'), ctx, {{ filename: f }});
ctx.source = JSON.parse(fs.readFileSync('tools/est-test/sample.json', 'utf8'));
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_difference_text_and_row_reuse():
result = run_js(
"""(() => {
const rows = [{ Name: '순공사비', Cost: 100, SC: 120 }, { Name: '', Cost: 0 }, { Name: '', Cost: 0 }];
const less = EstJungSang.difference(rows);
rows[0].Cost = 150;
const more = EstJungSang.difference(rows);
return { less, more, at: rows.findIndex((r) => r.LinkIndex === 66), size: rows.length, row: rows[1] };
})()"""
)
assert result["less"] == "(감)20" and result["more"] == "(증)30"
assert result["at"] == 1 and result["size"] == 3
assert result["row"]["Name"] == "." and result["row"]["EndLineIndex"] == 1
def test_toggle_copies_original_amounts_and_recalc_rewrites_difference():
result = run_js(
"""(() => {
const calc = (p) => EstNative.calculate(EstModel.validate(p));
let p = calc(structuredClone(source));
const before = p.tables.Wonga.map((r) => Number(r.Cost) || 0);
const fixed = p.tables.Wonga.findIndex((r) => Number(r.LinkIndex) === 55);
EstJungSang.toggle(p);
const copied = p.tables.Wonga.every((r, i) => r.LinkIndex === 66 || Number(r.SC) === (before[i] ?? 0));
p = calc(p);
const zero = p.tables.Wonga.find((r) => r.LinkIndex === 66).VSusic;
const row = p.tables.EstMainDat.find((r) => Number(r.GN) > 0 && Number(r.TU) > 0 && !Number(r.Level));
row.GN = Number(row.GN) * 2;
p = calc(p);
const diff = p.tables.Wonga.find((r) => r.LinkIndex === 66).VSusic;
const errors = p.calculation.errors.length;
EstJungSang.toggle(p);
const off = { show: p.options.JungSangShow, has66: p.tables.Wonga.some((r) => r.LinkIndex === 66),
keptSC: p.tables.Wonga.some((r) => Number(r.SC) > 0) };
return { copied, released: Number(p.tables.Wonga[fixed].LinkIndex), zero, diff, errors, off,
columns: EstJungSang.columns({ options: { JungSangShow: true } }, ['Name', 'VSusic', 'Cost']) };
})()"""
)
assert result["copied"] is True
assert result["released"] == 0
assert re.match(r"^(0|\((증|감)\)\d+)$", result["zero"])
assert result["diff"].startswith("(증)")
assert result["errors"] == 0
assert result["off"] == {"show": False, "has66": False, "keptSC": True}
assert result["columns"] == ["Name", "VSusic", "SC", "Cost"]