- 엑셀형 산출서 BIFF 수식 해석·다시 계산·수식줄 편집·4방향 합·수량으로 지정(가져올 때 값이 같은 합계 셀 추정 연결), 셀 편집 시 ESTX 저장 거부 - 원가 행 계산을 원본 c9d278 끝부분대로: 소수 4자리 반올림 뒤 원 미만 절사, Diget>0 행 자리맞춤(0x11293e8) - 원가계산서 「선택 행 자릿수 설정」을 원본 선택항목 절하하기 대화로(도급액 행 거부, 입력 행 원금액 기준) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
2.7 KiB
Python
55 lines
2.7 KiB
Python
"""EST 테스트 앱 엑셀형 수량산출서(.xls OLE2/BIFF8) 읽기 — 원본 TFRMMULEXCEL 본문."""
|
|
|
|
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")
|
|
|
|
|
|
def test_reads_embedded_excel_sheets_from_installed_main():
|
|
if not MAIN.exists():
|
|
pytest.skip("installed EST main sample unavailable")
|
|
script = """
|
|
const fs = require('fs'), imp = require(process.cwd() + '/tools/est-test/import-estx.cjs');
|
|
const p = imp.importEstx(fs.readFileSync(process.argv[1]));
|
|
const sheets = p.quantitySheets.filter((s) => s.excel);
|
|
const first = sheets.find((s) => s.Code === 'N0000000136').excel[0];
|
|
const formulas = Object.values(first.cells).filter((c) => c.formula);
|
|
process.stdout.write(JSON.stringify({ count: sheets.length, name: first.name,
|
|
title: first.cells['1,1'].value, station: first.cells['6,1'].value, number: first.cells['6,2'].value,
|
|
formulas: formulas.length, numeric: formulas.every((c) => typeof c.value === 'number' || typeof c.value === 'string') }));
|
|
"""
|
|
result = json.loads(
|
|
subprocess.check_output(["node", "-e", script, str(MAIN)], cwd=ROOT).decode("utf-8")
|
|
)
|
|
assert result == {
|
|
"count": 6,
|
|
"name": "Sheet1",
|
|
"title": "토적계산표",
|
|
"station": "No.1",
|
|
"number": 20,
|
|
"formulas": 16,
|
|
"numeric": True,
|
|
}
|
|
|
|
|
|
def test_rejects_non_ole_and_renders_grid():
|
|
script = """
|
|
const fs = require('fs'), vm = require('vm');
|
|
const { readXls } = require(process.cwd() + '/tools/est-test/xls-read.cjs');
|
|
let message = ''; try { readXls(Buffer.from('not an xls file at all')); } catch (e) { message = e.message; }
|
|
const ctx = vm.createContext({ structuredClone, EstApp: { esc: (v) => String(v), number: (v) => String(v), state: {} } });
|
|
for (const f of ['native-excel-sheet.cjs', 'native-excel-view.js', 'native-quantity-sheets.js'])
|
|
vm.runInContext(fs.readFileSync('tools/est-test/' + f, 'utf8'), ctx);
|
|
ctx.sheet = { excel: [{ name: 'S', cells: { '0,0': { value: '측점' }, '1,1': { value: 3, formula: true } } }] };
|
|
const html = vm.runInContext('EstQuantitySheets.excelView(sheet)', ctx);
|
|
process.stdout.write(JSON.stringify({ message, html: [html.includes('측점'), html.includes('<th>B</th>'), html.includes('font-weight:bold'), vm.runInContext('EstQuantitySheets.excelView({})', ctx)] }));
|
|
"""
|
|
result = json.loads(subprocess.check_output(["node", "-e", script], cwd=ROOT).decode("utf-8"))
|
|
assert result["message"].startswith("엑셀형 수량산출서 형식")
|
|
assert result["html"] == [True, True, True, ""]
|