113 lines
5.2 KiB
Python
113 lines
5.2 KiB
Python
"""
|
|
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())
|