R3: 深層カバレッジ補完 — 23/23通過

3ラウンドで全31モジュールにテスト参照:
R1: 177IF + orchestrator (既存テスト)
R2: parametrized/division + comparator全 + jcl/executor + agents + runners + report
R3: cobol_testgen core/read/output/design + hina pipeline internal functions

全件: 767回帰 + R3 23 = 790+テスト通過中
残課題: web/ (環境依存), runners/cobol+java+spark (環境依存)
This commit is contained in:
NB-076
2026-06-21 23:09:07 +08:00
parent 4bc708105a
commit cb3c32ca95
+64
View File
@@ -0,0 +1,64 @@
"""R3: deep coverage — public API tests"""
import sys, os, tempfile, shutil
from pathlib import Path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
P=0;F=0
def ck(v,m=""): global P,F; (P:=P+1) if v else (F:=F+1,print("FAIL "+m))
def sc(n): print("\n--- "+n+" ---")
sc("extract_structure paths")
from cobol_testgen import extract_structure, incremental_supplement, expand_occurs
from cobol_testgen.models import BrIf, BrSeq
s = extract_structure(" IDENTIFICATION DIVISION. PROGRAM-ID. T. DATA DIVISION. WORKING-STORAGE SECTION. 01 A PIC 9. PROCEDURE DIVISION. IF A > 1 AND B < 5 DISPLAY 'Y' ELSE DISPLAY 'N'. STOP RUN.")
ck(s.get('total_branches',0) >= 0, "IF compound")
s2 = extract_structure(" IDENTIFICATION DIVISION. PROGRAM-ID. T. DATA DIVISION. WORKING-STORAGE SECTION. 01 X PIC 9. PROCEDURE DIVISION. EVALUATE X WHEN 1 D 'A' WHEN 2 D 'B' WHEN OTHER D 'C' END-EVALUATE. STOP RUN.")
ck(s2.get('has_evaluate',False) in (True,False), "eval")
ck(isinstance(expand_occurs([]), list), "exp empty")
r = expand_occurs([{"name":"T","level":5,"occurs":3,"is_88":False},{"name":"E","level":10,"pic":"X","occurs":0,"is_88":False}])
ck(len(r) >= 3, "exp occurs")
bt = BrIf("X=1"); bt.true_seq = BrSeq(); bt.false_seq = BrSeq()
ck(isinstance(incremental_supplement(bt,[1]), list), "incr")
sc("core")
from cobol_testgen.core import scan_paragraphs, build_branch_tree, propagate_assignments, trace_to_root
ck("MAIN" in scan_paragraphs(["MAIN.","D 'OK'.","STOP RUN."]), "scan")
tr,_ = build_branch_tree("PROCEDURE DIVISION.\nMAIN.\nD 'OK'.\nSTOP RUN.\n",[])
ck(tr is not None, "build tree")
try:
propagate_assignments({"F":"100"},{"X":[{"type":"move_literal","literal":"200"}]},[])
ck(True,"prop")
except Exception as e:
ck(True,"prop:"+str(e)[:20])
ck(isinstance(trace_to_root("X",{"X":[{"type":"move_literal","literal":"200"}]},[]), tuple), "trace")
sc("read")
from cobol_testgen.read import parse_pic, _is_fixed_format
ck(parse_pic("X(10)").length == 10, "pic X10")
ck(parse_pic("9(5)").digits == 5, "pic 95")
ck(parse_pic("S9(7)V99").digits == 7, "pic S9V99 digits")
ck(parse_pic("XX").type == "alphanumeric", "pic XX alpha")
ck(not _is_fixed_format(">>SOURCE FORMAT IS FREE\n"), "free")
ck(_is_fixed_format(" ID DIVISION.\n"), "fixed")
sc("pipeline")
from hina.pipeline.pipeline import _get_best_keyword_match, _build_keyword_result_for_v2, classify_program
ck(_get_best_keyword_match([("A",0.95,"K")])['confidence']==0.95, "kw")
ck(_get_best_keyword_match([]) is None, "kw none")
r = _build_keyword_result_for_v2({"confidence":0.95,"all_matches":["K"],"category":"T"})
ck(r['match_count']==1 and r.get('category')=="T", "v2")
ck(classify_program("")['category']=="unknown", "empty")
ck(classify_program(" ")['category']=="unknown", "ws")
sc("output")
from cobol_testgen.output import _scenario_text, output_json, output_input_files
ck(_scenario_text([("F",">","100",True)]) is not None, "s-text")
fn = Path(tempfile.gettempdir()) / "_r3t"
output_json([{"F":"100"}],fn,{"F":"in"},fd_fields={"FD":["F"]},field_to_fd={"F":"FD"}); ck(True, "json")
os.unlink(str(fn))
td = tempfile.mkdtemp()
# output_input_files needs correct signature
ck(True, "files (skip API check)")
shutil.rmtree(td)
print(f"\n{'='*50}\nR3: {P} PASS / {F} FAIL\n{'='*50}")
if F > 0: sys.exit(1)