| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2023-10-28 00:18:33 +02:00
										 |  |  | import unittest | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | from argparse import Namespace | 
					
						
							|  |  |  | from typing import Dict, FrozenSet, Tuple, Any, ClassVar | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | from BaseClasses import MultiWorld | 
					
						
							| 
									
										
										
										
											2023-10-28 00:18:33 +02:00
										 |  |  | from Utils import cache_argsless | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | from test.TestBase import WorldTestBase | 
					
						
							| 
									
										
										
										
											2023-07-30 13:17:12 -05:00
										 |  |  | from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld | 
					
						
							| 
									
										
										
										
											2023-10-10 15:30:20 -05:00
										 |  |  | from .. import StardewValleyWorld | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  | from ..mods.mod_data import ModNames | 
					
						
							| 
									
										
										
										
											2023-07-30 13:17:12 -05:00
										 |  |  | from worlds.AutoWorld import call_all | 
					
						
							| 
									
										
										
										
											2023-10-10 15:30:20 -05:00
										 |  |  | from ..options import Cropsanity, SkillProgression, SpecialOrderLocations, Friendsanity, NumberOfLuckBuffs, SeasonRandomization, ToolProgression, \ | 
					
						
							|  |  |  |     ElevatorProgression, Museumsanity, BackpackProgression, BuildingProgression, ArcadeMachineLocations, HelpWantedLocations, Fishsanity, NumberOfMovementBuffs, \ | 
					
						
							|  |  |  |     BundleRandomization, BundlePrice, FestivalLocations, FriendsanityHeartSize, ExcludeGingerIsland, TrapItems, Goal, Mods | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 00:18:33 +02:00
										 |  |  | class SVTestCase(unittest.TestCase): | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |     player: ClassVar[int] = 1 | 
					
						
							| 
									
										
										
										
											2023-10-28 00:18:33 +02:00
										 |  |  |     """Set to False to not skip some 'extra' tests""" | 
					
						
							|  |  |  |     skip_extra_tests: bool = True | 
					
						
							|  |  |  |     """Set to False to run tests that take long""" | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |     skip_long_tests: bool = True | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 00:18:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class SVTestBase(WorldTestBase, SVTestCase): | 
					
						
							|  |  |  |     game = "Stardew Valley" | 
					
						
							|  |  |  |     world: StardewValleyWorld | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |     def world_setup(self, *args, **kwargs): | 
					
						
							|  |  |  |         super().world_setup(*args, **kwargs) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         long_tests_key = "long" | 
					
						
							|  |  |  |         if long_tests_key in os.environ: | 
					
						
							|  |  |  |             self.skip_long_tests = not bool(os.environ[long_tests_key]) | 
					
						
							| 
									
										
										
										
											2023-03-04 12:34:51 -05:00
										 |  |  |         if self.constructed: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             self.world = self.multiworld.worlds[self.player]  # noqa | 
					
						
							| 
									
										
										
										
											2023-03-04 12:34:51 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def run_default_tests(self) -> bool: | 
					
						
							|  |  |  |         # world_setup is overridden, so it'd always run default tests when importing SVTestBase | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         is_not_stardew_test = type(self) is not SVTestBase | 
					
						
							|  |  |  |         should_run_default_tests = is_not_stardew_test and super().run_default_tests | 
					
						
							|  |  |  |         return should_run_default_tests | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 00:18:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | @cache_argsless | 
					
						
							|  |  |  | def minimal_locations_maximal_items(): | 
					
						
							|  |  |  |     min_max_options = { | 
					
						
							|  |  |  |         SeasonRandomization.internal_name: SeasonRandomization.option_randomized, | 
					
						
							| 
									
										
										
										
											2023-11-18 13:35:57 -05:00
										 |  |  |         Cropsanity.internal_name: Cropsanity.option_enabled, | 
					
						
							| 
									
										
										
										
											2023-10-28 00:18:33 +02:00
										 |  |  |         BackpackProgression.internal_name: BackpackProgression.option_vanilla, | 
					
						
							|  |  |  |         ToolProgression.internal_name: ToolProgression.option_vanilla, | 
					
						
							|  |  |  |         SkillProgression.internal_name: SkillProgression.option_vanilla, | 
					
						
							|  |  |  |         BuildingProgression.internal_name: BuildingProgression.option_vanilla, | 
					
						
							|  |  |  |         ElevatorProgression.internal_name: ElevatorProgression.option_vanilla, | 
					
						
							|  |  |  |         ArcadeMachineLocations.internal_name: ArcadeMachineLocations.option_disabled, | 
					
						
							|  |  |  |         SpecialOrderLocations.internal_name: SpecialOrderLocations.option_disabled, | 
					
						
							|  |  |  |         HelpWantedLocations.internal_name: 0, | 
					
						
							|  |  |  |         Fishsanity.internal_name: Fishsanity.option_none, | 
					
						
							|  |  |  |         Museumsanity.internal_name: Museumsanity.option_none, | 
					
						
							|  |  |  |         Friendsanity.internal_name: Friendsanity.option_none, | 
					
						
							|  |  |  |         NumberOfMovementBuffs.internal_name: 12, | 
					
						
							|  |  |  |         NumberOfLuckBuffs.internal_name: 12, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return min_max_options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cache_argsless | 
					
						
							|  |  |  | def allsanity_options_without_mods(): | 
					
						
							|  |  |  |     allsanity = { | 
					
						
							|  |  |  |         Goal.internal_name: Goal.option_perfection, | 
					
						
							|  |  |  |         BundleRandomization.internal_name: BundleRandomization.option_shuffled, | 
					
						
							|  |  |  |         BundlePrice.internal_name: BundlePrice.option_expensive, | 
					
						
							|  |  |  |         SeasonRandomization.internal_name: SeasonRandomization.option_randomized, | 
					
						
							| 
									
										
										
										
											2023-11-18 13:35:57 -05:00
										 |  |  |         Cropsanity.internal_name: Cropsanity.option_enabled, | 
					
						
							| 
									
										
										
										
											2023-10-28 00:18:33 +02:00
										 |  |  |         BackpackProgression.internal_name: BackpackProgression.option_progressive, | 
					
						
							|  |  |  |         ToolProgression.internal_name: ToolProgression.option_progressive, | 
					
						
							|  |  |  |         SkillProgression.internal_name: SkillProgression.option_progressive, | 
					
						
							|  |  |  |         BuildingProgression.internal_name: BuildingProgression.option_progressive, | 
					
						
							|  |  |  |         FestivalLocations.internal_name: FestivalLocations.option_hard, | 
					
						
							|  |  |  |         ElevatorProgression.internal_name: ElevatorProgression.option_progressive, | 
					
						
							|  |  |  |         ArcadeMachineLocations.internal_name: ArcadeMachineLocations.option_full_shuffling, | 
					
						
							|  |  |  |         SpecialOrderLocations.internal_name: SpecialOrderLocations.option_board_qi, | 
					
						
							|  |  |  |         HelpWantedLocations.internal_name: 56, | 
					
						
							|  |  |  |         Fishsanity.internal_name: Fishsanity.option_all, | 
					
						
							|  |  |  |         Museumsanity.internal_name: Museumsanity.option_all, | 
					
						
							|  |  |  |         Friendsanity.internal_name: Friendsanity.option_all_with_marriage, | 
					
						
							|  |  |  |         FriendsanityHeartSize.internal_name: 1, | 
					
						
							|  |  |  |         NumberOfMovementBuffs.internal_name: 12, | 
					
						
							|  |  |  |         NumberOfLuckBuffs.internal_name: 12, | 
					
						
							|  |  |  |         ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_false, | 
					
						
							|  |  |  |         TrapItems.internal_name: TrapItems.option_nightmare, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return allsanity | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @cache_argsless | 
					
						
							|  |  |  | def allsanity_options_with_mods(): | 
					
						
							|  |  |  |     allsanity = {} | 
					
						
							|  |  |  |     allsanity.update(allsanity_options_without_mods()) | 
					
						
							|  |  |  |     all_mods = ( | 
					
						
							|  |  |  |         ModNames.deepwoods, ModNames.tractor, ModNames.big_backpack, | 
					
						
							|  |  |  |         ModNames.luck_skill, ModNames.magic, ModNames.socializing_skill, ModNames.archaeology, | 
					
						
							|  |  |  |         ModNames.cooking_skill, ModNames.binning_skill, ModNames.juna, | 
					
						
							|  |  |  |         ModNames.jasper, ModNames.alec, ModNames.yoba, ModNames.eugene, | 
					
						
							|  |  |  |         ModNames.wellwick, ModNames.ginger, ModNames.shiko, ModNames.delores, | 
					
						
							|  |  |  |         ModNames.ayeisha, ModNames.riley, ModNames.skull_cavern_elevator | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     allsanity.update({Mods.internal_name: all_mods}) | 
					
						
							|  |  |  |     return allsanity | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | pre_generated_worlds = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Mostly a copy of test.general.setup_solo_multiworld, I just don't want to change the core. | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  | def setup_solo_multiworld(test_options=None, seed=None, | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                           _cache: Dict[FrozenSet[Tuple[str, Any]], MultiWorld] = {}) -> MultiWorld:  # noqa | 
					
						
							|  |  |  |     if test_options is None: | 
					
						
							|  |  |  |         test_options = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Yes I reuse the worlds generated between tests, its speeds the execution by a couple seconds | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |     frozen_options = frozenset(test_options.items()).union({seed}) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     if frozen_options in _cache: | 
					
						
							|  |  |  |         return _cache[frozen_options] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-30 13:17:12 -05:00
										 |  |  |     multiworld = setup_base_solo_multiworld(StardewValleyWorld, ()) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |     multiworld.set_seed(seed) | 
					
						
							|  |  |  |     # print(f"Seed: {multiworld.seed}") # Uncomment to print the seed for every test | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     args = Namespace() | 
					
						
							| 
									
										
										
										
											2023-10-10 15:30:20 -05:00
										 |  |  |     for name, option in StardewValleyWorld.options_dataclass.type_hints.items(): | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         value = option(test_options[name]) if name in test_options else option.from_any(option.default) | 
					
						
							|  |  |  |         setattr(args, name, {1: value}) | 
					
						
							|  |  |  |     multiworld.set_options(args) | 
					
						
							|  |  |  |     for step in gen_steps: | 
					
						
							|  |  |  |         call_all(multiworld, step) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _cache[frozen_options] = multiworld | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return multiworld |