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("
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()