kills, deaths, mob_kills dict, play_time_seconds, unlocked_moves set on Player. New player_stats SQLite table with save/load functions.
112 lines
3.3 KiB
Python
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"}
|