mud/tests/test_player_stats.py
Jared Miller a398227814
Add player stats model and persistence
kills, deaths, mob_kills dict, play_time_seconds, unlocked_moves set
on Player. New player_stats SQLite table with save/load functions.
2026-02-14 11:40:45 -05:00

112 lines
3.3 KiB
Python

"""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"}