import pandas as pd from models.shared_matchup_engine import compose_shared_matchup_context def test_compose_shared_matchup_context_empty_inputs(): result = compose_shared_matchup_context( batter_name="", pitcher_name="", batter_statcast_df=pd.DataFrame(), pitcher_statcast_df=pd.DataFrame(), ) assert result["expected_pitch_mix_by_count"] == {} assert result["predicted_attack_regions"] == [] assert result["expected_pitch_family_mix"] == {} assert "shared_composer" in result["component_source_map"] def test_compose_shared_matchup_context_reuses_runtime_cache(): batter_df = pd.DataFrame( [ { "player_name": "Batter One", "pitch_name": "Slider", "pitch_type": "SL", "description": "swinging_strike", "plate_x": 0.1, "plate_z": 2.5, "stand": "L", "p_throws": "R", "release_speed": 95.0, "release_spin_rate": 2400, "release_extension": 6.2, } ] * 40 ) runtime_cache: dict[str, object] = {} first = compose_shared_matchup_context( batter_name="Batter One", pitcher_name="Pitcher One", batter_statcast_df=batter_df, pitcher_statcast_df=batter_df, batter_features={"batter_stand": "L"}, pitcher_row={"p_throws": "R"}, game_row={"away_team": "Away", "home_team": "Home"}, runtime_cache=runtime_cache, ) second = compose_shared_matchup_context( batter_name="Batter One", pitcher_name="Pitcher One", batter_statcast_df=batter_df, pitcher_statcast_df=batter_df, batter_features={"batter_stand": "L"}, pitcher_row={"p_throws": "R"}, game_row={"away_team": "Away", "home_team": "Home"}, runtime_cache=runtime_cache, ) assert first == second assert "shared_matchup_context" in runtime_cache