"""测试 PAPER_FACTORS 中所有因子的 DSL 公式解析。

排除已注释（# TODO）的因子，其余必须能被本地 FormulaParser 正确解析。
"""

import pytest

from src.factorminer.core.library_io import PAPER_FACTORS
from src.factors.parser import FormulaParser
from src.factors.registry import FunctionRegistry


@pytest.fixture(scope="module")
def parser():
    """提供共享的 FormulaParser 实例。"""
    return FormulaParser(FunctionRegistry())


class TestPaperFactorParsing:
    """验证 110 个 paper factors 的 DSL 解析成功率。"""

    def test_all_paper_factors_parse(self, parser):
        """遍历 PAPER_FACTORS，断言每个非 TODO 公式都能成功解析。"""
        success = 0
        skipped = 0
        failures = []

        for entry in PAPER_FACTORS:
            formula = entry["formula"]
            name = entry["name"]

            if formula.startswith("# TODO:"):
                skipped += 1
                continue

            try:
                parser.parse(formula)
                success += 1
            except Exception as e:
                failures.append((name, formula, str(e)))

        total = len(PAPER_FACTORS)
        print(f"[paper_factors] 成功 {success}/{total}，跳过 {skipped} 个未实现算子")

        assert not failures, "以下因子解析失败：\n" + "\n".join(
            f"  - {name}: {err}\n    formula: {formula}"
            for name, formula, err in failures
        )

    def test_todo_ratio_acceptable(self):
        """确保 TODO 比例不过高（当前阈值 20%）。"""
        todo_count = sum(1 for e in PAPER_FACTORS if e["formula"].startswith("# TODO:"))
        ratio = todo_count / len(PAPER_FACTORS)
        assert ratio <= 0.20, f"TODO 因子比例 {ratio:.1%} 超过 20%"
