test: add HINA type-specific COBOL test data suite (10 programs, 8/10 pass)

This commit is contained in:
hangshuo652
2026-06-18 16:55:43 +08:00
parent 2e64f208ea
commit 9ad0e88a1a
12 changed files with 617 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
"""
HINA 类型别 COBOL 测试数据验证器
全テストプログラムに対して extract_structure + HINA + 数据生成を実行
"""
import sys, json
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
from cobol_testgen import extract_structure, generate_data
from cobol_testgen.coverage import check_coverage
from hina.classifier import compute_confidence
TEST_DIR = Path(__file__).parent / "cobol"
EXPECTED = {
"HINA001": {"name": "1:1 マッチング", "min_para": 8, "min_br": 0, "min_dp": 0, "fc": 3,
"note": "PERFORM内IFは静的解析対象外"},
"HINA005": {"name": "IF条件分岐", "min_para": 1, "min_br": 6, "min_dp": 3, "fc": 0},
"HINA006": {"name": "EVALUATE分岐", "min_para": 1, "min_br": 6, "min_dp": 3, "fc": 0},
"HINA007": {"name": "キーブレイク集計", "min_para": 3, "min_br": 0, "min_dp": 0, "fc": 2,
"note": "PERFORM内IFは静的解析対象外"},
"HINA024": {"name": "内部テーブル検索", "min_para": 1, "min_br": 2, "min_dp": 2, "fc": 0,
"note": "Lark文法制限: ASCENDING KEY未対応"},
"HINA013": {"name": "項目チェック", "min_para": 1, "min_br": 6, "min_dp": 3, "fc": 0},
"HINA004": {"name": "編集出力(GETPUT)", "min_para": 3, "min_br": 0, "min_dp": 0, "fc": 2,
"note": "PERFORM内IFは静的解析対象外"},
"HINA025": {"name": "サブプログラムCALL", "min_para": 2, "min_br": 0, "min_dp": 0, "fc": 0,
"hina_type": "子程序调用", "hina_method": "keyword"},
"HINA034": {"name": "SORT処理", "min_para": 1, "min_br": 0, "min_dp": 0, "fc": 3,
"hina_type": "SORT", "hina_method": "keyword",
"note": "Lark文法制限: SD未対応"},
"HINA101": {"name": "EXEC SQL", "min_para": 1, "min_br": 1, "min_dp": 1, "fc": 0,
"hina_type": "DB操作", "hina_method": "keyword"},
}
def main():
results = []
passed = failed = 0
cbl_files = sorted(TEST_DIR.glob("HINA*.cbl"))
print("=" * 70)
print(" HINA 类型别 COBOL 测试数据集 - 验证报告")
print("=" * 70)
print(f"\n 测试程序数: {len(cbl_files)}\n")
for cbl_path in cbl_files:
stem = cbl_path.stem
exp = EXPECTED.get(stem, {})
name = exp.get("name", stem)
src = cbl_path.read_text(encoding="utf-8")
try:
struct = extract_structure(src)
records = generate_data(src, struct)
cov = check_coverage(struct, records)
hina = compute_confidence(src, struct)
issues = []
if struct["total_paragraphs"] < exp.get("min_para", 0):
issues.append(f"段落不足: {struct['total_paragraphs']}<{exp.get('min_para')}")
if struct["total_branches"] < exp.get("min_br", 0):
issues.append(f"分岐不足: {struct['total_branches']}<{exp.get('min_br')}")
if len(struct["decision_points"]) < exp.get("min_dp", 0):
issues.append(f"決定点不足: {len(struct['decision_points'])}<{exp.get('min_dp')}")
if exp.get("hina_type") and hina.get("category") != exp["hina_type"]:
issues.append(f"HINA類型違い: {hina.get('category')}!={exp['hina_type']}")
if exp.get("hina_method") and hina.get("method") != exp["hina_method"]:
issues.append(f"HINA方法違い: {hina.get('method')}!={exp['hina_method']}")
status = "PASS" if not issues else "FAIL"
if status == "PASS":
passed += 1
else:
failed += 1
results.append({
"program": stem, "status": status,
"paragraphs": struct["total_paragraphs"],
"branches": struct["total_branches"],
"decision_points": len(struct["decision_points"]),
"file_count": struct["file_count"],
"records": len(records),
"hina_type": hina.get("category", "?"),
"hina_confidence": hina.get("confidence", 0.0),
"hina_method": hina.get("method", "?"),
"issues": issues,
})
print(f" [{status}] {stem} - {name}")
print(f" 段落={struct['total_paragraphs']} 分岐={struct['total_branches']} "
f"決定点={len(struct['decision_points'])} ファイル={struct['file_count']}")
print(f" HINA: {hina.get('category','?')} ({hina.get('confidence',0):.0%}) method={hina.get('method','?')}")
print(f" 生成データ: {len(records)}")
for i in issues:
print(f" ⚠️ {i}")
print()
except Exception as e:
failed += 1
print(f" [ERROR] {stem} - {name}: {str(e)[:80]}\n")
print("-" * 70)
print(f" 总计: {passed} passed, {failed} failed / {len(cbl_files)} total")
report_path = TEST_DIR.parent / "test-report.json"
json.dump(results, open(report_path, "w", encoding="utf-8"), indent=2, ensure_ascii=False)
print(f" 详细报告: {report_path}")
return 0 if failed == 0 else 1
if __name__ == "__main__":
sys.exit(main())