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