批次1: 项目结构 + SQLite 存储层 + 数据模型 批次2: REST API (http.server) 批次3: LLM 编译器 (支持 OpenAI/Anthropic) 批次4: RestrictedPython 规则执行器 批次5: 规则匹配器 + LLM Callback 兜底 批次6: 冲突检测器 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
95 lines
2.5 KiB
Python
95 lines
2.5 KiB
Python
"""Tests for LLM compiler."""
|
||
import pytest
|
||
from rule_engine.compiler import (
|
||
build_compile_prompt,
|
||
extract_code_block,
|
||
RuleCompiler,
|
||
mock_llm_response
|
||
)
|
||
|
||
|
||
def test_build_compile_prompt():
|
||
"""验证 prompt 模板构建。"""
|
||
prompt = build_compile_prompt("如果用户是会员则打折")
|
||
assert "如果用户是会员则打折" in prompt
|
||
assert "def rule(facts: dict)" in prompt
|
||
|
||
|
||
def test_extract_code_block_with_python():
|
||
"""验证从 markdown 代码块提取 Python 代码。"""
|
||
text = '''这是一些解释文字
|
||
|
||
```python
|
||
def rule(facts: dict) -> dict:
|
||
if facts.get("subscription") == "premium":
|
||
return {"action": "discount"}
|
||
return None
|
||
```
|
||
|
||
更多文字
|
||
'''
|
||
code = extract_code_block(text)
|
||
assert code is not None
|
||
assert 'def rule(facts: dict)' in code
|
||
assert 'subscription' in code
|
||
|
||
|
||
def test_extract_code_block_without_language():
|
||
"""验证不带语言标识的代码块。"""
|
||
text = '''
|
||
```
|
||
def rule(facts):
|
||
return None
|
||
```
|
||
'''
|
||
code = extract_code_block(text)
|
||
assert code is not None
|
||
assert 'def rule' in code
|
||
|
||
|
||
def test_extract_code_block_plain():
|
||
"""验证纯代码(无代码块)。"""
|
||
code = 'def rule(facts):\n return None'
|
||
result = extract_code_block(code)
|
||
assert result == code
|
||
|
||
|
||
def test_extract_code_block_invalid():
|
||
"""验证无效输入返回 None。"""
|
||
assert extract_code_block("这是一个普通文本") is None
|
||
assert extract_code_block("") is None
|
||
|
||
|
||
def test_mock_llm_response_premium():
|
||
"""验证 mock 响应生成(premium 场景)。"""
|
||
code = mock_llm_response("如果用户是 premium 会员")
|
||
assert "premium" in code
|
||
assert "def rule" in code
|
||
|
||
|
||
def test_mock_llm_response_default():
|
||
"""验证 mock 响应生成(默认场景)。"""
|
||
code = mock_llm_response("普通规则")
|
||
assert "def rule" in code
|
||
|
||
|
||
def test_rule_compiler_validate_syntax_valid():
|
||
"""验证语法检查通过。"""
|
||
compiler = RuleCompiler()
|
||
code = 'def rule(facts):\n return None'
|
||
assert compiler.validate_syntax(code) is True
|
||
|
||
|
||
def test_rule_compiler_validate_syntax_invalid():
|
||
"""验证语法检查失败。"""
|
||
compiler = RuleCompiler()
|
||
code = 'def rule(facts):\n return None\n\nextra invalid'
|
||
assert compiler.validate_syntax(code) is False
|
||
|
||
|
||
def test_rule_compiler_validate_syntax_syntax_error():
|
||
"""验证语法错误检测。"""
|
||
compiler = RuleCompiler()
|
||
code = 'def rule(facts):\n if .'
|
||
assert compiler.validate_syntax(code) is False
|