You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.6 KiB
Python
86 lines
2.6 KiB
Python
# backend/tests/test_nl_parser.py — 자연어 파서 골든 + 휴리스틱 폴백
|
|
import pytest
|
|
|
|
from app.automation.nl_parser import parse_rule
|
|
from tests._fake_llm import FakeLLMProvider
|
|
|
|
GOLDEN = [
|
|
(
|
|
"출장 전날엔 저녁 일정 비워줘",
|
|
"cal",
|
|
"출장 전날이 되면",
|
|
"18시 이후 일정이 있으면",
|
|
"다른 날로 옮기자고 제안",
|
|
),
|
|
(
|
|
"뉴스레터는 모아서 저녁에 보여줘",
|
|
"mail",
|
|
"뉴스레터 메일 도착",
|
|
None,
|
|
"받은편지함 건너뛰고 18:30 다이제스트로",
|
|
),
|
|
(
|
|
"운동을 3일 거르면 산책 잡아줘",
|
|
"life",
|
|
"운동 기록 3일 연속 없음",
|
|
"저녁에 빈 시간이 있으면",
|
|
"30분 산책 블록 제안",
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("text,cat,trig,cond,action", GOLDEN)
|
|
def test_golden_examples(text, cat, trig, cond, action):
|
|
r = parse_rule(text)
|
|
assert r.matched and r.cat == cat
|
|
assert r.trigger == trig and r.cond == cond and r.action == action
|
|
assert r.model == "example"
|
|
|
|
|
|
def test_heuristic_fallback_classifies_cat():
|
|
# examples 미일치 → 휴리스틱(명시 provider 로 환경(Ollama 가동 여부) 무관 결정적)
|
|
r = parse_rule("영수증 들어오면 자동으로 정리해줘", provider=FakeLLMProvider())
|
|
assert r.matched and r.cat == "life" and r.model == "heuristic"
|
|
|
|
|
|
def test_empty_input_not_matched():
|
|
r = parse_rule("") # 빈 입력은 LLM 호출 없이 미매칭
|
|
assert not r.matched
|
|
|
|
|
|
class _FakeProvider:
|
|
name = "fake"
|
|
model = "fake-llm"
|
|
|
|
def health(self):
|
|
return {"reachable": True}
|
|
|
|
def generate_json(self, prompt, schema=None):
|
|
return {
|
|
"name": "회의록 자동화",
|
|
"cat": "cal",
|
|
"trigger": "회의 종료",
|
|
"cond": None,
|
|
"action": "요약 작성",
|
|
"confidence": 0.9,
|
|
}
|
|
|
|
def classify_capture(self, raw, context): # pragma: no cover
|
|
raise NotImplementedError
|
|
|
|
|
|
def test_llm_path_uses_provider_json():
|
|
r = parse_rule("회의 끝나면 요약해줘", provider=_FakeProvider())
|
|
assert r.matched and r.cat == "cal" and r.action == "요약 작성"
|
|
assert r.model == "llm:fake-llm"
|
|
|
|
|
|
class _BrokenProvider(_FakeProvider):
|
|
def generate_json(self, prompt, schema=None):
|
|
raise RuntimeError("llm down")
|
|
|
|
|
|
def test_llm_exception_falls_back_to_heuristic():
|
|
r = parse_rule("영수증 들어오면 정리해줘", provider=_BrokenProvider())
|
|
assert r.matched and r.model == "heuristic"
|