forked from Ikalus1988/MisakaNet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_domain_extraction.py
More file actions
147 lines (110 loc) · 5.39 KB
/
Copy pathtest_domain_extraction.py
File metadata and controls
147 lines (110 loc) · 5.39 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
147
"""Tests for domain extraction from lesson file paths and frontmatter.
Covers acceptance criteria from issue #297:
- lessons/core/xxx.md → domain from frontmatter
- lessons/contrib/xxx.md → domain from frontmatter
- missing domain field → fallback to "uncategorized"
- domain normalization ("DevOps" → "devops")
"""
import json
import tempfile
import unittest
from pathlib import Path
import sys
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))
from misakanet.search.engine import _parse_json_frontmatter, _parse_yaml_frontmatter
def extract_domain(content: str) -> str:
"""Extract domain from lesson content (mirrors engine.py logic)."""
meta = _parse_json_frontmatter(content) or _parse_yaml_frontmatter(content) or {}
domain = meta.get("domain", "")
if isinstance(domain, list):
domain = domain[0] if domain else ""
return domain
class TestDomainFromFrontmatter(unittest.TestCase):
"""Domain is correctly extracted from frontmatter."""
def test_json_frontmatter_with_domain(self):
content = '---\n{"title": "Test", "domain": "devops", "status": "published"}\n---\n# Content\n'
self.assertEqual(extract_domain(content), "devops")
def test_yaml_frontmatter_with_domain(self):
content = '---\ntitle: Test\ndomain: networking\nstatus: published\n---\n# Content\n'
self.assertEqual(extract_domain(content), "networking")
def test_domain_from_list(self):
content = '---\n{"title": "Test", "domain": ["devops", "networking"]}\n---\n# Content\n'
self.assertEqual(extract_domain(content), "devops")
def test_domain_case_preserved(self):
content = '---\n{"title": "Test", "domain": "DevOps"}\n---\n# Content\n'
# Domain is preserved as-is in extraction (normalization happens elsewhere)
self.assertEqual(extract_domain(content), "DevOps")
class TestMissingDomain(unittest.TestCase):
"""Missing domain field → fallback to empty string."""
def test_no_domain_field(self):
content = '---\n{"title": "Test", "status": "published"}\n---\n# Content\n'
self.assertEqual(extract_domain(content), "")
def test_empty_domain_field(self):
content = '---\n{"title": "Test", "domain": ""}\n---\n# Content\n'
self.assertEqual(extract_domain(content), "")
def test_null_domain_field(self):
content = '---\n{"title": "Test", "domain": null}\n---\n# Content\n'
# JSON null → Python None → should be handled
result = extract_domain(content)
self.assertIn(result, ["", None])
class TestDomainNormalization(unittest.TestCase):
"""Domain normalization behavior."""
def test_uppercase_domain_preserved(self):
content = '---\n{"title": "Test", "domain": "DevOps"}\n---\n# Content\n'
# Extraction preserves case; normalization is done at search time
self.assertEqual(extract_domain(content), "DevOps")
def test_mixed_case_domain(self):
content = '---\n{"title": "Test", "domain": "AI-ML"}\n---\n# Content\n'
self.assertEqual(extract_domain(content), "AI-ML")
def test_domain_with_spaces(self):
content = '---\n{"title": "Test", "domain": "agent collaboration"}\n---\n# Content\n'
self.assertEqual(extract_domain(content), "agent collaboration")
class TestEdgeCases(unittest.TestCase):
"""Edge cases for domain extraction."""
def test_no_frontmatter(self):
content = '# Just a heading\n\nSome content.\n'
self.assertEqual(extract_domain(content), "")
def test_empty_file(self):
content = ''
self.assertEqual(extract_domain(content), "")
def test_malformed_json(self):
content = '---\n{invalid json\n---\n# Content\n'
# Should fall back to YAML parser
result = extract_domain(content)
self.assertIsNotNone(result)
def test_yaml_domain_with_quotes(self):
content = "---\ntitle: Test\ndomain: \"devops\"\n---\n# Content\n"
self.assertEqual(extract_domain(content), "devops")
class TestDomainInRealLessons(unittest.TestCase):
"""Test domain extraction from actual lesson files."""
def test_contrib_lesson_has_domain(self):
"""Verify contrib lessons have domain in frontmatter."""
lessons_dir = PROJECT_ROOT / "lessons" / "contrib"
if not lessons_dir.exists():
self.skipTest("lessons/contrib not found")
# Find a lesson with domain
for f in lessons_dir.glob("*.md"):
content = f.read_text(encoding="utf-8")
domain = extract_domain(content)
if domain:
# Found a lesson with domain
self.assertIsInstance(domain, str)
self.assertTrue(len(domain) > 0)
return
self.skipTest("No lessons with domain found")
def test_core_lesson_has_domain(self):
"""Verify core lessons have domain in frontmatter."""
lessons_dir = PROJECT_ROOT / "lessons" / "core"
if not lessons_dir.exists():
self.skipTest("lessons/core not found")
for f in lessons_dir.glob("*.md"):
content = f.read_text(encoding="utf-8")
domain = extract_domain(content)
if domain:
self.assertIsInstance(domain, str)
self.assertTrue(len(domain) > 0)
return
self.skipTest("No lessons with domain found")
if __name__ == "__main__":
unittest.main()