- 옛 「옵션 보이기 · 그룹」 화면을 정의 편집 화면으로 넓힘(시스템 관리자 고쳐 씀 · 다른 역할 읽기만) - 자료 손질 = M02_SO_Def_Model.ts(정의 틀 48-1 꼴) · 시험 test_m02_so_def_model.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
88 lines
3.0 KiB
Python
88 lines
3.0 KiB
Python
"""M02 구조물 정의 편집 화면 자료 손질(`M02_SO_Def_Model.ts` · PLAN 48-2) 단위검증.
|
|
|
|
프론트에 JS 테스트 러너가 없어 Node 헬퍼(`helper_m02_so_def_model.cjs`)가 TS 를 트랜스파일해 돌리고
|
|
pytest 는 그 결과(JSON)를 판정.
|
|
|
|
못박는 것
|
|
- 배치 격자: 안 정한 옵션은 차례대로 · 정한 자리 먼저 · 너비 ≤ 칸 수 · 안 씀 빠짐 · 겹침 찾음.
|
|
- 규칙: 없는 값 · 자기 자신 · 없는 하위 선택지 · 그러면 비었음 · 좁힌 선택지 밖 기본값은 틀린 줄
|
|
(서버 `M02_SO_Definition._rule_errors` 와 같은 뜻) · 고르기 아닌 상위는 값 검사 안 함.
|
|
- 저장 전 검사: 깨끗한 정의 = 빈 목록 · 이름 겹침 · 배치 겹침 · 빈 선택지 = 까닭 글.
|
|
- 선택지 이름 바꿈 · 뺌은 그 옵션 기본값 · 같은 종류 규칙도 같이 고침.
|
|
- 순서: 구조물군 = 키 차례 · 종류 = 같은 군 안에서만.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def r() -> dict:
|
|
proc = subprocess.run(
|
|
["node", str(HERE / "helper_m02_so_def_model.cjs")],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=60,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
def test_배치_자동_채움(r) -> None:
|
|
assert r["auto"] == {
|
|
"a": {"줄": 1, "칸": 1, "너비": 1},
|
|
"b": {"줄": 1, "칸": 2, "너비": 1},
|
|
"c": {"줄": 2, "칸": 1, "너비": 1},
|
|
}
|
|
|
|
|
|
def test_배치_정한_자리_먼저_너비는_칸수까지(r) -> None:
|
|
assert r["fixed"]["c"] == {"줄": 1, "칸": 1, "너비": 2}
|
|
assert r["fixed"]["a"] == {"줄": 2, "칸": 1, "너비": 1}
|
|
assert r["fixed"]["b"] == {"줄": 2, "칸": 2, "너비": 1}
|
|
|
|
|
|
def test_안씀은_격자에서_빠짐(r) -> None:
|
|
assert set(r["off"]) == {"b", "c"}
|
|
assert r["off"]["b"] == {"줄": 1, "칸": 1, "너비": 1}
|
|
|
|
|
|
def test_겹침(r) -> None:
|
|
assert r["overlap"] == ["a", "b"]
|
|
|
|
|
|
def test_규칙_틀린_줄(r) -> None:
|
|
assert r["rules"] == [False, True, True, True, True, False, True]
|
|
|
|
|
|
def test_이름_검사(r) -> None:
|
|
assert r["names"] == ["(빈 이름)", "가"]
|
|
|
|
|
|
def test_저장_전_검사(r) -> None:
|
|
assert r["clean"] == []
|
|
assert any("옵션 이름" in t for t in r["broken"])
|
|
assert any("배치 겹침" in t for t in r["broken"])
|
|
assert any("선택지가 있어야" in t for t in r["broken"])
|
|
|
|
|
|
def test_선택지_이름_바꿈_뺌은_기본값_규칙도_같이(r) -> None:
|
|
assert r["rename"] == [["엑스", "y"], "엑스", ["엑스", "y"], ["피"], "피"]
|
|
assert r["drop"] == [["q"], [], False]
|
|
|
|
|
|
def test_순서_기준측점_새키(r) -> None:
|
|
assert r["family"] == [False, True, ["B", "A"]]
|
|
assert r["type"] == [False, True, ["k2", "k1", "k3"]]
|
|
assert r["base"] == [True, False]
|
|
assert r["step"] == [False, True, [2, 1, 3]]
|
|
assert r["newKey"] == [True, True]
|