Files
document-haness/scripts/tests/test_figure_overlap.py
T
DongHyeonkaandClaude Opus 5 ab59130196 chore: 이전 세션이 남긴 변경을 커밋한다
이번 파이프라인 작업과 무관하게 작업 트리에 남아 있던 것을 그대로 올린다.
사용자가 「전부 커밋」으로 정했고, 이번 작업과 섞이지 않게 커밋만 나눴다.

대부분은 clean-architecture-backend-template 의 그림 정본 재배치다 —
final/assets/diagrams/<이름>/ 에 있던 것이 CLAUDE.md 가 적은 배치인
final/assets/<이름>/ 로 옮겨졌고 .techviz/<이름>/ 이 함께 들어왔다.
삽입 줄의 대부분(3.15M)이 그 .techviz context.json 이다.

그 밖에 ca-tmpl·document-haness 의 정리, .claude/agents/ 열한 개,
writing-practitioner-guides 스킬, .playwright-mcp 세션 산출물,
scripts/check-ssot-facts.py 와 그 시험이 들어 있다.

이 커밋의 내용은 내가 만든 것이 아니라 이전 세션이 남긴 것이고 검증하지 않았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 11:02:02 +09:00

123 lines
5.1 KiB
Python

"""그림 겹침 검사기. 겹친 것을 실제로 잡고 안 겹친 것은 안 잡는지 본다."""
import os
import subprocess
import sys
import tempfile
import unittest
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
SCRIPT = os.path.join(ROOT, "scripts", "check-figure-overlap.py")
HEAD = '<svg xmlns="http://www.w3.org/2000/svg"><rect class="canvas" width="400" height="300"/>'
TAIL = "</svg>"
def svg(*rects):
return HEAD + "".join(rects) + TAIL
def rect(cls, x, y, w, h):
return f'<rect class="{cls}" x="{x}" y="{y}" width="{w}" height="{h}"/>'
def run(body):
with tempfile.NamedTemporaryFile("w", suffix=".svg", delete=False,
encoding="utf-8") as fh:
fh.write(body)
path = fh.name
try:
p = subprocess.run([sys.executable, SCRIPT, "--file", path],
capture_output=True, text=True, cwd=ROOT)
return p.returncode, p.stdout + p.stderr
finally:
os.unlink(path)
class Overlap(unittest.TestCase):
def test_안_겹치면_통과한다(self):
code, out = run(svg(rect("group-box", 0, 0, 100, 100),
rect("group-box", 150, 0, 100, 100)))
self.assertEqual(code, 0, out)
self.assertIn("PASS", out)
def test_맞닿기만_한_것은_겹친_것이_아니다(self):
code, out = run(svg(rect("group-box", 0, 0, 100, 100),
rect("group-box", 100, 0, 100, 100)))
self.assertEqual(code, 0, out)
def test_구역_둘이_겹치면_잡는다(self):
code, out = run(svg(rect("group-box", 0, 0, 100, 100),
rect("group-box", 50, 50, 100, 100)))
self.assertEqual(code, 1)
self.assertIn("구역 둘이 겹쳐 그려졌다", out)
def test_이음_라벨이_상자에_먹히면_잡는다(self):
code, out = run(svg(rect("node-shape kind-service", 100, 100, 120, 60),
rect("edge-label-bg", 80, 110, 60, 20)))
self.assertEqual(code, 1)
self.assertIn("이음 라벨이 상자에 먹혔다", out)
def test_구역_이름이_서로를_덮으면_잡는다(self):
code, out = run(svg(rect("group-label-bg", 10, 10, 120, 22),
rect("group-label-bg", 20, 12, 120, 22)))
self.assertEqual(code, 1)
self.assertIn("구역 이름이 서로를 덮는다", out)
def test_상자_안에_든_상자는_설계다(self):
"""node-shape 가 group-box 안에 드는 것은 정상이라 잡지 않는다."""
code, out = run(svg(rect("group-box", 0, 0, 200, 200),
rect("node-shape kind-service", 20, 20, 80, 40)))
self.assertEqual(code, 0, out)
def test_겹친_자리의_이름을_말해_준다(self):
body = svg(rect("node-shape kind-service", 100, 100, 120, 60),
rect("edge-label-bg", 80, 110, 60, 20)) \
.replace(TAIL, '<text class="edge-label" x="82" y="124">토큰</text>' + TAIL)
code, out = run(body)
self.assertEqual(code, 1)
self.assertIn("토큰", out)
class Project(unittest.TestCase):
@unittest.skipUnless(os.path.isdir(os.path.join(ROOT, "docs/keycloak/final/assets")),
"keycloak 그림이 없다")
def test_프로젝트_단위로도_돈다(self):
p = subprocess.run([sys.executable, SCRIPT, "keycloak"],
capture_output=True, text=True, cwd=ROOT)
self.assertIn("FIGURE OVERLAP", p.stdout)
if __name__ == "__main__":
unittest.main()
class UnseenIsNotClean(unittest.TestCase):
"""「안 겹친다」와 「못 봤다」는 다른 출력이다.
이 검사기는 techviz 렌더러가 붙인 `class` 로만 상자를 알아본다. 손으로 그린 SVG 에는
그 class 가 없어 `boxes()` 가 비고, 겹칠 짝이 없으니 겹침 0 이 나온다. 고치기 전에는
그것을 `그림 182 · 겹친 그림 0` 으로 찍었는데 **실제로 본 것은 18장**이었다.
나머지 164장은 안 겹친 것이 아니라 볼 수 없었던 것이다.
"""
HAND_DRAWN = ('<svg xmlns="http://www.w3.org/2000/svg">'
'<rect x="0" y="0" width="400" height="300" fill="#fff"/>'
'<rect x="10" y="10" width="100" height="40"/>'
'<rect x="20" y="20" width="100" height="40"/>'
'<text x="30" y="30">겹친 상자 둘</text></svg>')
def test_a_hand_drawn_svg_is_counted_as_unseen(self):
_, out = run(self.HAND_DRAWN)
self.assertIn("못 본 그림 1", out, out)
self.assertIn("본 그림 0", out, out)
def test_a_hand_drawn_svg_does_not_read_as_checked(self):
"""상자가 실제로 겹쳐 있는데도 이 검사기는 답하지 못한다. 그 사실이 보여야 한다."""
_, out = run(self.HAND_DRAWN)
self.assertIn("답하지 못한다", out, out)
def test_a_techviz_svg_is_counted_as_seen(self):
_, out = run(svg(rect("node-shape", 10, 10, 100, 40)))
self.assertIn("본 그림 1", out, out)
self.assertNotIn("못 본 그림", out, out)