Files

67 lines
2.7 KiB
Python

"""Run with: uv run python -m unittest discover -s tests -v"""
import asyncio
import json
import os
from pathlib import Path
import tempfile
from types import SimpleNamespace
import unittest
from unittest.mock import Mock, patch
os.environ["SDL_VIDEODRIVER"] = "dummy"
os.environ["SDL_AUDIODRIVER"] = "dummy"
import pygame
from src.game import Game
from src.highscore import Highscore
class WebCompatibilityTests(unittest.TestCase):
def test_loop_yields_and_renders_all_screens(self):
async def exercise(state):
game = Game()
game.player_name = "Test Student"
game.state = state
if state == "endscreen":
game.show_endscreen(won=False)
yielded = []
asyncio.get_running_loop().call_soon(yielded.append, True)
await game.run(max_frames=2)
self.assertTrue(yielded, "Game loop must yield to the browser")
with patch.object(Highscore, "load_scores", return_value=[]), patch.object(Highscore, "save_scores"):
for state in ("startscreen", "game", "endscreen"):
asyncio.run(exercise(state))
def test_highscore_storage(self):
pygame.font.init()
with tempfile.TemporaryDirectory() as directory:
path = str(Path(directory) / "scores.json")
scores = Highscore(path)
self.assertEqual(scores.load_scores(), [])
scores.add_score("Desktop", 5, 12, False)
self.assertEqual(Highscore(path).load_scores()[0]["name"], "Desktop")
storage = {}
window = SimpleNamespace(localStorage=SimpleNamespace(
getItem=storage.get,
setItem=storage.__setitem__,
))
with patch("src.highscore.sys.platform", "emscripten"), patch("src.highscore.window", window, create=True):
scores.add_score("Browser", 10, 20, False)
Path(path).unlink() # Simulate a fresh browser virtual filesystem.
self.assertEqual(Highscore(path).get_top_scores()[0]["name"], "Browser")
self.assertEqual(len(json.loads(storage[f"silent-fh:{path}"])), 2)
storage[f"silent-fh:{path}"] = "invalid json"
self.assertEqual(scores.load_scores(), [])
scores.save_scores([])
window.localStorage.getItem = Mock(side_effect=RuntimeError("blocked"))
window.localStorage.setItem = Mock(side_effect=RuntimeError("blocked"))
scores.add_score("Fallback", 1, 1, False)
self.assertEqual(scores.load_scores()[0]["name"], "Fallback")
pygame.quit()
if __name__ == "__main__":
unittest.main()