"""Unit tests for the chess-style Elo math in :mod:`tavolo.elo`.""" from __future__ import annotations import unittest from tavolo.elo import ( INITIAL_RATING, K_FACTOR, expected_score, match_delta, team_rating, ) class ExpectedScoreTest(unittest.TestCase): def test_equal_ratings_give_even_odds(self) -> None: self.assertAlmostEqual(0.5, expected_score(1500, 1500)) def test_higher_rating_is_favoured(self) -> None: self.assertGreater(expected_score(1700, 1500), 0.5) self.assertLess(expected_score(1500, 1700), 0.5) def test_scores_sum_to_one(self) -> None: self.assertAlmostEqual( 1.0, expected_score(1600, 1400) + expected_score(1400, 1600) ) def test_four_hundred_points_is_ten_to_one(self) -> None: self.assertAlmostEqual(10 / 11, expected_score(1900, 1500)) class TeamRatingTest(unittest.TestCase): def test_mean_of_members(self) -> None: self.assertEqual(1600, team_rating([1500, 1700])) def test_empty_team_rejected(self) -> None: with self.assertRaises(ValueError): team_rating([]) class MatchDeltaTest(unittest.TestCase): def test_equal_teams_exchange_half_k(self) -> None: delta = match_delta([1500, 1500], [1500, 1500], winner_team=0) self.assertEqual(K_FACTOR // 2, delta) def test_favourite_gains_less_than_underdog(self) -> None: favourite = match_delta([1700, 1700], [1500, 1500], winner_team=0) underdog = match_delta([1500, 1500], [1700, 1700], winner_team=0) self.assertGreater(underdog, favourite) self.assertGreater(favourite, 0) def test_losing_side_loses_the_winners_gain(self) -> None: # Zero-sum: the losers' delta is the negation of the winners'. win = match_delta([1600, 1500], [1400, 1500], winner_team=0) loss = match_delta([1600, 1500], [1400, 1500], winner_team=1) self.assertEqual(-win, -abs(win)) # winner gains # Losing the same pairing costs K * E, winning gains K * (1 - E); # both are computed from the same expectation, so loss = win - K. self.assertEqual(win - K_FACTOR, loss) def test_team_average_decides_not_individual_ratings(self) -> None: # [1700, 1300] averages 1500, same as [1500, 1500]. mixed = match_delta([1700, 1300], [1500, 1500], winner_team=0) even = match_delta([1500, 1500], [1500, 1500], winner_team=0) self.assertEqual(even, mixed) def test_initial_rating_constant(self) -> None: self.assertEqual(1500, INITIAL_RATING) self.assertEqual(32, K_FACTOR) if __name__ == "__main__": unittest.main()