Files
Aislo/resources/tester/test_est_quantity_sheets.py
T
eomsangdonandClaude Opus 5.5 029c7dab5a feat(est-test): 산출 줄 수량 지정과 지정 해제
- 드래그한 숫자를 결과 표지로 감싸 수량 항목 생성, 품명·규격·단위 표지 반영
- 커서 위치 결과 해제와 미사용 항목 삭제, 내역 연결 항목은 거부
- 이 편집의 ESTX 저장은 명확한 문구로 거부

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

144 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""EST 테스트 앱 수량산출서 복사·순서 이동과 ESTX 저장 거부."""
import json
import subprocess
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
MAIN = Path("C:/Dasansoft/Est Plus 2/Data/ProjectData/main.estx")
LOAD = """
const fs = require('fs'), vm = require('vm');
const ctx = vm.createContext({ structuredClone, console });
vm.runInContext(fs.readFileSync('tools/est-test/native-quantity-sheets.js', 'utf8'), ctx);
const run = (code) => vm.runInContext(code, ctx);
"""
def node(script: str, *args: str):
out = subprocess.check_output(["node", "-e", LOAD + script, *args], cwd=ROOT)
return json.loads(out.decode("utf-8"))
def test_copy_inserts_below_with_new_code_and_cleared_links():
result = node("""
ctx.project = { quantitySheets: [
{ Code: 'A', Name: '토공', items: [{ Code: 'r000000', TargetCode: 'D1', TargetKey: 'id:3', LinkCode: 'D1' }], rows: [{ LineData: 'x', markers: ['r000000'] }] },
{ Code: 'B', Name: '포장', items: [], rows: [] },
] };
const first = run("EstQuantitySheets.copy(project, 'A', 'u1')");
const second = run("EstQuantitySheets.copy(project, 'A', 'u1')");
const p = ctx.project;
process.stdout.write(JSON.stringify({
first, second, order: p.quantitySheets.map((s) => s.Code), name: p.quantitySheets[1].Name,
link: p.quantitySheets[1].items[0], original: p.quantitySheets[0].items[0].TargetCode,
rows: p.quantitySheets[1].rows[0].markers,
}));
""")
assert result == {
"first": "Qu1",
"second": "Qu1_2",
"order": ["A", "Qu1_2", "Qu1", "B"],
"name": "토공 복사본",
"link": {"Code": "r000000", "TargetCode": "", "TargetKey": ""},
"original": "D1",
"rows": ["r000000"],
}
def test_move_swaps_and_stops_at_edges():
result = node("""
ctx.project = { quantitySheets: [{ Code: 'A' }, { Code: 'B' }, { Code: 'C' }] };
const out = [run("EstQuantitySheets.move(project, 'B', -1)"), run("EstQuantitySheets.move(project, 'B', -1)"),
run("EstQuantitySheets.move(project, 'C', 1)")];
process.stdout.write(JSON.stringify({ out, order: ctx.project.quantitySheets.map((s) => s.Code) }));
""")
assert result == {"out": [True, False, False], "order": ["B", "A", "C"]}
def test_estx_export_refuses_reordered_sheets():
if not MAIN.exists():
pytest.skip("installed EST main sample unavailable")
result = node(
"""
const imp = require('./tools/est-test/import-estx.cjs'), ex = require('./tools/est-test/export-estx.cjs');
ctx.project = imp.importEstx(fs.readFileSync(process.argv[1]));
run("EstQuantitySheets.move(project, project.quantitySheets[0].Code, 1)");
let message = '';
try { ex.exportEstx(ctx.project); } catch (e) { message = e.message; }
process.stdout.write(JSON.stringify(message));
""",
str(MAIN),
)
assert result.startswith("수량산출서 순서 변경은 ESTX")
MARK = r"""(()=>{
const sheet={Code:'N1',options:{digits:2,roundMode:2},items:[{Code:'r000000',Name:'가'}],
rows:[{LineData:' \x0e잔토\x0e \x130.15\x13 2×3 = 6 \x15㎥\x15 그리고 \x125\x12',markers:['r000000']}]};
const shown=EstText.display(sheet.rows[0].LineData);
const at=shown.indexOf('6 ');
const out=[];
const t=(fn)=>{try{fn();out.push('ok');}catch(e){out.push(e.message.slice(0,6));}};
t(()=>EstQuantitySheets.mark(sheet,0,at,at+1,'r000001'));
const item=sheet.items.find(i=>i.Code==='r000001');
const markers=[...sheet.rows[0].markers];
const calc=EstQuantity.calculate(sheet).items.map(i=>[i.Code,i.GN]);
t(()=>EstQuantitySheets.mark(sheet,0,at+4,at+5,'r000002'));
t(()=>EstQuantitySheets.mark(sheet,0,0,3,'r000002'));
const inside=EstText.display(sheet.rows[0].LineData).indexOf('⟦결과⟧6')+5;
t(()=>EstQuantitySheets.free(sheet,0,inside));
const after=EstText.display(sheet.rows[0].LineData);
sheet.items[0].TargetCode='D1';
const last=after.lastIndexOf('⟦결과⟧')-1;
t(()=>EstQuantitySheets.free(sheet,0,last));
return {out,markers,item:[item.Name,item.Size,item.Unite],calc,
back:after===shown,items:sheet.items.map(i=>i.Code)};
})()"""
def test_mark_and_free_quantity_in_existing_line():
files = ["native-math.js", "native-formula.js", "native-text.js", "native-quantity.cjs"]
result = node(
f"""
for (const f of {json.dumps(files)})
vm.runInContext(fs.readFileSync('tools/est-test/' + f, 'utf8'), ctx, {{ filename: f }});
process.stdout.write(JSON.stringify(run({json.dumps(MARK)})));
"""
)
assert result["markers"] == ["r000001", "r000000"]
assert result["item"] == ["잔토", "0.15", "㎥"]
assert ["r000001", 6] in result["calc"]
assert result["back"] is True
assert result["items"] == ["r000000"]
assert [m[:2] for m in result["out"]] == ["ok", "이미", "산출", "ok", "내역"]
def test_estx_export_refuses_marker_edit():
if not MAIN.exists():
pytest.skip("installed EST main sample unavailable")
files = ["native-math.js", "native-formula.js", "native-text.js", "native-quantity.cjs"]
result = node(
f"""
for (const f of {json.dumps(files)})
vm.runInContext(fs.readFileSync('tools/est-test/' + f, 'utf8'), ctx, {{ filename: f }});
const imp = require('./tools/est-test/import-estx.cjs'), ex = require('./tools/est-test/export-estx.cjs');
ctx.project = imp.importEstx(fs.readFileSync(process.argv[1]));
run(`(() => {{
for (const s of project.quantitySheets)
for (let i = 0; i < s.rows.length; i++) {{
const code = s.rows[i].markers[0], item = s.items.find((x) => x.Code === code);
if (!code || !item || item.TargetCode || item.TargetKey) continue;
const t = EstText.display(s.rows[i].LineData);
return EstQuantitySheets.free(s, i, t.indexOf('⟦결과⟧') + 4);
}}
}})()`);
let message = '';
try {{ ex.exportEstx(ctx.project); }} catch (e) {{ message = e.message; }}
process.stdout.write(JSON.stringify(message));
""",
str(MAIN),
)
assert result.startswith("산출 줄의 수량 지정·해제는 ESTX")