"""EST 테스트 앱 예정공정표 눈금 단위(원본 1·5·10·15·20일, 1주, 1개월).""" import json import subprocess from pathlib import Path ROOT = Path(__file__).resolve().parents[2] def run_js(code: str): runner = f""" const fs = require('fs'), vm = require('vm'); const ctx = vm.createContext({{ structuredClone, console }}); vm.runInContext(fs.readFileSync('tools/est-test/native-schedule.js', 'utf8'), ctx); 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_day_week_month_ticks(): result = run_js( """(() => { const t = (s, e, k, n) => EstSchedule.ticks(s, e, k, n); const week = t('2026-01-01', '2026-01-28', '1w'); const month = t('2026-01-15', '2026-04-10', '1m'); const tenth = t('2026-01-01', '2026-01-30', '10d'); const many = t('2026-01-01', '2026-12-31', '1d', 60); let bad = ''; try { t('2026-01-01', '2026-01-02', 'x'); } catch (e) { bad = e.message; } return { week: week.ticks.map((x) => [x.label, Math.round(x.left)]), month: month.ticks.map((x) => x.label), tenth: tenth.ticks.map((x) => x.label), cut: many.cut, count: many.ticks.length, empty: t('', '', '1d').ticks.length, bad }; })()""" ) assert result["week"] == [["01-01", 0], ["01-08", 25], ["01-15", 50], ["01-22", 75]] assert result["month"] == ["2026-01", "2026-02", "2026-03", "2026-04"] assert result["tenth"] == ["01-01", "01-11", "01-21"] assert result["cut"] is True and result["count"] == 60 assert result["empty"] == 0 assert result["bad"] == "눈금 단위를 고르세요."