76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
import sys
|
|
import unittest
|
|
from decimal import Decimal
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock
|
|
|
|
AI_ENGINE_ROOT = Path(__file__).resolve().parents[1]
|
|
if str(AI_ENGINE_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(AI_ENGINE_ROOT))
|
|
|
|
from core.engines.odds_predictor import OddsPredictorEngine
|
|
from features.sidelined_analyzer import SidelinedAnalyzer
|
|
|
|
|
|
class EngineNullSafetyTests(unittest.TestCase):
|
|
def test_odds_predictor_accepts_decimal_inputs_without_crashing(self):
|
|
engine = OddsPredictorEngine()
|
|
|
|
prediction = engine.predict(
|
|
odds_data={
|
|
"ms_h": Decimal("2.10"),
|
|
"ms_d": Decimal("3.25"),
|
|
"ms_a": Decimal("3.60"),
|
|
"ou25_o": Decimal("1.90"),
|
|
},
|
|
)
|
|
|
|
self.assertGreater(prediction.market_home_prob, 0.0)
|
|
self.assertGreater(prediction.market_draw_prob, 0.0)
|
|
self.assertGreater(prediction.market_away_prob, 0.0)
|
|
|
|
def test_sidelined_analyzer_handles_non_numeric_fields(self):
|
|
analyzer = SidelinedAnalyzer.__new__(SidelinedAnalyzer)
|
|
analyzer.position_weights = {"K": 0.35, "D": 0.20, "O": 0.25, "F": 0.30}
|
|
analyzer.max_rating = 10
|
|
analyzer.adaptation_threshold = 10
|
|
analyzer.adaptation_discount = 0.5
|
|
analyzer.goalkeeper_penalty = 0.15
|
|
analyzer.confidence_boost = 10
|
|
analyzer.max_impact = 0.85
|
|
analyzer.key_player_threshold = 3
|
|
analyzer.recent_matches_lookback = 15
|
|
analyzer._fetch_player_stats = MagicMock(return_value={})
|
|
|
|
result = analyzer.analyze(
|
|
{
|
|
"totalSidelined": 2,
|
|
"players": [
|
|
{
|
|
"playerId": "p1",
|
|
"playerName": "Player One",
|
|
"positionShort": "O",
|
|
"matchesMissed": "N/A",
|
|
"average": "?",
|
|
"type": "injury",
|
|
},
|
|
{
|
|
"playerId": "p2",
|
|
"playerName": "Player Two",
|
|
"positionShort": "K",
|
|
"matchesMissed": "12",
|
|
"average": "6.7",
|
|
"type": "suspension",
|
|
},
|
|
],
|
|
},
|
|
)
|
|
|
|
self.assertEqual(result.total_sidelined, 2)
|
|
self.assertGreaterEqual(result.impact_score, 0.0)
|
|
self.assertTrue(len(result.player_details) >= 2)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|