fix: stale docstring + add decision-only pitcher test

- evaluate_card() docstring: "Override for PlayerSeasonStats" →
  "Override for BattingSeasonStats/PitchingSeasonStats"
- New test_decision_only_pitcher: exercises the edge case where a pitcher
  has a Decision row but no StratPlay rows, verifying _get_player_pairs()
  correctly includes them via the Decision table scan

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2026-03-19 10:31:16 -05:00
parent 4211bd69e0
commit 46c85e6874
2 changed files with 59 additions and 2 deletions

View File

@ -65,8 +65,8 @@ def evaluate_card(
Args: Args:
player_id: Player primary key. player_id: Player primary key.
team_id: Team primary key. team_id: Team primary key.
_stats_model: Override for PlayerSeasonStats (used in tests to avoid _stats_model: Override for BattingSeasonStats/PitchingSeasonStats
importing from db_engine before WP-07 merges). (used in tests to inject a stub model with all stat fields).
_state_model: Override for EvolutionCardState (used in tests to avoid _state_model: Override for EvolutionCardState (used in tests to avoid
importing from db_engine before WP-05 merges). importing from db_engine before WP-05 merges).
_compute_value_fn: Override for formula_engine.compute_value_for_track _compute_value_fn: Override for formula_engine.compute_value_for_track

View File

@ -851,3 +851,60 @@ def test_partial_reprocessing_heals(
assert stats.doubles == 1 assert stats.doubles == 1
assert stats.strikeouts == 1 assert stats.strikeouts == 1
assert stats.games == 1 assert stats.games == 1
def test_decision_only_pitcher(team_a, team_b, player_batter, player_pitcher, game):
"""A pitcher with a Decision but no StratPlay rows still gets stats recorded.
What: Create a second pitcher who has a Decision (win) for the game but
does not appear in any StratPlay rows. After update_season_stats(), the
decision-only pitcher should have a PitchingSeasonStats row with wins=1
and all play-level stats at 0.
Why: In rare cases a pitcher may be credited with a decision without
recording any plays (e.g. inherited runner scoring rules, edge cases in
game simulation). The old code handled this in _apply_decisions(); the
new code must include Decision-scanned pitchers in _get_player_pairs().
"""
relief_pitcher = _make_player("Relief Pitcher", pos="RP")
# The main pitcher has plays
make_play(
game,
1,
player_batter,
team_a,
player_pitcher,
team_b,
pa=1,
ab=1,
outs=1,
)
# The relief pitcher has a Decision but NO StratPlay rows
Decision.create(
season=11,
game=game,
pitcher=relief_pitcher,
pitcher_team=team_b,
win=1,
loss=0,
is_save=0,
hold=0,
b_save=0,
is_start=False,
)
update_season_stats(game.id)
# The relief pitcher should have a PitchingSeasonStats row
stats = PitchingSeasonStats.get(
PitchingSeasonStats.player == relief_pitcher,
PitchingSeasonStats.team == team_b,
PitchingSeasonStats.season == 11,
)
assert stats.wins == 1
assert stats.games == 0 # no plays, so COUNT(DISTINCT game) = 0
assert stats.outs == 0
assert stats.strikeouts == 0
assert stats.games_started == 0