"""Tests for player stats tracking and persistence.""" import pytest from mudlib.player import Player from mudlib.store import init_db, load_player_stats, save_player_stats @pytest.fixture def db(tmp_path): """Create a temporary test database.""" db_path = tmp_path / "test.db" init_db(db_path) return db_path @pytest.fixture def player_with_stats(mock_reader, mock_writer, test_zone): """Create a player with non-default stats.""" p = Player(name="Ryu", x=0, y=0, reader=mock_reader, writer=mock_writer) p.location = test_zone p.kills = 5 p.deaths = 2 p.mob_kills = {"goblin": 3, "rat": 2} p.play_time_seconds = 3600.0 p.unlocked_moves = {"roundhouse", "sweep"} p.session_start = 1234567890.0 return p def test_player_stats_fields_exist_with_defaults(player): """Player stats fields exist with correct default values.""" assert player.kills == 0 assert player.deaths == 0 assert player.mob_kills == {} assert player.play_time_seconds == 0.0 assert player.unlocked_moves == set() assert player.session_start == 0.0 def test_stats_persistence_round_trip(db, player_with_stats): """Stats can be saved and loaded back correctly.""" # Save stats save_player_stats(player_with_stats, db) # Load stats back stats = load_player_stats(player_with_stats.name, db) # Verify all values match assert stats["kills"] == 5 assert stats["deaths"] == 2 assert stats["mob_kills"] == {"goblin": 3, "rat": 2} assert stats["play_time_seconds"] == 3600.0 assert stats["unlocked_moves"] == {"roundhouse", "sweep"} def test_stats_persistence_with_fresh_player(db, player): """Loading stats for player without stats row returns defaults.""" # player exists in accounts but has no stats row yet stats = load_player_stats(player.name, db) # Should get defaults assert stats["kills"] == 0 assert stats["deaths"] == 0 assert stats["mob_kills"] == {} assert stats["play_time_seconds"] == 0.0 assert stats["unlocked_moves"] == set() def test_stats_table_created_on_init_db(tmp_path): """init_db creates the player_stats table.""" import sqlite3 db_path = tmp_path / "test.db" init_db(db_path) conn = sqlite3.connect(db_path) cursor = conn.cursor() # Check table exists cursor.execute( "SELECT name FROM sqlite_master WHERE type='table' AND name='player_stats'" ) result = cursor.fetchone() conn.close() assert result is not None assert result[0] == "player_stats" def test_stats_update_existing_row(db, player_with_stats): """Updating stats for existing player overwrites old values.""" # Save initial stats save_player_stats(player_with_stats, db) # Modify stats player_with_stats.kills = 10 player_with_stats.deaths = 5 player_with_stats.mob_kills = {"dragon": 1} player_with_stats.play_time_seconds = 7200.0 player_with_stats.unlocked_moves = {"fireball"} # Save again save_player_stats(player_with_stats, db) # Load and verify new values stats = load_player_stats(player_with_stats.name, db) assert stats["kills"] == 10 assert stats["deaths"] == 5 assert stats["mob_kills"] == {"dragon": 1} assert stats["play_time_seconds"] == 7200.0 assert stats["unlocked_moves"] == {"fireball"}