#!/usr/bin/env python3 """db execparams 参数装载逻辑离线自测(不连库)。 跑法(仓库根目录):.venv/bin/python tests/skills/访问数据库/test_db_params.py """ import io import json import sys from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[3] SCRIPTS_DIR = PROJECT_ROOT / "muse" / "authority" / "evidence" / "skills" / "访问数据库" / "scripts" sys.path.insert(0, str(SCRIPTS_DIR)) import click # noqa: E402 import db # noqa: E402 def expect_exc(fn, msg): try: fn() except click.ClickException: return raise AssertionError(f"应抛 ClickException:{msg}") def main(): # --param 按序 assert db._read_params(False, ("a", "b")) == ["a", "b"] assert db._read_params(False, ()) == [] # --stdin 合法 JSON 数组(含 null/数字) assert db._read_params(True, (), stream=io.StringIO('["x", 1, null]')) == ["x", 1, None] # 大对象(含中文引号/换行)经 stdin 不破坏 big = '中文"引号"\n换行\\反斜杠' * 5000 assert db._read_params(True, (), stream=io.StringIO(json.dumps([big])))[0] == big # --stdin 与 --param 互斥 expect_exc(lambda: db._read_params(True, ("a",)), "--stdin 与 --param 互斥") # 非法 JSON expect_exc(lambda: db._read_params(True, (), stream=io.StringIO("not json")), "非法 JSON") # 非数组 expect_exc(lambda: db._read_params(True, (), stream=io.StringIO('{"a":1}')), "非数组") # exec / execparams:拒绝 DDL 与裸 DELETE expect_exc(lambda: db._guard_exec("CREATE TABLE t (id int)"), "exec 拒 DDL") expect_exc(lambda: db._guard_exec("DELETE FROM t"), "exec 拒裸 DELETE") expect_exc(lambda: db._guard_execparams("ALTER TABLE t ADD COLUMN x int"), "execparams 拒 DDL") expect_exc(lambda: db._guard_execparams("DELETE FROM t"), "execparams 拒裸 DELETE") db._guard_exec("UPDATE t SET x=1 WHERE id=1") db._guard_execparams("DELETE FROM t WHERE id=%s") print("PASS:db execparams 参数装载与写守卫全部通过") if __name__ == "__main__": main()