122 lines
4.5 KiB
Python
122 lines
4.5 KiB
Python
"""决策点行号定位测试(T4 修复)。
|
||
|
||
注入 SQLCODE 映射代码后,gixpp 输出的 pp.cbl 中 `IF SQLCODE = -803`
|
||
等语句行号发生偏移。`locate_decision_lines` 必须精确定位到
|
||
`IF SQLCODE = -803` 所在行,而非 `IF SQLCODE = -1555` 或映射块的 END-IF。
|
||
"""
|
||
|
||
import sys, os, re
|
||
sys.stdout.reconfigure(encoding='utf-8')
|
||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
|
||
from cobol_testgen.coverage import _build_search_patterns, _normalize, locate_decision_lines
|
||
|
||
|
||
class D:
|
||
kind = 'IF'
|
||
label = 'IF SQLCODE = -803'
|
||
condition = None
|
||
|
||
|
||
def test_if_pattern_does_not_duplicate_if_keyword():
|
||
"""IF 决策点模式不能是 'IF IF ...'(label 已含 IF)"""
|
||
dp = D()
|
||
pats = _build_search_patterns(dp)
|
||
assert pats, "patterns should not be empty"
|
||
for p in pats:
|
||
assert "IF\\b\\s+IF" not in p, f"duplicated IF keyword in pattern: {p}"
|
||
|
||
|
||
def test_if_pattern_matches_exact_condition_line():
|
||
"""模式应匹配 'IF SQLCODE = -803' 行,而不匹配 -1555/-19"""
|
||
dp = D()
|
||
pats = _build_search_patterns(dp)
|
||
assert pats[0] is not None
|
||
assert re.search(pats[0], "IF SQLCODE = -803") is not None
|
||
assert re.search(pats[0], "IF SQLCODE = -1555") is None
|
||
assert re.search(pats[0], "IF SQLCODE = -19") is None
|
||
assert re.search(pats[0], "IF SQLCODE = -2067") is None
|
||
|
||
|
||
def test_locate_finds_shifted_line_in_pp_source():
|
||
"""pp.cbl 中注入映射后,决策点定位到正确的 -803 行"""
|
||
pp = (
|
||
" CALL \"GIXSQLEndSQL\"\n"
|
||
" END-CALL.\n"
|
||
" IF SQLCODE = -1555\n"
|
||
" MOVE -803 TO SQLCODE\n"
|
||
" END-IF\n"
|
||
" IF SQLCODE = -2067\n"
|
||
" MOVE -803 TO SQLCODE\n"
|
||
" END-IF\n"
|
||
" IF SQLCODE = -19\n"
|
||
" MOVE -803 TO SQLCODE\n"
|
||
" END-IF\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"
|
||
)
|
||
dp = D()
|
||
dp.source_line = 0
|
||
locate_decision_lines([dp], pp)
|
||
assert dp.source_line == 15, f"expected line 15 (IF SQLCODE = -803), got {dp.source_line}"
|
||
|
||
|
||
class MultiLineD:
|
||
kind = 'IF'
|
||
label = 'MERGE-REC-TYPE = CNS-PAY-TYPE-SALARY'
|
||
condition = None
|
||
|
||
|
||
def test_locate_multiline_if_condition():
|
||
"""条件被换行拆分的 IF 应定位到 'IF <首字段>' 起始行。
|
||
|
||
MERGE 输出过程的 IF MERGE-REC-TYPE / = CNS-PAY-TYPE-SALARY 分两行,
|
||
单行模式无法匹配;应回退到按首字段定位 IF 行(gcov 分支标记依赖源行)。
|
||
"""
|
||
pp = (
|
||
" PERFORM WITH TEST AFTER\n"
|
||
" UNTIL WRK-MERGE-EOF-Y\n"
|
||
" RETURN MERGE-FILE\n"
|
||
" INTO MERGE-REC\n"
|
||
" AT END\n"
|
||
" SET WRK-MERGE-EOF-Y TO TRUE\n"
|
||
" END-RETURN\n"
|
||
" IF NOT WRK-MERGE-EOF-Y\n"
|
||
" MOVE MERGE-EMP-ID\n"
|
||
" TO WRK-CURRENT-EMP\n"
|
||
" IF MERGE-REC-TYPE\n"
|
||
" = CNS-PAY-TYPE-SALARY\n"
|
||
" MOVE MERGE-PAY-AMOUNT\n"
|
||
" TO WRK-SALARY-AMOUNT\n"
|
||
" ELSE\n"
|
||
" MOVE MERGE-PAY-AMOUNT\n"
|
||
" TO WRK-BONUS-AMOUNT\n"
|
||
" END-IF\n"
|
||
" END-IF\n"
|
||
" END-PERFORM.\n"
|
||
)
|
||
dp = MultiLineD()
|
||
dp.source_line = 0
|
||
locate_decision_lines([dp], pp)
|
||
assert dp.source_line == 11, f"expected line 11 (IF MERGE-REC-TYPE), got {dp.source_line}"
|
||
|
||
|
||
def test_locate_multiline_if_does_not_mislocate_other_if():
|
||
"""首字段定位不应误命中其它字段相同的 IF(如 IF NOT WRK-MERGE-EOF-Y 前的 WRK 前缀)。"""
|
||
pp = (
|
||
" IF NOT WRK-MERGE-EOF-Y\n"
|
||
" IF MERGE-REC-TYPE\n"
|
||
" = CNS-PAY-TYPE-SALARY\n"
|
||
" MOVE MERGE-PAY-AMOUNT\n"
|
||
" TO WRK-SALARY-AMOUNT\n"
|
||
" END-IF\n"
|
||
" END-IF.\n"
|
||
)
|
||
dp = MultiLineD()
|
||
dp.source_line = 0
|
||
locate_decision_lines([dp], pp)
|
||
assert dp.source_line == 2, f"expected line 2 (IF MERGE-REC-TYPE), got {dp.source_line}"
|