docs: settle host import leading-star and lookup label contract
All checks were successful
技能自动化发布 / release (push) Successful in 19s

This commit is contained in:
2026-10-23 17:31:11 +08:00
parent de127d7e71
commit 8a8fa3cb0c
12 changed files with 331 additions and 7 deletions

View File

@@ -241,6 +241,8 @@ LOGGING_006_EXEMPT_BASENAMES = frozenset(
"task_run_support.py",
"entitlement_service.py",
"sibling_bridge.py",
# Pure Excel/CSV header helpers for replaces:import; no domain side effects.
"table_file_import.py",
}
)

View File

@@ -382,6 +382,10 @@ class TestDocsStandards(unittest.TestCase):
"drop_deprecated_user_table",
"孤儿物理表",
"_jiangchang_grid_presentation",
"导入模板表头必填标记",
"*显示名",
"table_file_import.py",
"导入模板 lookup 单元格",
):
self.assertIn(marker, text, msg=f"SCHEMA.md missing {marker!r}")
@@ -432,8 +436,21 @@ class TestDocsStandards(unittest.TestCase):
"visibleWhen",
"grid_help",
"列筛选",
"导入表头与 lookup 单元格",
"table_file_import.py",
"*长尾词",
"{value} · {label}",
):
self.assertIn(marker, text, msg=f"ACTIONS.md missing {marker!r}")
checklist = self._read("development/CHECKLIST.md")
self.assertIn("A4-14", checklist)
self.assertIn("table_file_import.py", checklist)
self.assertTrue(
os.path.isfile(
os.path.join(get_skill_root(), "scripts/service/table_file_import.py")
),
msg="scripts/service/table_file_import.py missing",
)
self.assertTrue(
os.path.isfile(
os.path.join(get_skill_root(), "assets/examples/lookup-skill-cli.action.example.json")

View File

@@ -0,0 +1,67 @@
"""宿主导入模板表头 / lookup 展示值契约(replaces:import)。"""
from __future__ import annotations
import csv
import tempfile
import unittest
from pathlib import Path
class TableFileImportTests(unittest.TestCase):
def test_normalize_header_host_leading_and_legacy_trailing_star(self) -> None:
from service.table_file_import import map_headers, normalize_header
self.assertEqual(normalize_header("*长尾词"), "长尾词")
self.assertEqual(normalize_header("* 长尾词"), "长尾词")
self.assertEqual(normalize_header("长尾词*"), "长尾词")
self.assertEqual(normalize_header("*关键词*"), "关键词")
self.assertEqual(normalize_header("*关键词(必填)"), "关键词")
self.assertEqual(normalize_header("名称"), "名称")
aliases = {
"phrase": ("长尾词", "phrase", "问题"),
"keyword_id": ("所属关键词", "keyword_id", "关键词编号"),
}
mapping = map_headers(["*长尾词", "所属关键词"], aliases)
self.assertEqual(mapping.get("phrase"), 0)
self.assertEqual(mapping.get("keyword_id"), 1)
mapping_legacy = map_headers(["长尾词*", "所属关键词"], aliases)
self.assertEqual(mapping_legacy.get("phrase"), 0)
def test_optional_int_accepts_lookup_display_label(self) -> None:
from service.table_file_import import optional_int
self.assertEqual(optional_int("157"), 157)
self.assertEqual(optional_int("157 · 波兰小包专线"), 157)
self.assertEqual(optional_int("157·波兰小包专线"), 157)
self.assertEqual(optional_int("2 · 通用私信-留资"), 2)
self.assertIsNone(optional_int(""))
with self.assertRaises(ValueError):
optional_int("波兰小包专线")
def test_load_table_rows_skips_example_and_maps_leading_star(self) -> None:
from service.table_file_import import load_table_rows
aliases = {
"phrase": ("长尾词",),
"keyword_id": ("所属关键词",),
}
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "rows.csv"
with path.open("w", encoding="utf-8-sig", newline="") as fh:
writer = csv.writer(fh)
writer.writerow(["*长尾词", "所属关键词"])
writer.writerow(["【示例】示例长尾词", "152 · 示例"])
writer.writerow(["波兰小包专线怎么选", "157 · 波兰小包专线"])
rows = load_table_rows(str(path), aliases=aliases)
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0]["phrase"], "波兰小包专线怎么选")
self.assertEqual(rows[0]["keyword_id"], "157 · 波兰小包专线")
self.assertEqual(rows[0]["_row"], "3")
if __name__ == "__main__":
unittest.main()