test: cover between/hostvar/gcov-merge, class conditions, schema drop-tables, gixsql fixes

This commit is contained in:
hangshuo652
2026-08-09 17:43:16 +08:00
parent 273a3f8211
commit ff51bda962
22 changed files with 2559 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
"""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