"""714-3 텍스트 수식 입력 단추 지킴 시험 — 줄이 쓰는 입력 고르기(순수 함수 · node) + 이음 글. `M01_MasterData_UI_LogicLab_Formula.ts` 「순수 셈」 구간만 떼어 돌림(화면 · 서버 없음). """ import json import shutil import subprocess from pathlib import Path import pytest M01 = Path(__file__).resolve().parents[2] / "M01_MasterData" FX = M01 / "M01_MasterData_UI_LogicLab_Formula.ts" pytestmark = pytest.mark.skipif(shutil.which("node") is None, reason="node 가 없음") def _run(body: str) -> object: text = FX.read_text(encoding="utf-8") pure = text[text.index("/* ── 순수 셈: 줄이 쓰는 입력 ── */") : text.index("/* ── 순수 셈 끝 ── */")] out = subprocess.run( ["node", "--experimental-strip-types", "--no-warnings", "--input-type=module-typescript", "-e", pure + "\n" + body], capture_output=True, text=True, encoding="utf-8", timeout=60, ) # fmt: skip assert out.returncode == 0, out.stderr return json.loads(out.stdout) def test_표_행_열쇠와_이름_조각(): got = _run( """ const line = { 조각: [ { kind: "표", 글: "25 · 깬잡석", 참조: { 키: "QF1", 행: { 뒷길이: 25, 돌: "깬잡석", 줄번호: 3 } } }, { kind: "기호", 글: "*" }, { kind: "값", 글: "두께", 값: "20" }, { kind: "값", 글: "0.009" }, { kind: "값", 글: "뒷길이", 값: "99" }, ], 요소조각: [{ kind: "표", 글: "x", 참조: { 키: "QF2", 행: 4 } }], }; console.log(JSON.stringify(usedInputs(line, ["뒷길이", "돌", "두께", "쌓기"]))); """ ) # 처음 나온 값 · 입력 아닌 열쇠(줄번호) · 이름 없는 수(0.009) · 행 번호(4) 는 뺌 assert got == [["뒷길이", "25"], ["돌", "깬잡석"], ["두께", "20"]] def test_빈_줄(): assert _run('console.log(JSON.stringify(usedInputs({}, ["a"])))') == [] def test_이음_시험_입력만_고침(): lab = (M01 / "M01_MasterData_UI_LogicLab.ts").read_text(encoding="utf-8") detail = (M01 / "M01_MasterData_UI_LogicLab_Detail.ts").read_text(encoding="utf-8") # 텍스트 수식 고침 = 시험 계산 입력 + 다시 셈(흐름 예시값과 같은 길) · 캐시(drafts)에 안 들어감 assert "onInput: (name, v) => syncLeft(current, { [name]: v }, true)" in lab assert "onInput: ctx.onInput" in detail fx = FX.read_text(encoding="utf-8") assert "touch" not in fx and "drafts" not in fx