// niceTickStep 자체검증 — B06_Section_UI_Section_Common.ts와 같은 로직(의존 없이 복제). // 실행: node tmp/tests/test_nice_tick_step.mjs import assert from "node:assert/strict"; function niceTickStep(span, targetCount, maxCount) { if (!(span > 0)) return 1; const exponent = Math.floor(Math.log10(span / targetCount)); let best = Math.pow(10, exponent + 2); let bestError = Infinity; for (const power of [exponent - 1, exponent, exponent + 1, exponent + 2]) { for (const mantissa of [1, 2, 5]) { const step = mantissa * Math.pow(10, power); const count = Math.floor(span / step) + 1; if (count > Math.max(2, maxCount)) continue; const error = Math.abs(count - targetCount); if (error < bestError) { bestError = error; best = step; } } } return best; } const counts = (span, step) => Math.floor(span / step) + 1; // 1·2·5 계열만 나온다 + 개수는 상한 이하, 목표 10에 근접. for (const span of [0.4, 1, 3.7, 8, 21, 27, 63, 140, 900, 4200]) { const step = niceTickStep(span, 10, 20); const mantissa = step / Math.pow(10, Math.round(Math.log10(step / 5)) - 0 || 0); assert.ok(step > 0, `step>0 (span=${span})`); const norm = step / Math.pow(10, Math.floor(Math.log10(step) + 1e-9)); assert.ok([1, 2, 5].some((m) => Math.abs(norm - m) < 1e-9), `1·2·5 계열 아님: ${step}`); assert.ok(counts(span, step) <= 20, `상한 초과: span=${span} step=${step}`); assert.ok(counts(span, step) >= 3, `너무 성김: span=${span} step=${step}`); void mantissa; } // 표고 27m 범위, 화면 여유 충분 → 2m 간격 10줄. assert.equal(niceTickStep(27, 10, 20), 2); // 화면이 낮아 6줄까지만 → 5m 간격. assert.equal(niceTickStep(27, 10, 6), 5); // 좁은 횡단(2m) → 0.2m 간격. assert.equal(niceTickStep(2, 10, 20), 0.2); // 범위 0 방어. assert.equal(niceTickStep(0, 10, 10), 1); console.log("ok");