exorcist-game/tests/test_main.py
Jarian 7ec5ae1664 fix: batch fix all 14 issues
- Fix memory test infinite loop (#1, #3) — add max iterations counter
- Fix os.system command injection (#2, #4) — use subprocess with list args
- Fix demon difficulty scaling (#5) — scale health/damage per cycle
- Fix relative import (#6) — absolute imports with sys.path fallback
- Fix normalize_text non-ASCII (#7) — use isalpha/isdigit instead of isalnum
- Fix calculate_similarity word order (#8) — set-based intersection
- Add CMD to Dockerfile (#9)
- Remove test files from prod image (#10) — .dockerignore + strip tests COPY
- Fix test class import (#11) — lazy import in test methods
- Fix pyproject.toml duplicate pytest (#12) — move to dev optional deps
- Add resource limits to compose (#13)
- Fix verses.json quality (#14) — fix garbled verse text
2026-07-05 22:22:41 +00:00

102 lines
3.2 KiB
Python

"""Tests for main game module validation."""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from data import load_verses, normalize_text
from main import calculate_similarity, get_hint
class TestCalculateSimilarity:
"""Tests for string similarity calculation used in partial credit."""
def test_identical_strings(self) -> None:
"""Identical normalized strings have 1.0 similarity."""
text = "hello world"
assert calculate_similarity(text, text) == 1.0
def test_completely_different(self) -> None:
"""Completely different strings have 0.0 similarity."""
assert calculate_similarity("abc", "xyz") == 0.0
def test_partial_match(self) -> None:
"""Partially matching strings have intermediate similarity."""
sim = calculate_similarity("hello world", "hello there")
assert 0.0 < sim < 1.0
def test_empty_strings(self) -> None:
"""Two empty strings have 1.0 similarity."""
assert calculate_similarity("", "") == 1.0
def test_one_empty(self) -> None:
"""One empty and one non-empty string have 0.0 similarity."""
assert calculate_similarity("hello", "") == 0.0
assert calculate_similarity("", "hello") == 0.0
class TestGetHint:
"""Tests for hint generation showing first letters."""
def test_basic_hint(self) -> None:
"""Hint shows first letter of each word."""
hint = get_hint("Hello world")
assert hint == "H w"
def test_full_verse_hint(self) -> None:
"""Hint works with full verse text."""
verse = "I have given you authority to trample"
hint = get_hint(verse)
assert hint == "I h g y a t t"
def test_single_word(self) -> None:
"""Single word returns its first letter."""
assert get_hint("Hello") == "H"
class TestGameInitialization:
"""Tests for game initialization and state."""
def test_verses_load(self) -> None:
"""Game can load verses without error."""
verses = load_verses()
assert len(verses) > 0
def test_starting_verses(self) -> None:
"""Starting verses (difficulty 1) are available."""
verses = load_verses()
easy = [v for v in verses if v["difficulty"] == 1]
assert len(easy) >= 4
def test_normalize_consistency(self) -> None:
"""Normalization is consistent across calls."""
text = "The Lord is my light and my salvation."
assert normalize_text(text) == normalize_text(text)
class TestDemonData:
"""Tests for demon encounter data."""
def test_demons_exist(self) -> None:
"""Demon list is populated."""
from main import DEMONS
assert len(DEMONS) > 0
def test_demon_structure(self) -> None:
"""Each demon has required fields."""
from main import DEMONS
required = {"name", "health", "weaknesses", "damage"}
for demon in DEMONS:
assert required.issubset(demon.keys())
def test_escalating_difficulty(self) -> None:
"""Demons have escalating health values."""
from main import DEMONS
healths = [d["health"] for d in DEMONS]
for i in range(1, len(healths)):
assert healths[i] > healths[i - 1]