""" COBOL 语句基准样本自动验证脚本。 验证每个样本: 1. preprocess 正确 2. extract_structure 返回非空结构 3. BRANCHES 元注释与 total_branches 一致 4. generate_data 至少生成 1 条记录 5. 无未捕获异常 """ import glob import re import sys sys.path.insert(0, '.') from cobol_testgen import extract_structure, generate_data, preprocess def extract_meta(path: str) -> dict: """从 * BRANCHES/STATEMENT 注释提取元信息。""" text = open(path, encoding='utf-8').read() meta = {} m = re.search(r'\* BRANCHES:\s*(\d+)', text) if m: meta['branches'] = int(m.group(1)) m = re.search(r'\* STATEMENT:\s*(.+)', text) if m: meta['statement'] = m.group(1).strip() m = re.search(r'\* FEATURE:\s*(.+)', text) if m: meta['feature'] = m.group(1).strip() return meta def main(): files = sorted(glob.glob('test-data/cobol/statement_*/ST-*.cbl')) if not files: files = sorted(glob.glob('../test-data/cobol/statement_*/ST-*.cbl')) passed = 0 failed = 0 errors = [] for f in files: name = f.split('/')[-1].replace('.cbl', '') meta = extract_meta(f) print(f' {name:30} ', end='', flush=True) try: source = open(f, encoding='utf-8').read() except Exception as e: print(f'❌ READ ERROR: {e}') failed += 1 errors.append((name, 'read_error', str(e))) continue # Test 1: preprocess try: pp = preprocess(source) except Exception as e: print(f'❌ PREPROCESS ERROR: {e}') failed += 1 errors.append((name, 'preprocess', str(e))) continue # Test 2: extract_structure try: struct = extract_structure(source) except Exception as e: print(f'❌ EXTRACT ERROR: {e}') failed += 1 errors.append((name, 'extract_structure', str(e))) continue if struct is None or (struct.get('total_paragraphs', 0) == 0 and struct.get('total_branches', 0) == 0): print('⚠️ WARN: empty structure') # pass through — some file-only programs may have no branches else: # Test 3: BRANCHES meta check expected_branches = meta.get('branches', 0) actual_branches = struct.get('total_branches', 0) if expected_branches and expected_branches != actual_branches: print(f'⚠️ META BRANCH {expected_branches}≠{actual_branches} ', end='') else: pass # Test 4: generate_data try: data = generate_data(source, struct) if not data: print('⚠️ NO DATA ', end='') except Exception as e: print(f'⚠️ GENERATE WARN: {e} ', end='') print('✅') passed += 1 print(f'\n=== 结果: {passed} passed, {failed} failed ===') if errors: print('\n失败明细:') for name, stage, msg in errors: print(f' {name}: {stage} — {msg}') return 1 if failed > 0 else 0 if __name__ == '__main__': sys.exit(main())