Files
Aislo/resources/tester/test_est_estimate_print.py
T
eomsangdonandClaude Opus 5.5 f8f4be7c75 feat(est-test): 견적서 작성과 공급자정보 .einf
- 원본 처리 근거대로 레벨 행 선택, 7열, 1쪽 머리·공급자·한글 합계금액, 쪽 나눔
- 공사별 설정 저장, 원본 INI 형식 공급자정보 저장·불러오기, 미리보기·인쇄

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 20:24:31 +09:00

71 lines
3.1 KiB
Python

"""EST 테스트 앱 견적서 작성(원본 TfrmEstiMatePrn — 레벨 행 선택·열·합계금액·쪽 나눔·.einf)."""
import json
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-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",
"native-docs.js",
"native-estimate-print.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_rows_total_pages_and_ini():
result = run_js(
"""(() => {
const p = EstNative.calculate(EstModel.validate(structuredClone(source)));
const all = EstEstimatePrint.rows(p, 0).length, est = p.tables.EstMainDat.length;
const lvl = EstEstimatePrint.rows(p, 2);
const okLevel = lvl.every((r) => Number(r.Level) >= 2 || [54, 55, 58].includes(Number(r.LinkIndex)));
const pages = EstEstimatePrint.pages(Array.from({ length: 70 }, (_, i) => i), 27, 36).map((x) => x.length);
const s = { ...EstEstimatePrint.settings(p), ComPany_Name: '(주)시험', Company_Show: false, F_PageCount: 20 };
const ini = EstEstimatePrint.toIni(s);
const back = EstEstimatePrint.fromIni(ini);
const html = EstEstimatePrint.html(p, { ...s, Level: 2 });
let bad = ''; try { EstEstimatePrint.pages([1], 0, 1); } catch (e) { bad = e.message; }
return { all: all === est, okLevel, some: lvl.length > 0 && lvl.length < est, pages,
total: EstEstimatePrint.totalText(EstEstimatePrint.total(p)),
ini: ini.includes('[EstiPrnCompanyInfo]') && ini.includes('ComPany_Name=(주)시험') && ini.includes('Company_Show=0'),
back: [back.ComPany_Name, back.Company_Show, back.F_PageCount, back.Project_Name === undefined],
html: [html.includes('견 적 서'), html.includes('아래와 같이 견적합니다'), html.includes('공<br>급'), html.includes('공급가액')],
bad };
})()"""
)
assert result["all"] is True and result["okLevel"] is True and result["some"] is True
assert result["pages"] == [27, 36, 7]
assert result["total"] == " 일금:구천칠백일십구만구천원정 (₩97,199,000원정)"
assert result["ini"] is True
assert result["back"] == ["(주)시험", False, 20, True]
assert result["html"] == [True, True, False, True]
assert result["bad"] == "쪽당 줄 수는 1 이상입니다."