import math import pytest from helpers.refractor_test_data import calculate_plays_needed class TestCalculatePlaysNeeded: """Test the pure function that computes how many synthetic plays are needed to push a card's refractor value over the next tier threshold. The formulas are: - batter: each HR play = 9 value (1 PA + 4 TB * 2) - sp/rp: each K play = 4/3 value (1/3 IP + 1 K) """ def test_batter_exact_threshold(self): """When the gap is exactly divisible by 9, no extra plays needed.""" result = calculate_plays_needed(gap=27, card_type="batter") assert result["num_plays"] == 3 assert result["total_value"] == 27 assert result["value_per_play"] == 9 def test_batter_rounds_up(self): """When gap isn't divisible by 9, round up to overshoot.""" result = calculate_plays_needed(gap=10, card_type="batter") assert result["num_plays"] == 2 # ceil(10/9) = 2 assert result["total_value"] == 18 def test_batter_gap_of_one(self): """Even a gap of 1 requires one play.""" result = calculate_plays_needed(gap=1, card_type="batter") assert result["num_plays"] == 1 assert result["total_value"] == 9 def test_sp_exact_threshold(self): """SP: each K play = 4/3 value.""" result = calculate_plays_needed(gap=4, card_type="sp") assert result["num_plays"] == 3 # ceil(4 / (4/3)) = 3 assert result["value_per_play"] == pytest.approx(4 / 3) def test_rp_same_as_sp(self): """RP uses the same formula as SP.""" result = calculate_plays_needed(gap=4, card_type="rp") assert result["num_plays"] == 3 def test_zero_gap_returns_one_play(self): """If already at threshold, still need 1 play to push over.""" result = calculate_plays_needed(gap=0, card_type="batter") assert result["num_plays"] == 1