mirror of
https://github.com/RichieCahill/dotfiles.git
synced 2026-04-19 21:59:09 -04:00
Add comprehensive test suite achieving 99% code coverage
Added 35 test files with 502 tests covering all Python modules including API routes, ORM models, splendor game logic/TUI, heater controller, weather service, NixOS installer, ZFS dataset management, and utilities. Coverage improved from 11% to 99% (2540/2564 statements covered). https://claude.ai/code/session_01SVzgLDUS1Cdc4eh1ijETTh
This commit is contained in:
143
tests/test_splendor_bot3_4.py
Normal file
143
tests/test_splendor_bot3_4.py
Normal file
@@ -0,0 +1,143 @@
|
||||
"""Tests for PersonalizedBot3 and PersonalizedBot4 edge cases."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
|
||||
from python.splendor.base import (
|
||||
BASE_COLORS,
|
||||
GEM_COLORS,
|
||||
BuyCard,
|
||||
Card,
|
||||
GameConfig,
|
||||
GameState,
|
||||
PlayerState,
|
||||
ReserveCard,
|
||||
TakeDifferent,
|
||||
create_random_cards,
|
||||
create_random_nobles,
|
||||
new_game,
|
||||
run_game,
|
||||
)
|
||||
from python.splendor.bot import (
|
||||
PersonalizedBot2,
|
||||
PersonalizedBot3,
|
||||
PersonalizedBot4,
|
||||
RandomBot,
|
||||
)
|
||||
|
||||
|
||||
def _make_card(tier: int = 1, points: int = 0, color: str = "white", cost: dict | None = None) -> Card:
|
||||
if cost is None:
|
||||
cost = dict.fromkeys(GEM_COLORS, 0)
|
||||
return Card(tier=tier, points=points, color=color, cost=cost)
|
||||
|
||||
|
||||
def _make_game(bots: list) -> GameState:
|
||||
cards = create_random_cards()
|
||||
nobles = create_random_nobles()
|
||||
config = GameConfig(cards=cards, nobles=nobles, turn_limit=100)
|
||||
return new_game(bots, config)
|
||||
|
||||
|
||||
def test_personalized_bot3_reserves_from_deck() -> None:
|
||||
"""Test PersonalizedBot3 reserves from deck when no tokens."""
|
||||
random.seed(42)
|
||||
bot = PersonalizedBot3("pbot3")
|
||||
game = _make_game([bot, RandomBot("r")])
|
||||
p = game.players[0]
|
||||
p.strategy = bot
|
||||
|
||||
# Clear bank to force reserve
|
||||
for c in BASE_COLORS:
|
||||
game.bank[c] = 0
|
||||
# Clear table to prevent buys
|
||||
for tier in (1, 2, 3):
|
||||
game.table_by_tier[tier] = []
|
||||
|
||||
action = bot.choose_action(game, p)
|
||||
assert isinstance(action, (ReserveCard, TakeDifferent))
|
||||
|
||||
|
||||
def test_personalized_bot3_fallback_take_different() -> None:
|
||||
"""Test PersonalizedBot3 falls back to TakeDifferent."""
|
||||
random.seed(42)
|
||||
bot = PersonalizedBot3("pbot3")
|
||||
game = _make_game([bot, RandomBot("r")])
|
||||
p = game.players[0]
|
||||
p.strategy = bot
|
||||
|
||||
# Empty everything
|
||||
for c in BASE_COLORS:
|
||||
game.bank[c] = 0
|
||||
for tier in (1, 2, 3):
|
||||
game.table_by_tier[tier] = []
|
||||
game.decks_by_tier[tier] = []
|
||||
|
||||
action = bot.choose_action(game, p)
|
||||
assert isinstance(action, TakeDifferent)
|
||||
|
||||
|
||||
def test_personalized_bot4_reserves_from_deck() -> None:
|
||||
"""Test PersonalizedBot4 reserves from deck."""
|
||||
random.seed(42)
|
||||
bot = PersonalizedBot4("pbot4")
|
||||
game = _make_game([bot, RandomBot("r")])
|
||||
p = game.players[0]
|
||||
p.strategy = bot
|
||||
|
||||
for c in BASE_COLORS:
|
||||
game.bank[c] = 0
|
||||
for tier in (1, 2, 3):
|
||||
game.table_by_tier[tier] = []
|
||||
|
||||
action = bot.choose_action(game, p)
|
||||
assert isinstance(action, (ReserveCard, TakeDifferent))
|
||||
|
||||
|
||||
def test_personalized_bot4_fallback() -> None:
|
||||
"""Test PersonalizedBot4 fallback with empty everything."""
|
||||
random.seed(42)
|
||||
bot = PersonalizedBot4("pbot4")
|
||||
game = _make_game([bot, RandomBot("r")])
|
||||
p = game.players[0]
|
||||
p.strategy = bot
|
||||
|
||||
for c in BASE_COLORS:
|
||||
game.bank[c] = 0
|
||||
for tier in (1, 2, 3):
|
||||
game.table_by_tier[tier] = []
|
||||
game.decks_by_tier[tier] = []
|
||||
|
||||
action = bot.choose_action(game, p)
|
||||
assert isinstance(action, TakeDifferent)
|
||||
|
||||
|
||||
def test_personalized_bot2_fallback_empty_colors() -> None:
|
||||
"""Test PersonalizedBot2 with very few available colors."""
|
||||
random.seed(42)
|
||||
bot = PersonalizedBot2("pbot2")
|
||||
game = _make_game([bot, RandomBot("r")])
|
||||
p = game.players[0]
|
||||
p.strategy = bot
|
||||
|
||||
# No table cards, no affordable reserved
|
||||
for tier in (1, 2, 3):
|
||||
game.table_by_tier[tier] = []
|
||||
# Set exactly 2 colors
|
||||
for c in BASE_COLORS:
|
||||
game.bank[c] = 0
|
||||
game.bank["white"] = 1
|
||||
game.bank["blue"] = 1
|
||||
|
||||
action = bot.choose_action(game, p)
|
||||
assert action is not None
|
||||
|
||||
|
||||
def test_full_game_with_bot3_and_bot4() -> None:
|
||||
"""Test a full game with bot3 and bot4."""
|
||||
random.seed(42)
|
||||
bots = [PersonalizedBot3("b3"), PersonalizedBot4("b4")]
|
||||
game = _make_game(bots)
|
||||
winner, turns = run_game(game)
|
||||
assert winner is not None
|
||||
Reference in New Issue
Block a user