Files
cobol-java-v3/tests/cobol_testgen/test_search_phase3.py
T

109 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""SEARCH 分支路径生成 + 二元 COMPUTE 链反演(Phase 3 — TDD RED
目标:KYU05DED SEARCH WHEN 分支(#9)从不可达变为可达,
配合二元 `-` COMPUTEWRK-TAXABLE-INCOME = WRK-GROSS-PAYMENT - CNS-TAX-BASIC-DEDUCTION
反演到输入 R01GROSS-PAYMENT。
"""
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from cobol_testgen.design_mcdc import enum_paths
from cobol_testgen.core import trace_to_root, invert_through_chain
from cobol_testgen.coverage import collect_decision_points, mark_coverage
from cobol_testgen.models import BrSearch, BrSeq, CondLeaf, CondAnd
def _make_search_node():
node = BrSearch("IW-ENTRY")
node.when_list = [("A <= SUBJ", BrSeq())]
node.cond_trees = [CondLeaf("A", "<=", "SUBJ")]
node.has_at_end = True
node.at_end_seq = BrSeq()
return node
FIELDS = [
{"name": "A(1)", "pic_info": {"type": "numeric", "digits": 9}},
{"name": "SUBJ", "pic_info": {"type": "numeric", "digits": 9}},
]
# ── 1. enum_paths 生成 SEARCH WHEN 路径 ──
def test_enum_paths_search_marks_when_branch():
"""enum_paths 对 BrSearch 应生成 WHEN 路径,使 _mark_search 标记 WHEN 分支"""
node = _make_search_node()
paths = enum_paths(node, FIELDS)
assert len(paths) >= 1
dps, _ = collect_decision_points(node, FIELDS, [0])
mark_coverage(dps, [], paths, FIELDS)
dp = dps[0]
assert dp.kind == "SEARCH"
assert "WHEN A <= SUBJ" in dp.active_branches
def test_enum_paths_search_marks_at_end():
"""enum_paths 应生成 AT END 路径(带不匹配 WHEN 叶的约束)"""
node = _make_search_node()
paths = enum_paths(node, FIELDS)
dps, _ = collect_decision_points(node, FIELDS, [0])
mark_coverage(dps, [], paths, FIELDS)
dp = dps[0]
assert "AT END" in dp.active_branches
# ── 2. trace_to_root / invert_through_chain 二元 `-` 反演 ──
def test_trace_minus_constant_field_to_input():
"""2 源 `-` COMPUTESUBJ = GROSS - DEDDED 常量 VALUE)→ 追溯到 INPUT-GROSS"""
assignments = {
"SUBJ": [{"type": "compute", "source_vars": ["GROSS", "DED"],
"op": "-", "expr": "GROSS - DED"}],
"GROSS": [{"type": "move", "source_vars": ["INPUT-GROSS"]}],
}
fields = [
{"name": "DED", "pic_info": {"type": "numeric", "digits": 6}, "value": "50000"},
{"name": "INPUT-GROSS", "pic_info": {"type": "numeric", "digits": 9}},
]
root, chain = trace_to_root("SUBJ", assignments, fields)
assert root == "INPUT-GROSS"
# 2 源 `-` COMPUTE 常量侧被折叠为单源 compute + const
assert any(a.get("const") == float("50000") for _, a in chain)
def test_invert_minus_constant_field_boundary():
"""SUBJ >= 4701 → GROSS - 50000 >= 4701 → INPUT-GROSS >= 54701"""
assignments = {
"SUBJ": [{"type": "compute", "source_vars": ["GROSS", "DED"],
"op": "-", "expr": "GROSS - DED"}],
"GROSS": [{"type": "move", "source_vars": ["INPUT-GROSS"]}],
}
fields = [
{"name": "DED", "pic_info": {"type": "numeric", "digits": 6}, "value": "50000"},
{"name": "INPUT-GROSS", "pic_info": {"type": "numeric", "digits": 9}},
]
root, chain = trace_to_root("SUBJ", assignments, fields)
new_root, op, val = invert_through_chain(root, chain, ">=", "4701")
assert new_root == "INPUT-GROSS"
assert op == ">="
assert float(val) >= 54701
# ── 3. _mark_search 单 CondLeaf 字段对字段(应已绿,防止回归)──
def test_mark_search_field_to_field_constraint():
"""SUBJ <= A(1) 形态约束命中 WHEN 叶(value 侧基准字段匹配)"""
from cobol_testgen.coverage import DecisionPoint
dp = DecisionPoint(id=1, kind="SEARCH", label="IW-ENTRY",
branch_names=["WHEN A <= SUBJ", "AT END"])
dp.when_list = [("A <= SUBJ", BrSeq())]
dp.cond_trees = [CondLeaf("A", "<=", "SUBJ")]
dp.has_other = True
branch_paths = [
([("SUBJ", "<=", "A(1)", True)], []),
]
mark_coverage([dp], [], branch_paths, FIELDS)
assert "WHEN A <= SUBJ" in dp.active_branches
assert "AT END" not in dp.active_branches