forked from Ikalus1988/MisakaNet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_search_knowledge_stdout.py
More file actions
146 lines (116 loc) · 5.56 KB
/
Copy pathtest_search_knowledge_stdout.py
File metadata and controls
146 lines (116 loc) · 5.56 KB
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
143
144
145
146
import io
import json
import unittest
from pathlib import Path
from unittest import mock
import search_knowledge
class ReconfigurableStdout(io.StringIO):
def __init__(self):
super().__init__()
self.reconfigure_calls = []
def reconfigure(self, **kwargs):
self.reconfigure_calls.append(kwargs)
class TestSearchKnowledgeStdout(unittest.TestCase):
def test_ensure_utf8_stdout_reconfigures_stream(self):
stdout = ReconfigurableStdout()
with mock.patch.object(search_knowledge.sys, "stdout", stdout):
search_knowledge._ensure_utf8_stdout()
self.assertEqual(
stdout.reconfigure_calls,
[{"encoding": "utf-8", "errors": "replace"}],
)
def test_ensure_utf8_stdout_ignores_unsupported_stream(self):
stdout = io.StringIO()
with mock.patch.object(search_knowledge.sys, "stdout", stdout):
search_knowledge._ensure_utf8_stdout()
def test_json_result_uses_required_schema(self):
doc = mock.Mock(
title="Database locked",
domain="database",
tags=["sqlite", "locking"],
filepath=Path(search_knowledge.__file__).parent / "lessons" / "example.md",
content="---\ntitle: Example\n---\n\nA useful preview.",
)
result = search_knowledge._json_result(0.12345678, doc)
self.assertEqual(
set(result), {"title", "domain", "tags", "score", "path", "preview", "freshness"}
)
self.assertEqual(result["path"], "lessons/example.md")
self.assertEqual(result["score"], 0.123457)
def test_json_result_includes_match_reason_when_query_is_provided(self):
doc = mock.Mock(
title="Network timeout",
domain="devops",
tags=["network", "retry"],
filepath=Path(search_knowledge.__file__).parent / "lessons" / "example.md",
content="---\ntitle: Example\n---\n\nRetry the network timeout with backoff.",
)
result = search_knowledge._json_result(0.5, doc, query="timeout network")
self.assertIn("title keyword 'timeout'", result["match_reason"])
self.assertIn("tag 'network'", result["match_reason"])
self.assertIn("[timeout]", result["preview_highlighted"].lower())
def test_json_result_includes_score_breakdown_when_verbose(self):
doc = mock.Mock(
title="Network timeout",
domain="devops",
status="published",
reference="",
scope="",
source="manual",
tags=["network"],
filepath=Path(search_knowledge.__file__).parent / "lessons" / "example.md",
content="Network timeout retry.",
score_baseline=0.1,
is_draft=False,
mtime=0.0,
)
result = search_knowledge._json_result(0.5, doc, query="timeout", verbose=True)
self.assertIn("score_breakdown", result)
self.assertIn("bm25", result["score_breakdown"])
self.assertIn("metadata", result["score_breakdown"])
def test_json_error_is_parseable(self):
stdout = io.StringIO()
with mock.patch.object(search_knowledge.sys, "stdout", stdout):
search_knowledge._print_json_error("query failed")
self.assertEqual(json.loads(stdout.getvalue()), {"error": "query failed"})
class TestRemoteDocs(unittest.TestCase):
"""PRD ④: --remote mode loads lessons from the D1 service."""
def _mock_response(self, payload):
resp = mock.Mock()
resp.read.return_value = json.dumps(payload).encode("utf-8")
resp.__enter__ = mock.Mock(return_value=resp)
resp.__exit__ = mock.Mock(return_value=False)
return resp
def test_load_remote_docs_builds_cached_docs(self):
payload = [
{"id": "pip-mirror", "title": "pip timeout mirror", "domain": "python",
"status": "published", "tags": ["pip"], "path": "lessons/core/pip-mirror.md",
"description": "use a mirror", "problem": "pip times out"},
{"id": "dco", "title": "DCO signoff", "domain": "git",
"status": "published", "tags": ["dco"], "path": "lessons/core/dco.md",
"description": "signoff required", "problem": ""},
]
with mock.patch("urllib.request.urlopen", return_value=self._mock_response(payload)):
docs = search_knowledge._load_remote_docs()
self.assertEqual(len(docs), 2)
self.assertEqual(docs[0].filename, "pip-mirror")
self.assertEqual(docs[0].title, "pip timeout mirror")
self.assertEqual(docs[0].domain, "python")
self.assertEqual(docs[0].tags, ["pip"])
self.assertTrue(docs[0].content) # description used as content
# filepath absolute under repo root → _doc_cache_id works
self.assertTrue(docs[0].filepath.is_absolute())
def test_load_remote_docs_falls_back_to_problem_field(self):
payload = [
{"id": "x", "title": "X", "domain": "devops", "status": "published",
"tags": [], "path": "lessons/contrib/x.md", "problem": "the failure"},
]
with mock.patch("urllib.request.urlopen", return_value=self._mock_response(payload)):
docs = search_knowledge._load_remote_docs()
self.assertIn("the failure", docs[0].content)
def test_load_remote_docs_rejects_non_list(self):
with mock.patch("urllib.request.urlopen", return_value=self._mock_response({"error": "x"})):
with self.assertRaises(RuntimeError):
search_knowledge._load_remote_docs()
if __name__ == "__main__":
unittest.main()