import importlib.util import sys import tempfile import unittest import zipfile from pathlib import Path SCRIPT = ( Path(__file__).parents[2] / "plugins" / "doc" / "skills" / "docx-to-md" / "scripts" / "convert.py" ) SPEC = importlib.util.spec_from_file_location("docx_to_md_convert", SCRIPT) MODULE = importlib.util.module_from_spec(SPEC) assert SPEC.loader is not None sys.modules[SPEC.name] = MODULE SPEC.loader.exec_module(MODULE) class DocxToMarkdownTest(unittest.TestCase): """验证转换器的核心内容、覆盖保护和输入边界。""" def make_docx(self, path: Path) -> None: """创建只包含公开 OOXML 结构的最小测试文档。""" document = """ 测试标题 加粗正文 示例链接 列表项目 名称值 A1 """ styles = """ """ numbering = """ """ relationships = """ """ with zipfile.ZipFile(path, "w") as archive: archive.writestr("word/document.xml", document) archive.writestr("word/styles.xml", styles) archive.writestr("word/numbering.xml", numbering) archive.writestr("word/_rels/document.xml.rels", relationships) archive.writestr("word/media/test.png", b"\x89PNG\r\n\x1a\n") archive.writestr("word/comments.xml", "") def test_convert_common_content_and_report_warning(self) -> None: """常见结构应转换,无法处理的批注应明确告警。""" with tempfile.TemporaryDirectory() as temp: root = Path(temp) source = root / "sample.docx" output = root / "result" self.make_docx(source) result = MODULE.DocxConverter(source, output).convert() markdown = result.output_file.read_text(encoding="utf-8") self.assertIn("# 测试标题", markdown) self.assertIn("**加粗正文**", markdown) self.assertIn("[示例链接](https://example.com)", markdown) self.assertIn("- 列表项目", markdown) self.assertIn("| 名称 | 值 |", markdown) self.assertIn("![图片](images/image-", markdown) self.assertEqual(result.images, 1) self.assertTrue(any("批注" in warning for warning in result.warnings)) def test_existing_output_requires_force(self) -> None: """默认不得写入已有输出目录,显式覆盖后才可继续。""" with tempfile.TemporaryDirectory() as temp: root = Path(temp) source = root / "sample.docx" output = root / "result" self.make_docx(source) output.mkdir() with self.assertRaises(FileExistsError): MODULE.DocxConverter(source, output).convert() result = MODULE.DocxConverter(source, output, force=True).convert() self.assertTrue(result.output_file.exists()) def test_cli_rejects_non_docx(self) -> None: """命令行入口应拒绝扩展名不正确的文件。""" with tempfile.TemporaryDirectory() as temp: source = Path(temp) / "sample.txt" source.write_text("not docx", encoding="utf-8") self.assertEqual(MODULE.main([str(source)]), 2) if __name__ == "__main__": unittest.main()