Add DAT finale flow, editor, and new soundtrack assets
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
from engine import maze
|
||||
from rats import (
|
||||
GAME_END_LEVEL_CLEAR,
|
||||
GAME_END_RUN_COMPLETE,
|
||||
MiceMaze,
|
||||
RUN_COMPLETE_MUSIC,
|
||||
)
|
||||
|
||||
|
||||
def build_dummy(level_index):
|
||||
dummy = MiceMaze.__new__(MiceMaze)
|
||||
dummy.map = SimpleNamespace(source_path=Path("/tmp/level.dat"))
|
||||
dummy.current_level = level_index
|
||||
dummy.total_levels = maze.DEFAULT_LEVELS_PER_DAT_FILE
|
||||
dummy.points = 1234
|
||||
dummy.run_recorded = False
|
||||
dummy.combined_scores = None
|
||||
dummy.game_status = "game"
|
||||
dummy.game_end = (False, None)
|
||||
dummy.menu_screen = None
|
||||
dummy.units = {}
|
||||
dummy.assets = {"BMP_WEWIN": object(), "end": object()}
|
||||
dummy.explosions = {"LEFT": object(), "RIGHT": object(), "UP": object(), "DOWN": object()}
|
||||
dummy.count_rats = lambda: 0
|
||||
dummy.start_menu_animation_started_at = 0
|
||||
dummy._difficulty_config = lambda: {"label": "Hard"}
|
||||
|
||||
sounds = []
|
||||
dialogs = []
|
||||
stats = []
|
||||
saves = []
|
||||
load_calls = []
|
||||
|
||||
dummy.render_engine = SimpleNamespace(
|
||||
stop_sound=lambda: sounds.append(("stop",)),
|
||||
play_sound=lambda *args, **kwargs: sounds.append((args, kwargs)),
|
||||
dialog=lambda *args, **kwargs: dialogs.append((args, kwargs)),
|
||||
)
|
||||
dummy.profile_integration = SimpleNamespace(
|
||||
update_game_stats=lambda score, completed=True: stats.append((score, completed)) or True,
|
||||
get_device_leaderboard=lambda limit: [{"user_id": "Player1", "best_score": 1234}][:limit],
|
||||
get_profile_name=lambda: "Player1",
|
||||
)
|
||||
dummy.save_score = lambda: saves.append(dummy.points)
|
||||
dummy.load_level = lambda *args, **kwargs: load_calls.append((args, kwargs))
|
||||
|
||||
return dummy, dialogs, stats, saves, load_calls
|
||||
|
||||
|
||||
class FinalLevelFlowTests(unittest.TestCase):
|
||||
def test_debug_flag_helper_opens_final_dialog_without_recording_score(self):
|
||||
dummy, _, stats, saves, _ = build_dummy(3)
|
||||
|
||||
dummy.activate_debug_run_complete_dialog(score=777)
|
||||
|
||||
self.assertEqual(dummy.current_level, dummy.total_levels - 1)
|
||||
self.assertEqual(dummy.points, 777)
|
||||
self.assertEqual(dummy.game_end, (True, GAME_END_RUN_COMPLETE))
|
||||
self.assertTrue(dummy.run_recorded)
|
||||
self.assertEqual(dummy.game_status, "paused")
|
||||
self.assertEqual(stats, [])
|
||||
self.assertEqual(saves, [])
|
||||
|
||||
def test_run_complete_screen_uses_dedicated_music(self):
|
||||
dummy, _, _, _, _ = build_dummy(3)
|
||||
music_calls = []
|
||||
dummy.render_engine.play_music = lambda track, loop=True: music_calls.append((track, loop)) or True
|
||||
dummy.render_engine.pause_music = lambda: music_calls.append(("pause", False))
|
||||
dummy.game_end = (True, GAME_END_RUN_COMPLETE)
|
||||
|
||||
dummy.update_background_music()
|
||||
|
||||
self.assertEqual(music_calls, [(RUN_COMPLETE_MUSIC, True)])
|
||||
|
||||
def test_advance_level_does_not_wrap_after_last_dat_level(self):
|
||||
dummy, _, stats, saves, load_calls = build_dummy(maze.DEFAULT_LEVELS_PER_DAT_FILE - 1)
|
||||
|
||||
dummy.advance_level()
|
||||
|
||||
self.assertEqual(dummy.game_end, (True, GAME_END_RUN_COMPLETE))
|
||||
self.assertTrue(dummy.run_recorded)
|
||||
self.assertEqual(stats, [(1234, True)])
|
||||
self.assertEqual(saves, [1234])
|
||||
self.assertEqual(load_calls, [])
|
||||
|
||||
def test_regular_level_clear_keeps_run_open(self):
|
||||
dummy, _, stats, saves, _ = build_dummy(4)
|
||||
|
||||
result = dummy.game_over()
|
||||
|
||||
self.assertTrue(result)
|
||||
self.assertEqual(dummy.game_end, (True, GAME_END_LEVEL_CLEAR))
|
||||
self.assertFalse(dummy.run_recorded)
|
||||
self.assertEqual(dummy.combined_scores, [{"user_id": "Player1", "best_score": 1234}])
|
||||
self.assertEqual(stats, [])
|
||||
self.assertEqual(saves, [])
|
||||
|
||||
def test_final_dat_level_records_score_and_shows_dedicated_dialog(self):
|
||||
dummy, dialogs, stats, saves, _ = build_dummy(maze.DEFAULT_LEVELS_PER_DAT_FILE - 1)
|
||||
|
||||
result = dummy.game_over()
|
||||
|
||||
self.assertTrue(result)
|
||||
self.assertEqual(dummy.game_end, (True, GAME_END_RUN_COMPLETE))
|
||||
self.assertTrue(dummy.run_recorded)
|
||||
self.assertEqual(stats, [(1234, True)])
|
||||
self.assertEqual(saves, [1234])
|
||||
self.assertEqual(dummy.combined_scores, [{"user_id": "Player1", "best_score": 1234}])
|
||||
|
||||
dummy.game_over()
|
||||
|
||||
self.assertEqual(dialogs[-1][0][0], "THE END")
|
||||
self.assertEqual(dialogs[-1][1]["style"], "run_complete")
|
||||
self.assertEqual(dialogs[-1][1]["current_score"], 1234)
|
||||
self.assertIs(dialogs[-1][1]["image"], dummy.assets["end"])
|
||||
|
||||
def test_return_after_final_dialog_goes_back_to_start_menu(self):
|
||||
dummy, _, _, _, load_calls = build_dummy(maze.DEFAULT_LEVELS_PER_DAT_FILE - 1)
|
||||
dummy.game_end = (True, GAME_END_RUN_COMPLETE)
|
||||
dummy.game_status = "paused"
|
||||
|
||||
dummy.reset_game()
|
||||
|
||||
self.assertEqual(
|
||||
load_calls,
|
||||
[((0,), {"preserve_points": False, "show_menu": True, "menu_screen": "start"})],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user