- Create tests/ package with Django/Evennia environment setup - Add test_audited_character.py: at_object_creation, at_post_move, at_pre_cmd, at_pre_puppet, at_post_unpuppet, prune_audit_history, get_audit_summary, and audit log rate limiting tests - Add test_commands.py: CmdExamine, CmdRooms, CmdStatus, CmdMap, CmdAcademy, CmdSmell, CmdListen, CmdWho (presence and attribute tests) - Add test_rebuild_world.py: parse_wing_file, ROOM_CONFIG consistency, WING_INFO metadata, bidirectional exit verification concept - Uses evennia.utils.test_resources for serverless testing
160 lines
4.8 KiB
Python
160 lines
4.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Unit tests for commands in Timmy Academy.
|
|
|
|
Tests the following commands:
|
|
- CmdExamine
|
|
- CmdRooms
|
|
- CmdStatus
|
|
- CmdMap
|
|
- CmdAcademy
|
|
- CmdSmell
|
|
- CmdListen
|
|
- CmdWho
|
|
"""
|
|
|
|
import pytest
|
|
from evennia.utils.test_resources import EvenniaTestCase
|
|
from commands.command import (
|
|
CmdExamine, CmdRooms, CmdStatus, CmdMap,
|
|
CmdAcademy, CmdSmell, CmdListen, CmdWho
|
|
)
|
|
from evennia import create_object
|
|
from typeclasses.rooms import Room
|
|
from typeclasses.audited_character import AuditedCharacter
|
|
|
|
|
|
class TestCommands(EvenniaTestCase):
|
|
"""Test suite for Timmy Academy commands."""
|
|
|
|
def setUp(self):
|
|
"""Set up a caller (account/character) and a test room."""
|
|
super().setUp()
|
|
# Create a character for the caller
|
|
self.char = self.create_object(AuditedCharacter, key="Tester")
|
|
self.account = self.account
|
|
self.account.puppet_object(self.char)
|
|
|
|
# Create a test room with basic attributes
|
|
self.room = self.create_object(Room, key="TestRoom")
|
|
self.room.db.desc = "A simple test room."
|
|
self.room.db.wing = "hub"
|
|
self.char.location = self.room
|
|
|
|
def test_cmd_examine_room_no_args(self):
|
|
"""CmdExamine without args should show room details."""
|
|
cmd = CmdExamine()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "examine"
|
|
# Call func — should not raise
|
|
cmd.func()
|
|
|
|
def test_cmd_examine_with_atmosphere(self):
|
|
"""CmdExamine should display atmosphere when present."""
|
|
self.room.db.atmosphere = {"mood": "calm", "temperature": "warm"}
|
|
cmd = CmdExamine()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "examine"
|
|
cmd.func()
|
|
# If no exception, test passes
|
|
|
|
def test_cmd_rooms_lists_rooms(self):
|
|
"""CmdRooms should list available rooms."""
|
|
cmd = CmdRooms()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "rooms"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_cmd_status_shows_info(self):
|
|
"""CmdStatus should display agent status."""
|
|
cmd = CmdStatus()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "@status"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_cmd_map_shows_wing_map(self):
|
|
"""CmdMap should display ASCII map for current wing."""
|
|
cmd = CmdMap()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "@map"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_cmd_academy_shows_overview(self):
|
|
"""CmdAcademy should show all wings summary."""
|
|
cmd = CmdAcademy()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "@academy"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_cmd_smell_with_atmosphere(self):
|
|
"""CmdSmell should output scent from atmosphere."""
|
|
self.room.db.atmosphere = {"smells": "fresh pine"}
|
|
cmd = CmdSmell()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "smell"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_cmd_smell_no_atmosphere(self):
|
|
"""CmdSmell should handle room without atmosphere gracefully."""
|
|
cmd = CmdSmell()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "smell"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_cmd_listen_with_atmosphere(self):
|
|
"""CmdListen should output sounds from atmosphere."""
|
|
self.room.db.atmosphere = {"sounds": "birds chirping", "mood": "peaceful"}
|
|
cmd = CmdListen()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "listen"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_cmd_listen_no_atmosphere(self):
|
|
"""CmdListen should handle room without atmosphere."""
|
|
cmd = CmdListen()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "listen"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_cmd_who_shows_online(self):
|
|
"""CmdWho should list online accounts."""
|
|
cmd = CmdWho()
|
|
cmd.caller = self.char
|
|
cmd.args = ""
|
|
cmd.key = "@who"
|
|
cmd.func()
|
|
# Should not raise
|
|
|
|
def test_commands_have_required_attributes(self):
|
|
"""All command classes must define key and locks."""
|
|
commands = [
|
|
CmdExamine, CmdRooms, CmdStatus, CmdMap,
|
|
CmdAcademy, CmdSmell, CmdListen, CmdWho
|
|
]
|
|
for cmd_class in commands:
|
|
self.assertTrue(hasattr(cmd_class, 'key'),
|
|
f"{cmd_class.__name__} missing 'key'")
|
|
self.assertTrue(hasattr(cmd_class, 'locks'),
|
|
f"{cmd_class.__name__} missing 'locks'")
|
|
# key should be a non-empty string
|
|
self.assertIsInstance(cmd_class.key, str)
|
|
self.assertTrue(len(cmd_class.key) > 0)
|