"""DE-01~08: cobol_testgen design 模块 — 路径枚举 + 值生成 + 约束应用""" import sys, os sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from cobol_testgen.design import ( enum_paths, _filter_stop, _cap_paths, apply_constraint, make_base_record, generate_records, sync_redefined_fields, apply_occurs_depending, _STOP, ) from cobol_testgen.models import BrSeq, BrIf, BrEval, Assign # ── DE-01: enum_paths ── def test_enum_paths_assign(): """赋值节点 → 单路径含 assignment""" node = Assign("WS-RESULT", {"source": "MOVE", "source_vars": ["WS-INPUT"]}) paths = enum_paths(node, []) assert len(paths) == 1 _, assignments = paths[0] assert "WS-RESULT" in assignments def test_enum_paths_empty(): """空 BrSeq → 单路径""" paths = enum_paths(BrSeq(), []) assert len(paths) >= 1 # ── _filter_stop / _cap_paths ── def test_filter_stop_removes_stop(): """_filter_stop 移除 __STOP__""" cons = [("A", ">", "0", True), _STOP, ("B", "<", "5", True)] filtered = _filter_stop(cons) assert len(filtered) == 2 def test_cap_paths_within_limit(): """限制内全部保留""" paths = [(f"p{i}", {}) for i in range(10)] capped = _cap_paths(paths) assert len(capped) == 10 # ── apply_constraint ── def test_apply_constraint_numeric(): """DE-02: 数值约束 field > 100""" rec = {"WS-AMOUNT": 0} fields = [{"name": "WS-AMOUNT", "pic": "9(7)", "pic_info": {"type": "numeric", "digits": 7, "decimal": 0}}] apply_constraint(rec, "WS-AMOUNT", ">", "100", True, fields) assert int(rec["WS-AMOUNT"]) > 100 def test_apply_constraint_alpha(): """DE-03: 文字约束 field = 'ABC'""" rec = {"WS-CODE": " " * 3} fields = [{"name": "WS-CODE", "pic": "X(3)", "pic_info": {"type": "alphanumeric", "length": 3}}] apply_constraint(rec, "WS-CODE", "=", "ABC", True, fields) # 由于 fill 策略,可能是字首字母重复填充 val = rec["WS-CODE"] assert isinstance(val, str) and len(val) == 3 # ── make_base_record ── def test_make_base_record(): """DE-08: 序列值 基础记录""" fields = [{"name": "WS-AMOUNT", "pic": "9(7)", "pic_info": {"type": "numeric", "digits": 7, "decimal": 0}}] rec = make_base_record(1, fields) assert "WS-AMOUNT" in rec # ── generate_records ── def test_generate_records_basic(): """DE-05: 已知路径生成记录""" paths = [([("WS-AMOUNT", ">", "100", True)], {})] fields = [{"name": "WS-AMOUNT", "pic": "9(7)", "pic_info": {"type": "numeric", "digits": 7, "decimal": 0}}] records, path_out = generate_records(paths, fields) assert len(records) >= 1 assert "WS-AMOUNT" in records[0] def test_generate_records_empty_paths(): """空路径 → 1条基础记录""" records, path_out = generate_records([], []) assert len(records) == 1 # 实现默认生成一条基础记录 assert isinstance(records[0], dict) # ── sync_redefined_fields / apply_occurs_depending ── def test_sync_redefined(): """DE-06: REDEFINES 字段同步""" rec = {"WS-BLOCK": "12345", "WS-BLOCK-REDEF": ""} fields = [ {"name": "WS-BLOCK", "pic": "X(5)", "pic_info": {"type": "alphanumeric", "length": 5}, "offset": 0, "length": 5}, {"name": "WS-BLOCK-REDEF", "redefines": "WS-BLOCK", "pic": "9(5)", "pic_info": {"type": "numeric", "digits": 5, "decimal": 0}, "offset": 0, "length": 5}, ] # 只是验证不崩溃 sync_redefined_fields(rec, fields) assert True def test_apply_occurs_depending(): """DE-07: ODO 依赖字段设置""" rec = {"WS-TABLE-SIZE": 5, "WS-TABLE": ""} fields = [ {"name": "WS-TABLE-SIZE", "pic": "9(2)", "pic_info": {"type": "numeric", "digits": 2, "decimal": 0}}, {"name": "WS-TABLE", "occurs_depending": "WS-TABLE-SIZE", "pic_info": {"type": "numeric", "digits": 5, "decimal": 0}}, ] # 验证不崩溃 apply_occurs_depending(rec, fields) assert True