Mi2dRPGamEng/tests/test_dev_tools.py

227 lines
6.8 KiB
Python

from pathlib import Path
import pytest
from engine.character import Character
from engine.defs import DefRegistry
from engine.dev_config import DevConfig
from engine.dev_tools import DevFactionMenu, DevSpawnMenu, DevTurretMenu
from engine.inventory import Inventory
DEFS_DIR = Path(__file__).resolve().parent.parent / "resources" / "defs"
@pytest.fixture()
def registry():
return DefRegistry.load(DEFS_DIR)
def make_human(registry, **kwargs) -> Character:
return Character(species_id="human", default_body_parts=registry.new_default_body_parts("human"), **kwargs)
# --- DevSpawnMenu -------------------------------------------------------------------------------
def test_menu_defaults_to_every_loaded_non_secret_item_def_sorted(registry):
menu = DevSpawnMenu(registry)
expected = sorted(def_id for def_id, item_def in registry.item_defs.items() if not item_def.secret)
assert menu.item_ids == expected
assert menu.selected_item_id() == menu.item_ids[0]
def test_menu_excludes_secret_items(registry):
menu = DevSpawnMenu(registry)
assert "cyberdeck_the_miro_model_3a" not in menu.item_ids
def test_cycle_wraps_around(registry):
menu = DevSpawnMenu(registry)
menu.cycle(-1)
assert menu.selected_item_id() == menu.item_ids[-1]
def test_spawn_into_places_the_item_when_inventory_has_room(registry):
menu = DevSpawnMenu(registry)
character = make_human(registry)
character.inventory = Inventory(4, 4)
assert menu.spawn_into(character) is True
assert len(character.inventory.items()) == 1
def test_spawn_into_fails_without_an_inventory(registry):
menu = DevSpawnMenu(registry)
character = make_human(registry)
assert menu.spawn_into(character) is False
def test_spawn_into_fails_when_inventory_is_full(registry):
menu = DevSpawnMenu(registry)
character = make_human(registry)
character.inventory = Inventory(1, 1)
item_def = registry.get_item_def(menu.selected_item_id())
if item_def.width > 1 or item_def.height > 1:
pytest.skip("first item def doesn't fit a 1x1 inventory to begin with")
assert menu.spawn_into(character) is True
assert menu.spawn_into(character) is False
# --- DevTurretMenu --------------------------------------------------------------------------------
def test_turret_menu_defaults_to_every_turret_entity_def_sorted(registry):
menu = DevTurretMenu(registry)
assert menu.entity_def_ids == ["turret_autocannon", "turret_pistol"]
assert menu.selected_entity_def_id() == "turret_autocannon"
def test_turret_menu_excludes_non_turret_entity_defs(registry):
menu = DevTurretMenu(registry)
assert "player" not in menu.entity_def_ids
assert "npc_reptilian" not in menu.entity_def_ids
assert "companion_dog" not in menu.entity_def_ids
def test_turret_menu_cycle_wraps_around(registry):
menu = DevTurretMenu(registry)
menu.cycle(-1)
assert menu.selected_entity_def_id() == menu.entity_def_ids[-1]
def test_turret_menu_selected_entity_def_id_is_none_when_empty(registry):
menu = DevTurretMenu(registry)
menu.entity_def_ids = []
assert menu.selected_entity_def_id() is None
# --- DevFactionMenu --------------------------------------------------------------------------------
def test_type_char_builds_up_the_input_text():
menu = DevFactionMenu()
menu.type_char("h")
menu.type_char("i")
assert menu.input_text == "hi"
def test_backspace_removes_the_last_typed_character():
menu = DevFactionMenu()
menu.type_char("h")
menu.type_char("i")
menu.backspace()
assert menu.input_text == "h"
def test_typing_is_capped_at_max_faction_tag_length():
menu = DevFactionMenu()
for ch in "x" * 40:
menu.type_char(ch)
assert len(menu.input_text) == 24
def test_add_tag_appends_the_typed_text_and_clears_the_input(registry):
menu = DevFactionMenu()
character = make_human(registry)
menu.type_char("h")
menu.type_char("o")
menu.type_char("s")
menu.type_char("t")
menu.type_char("i")
menu.type_char("l")
menu.type_char("e")
assert menu.add_tag(character) is True
assert character.factions == ["hostile"]
assert menu.input_text == ""
def test_add_tag_trims_whitespace(registry):
menu = DevFactionMenu()
character = make_human(registry)
for ch in " crew ":
menu.type_char(ch)
menu.add_tag(character)
assert character.factions == ["crew"]
def test_add_tag_is_a_noop_for_blank_input(registry):
menu = DevFactionMenu()
character = make_human(registry)
for ch in " ":
menu.type_char(ch)
assert menu.add_tag(character) is False
assert character.factions == []
def test_add_tag_is_a_noop_for_a_duplicate(registry):
menu = DevFactionMenu()
character = make_human(registry, factions=["crew"])
for ch in "crew":
menu.type_char(ch)
assert menu.add_tag(character) is False
assert character.factions == ["crew"]
def test_cycle_selected_wraps_around(registry):
menu = DevFactionMenu()
character = make_human(registry, factions=["a", "b", "c"])
menu.cycle_selected(character, -1)
assert menu.selected_index == 2
def test_cycle_selected_is_a_noop_without_any_tags(registry):
menu = DevFactionMenu()
character = make_human(registry)
menu.cycle_selected(character, 1)
assert menu.selected_index == 0
def test_remove_selected_removes_the_highlighted_tag(registry):
menu = DevFactionMenu()
character = make_human(registry, factions=["a", "b", "c"])
menu.selected_index = 1
assert menu.remove_selected(character) is True
assert character.factions == ["a", "c"]
def test_remove_selected_clamps_the_index_after_removing_the_last_tag(registry):
menu = DevFactionMenu()
character = make_human(registry, factions=["a", "b"])
menu.selected_index = 1
menu.remove_selected(character)
assert character.factions == ["a"]
assert menu.remove_selected(character) is True
assert character.factions == []
assert menu.selected_index == 0
def test_remove_selected_is_a_noop_without_any_tags(registry):
menu = DevFactionMenu()
character = make_human(registry)
assert menu.remove_selected(character) is False
# --- DevConfig ------------------------------------------------------------------------------------
def test_dev_config_defaults_to_disabled_when_file_missing(tmp_path):
config = DevConfig.load(tmp_path / "does_not_exist.conf")
assert config.enabled is False
def test_dev_config_toggle_flips_the_flag():
config = DevConfig()
config.toggle()
assert config.enabled is True
config.toggle()
assert config.enabled is False
def test_dev_config_save_and_reload_round_trips(tmp_path):
path = tmp_path / "dev.conf"
config = DevConfig(enabled=True)
config.save(path)
reloaded = DevConfig.load(path)
assert reloaded.enabled is True