feat(est-test): 찾기 창 다음찾기와 한 건 바꾸기
- 원본 찾기 창처럼 처음부터/현재위치부터 다음찾기로 행 이동, 호표 자동 전환 - 단가산출 찾은 행 한 건 바꾸기 뒤 다음 위치로 이동 - 편집 메뉴 찾기와 Ctrl+F 로 열기 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
"""EST 테스트 앱 찾기 창: 다음찾기 순서·호표 위치·산출근거 문구."""
|
||||
|
||||
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-find.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.project = JSON.parse(fs.readFileSync('tools/est-test/sample.json', 'utf8'));
|
||||
process.stdout.write(JSON.stringify(vm.runInContext({json.dumps(code)}, ctx)));
|
||||
"""
|
||||
out = subprocess.check_output(["node", "-e", runner], cwd=ROOT)
|
||||
return json.loads(out.decode("utf-8"))
|
||||
|
||||
|
||||
def test_next_walks_matches_in_order_and_stops_at_end():
|
||||
result = run_js("""(() => {
|
||||
const rows = [{Name:'터파기'},{Name:'되메우기'},{Name:'잔토 터파기',Size:'백호'},{Name:'포장'}];
|
||||
const first = EstFind.next(rows, '터파기', 0);
|
||||
const second = EstFind.next(rows, '터파기', first + 1);
|
||||
const end = EstFind.next(rows, '터파기', second + 1);
|
||||
const spec = EstFind.next(rows, '백호', 0);
|
||||
const loose = EstFind.next(rows, ' 잔토 ', 0);
|
||||
let empty = '';
|
||||
try { EstFind.next(rows, ' ', 0); } catch (e) { empty = e.message; }
|
||||
return {first, second, end, spec, loose, empty};
|
||||
})()""")
|
||||
assert result == {
|
||||
"first": 0,
|
||||
"second": 2,
|
||||
"end": -1,
|
||||
"spec": 2,
|
||||
"loose": 2,
|
||||
"empty": "검색어를 입력하세요.",
|
||||
}
|
||||
|
||||
|
||||
def test_search_reads_cost_line_text_and_skips_previous_values():
|
||||
result = run_js("""(() => {
|
||||
const rows = [
|
||||
{LineData:'\\x0e콘크리트\\x0e \\x13타설\\x13', Name_:'옛이름'},
|
||||
{Name:'다른 행'}
|
||||
];
|
||||
return {
|
||||
line: EstFind.next(rows, '타설', 0),
|
||||
old: EstFind.next(rows, '옛이름', 0)
|
||||
};
|
||||
})()""")
|
||||
assert result == {"line": 0, "old": -1}
|
||||
|
||||
|
||||
def test_group_position_for_head_rows():
|
||||
result = run_js("""(() => {
|
||||
const rows = project.tables.HeadMainDat;
|
||||
const titles = rows.map((r, i) => [i, r]).filter(([, r]) => Number(r.Index) > 0);
|
||||
const [start, title] = titles[1];
|
||||
const hit = EstFind.groupOf(rows, start + 1);
|
||||
return {code: hit.code === title.Code, position: hit.position};
|
||||
})()""")
|
||||
assert result == {"code": True, "position": 1}
|
||||
Reference in New Issue
Block a user