"""Stage 2 검증 (계획서 §4.6) — 정규화 산출물이 있을 때 ZFIR10070 실측 + 단위 테스트.""" from pathlib import Path import pytest from parser.run import parse_program from parser.statements import split_statements from parser.tokenizer import split_comment, tokenize_code ROOT = Path(__file__).resolve().parent.parent PROG_DIR = ROOT / "data" / "normalized" / "ZFIR10070" def test_split_comment(): assert split_comment("* full comment") == ("", "full comment", True) code, comment, full = split_comment("DATA lv_x TYPE i. \" inline") assert comment == "inline" and not full and "DATA" in code def test_string_literal_quote_not_comment(): code, comment, _ = split_comment("WRITE 'has \" inside'.") assert comment == "" and "'has \" inside'" in code def test_chain_expansion(): sts, _ = split_statements("DATA: a TYPE i,\n b TYPE i.", "T") assert len(sts) == 2 assert sts[0].upper[:2] == ["DATA", "A"] assert sts[1].upper[:2] == ["DATA", "B"] def test_tokenizer_identifiers(): toks = tokenize_code("zcl_fi_common=>f4_bukrs( ) gs_head-belnr TEXT-004 ") assert "zcl_fi_common=>f4_bukrs" in toks assert "gs_head-belnr" in toks assert "TEXT-004" in toks assert "" in toks @pytest.fixture(scope="module") def parsed(): if not PROG_DIR.exists(): pytest.skip("정규화 산출물 없음 — python -m ingest.normalize 먼저 실행") return parse_program(PROG_DIR) def test_f01_has_73_forms(parsed): forms = [u for u in parsed["units"] if u["unit_type"] == "FORM" and u["include"] == "ZFIR10070_F01"] assert len(forms) == 73 def test_gt_acdoct_declared_in_top(parsed): decls = [s for s in parsed["symbols"] if s["name"] == "GT_ACDOCT"] assert decls and decls[0]["decl_include"] == "ZFIR10070_TOP" assert decls[0]["scope"] == "global" def test_select_data_calls_select_gl_list(parsed): sd = next(u for u in parsed["units"] if u["name"] == "SELECT_DATA") targets = [c["target"] for c in sd["refs"]["calls"]] assert "SELECT_GL_LIST" in targets def test_external_perform_zfir00010(parsed): ext = [e for e in parsed["call_edges"] if e["external_name"] and "ZFIR00010" in str(e["external_name"])] assert any("CHECK_BUKRS" in e["external_name"] for e in ext) def test_text_symbol_004(parsed): t = next(x for x in parsed["text_symbols"] if x["symbol"] == "004") assert t["text"] == "회계단위 간편선택" def test_unknown_ratio_below_3pct(parsed): assert parsed["stats"]["unknown_ratio"] < 0.03