Tests: test that the game is beatable for WorldTestBases (#1495)
* Tests: test that the game is beatable for WorldTestBases * update docstring * don't test the bases with default options for real this time * invert the property so worlds can use it easier * setup check should be or * test class needs to always be constructed * skip default tests before multiworld setup * check if the calling method is in the base's __dict__ * shorter property and functional setup skipping * shorter property and functional setup skipping
This commit is contained in:
parent
805f33c39e
commit
21fb16291d
|
@ -112,7 +112,11 @@ class WorldTestBase(unittest.TestCase):
|
|||
self.world_setup()
|
||||
|
||||
def world_setup(self, seed: typing.Optional[int] = None) -> None:
|
||||
if type(self) is WorldTestBase:
|
||||
if type(self) is WorldTestBase or \
|
||||
(hasattr(WorldTestBase, self._testMethodName)
|
||||
and not self.run_default_tests and
|
||||
getattr(self, self._testMethodName).__code__ is
|
||||
getattr(WorldTestBase, self._testMethodName, None).__code__):
|
||||
return # setUp gets called for tests defined in the base class. We skip world_setup here.
|
||||
if not hasattr(self, "game"):
|
||||
raise NotImplementedError("didn't define game name")
|
||||
|
@ -208,16 +212,20 @@ class WorldTestBase(unittest.TestCase):
|
|||
|
||||
# following tests are automatically run
|
||||
@property
|
||||
def skip_default_tests(self) -> bool:
|
||||
def run_default_tests(self) -> bool:
|
||||
"""Not possible or identical to the base test that's always being run already"""
|
||||
constructed = hasattr(self, "game") and hasattr(self, "multiworld")
|
||||
return not constructed or (not self.options
|
||||
and self.setUp is WorldTestBase.setUp
|
||||
and self.world_setup is WorldTestBase.world_setup)
|
||||
return (self.options
|
||||
or self.setUp.__code__ is not WorldTestBase.setUp.__code__
|
||||
or self.world_setup.__code__ is not WorldTestBase.world_setup.__code__)
|
||||
|
||||
@property
|
||||
def constructed(self) -> bool:
|
||||
"""A multiworld has been constructed by this point"""
|
||||
return hasattr(self, "game") and hasattr(self, "multiworld")
|
||||
|
||||
def testAllStateCanReachEverything(self):
|
||||
"""Ensure all state can reach everything with the defined options"""
|
||||
if self.skip_default_tests:
|
||||
"""Ensure all state can reach everything and complete the game with the defined options"""
|
||||
if not (self.run_default_tests and self.constructed):
|
||||
return
|
||||
with self.subTest("Game", game=self.game):
|
||||
excluded = self.multiworld.exclude_locations[1].value
|
||||
|
@ -226,10 +234,13 @@ class WorldTestBase(unittest.TestCase):
|
|||
if location.name not in excluded:
|
||||
with self.subTest("Location should be reached", location=location):
|
||||
self.assertTrue(location.can_reach(state), f"{location.name} unreachable")
|
||||
with self.subTest("Beatable"):
|
||||
self.multiworld.state = state
|
||||
self.assertBeatable(True)
|
||||
|
||||
def testEmptyStateCanReachSomething(self):
|
||||
"""Ensure empty state can reach at least one location with the defined options"""
|
||||
if self.skip_default_tests:
|
||||
if not (self.run_default_tests and self.constructed):
|
||||
return
|
||||
with self.subTest("Game", game=self.game):
|
||||
state = CollectionState(self.multiworld)
|
||||
|
|
Loading…
Reference in New Issue