1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
#!/usr/bin/env python3
"""
Parser 模块单元测试
"""
import unittest
import tempfile
from pathlib import Path
from conventionalrp.core.parser import Parser
class TestParser(unittest.TestCase):
"""Parser 类的单元测试"""
def setUp(self):
"""设置测试环境"""
self.parser = Parser()
# 创建临时规则文件
self.temp_rules = tempfile.NamedTemporaryFile(
mode='w',
suffix='.json5',
delete=False,
encoding='utf-8'
)
self.temp_rules.write('''{
metadata: [{
type: "metadata",
patterns: ["^\\\\[(.+?)\\\\]\\\\s*<(.+?)>\\\\s*(.*)$"],
groups: ["timestamp", "speaker", "content"],
priority: 100
}],
content: [
{
type: "dice_roll",
match_type: "enclosed",
patterns: ["\\\\[d(\\\\d+)\\\\s*=\\\\s*(\\\\d+)\\\\]"],
groups: ["dice_type", "result"],
priority: 90
},
{
type: "dialogue",
match_type: "enclosed",
patterns: ["「(.+?)」"],
groups: ["dialogue_text"],
priority: 60
},
{
type: "text",
match_type: "prefix",
patterns: ["^(.+)$"],
groups: ["text_content"],
priority: 1
}
]
}''')
self.temp_rules.close()
# 创建临时日志文件
self.temp_log = tempfile.NamedTemporaryFile(
mode='w',
suffix='.txt',
delete=False,
encoding='utf-8'
)
self.temp_log.write('''[2025-10-24 14:30:01] <艾莉娅> 「我要检查这扇门」
[2025-10-24 14:30:05] <DiceBot> 检定结果: [d20 = 18]
[2025-10-24 14:30:10] <DM> 你发现了陷阱
''')
self.temp_log.close()
def tearDown(self):
"""清理测试环境"""
Path(self.temp_rules.name).unlink(missing_ok=True)
Path(self.temp_log.name).unlink(missing_ok=True)
def test_load_rules_success(self):
"""测试成功加载规则文件"""
self.parser.load_rules(self.temp_rules.name)
self.assertIn("metadata", self.parser.rules)
self.assertIn("content", self.parser.rules)
def test_load_rules_file_not_found(self):
"""测试加载不存在的规则文件"""
with self.assertRaises(FileNotFoundError):
self.parser.load_rules("nonexistent_file.json5")
def test_parse_log_success(self):
"""测试成功解析日志"""
self.parser.load_rules(self.temp_rules.name)
result = self.parser.parse_log(self.temp_log.name)
self.assertIsInstance(result, list)
self.assertGreater(len(result), 0)
# 检查第一条记录
first_entry = result[0]
self.assertIn("timestamp", first_entry)
self.assertIn("speaker", first_entry)
self.assertIn("content", first_entry)
self.assertEqual(first_entry["speaker"], "艾莉娅")
def test_parse_log_file_not_found(self):
"""测试解析不存在的日志文件"""
self.parser.load_rules(self.temp_rules.name)
with self.assertRaises(FileNotFoundError):
self.parser.parse_log("nonexistent_log.txt")
def test_match_metadata(self):
"""测试元数据匹配"""
self.parser.load_rules(self.temp_rules.name)
line = "[2025-10-24 14:30:01] <艾莉娅> 测试内容"
result = self.parser._match_metadata(line)
self.assertIsNotNone(result)
self.assertEqual(result["type"], "metadata")
self.assertEqual(result["timestamp"], "2025-10-24 14:30:01")
self.assertEqual(result["speaker"], "艾莉娅")
def test_parse_line_content_dialogue(self):
"""测试解析对话内容"""
self.parser.load_rules(self.temp_rules.name)
line = "「这是一段对话」"
result = self.parser._parse_line_content(line)
self.assertIsInstance(result, list)
self.assertGreater(len(result), 0)
self.assertEqual(result[0]["type"], "dialogue")
def test_parse_line_content_dice_roll(self):
"""测试解析骰子投掷"""
self.parser.load_rules(self.temp_rules.name)
line = "检定结果: [d20 = 18]"
result = self.parser._parse_line_content(line)
# 应该包含文本和骰子投掷
dice_tokens = [t for t in result if t["type"] == "dice_roll"]
self.assertGreater(len(dice_tokens), 0)
if __name__ == "__main__":
unittest.main()
|