"""SQLCODE 归一化注入测试(T3)。 gixsql+SQLite 对主键冲突返回 SQLCODE=-1555(SQLITE_CONSTRAINT_PRIMARYKEY), 而 DB2 语义是 -803。在预处理后的 COBOL 中注入通用归一化代码,把 SQLITE 约束错误码映射为 -803,使 `IF SQLCODE = -803` 分支可达。 """ import sys, os from pathlib import Path sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from runners.gixsql_runner import GixsqlCobolRunner def _make_runner(): return GixsqlCobolRunner(gixpp_path="gixpp", lib_path="lib") def _pp_text_with_if(): return ( " CALL \"GIXSQLEndSQL\"\n" " END-CALL.\n" " IF SQLCODE = 0\n" " ADD 1 TO CUN-DB-INS\n" " END-IF.\n" " IF SQLCODE = -803\n" " PERFORM 2000MAJSOR-UPD\n" " END-IF.\n" ) def test_normalize_injects_mapping_after_endsql(tmp_path): """GIXSQLEndSQL 后注入 SQLITE 约束错误 → -803 映射""" r = _make_runner() pp = tmp_path / "test_pp.cbl" pp.write_text(_pp_text_with_if(), encoding="utf-8") r._patch_sqlcode_normalize(pp) out = pp.read_text(encoding="utf-8") assert "SQLCODE = -1555" in out assert "MOVE -803 TO SQLCODE" in out assert "SQLCODE = -2067" in out def test_normalize_mapping_before_if_sqlcode(): """映射代码注入在 IF SQLCODE = -803 判断之前""" r = _make_runner() pp = Path(r'C:\Users\marye\AppData\Local\Temp\opencode\t3_pp.cbl') pp.parent.mkdir(parents=True, exist_ok=True) pp.write_text(_pp_text_with_if(), encoding="utf-8") r._patch_sqlcode_normalize(pp) out = pp.read_text(encoding="utf-8") # 映射代码必须在第一个 IF SQLCODE 之前 mapping_idx = out.find("MOVE -803 TO SQLCODE") if_idx = out.find("IF SQLCODE = -803") assert mapping_idx != -1 assert if_idx != -1 assert mapping_idx < if_idx def test_normalize_does_not_change_ok_path(): """归一化不影响 SQLCODE=0 成功路径""" r = _make_runner() pp = Path(r'C:\Users\marye\AppData\Local\Temp\opencode\t3b_pp.cbl') pp.write_text(_pp_text_with_if(), encoding="utf-8") r._patch_sqlcode_normalize(pp) out = pp.read_text(encoding="utf-8") assert "IF SQLCODE = 0" in out