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()
|
self.world_setup()
|
||||||
|
|
||||||
def world_setup(self, seed: typing.Optional[int] = None) -> None:
|
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.
|
return # setUp gets called for tests defined in the base class. We skip world_setup here.
|
||||||
if not hasattr(self, "game"):
|
if not hasattr(self, "game"):
|
||||||
raise NotImplementedError("didn't define game name")
|
raise NotImplementedError("didn't define game name")
|
||||||
|
@ -208,16 +212,20 @@ class WorldTestBase(unittest.TestCase):
|
||||||
|
|
||||||
# following tests are automatically run
|
# following tests are automatically run
|
||||||
@property
|
@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"""
|
"""Not possible or identical to the base test that's always being run already"""
|
||||||
constructed = hasattr(self, "game") and hasattr(self, "multiworld")
|
return (self.options
|
||||||
return not constructed or (not self.options
|
or self.setUp.__code__ is not WorldTestBase.setUp.__code__
|
||||||
and self.setUp is WorldTestBase.setUp
|
or self.world_setup.__code__ is not WorldTestBase.world_setup.__code__)
|
||||||
and self.world_setup is WorldTestBase.world_setup)
|
|
||||||
|
@property
|
||||||
|
def constructed(self) -> bool:
|
||||||
|
"""A multiworld has been constructed by this point"""
|
||||||
|
return hasattr(self, "game") and hasattr(self, "multiworld")
|
||||||
|
|
||||||
def testAllStateCanReachEverything(self):
|
def testAllStateCanReachEverything(self):
|
||||||
"""Ensure all state can reach everything with the defined options"""
|
"""Ensure all state can reach everything and complete the game with the defined options"""
|
||||||
if self.skip_default_tests:
|
if not (self.run_default_tests and self.constructed):
|
||||||
return
|
return
|
||||||
with self.subTest("Game", game=self.game):
|
with self.subTest("Game", game=self.game):
|
||||||
excluded = self.multiworld.exclude_locations[1].value
|
excluded = self.multiworld.exclude_locations[1].value
|
||||||
|
@ -226,10 +234,13 @@ class WorldTestBase(unittest.TestCase):
|
||||||
if location.name not in excluded:
|
if location.name not in excluded:
|
||||||
with self.subTest("Location should be reached", location=location):
|
with self.subTest("Location should be reached", location=location):
|
||||||
self.assertTrue(location.can_reach(state), f"{location.name} unreachable")
|
self.assertTrue(location.can_reach(state), f"{location.name} unreachable")
|
||||||
|
with self.subTest("Beatable"):
|
||||||
|
self.multiworld.state = state
|
||||||
|
self.assertBeatable(True)
|
||||||
|
|
||||||
def testEmptyStateCanReachSomething(self):
|
def testEmptyStateCanReachSomething(self):
|
||||||
"""Ensure empty state can reach at least one location with the defined options"""
|
"""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
|
return
|
||||||
with self.subTest("Game", game=self.game):
|
with self.subTest("Game", game=self.game):
|
||||||
state = CollectionState(self.multiworld)
|
state = CollectionState(self.multiworld)
|
||||||
|
|
Loading…
Reference in New Issue