2021-11-11 00:06:51 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import unittest
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-13 19:15:35 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-05 23:48:03 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from BaseClasses import CollectionState
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-13 19:15:35 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from worlds.AutoWorld import AutoWorldRegister, call_all
							 | 
						
					
						
							
								
									
										
										
										
											2023-02-15 15:46:10 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from . import setup_solo_multiworld
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-11 00:06:51 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class TestBase(unittest.TestCase):
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-22 06:00:27 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def test_create_item(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        """Test that a world can successfully create all items in its datapackage"""
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-11 00:06:51 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for game_name, world_type in AutoWorldRegister.world_types.items():
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-05 23:48:03 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            multiworld = setup_solo_multiworld(world_type, steps=("generate_early", "create_regions", "create_items"))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            proxy_world = multiworld.worlds[1]
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-11 00:06:51 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for item_name in world_type.item_name_to_id:
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-05 23:48:03 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                test_state = CollectionState(multiworld)
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-11 00:06:51 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                with self.subTest("Create Item", item_name=item_name, game_name=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    item = proxy_world.create_item(item_name)
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-05 23:48:03 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                with self.subTest("Item Name", item_name=item_name, game_name=game_name):
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-11 00:06:51 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    self.assertEqual(item.name, item_name)
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-01 17:25:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-05 23:48:03 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if item.advancement:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    with self.subTest("Item State Collect", item_name=item_name, game_name=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        test_state.collect(item, True)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    with self.subTest("Item State Remove", item_name=item_name, game_name=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        test_state.remove(item)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        self.assertEqual(test_state.prog_items, multiworld.state.prog_items,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                         "Item Collect -> Remove should restore empty state.")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    with self.subTest("Item State Collect No Change", item_name=item_name, game_name=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        # Non-Advancement should not modify state.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        test_state.collect(item)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        self.assertEqual(test_state.prog_items, multiworld.state.prog_items)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-22 06:00:27 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def test_item_name_group_has_valid_item(self):
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-01 17:25:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        """Test that all item name groups contain valid items. """
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # This cannot test for Event names that you may have declared for logic, only sendable Items.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # In such a case, you can add your entries to this Exclusion dict. Game Name -> Group Names
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        exclusion_dict = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "A Link to the Past":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {"Pendants", "Crystals"},
							 | 
						
					
						
							
								
									
										
										
										
											2022-11-09 15:07:14 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "Ocarina of Time":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {"medallions", "stones", "rewards", "logic_bottles"},
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-15 17:33:03 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "Starcraft 2":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {"Missions", "WoL Missions"},
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-17 19:23:05 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "Yu-Gi-Oh! 2006":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                {"Campaign Boss Beaten"}
							 | 
						
					
						
							
								
									
										
										
										
											2022-06-01 17:25:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for game_name, world_type in AutoWorldRegister.world_types.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            with self.subTest(game_name, game_name=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                exclusions = exclusion_dict.get(game_name, frozenset())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for group_name, items in world_type.item_name_groups.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if group_name not in exclusions:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        with self.subTest(group_name, group_name=group_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            for item in items:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                self.assertIn(item, world_type.item_name_to_id)
							 | 
						
					
						
							
								
									
										
										
										
											2022-09-05 01:02:40 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2023-10-22 06:00:27 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def test_item_name_group_conflict(self):
							 | 
						
					
						
							
								
									
										
										
										
											2023-01-18 15:45:48 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        """Test that all item name groups aren't also item names."""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for game_name, world_type in AutoWorldRegister.world_types.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            with self.subTest(game_name, game_name=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for group_name in world_type.item_name_groups:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    with self.subTest(group_name, group_name=group_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        self.assertNotIn(group_name, world_type.item_name_to_id)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-30 08:00:47 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def test_item_count_equal_locations(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        """Test that by the pre_fill step under default settings, each game submits items == locations"""
							 | 
						
					
						
							
								
									
										
										
										
											2022-09-05 01:02:40 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        for game_name, world_type in AutoWorldRegister.world_types.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            with self.subTest("Game", game=game_name):
							 | 
						
					
						
							
								
									
										
										
										
											2023-02-15 15:46:10 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                multiworld = setup_solo_multiworld(world_type)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-30 08:00:47 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                self.assertEqual(
							 | 
						
					
						
							
								
									
										
										
										
											2023-02-15 15:46:10 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    len(multiworld.itempool),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    len(multiworld.get_unfilled_locations()),
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-30 08:00:47 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    f"{game_name} Item count MUST match the number of locations",
							 | 
						
					
						
							
								
									
										
										
										
											2022-09-05 01:02:40 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                )
							 | 
						
					
						
							
								
									
										
										
										
											2023-02-15 15:46:10 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-13 19:15:35 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def test_items_in_datapackage(self):
							 | 
						
					
						
							
								
									
										
										
										
											2023-02-15 15:46:10 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        """Test that any created items in the itempool are in the datapackage"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for game_name, world_type in AutoWorldRegister.world_types.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            with self.subTest("Game", game=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                multiworld = setup_solo_multiworld(world_type)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for item in multiworld.itempool:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    self.assertIn(item.name, world_type.item_name_to_id)
							 | 
						
					
						
							
								
									
										
										
										
											2023-11-15 07:26:10 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-13 19:15:35 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def test_itempool_not_modified(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        """Test that worlds don't modify the itempool after `create_items`"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        gen_steps = ("generate_early", "create_regions", "create_items")
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-20 16:07:15 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        additional_steps = ("set_rules", "connect_entrances", "generate_basic", "pre_fill")
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-13 19:15:35 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        excluded_games = ("Links Awakening DX", "Ocarina of Time", "SMZ3")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        worlds_to_test = {game: world
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                          for game, world in AutoWorldRegister.world_types.items() if game not in excluded_games}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for game_name, world_type in worlds_to_test.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            with self.subTest("Game", game=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                multiworld = setup_solo_multiworld(world_type, gen_steps)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                created_items = multiworld.itempool.copy()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for step in additional_steps:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    with self.subTest("step", step=step):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        call_all(multiworld, step)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        self.assertEqual(created_items, multiworld.itempool,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                         f"{game_name} modified the itempool during {step}")
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-29 16:57:35 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def test_locality_not_modified(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        """Test that worlds don't modify the locality of items after duplicates are resolved"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        gen_steps = ("generate_early", "create_regions", "create_items")
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-20 16:07:15 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        additional_steps = ("set_rules", "connect_entrances", "generate_basic", "pre_fill")
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-29 16:57:35 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        worlds_to_test = {game: world for game, world in AutoWorldRegister.world_types.items()}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for game_name, world_type in worlds_to_test.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            with self.subTest("Game", game=game_name):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                multiworld = setup_solo_multiworld(world_type, gen_steps)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                local_items = multiworld.worlds[1].options.local_items.value.copy()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                non_local_items = multiworld.worlds[1].options.non_local_items.value.copy()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for step in additional_steps:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    with self.subTest("step", step=step):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        call_all(multiworld, step)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        self.assertEqual(local_items, multiworld.worlds[1].options.local_items.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                         f"{game_name} modified local_items during {step}")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        self.assertEqual(non_local_items, multiworld.worlds[1].options.non_local_items.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                         f"{game_name} modified non_local_items during {step}")
							 |