mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 12:11:33 -06:00
Tests: add test for 2-player-multiworlds (#2386)
* Tests: add test for all games multiworld and test for two player multiworld per game * make assertSteps behave like call_all * review improvements * fix stage calling and loc copying in accessibility * add docstrings * lttp is on the options api now * skip the all games multiworld for now. likely needs to be modified to test specific worlds * move skip to the class
This commit is contained in:
0
test/multiworld/__init__.py
Normal file
0
test/multiworld/__init__.py
Normal file
77
test/multiworld/test_multiworlds.py
Normal file
77
test/multiworld/test_multiworlds.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import unittest
|
||||
from typing import List, Tuple
|
||||
from unittest import TestCase
|
||||
|
||||
from BaseClasses import CollectionState, Location, MultiWorld
|
||||
from Fill import distribute_items_restrictive
|
||||
from Options import Accessibility
|
||||
from worlds.AutoWorld import AutoWorldRegister, call_all, call_single
|
||||
from ..general import gen_steps, setup_multiworld
|
||||
|
||||
|
||||
class MultiworldTestBase(TestCase):
|
||||
multiworld: MultiWorld
|
||||
|
||||
# similar to the implementation in WorldTestBase.test_fill
|
||||
# but for multiple players and doesn't allow minimal accessibility
|
||||
def fulfills_accessibility(self) -> bool:
|
||||
"""
|
||||
Checks that the multiworld satisfies locations accessibility requirements, failing if all locations are cleared
|
||||
but not beatable, or some locations are unreachable.
|
||||
"""
|
||||
locations = [loc for loc in self.multiworld.get_locations()]
|
||||
state = CollectionState(self.multiworld)
|
||||
while locations:
|
||||
sphere: List[Location] = []
|
||||
for n in range(len(locations) - 1, -1, -1):
|
||||
if locations[n].can_reach(state):
|
||||
sphere.append(locations.pop(n))
|
||||
self.assertTrue(sphere, f"Unreachable locations: {locations}")
|
||||
if not sphere:
|
||||
return False
|
||||
for location in sphere:
|
||||
if location.item:
|
||||
state.collect(location.item, True, location)
|
||||
return self.multiworld.has_beaten_game(state, 1)
|
||||
|
||||
def assertSteps(self, steps: Tuple[str, ...]) -> None:
|
||||
"""Calls each step individually, continuing if a step for a specific world step fails."""
|
||||
world_types = {world.__class__ for world in self.multiworld.worlds.values()}
|
||||
for step in steps:
|
||||
for player, world in self.multiworld.worlds.items():
|
||||
with self.subTest(game=world.game, step=step):
|
||||
call_single(self.multiworld, step, player)
|
||||
for world_type in sorted(world_types, key=lambda world: world.__name__):
|
||||
with self.subTest(game=world_type.game, step=f"stage_{step}"):
|
||||
stage_callable = getattr(world_type, f"stage_{step}", None)
|
||||
if stage_callable:
|
||||
stage_callable(self.multiworld)
|
||||
|
||||
|
||||
@unittest.skip("too slow for main")
|
||||
class TestAllGamesMultiworld(MultiworldTestBase):
|
||||
def test_fills(self) -> None:
|
||||
"""Tests that a multiworld with one of every registered game world can generate."""
|
||||
all_worlds = list(AutoWorldRegister.world_types.values())
|
||||
self.multiworld = setup_multiworld(all_worlds, ())
|
||||
for world in self.multiworld.worlds.values():
|
||||
world.options.accessibility.value = Accessibility.option_locations
|
||||
self.assertSteps(gen_steps)
|
||||
with self.subTest("filling multiworld", seed=self.multiworld.seed):
|
||||
distribute_items_restrictive(self.multiworld)
|
||||
call_all(self.multiworld, "post_fill")
|
||||
self.assertTrue(self.fulfills_accessibility(), "Collected all locations, but can't beat the game")
|
||||
|
||||
|
||||
class TestTwoPlayerMulti(MultiworldTestBase):
|
||||
def test_two_player_single_game_fills(self) -> None:
|
||||
"""Tests that a multiworld of two players for each registered game world can generate."""
|
||||
for world in AutoWorldRegister.world_types.values():
|
||||
self.multiworld = setup_multiworld([world, world], ())
|
||||
for world in self.multiworld.worlds.values():
|
||||
world.options.accessibility.value = Accessibility.option_locations
|
||||
self.assertSteps(gen_steps)
|
||||
with self.subTest("filling multiworld", seed=self.multiworld.seed):
|
||||
distribute_items_restrictive(self.multiworld)
|
||||
call_all(self.multiworld, "post_fill")
|
||||
self.assertTrue(self.fulfills_accessibility(), "Collected all locations, but can't beat the game")
|
Reference in New Issue
Block a user