81 lines
3.2 KiB
Python
81 lines
3.2 KiB
Python
from __future__ import annotations
|
||
|
||
import sys
|
||
import unittest
|
||
from pathlib import Path
|
||
|
||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||
|
||
from core.pysyntax import precheck_python # noqa: E402
|
||
|
||
|
||
class TestPrecheckPython(unittest.TestCase):
|
||
# ── 放行:合法码不误伤 ──
|
||
def test_clean_code_passes(self):
|
||
self.assertIsNone(precheck_python("import os\nx = 1 + 2\nprint(x)\n"))
|
||
|
||
def test_valid_chinese_in_string_passes(self):
|
||
"""中文正文在正确引号里 = 合法,绝不误报。"""
|
||
self.assertIsNone(precheck_python('x = "中文正文,含全角标点。没问题!"\n'))
|
||
|
||
def test_chinese_quotes_in_string_passes(self):
|
||
"""中文引号 “” 只是普通字符,不是分隔符,合法。"""
|
||
self.assertIsNone(precheck_python('x = "他说“你好”,然后走了。"\n'))
|
||
|
||
def test_empty_and_none_pass(self):
|
||
self.assertIsNone(precheck_python(None))
|
||
self.assertIsNone(precheck_python(""))
|
||
self.assertIsNone(precheck_python(" \n "))
|
||
self.assertIsNone(precheck_python(123)) # 非字符串
|
||
|
||
# ── A 类:中文串里 ASCII 引号提前闭合(样本 #1/#8/#16) ──
|
||
def test_ascii_quote_in_chinese_string(self):
|
||
code = 'T("(5)产学研合作:形成"产学研用"一体化链条。")\n'
|
||
hint = precheck_python(code)
|
||
self.assertIsNotNone(hint)
|
||
self.assertTrue(hint.startswith("[Error]"))
|
||
self.assertIn("第 1 行", hint)
|
||
self.assertIn("引号", hint) # 定向引号诊断
|
||
self.assertIn("write", hint) # 根治提示(正文进文件)
|
||
|
||
def test_unterminated_string_with_cjk(self):
|
||
code = "set_cell(c, '国际一流双碳大数据平台], '负责人')\n"
|
||
hint = precheck_python(code)
|
||
self.assertIsNotNone(hint)
|
||
self.assertIn("引号", hint)
|
||
|
||
# ── B 类:全角标点漏进代码位(样本 #7/#9) ──
|
||
def test_fullwidth_punct_in_code(self):
|
||
code = 'add_h("2025年12月", 14, center=True、name)\n'
|
||
hint = precheck_python(code)
|
||
self.assertIsNotNone(hint)
|
||
self.assertIn("半角", hint) # 全角→半角定向诊断
|
||
|
||
def test_fullwidth_paren_in_code(self):
|
||
code = 'set_cell(tbl, "响应函", "第五章(附件)中的要求。", "通过")\n(\n'
|
||
hint = precheck_python(code)
|
||
self.assertIsNotNone(hint)
|
||
|
||
# ── C 类:结构崩坏 ──
|
||
def test_unmatched_bracket(self):
|
||
hint = precheck_python("for i in enumerate(doc.paragraphs[:5()[:80]}'\")\n")
|
||
self.assertIsNotNone(hint)
|
||
self.assertTrue(hint.startswith("[Error]"))
|
||
|
||
# ── 非中文语法错:仍拦,但不追加中文根治提示 ──
|
||
def test_non_cjk_syntax_error(self):
|
||
hint = precheck_python("def f(:\n pass\n")
|
||
self.assertIsNotNone(hint)
|
||
self.assertTrue(hint.startswith("[Error]"))
|
||
self.assertNotIn("write 写进", hint) # 无中文正文,不追加"别拼中文进 py"
|
||
|
||
def test_lineno_reported(self):
|
||
code = "a = 1\nb = 2\nc = @\n"
|
||
hint = precheck_python(code)
|
||
self.assertIsNotNone(hint)
|
||
self.assertIn("第 3 行", hint)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|