♻️ refactor(tsl-api-reference): split lookup workflows and maintenance tooling

This commit is contained in:
csh
2026-08-20 17:47:48 +08:00
parent 9b95bf2682
commit cd0405d64b
18 changed files with 707 additions and 374 deletions
+92 -5
View File
@@ -16,6 +16,7 @@ SCRIPT = (
/ "lookup.py"
)
SKILL_MD = SCRIPT.parents[1] / "SKILL.md"
API_WORKFLOW = SCRIPT.parents[1] / "workflows" / "api-lookup.md"
def load_script():
@@ -573,7 +574,7 @@ class LookupTest(unittest.TestCase):
self.assertEqual(2, result.returncode)
self.assertIn("--limit must be >= 1", result.stderr)
def test_help_lists_all_bundled_scopes(self):
def test_help_derives_scopes_from_selected_index(self):
result = subprocess.run(
[sys.executable, str(SCRIPT), "--help"],
capture_output=True,
@@ -582,7 +583,9 @@ class LookupTest(unittest.TestCase):
)
self.assertEqual(0, result.returncode, result.stderr)
self.assertIn("builtin、dotnet 与 module", result.stdout)
self.assertIn("可用值从当前 function_index.tsv 读取", result.stdout)
self.assertNotIn("deprecated", result.stdout)
self.assertNotIn("--scope third", result.stdout)
def test_exact_search_uses_anchor_for_duplicate_signatures(self):
module = load_script()
@@ -775,14 +778,98 @@ class LookupTest(unittest.TestCase):
self.assertIn("DemoUnit.Document.Save", visibility.stdout)
def test_skill_documents_qualified_queries_and_legacy_index_compatibility(self):
text = SKILL_MD.read_text(encoding="utf-8")
skill_text = SKILL_MD.read_text(encoding="utf-8")
text = API_WORKFLOW.read_text(encoding="utf-8")
self.assertIn("workflows/api-lookup.md", skill_text)
self.assertIn("完全限定名称", text)
self.assertIn("--scope module", text)
self.assertIn("qualified_name", text)
self.assertIn("owner、kind、binding、visibility", text)
self.assertIn("owner、kind、", text)
self.assertIn("binding 和 visibility", text)
self.assertIn("class function", text)
self.assertIn("8 列", text)
self.assertIn("8 列索引", text)
self.assertIn("13 列索引", text)
def test_skill_routes_workflows_and_keeps_stop_resident(self):
skill_text = SKILL_MD.read_text(encoding="utf-8")
skill_root = SKILL_MD.parent
instruction_paths = sorted((skill_root / "workflows").glob("*.md"))
for path in instruction_paths:
self.assertIn(path.relative_to(skill_root).as_posix(), skill_text)
self.assertIn("🔴 CHECKPOINT · 🛑 STOP", skill_text)
self.assertIn("rc=1 不进入上述“API 缺失”分支", skill_text)
self.assertIn("原样名称或 `qualified_name`", skill_text)
self.assertIn("`profile_status=not_profiled`", skill_text)
def test_skill_instruction_package_has_no_reverse_dependencies(self):
skill_root = SKILL_MD.parent
package_text = "\n".join(
path.read_text(encoding="utf-8")
for path in [SKILL_MD, *sorted((skill_root / "workflows").glob("*.md"))]
)
for forbidden in (
"tsl-syntax-reference",
"references/maintenance.md",
"tools/tsl-codegen",
"scripts/build_dictionary.py",
"AGENTS.md",
"CONTEXT.md",
"docs/adr/",
):
self.assertNotIn(forbidden, package_text)
def test_repository_maintenance_doc_owns_api_data_maintenance(self):
readme = (
SKILL_MD.parents[2] / "tools" / "tsl-codegen" / "MAINTENANCE.md"
).read_text(encoding="utf-8")
for required in (
"TSL API 数据维护",
"class_lookup.py --check",
"tools/tsl-codegen/scripts/build_index.py",
"--skill-dir skills/tsl-api-reference",
"tools/tsl-codegen/scripts/build_dictionary.py",
"beautifulsoup4",
"profile_status=not_profiled",
):
self.assertIn(required, readme)
user_readme = (
SKILL_MD.parents[2] / "tools" / "tsl-codegen" / "README.md"
).read_text(encoding="utf-8")
for maintainer_only in (
"class_lookup.py --check",
"beautifulsoup4",
"--source-root <exported-html-dir>",
):
self.assertNotIn(maintainer_only, user_readme)
self.assertIn("profile_status=not_profiled", user_readme)
def test_public_cli_help_owns_status_and_exit_contracts(self):
skill_root = SKILL_MD.parent
expected = {
"lookup.py": ("退出码:", "--name 无匹配", "page#anchor"),
"class_lookup.py": ("输出状态:", "contract_status", "退出码:"),
"dictionary_lookup.py": ("status: ambiguous", "status: no_match", "退出码:"),
}
for script_name, fragments in expected.items():
with self.subTest(script=script_name):
result = subprocess.run(
[
sys.executable,
str(skill_root / "scripts" / script_name),
"--help",
],
capture_output=True,
text=True,
check=False,
)
self.assertEqual(0, result.returncode, result.stderr)
for fragment in fragments:
self.assertIn(fragment, result.stdout)
def test_keyword_search_includes_tags_and_summary(self):
module = load_script()