# -*- coding: utf-8 -*- """树脂模板打包与版本发布测试(issue #85)。 覆盖: 1. validate_version:semver 合法、assets 清单文件/目录存在; 2. 非法 semver → 问题列表; 3. package_template:按清单打包 zip(含 version.yaml + 资产文件/目录递归); 4. 打包前校验失败(资产缺失)→ ValueError; 5. render_release_notes:发布说明含版本/行业/基线/资产清单。 """ import os import sys import tempfile import unittest import zipfile _RESIN_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, _RESIN_DIR) from template_packaging import ( # noqa: E402 TEMPLATE_ROOT, VERSION_PATH, package_template, render_release_notes, validate_version, ) class TestValidateVersion(unittest.TestCase): """版本清单校验。""" def test_valid_template(self): self.assertEqual(validate_version(), []) def test_invalid_semver(self): tmp = tempfile.NamedTemporaryFile( "w", suffix=".yaml", delete=False, encoding="utf-8") tmp.write("version: abc\nassets: []\n") tmp.close() try: problems = validate_version(tmp.name) finally: os.unlink(tmp.name) self.assertTrue(any("semver" in p for p in problems)) def test_missing_asset_reported(self): tmp = tempfile.NamedTemporaryFile( "w", suffix=".yaml", delete=False, encoding="utf-8") tmp.write("version: 1.0.0\nassets: [no/such/file.yaml]\n") tmp.close() try: problems = validate_version(tmp.name) finally: os.unlink(tmp.name) self.assertTrue(any("缺失" in p for p in problems)) class TestPackage(unittest.TestCase): """打包。""" def test_package_zip_contents(self): with tempfile.TemporaryDirectory() as out: zip_path = package_template(output_dir=out) self.assertTrue(os.path.isfile(zip_path)) self.assertTrue(zip_path.endswith("resin-0.1.0.zip")) with zipfile.ZipFile(zip_path) as zf: names = zf.namelist() # 必含清单与核心资产 self.assertIn("version.yaml", names) self.assertIn("point-dict/point_dict.resin.csv", names) self.assertIn("rag-kb/kb.resin.template.yaml", names) # 目录递归(documents/ 8 篇) docs = [n for n in names if n.startswith("rag-kb/documents/")] self.assertEqual(len(docs), 8) def test_package_fails_on_missing_asset(self): tmp = tempfile.NamedTemporaryFile( "w", suffix=".yaml", delete=False, encoding="utf-8") tmp.write("version: 1.0.0\nassets: [no/such/file.yaml]\n") tmp.close() try: with self.assertRaises(ValueError): package_template(path=tmp.name) finally: os.unlink(tmp.name) class TestReleaseNotes(unittest.TestCase): """发布说明。""" def test_release_notes_content(self): notes = render_release_notes() self.assertIn("# iAOP-Template-Resin v0.1.0", notes) self.assertIn("吸附树脂", notes) self.assertIn("化工新材料AI平台", notes) self.assertIn("point-dict/point_dict.resin.csv", notes) self.assertIn("## 资产清单", notes) if __name__ == "__main__": unittest.main()