107 lines
3.4 KiB
Python
107 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
from data.majors_catalog.loader import MajorsCatalogLoader
|
|
|
|
|
|
def _write_catalog(root: Path) -> None:
|
|
national = root / "national"
|
|
national.mkdir(parents=True, exist_ok=True)
|
|
changes = root / "changes"
|
|
changes.mkdir(parents=True, exist_ok=True)
|
|
payload = {
|
|
"year": 2024,
|
|
"version": "2024.1",
|
|
"coverage_mode": "mvp_subset",
|
|
"source": "教育部普通高等学校本科专业目录(人工摘录校对)",
|
|
"source_url": "https://www.moe.gov.cn/",
|
|
"last_verified_at": "2026-06-17",
|
|
"majors": [
|
|
{
|
|
"code": "020101",
|
|
"name": "经济学",
|
|
"discipline": "经济学",
|
|
"category": "经济学类",
|
|
"degree": "经济学学士",
|
|
"is_directional": False,
|
|
"status": "active",
|
|
"year_added": 1998,
|
|
"year_removed": None,
|
|
"notes": None,
|
|
},
|
|
{
|
|
"code": "080901",
|
|
"name": "计算机科学与技术",
|
|
"discipline": "工学",
|
|
"category": "计算机类",
|
|
"degree": "工学学士",
|
|
"is_directional": False,
|
|
"status": "active",
|
|
"year_added": 1998,
|
|
"year_removed": None,
|
|
"notes": None,
|
|
},
|
|
{
|
|
"code": "120201K",
|
|
"name": "工商管理",
|
|
"discipline": "管理学",
|
|
"category": "工商管理类",
|
|
"degree": "管理学学士",
|
|
"is_directional": True,
|
|
"status": "renamed",
|
|
"year_added": 1998,
|
|
"year_removed": 2024,
|
|
"notes": "示例改名专业",
|
|
},
|
|
],
|
|
}
|
|
(national / "2024.json").write_text(
|
|
json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8"
|
|
)
|
|
(national / "latest.json").write_text(
|
|
json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8"
|
|
)
|
|
(changes / "2024-2026.md").write_text(
|
|
"# changes\n\n- sample\n", encoding="utf-8"
|
|
)
|
|
|
|
|
|
def test_majors_catalog_loader_reads_latest_and_supports_lookup(tmp_path: Path) -> None:
|
|
_write_catalog(tmp_path)
|
|
|
|
loader = MajorsCatalogLoader.from_catalog_root(tmp_path)
|
|
by_name = loader.lookup("计算机科学与技术")
|
|
by_code = loader.lookup("020101")
|
|
status = loader.build_status()
|
|
|
|
assert by_name is not None
|
|
assert by_name.code == "080901"
|
|
assert by_name.discipline == "工学"
|
|
assert by_code is not None
|
|
assert by_code.name == "经济学"
|
|
assert status.year == 2024
|
|
assert status.version == "2024.1"
|
|
assert status.major_count == 3
|
|
assert status.change_count == 1
|
|
assert status.risky_major_count == 1
|
|
assert status.coverage_mode == "mvp_subset"
|
|
assert "changes/2024-2026.md" in status.version_strategy
|
|
assert by_name.risk_tags == []
|
|
|
|
|
|
def test_majors_catalog_loader_lists_changes_for_non_active_majors(
|
|
tmp_path: Path,
|
|
) -> None:
|
|
_write_catalog(tmp_path)
|
|
|
|
loader = MajorsCatalogLoader.from_catalog_root(tmp_path)
|
|
changed = loader.list_changes()
|
|
|
|
assert len(changed) == 1
|
|
assert changed[0].code == "120201K"
|
|
assert changed[0].status == "renamed"
|
|
assert changed[0].risk_tags == ["non_active", "removed_in_last_2y"]
|