"""Offline tests of apptest's retry/slot logic (no game needed): python3 -m unittest tools/test_apptest.py""" import os import sys import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import apptest as A # noqa: E402 class FakeSession: def __init__(self, outcomes): self.outcomes = list(outcomes) # per start: None ok, or exception raised by start/tolevel self.data = tempfile.mkdtemp() self.starts = self.stops = 0 def start(self): self.starts += 1 o = self.outcomes.pop(0) if isinstance(o, A.Crash) and "start" in str(o): raise o self._next = o def tolevel(self, world=None, slot=3, on_menu=None): o = self._next if isinstance(o, A.Crash) and "level" in str(o): on_menu() raise o if o: raise o on_menu() return {"slot": slot} def shot(self, path, small=False): open(path, "w").close() def stop(self): self.stops += 1 class StartRetryTest(unittest.TestCase): def setUp(self): self.out = tempfile.mkdtemp() def test_early_crash_is_retried_once_and_reported(self): s, rep = FakeSession([A.Crash("start: page fault"), None]), {} A.start_to_level(s, (1, 1), self.out, rep) self.assertEqual(2, s.starts) self.assertEqual([{"attempt": 1, "phase": "start", "error": "start: page fault"}], rep["retries"]) self.assertEqual({"slot": 2}, rep["tolevel"]) self.assertTrue(os.path.exists(os.path.join(self.out, "retry1_failure.jpg"))) def test_missed_slot_screen_is_retried(self): s, rep = FakeSession([A.Timeout("timeout (45 s) waiting for save slot screen"), None]), {} A.start_to_level(s, (1, 1), self.out, rep) self.assertEqual("menu", rep["retries"][0]["phase"]) def test_crash_after_the_menu_is_not_retried(self): s, rep = FakeSession([A.Crash("level: page fault"), None]), {} with self.assertRaises(A.Crash): A.start_to_level(s, (1, 1), self.out, rep) self.assertEqual(1, s.starts) self.assertNotIn("retries", rep) def test_second_failure_and_no_retry_raise(self): s = FakeSession([A.Crash("start: a"), A.Crash("start: b")]) with self.assertRaises(A.Crash): A.start_to_level(s, None, self.out, {}) self.assertEqual(2, s.starts) s = FakeSession([A.Crash("start: a"), None]) with self.assertRaises(A.Crash): A.start_to_level(s, None, self.out, {}, retry=False) class SlotTextTest(unittest.TestCase): def test_slot_number_and_content(self): S = A.Session self.assertEqual(2, S._slot_no(". gespeichertes spiel 2 u leer | gespeichertes spiel 2 u leer")) self.assertEqual(3, S._slot_no("gespeichertes spiel 3 dorf kapitel 1")) self.assertIsNone(S._slot_no("eingabe neues spiel starten")) self.assertTrue(S._slot_ok("gespeichertes spiel 2 u testlevel kapitel 1 goldmünzen")) self.assertFalse(S._slot_ok("gespeichertes spiel 2 u leer")) if __name__ == "__main__": unittest.main()