# -*- coding: utf-8 -*- """Cell / Grid Presentation 契约:schema + 文档 + 示例。""" from __future__ import annotations import json import os import unittest from util.runtime_paths import get_skill_root def _skill_path(*parts: str) -> str: return os.path.join(get_skill_root(), *parts) def _load_json(*parts: str) -> dict: with open(_skill_path(*parts), encoding="utf-8") as f: return json.load(f) def _load_cell_schema() -> dict: return _load_json("assets", "schemas", "skill-cell-presentation.schema.json") def _load_cell_example() -> dict: return _load_json("assets", "examples", "skill-cell-presentation.example.json") def _load_grid_schema() -> dict: return _load_json("assets", "schemas", "skill-grid-presentation.schema.json") def _load_grid_example() -> dict: return _load_json("assets", "examples", "skill-grid-presentation.example.json") class TestCellPresentationContract(unittest.TestCase): def test_schema_file_exists_and_parses(self) -> None: schema = _load_cell_schema() self.assertEqual(schema.get("title"), "SkillCellPresentationDocument") self.assertIs(schema.get("additionalProperties"), False) self.assertEqual(schema["properties"]["schemaVersion"].get("const"), 1) tones = set(schema["$defs"]["tone"].get("enum") or []) self.assertEqual(tones, {"danger", "warning", "info", "success", "muted"}) def test_example_validates_against_schema(self) -> None: try: import jsonschema except ImportError: self.skipTest("jsonschema not installed") jsonschema.validate(instance=_load_cell_example(), schema=_load_cell_schema()) def test_actions_schema_defines_cell_presentation_enable_block(self) -> None: actions_schema = _load_json("assets", "schemas", "skill-actions.schema.json") self.assertIn("cellPresentation", actions_schema["properties"]) self.assertIn("cellPresentationDeclaration", actions_schema["$defs"]) def test_docs_and_example_exist(self) -> None: self.assertTrue(os.path.isfile(_skill_path("references", "CELL_PRESENTATION.md"))) self.assertTrue( os.path.isfile( _skill_path("assets", "schemas", "skill-cell-presentation.schema.json") ) ) self.assertTrue( os.path.isfile( _skill_path("assets", "examples", "skill-cell-presentation.example.json") ) ) self.assertTrue( os.path.isfile( _skill_path("assets", "schemas", "skill-grid-presentation.schema.json") ) ) self.assertTrue( os.path.isfile( _skill_path("assets", "examples", "skill-grid-presentation.example.json") ) ) def test_cell_presentation_md_covers_contract(self) -> None: path = _skill_path("references", "CELL_PRESENTATION.md") with open(path, encoding="utf-8") as f: text = f.read() for marker in ( "tone", "danger", "warning", "alert", "_jiangchang_cell_presentation", "_jiangchang_grid_presentation", "cellPresentation", "派生", "任意 CSS", "用途不限", "schemaVersion", "整行", "整列", "all", "格子 > 区域 > 行 > 列", "详情", ): self.assertIn(marker, text, msg=f"CELL_PRESENTATION.md missing {marker!r}") def test_grid_schema_file_exists_and_parses(self) -> None: schema = _load_grid_schema() self.assertEqual(schema.get("title"), "SkillGridPresentationDocument") self.assertIs(schema.get("additionalProperties"), False) self.assertEqual(schema["properties"]["schemaVersion"].get("const"), 1) tones = set(schema["$defs"]["tone"].get("enum") or []) self.assertEqual(tones, {"danger", "warning", "info", "success", "muted"}) self.assertIn("not", schema["$defs"]["ruleItem"]) def test_grid_example_validates_against_schema(self) -> None: try: import jsonschema except ImportError: self.skipTest("jsonschema not installed") jsonschema.validate(instance=_load_grid_example(), schema=_load_grid_schema()) def test_grid_schema_rejects_all_by_all(self) -> None: try: import jsonschema except ImportError: self.skipTest("jsonschema not installed") payload = { "schemaVersion": 1, "skill": "your-skill-slug", "table": "business_records", "rowKey": "id", "rules": [ { "ruleKey": "paint-everything", "rows": "all", "columns": "all", "tone": "danger", } ], } with self.assertRaises(jsonschema.ValidationError): jsonschema.validate(instance=payload, schema=_load_grid_schema()) def test_internal_metadata_hides_presentation_tables(self) -> None: from db.display_metadata import INTERNAL_METADATA_TABLES, METADATA_TABLES self.assertIn("_jiangchang_cell_presentation", INTERNAL_METADATA_TABLES) self.assertIn("_jiangchang_grid_presentation", INTERNAL_METADATA_TABLES) self.assertTrue(INTERNAL_METADATA_TABLES <= METADATA_TABLES) def test_template_actions_do_not_enable_presentation_by_default(self) -> None: manifest = _load_json("assets", "actions.json") self.assertNotEqual(manifest.get("cellPresentation", {}).get("enabled"), True) def test_checklist_covers_grid_presentation(self) -> None: path = _skill_path("development", "CHECKLIST.md") with open(path, encoding="utf-8") as f: text = f.read() self.assertIn("A6-15", text) self.assertIn("cellPresentation", text) self.assertIn("CELL_PRESENTATION.md", text) if __name__ == "__main__": unittest.main()