Stardew Valley: Cut tests by 3 minutes (#2375)
* Stardew Valley: Test: unify mods * Stardew Valley: Test: don't use SVTestBase where setUp is unused * Stardew Valley: Test: remove duplicate backpack test * Stardew Valley: Test: remove 2,3,4 heart tests assume the math is correct with just 2 points on the curve * Stardew Valley: Test: reduce duplicate test/gen runs * Stardew Valley: Test: Change 'long' tests to not use TestBase TestBase' setUp is not being used in the changed TestCases * Stardew Valley: Test: Use subtests and inheritance for backpacks * Stardew Valley: Test: add flag to skip some of the extensive tests by default
This commit is contained in:
parent
c470849cee
commit
e3112e5d51
|
@ -21,3 +21,11 @@ class ModNames:
|
|||
ayeisha = "Ayeisha - The Postal Worker (Custom NPC)"
|
||||
riley = "Custom NPC - Riley"
|
||||
skull_cavern_elevator = "Skull Cavern Elevator"
|
||||
|
||||
|
||||
all_mods = frozenset({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})
|
||||
|
|
|
@ -5,40 +5,41 @@ from .. import options
|
|||
class TestBackpackVanilla(SVTestBase):
|
||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_vanilla}
|
||||
|
||||
def test_no_backpack_in_pool(self):
|
||||
item_names = {item.name for item in self.multiworld.get_items()}
|
||||
self.assertNotIn("Progressive Backpack", item_names)
|
||||
def test_no_backpack(self):
|
||||
with self.subTest("no items"):
|
||||
item_names = {item.name for item in self.multiworld.get_items()}
|
||||
self.assertNotIn("Progressive Backpack", item_names)
|
||||
|
||||
def test_no_backpack_locations(self):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertNotIn("Large Pack", location_names)
|
||||
self.assertNotIn("Deluxe Pack", location_names)
|
||||
with self.subTest("no locations"):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertNotIn("Large Pack", location_names)
|
||||
self.assertNotIn("Deluxe Pack", location_names)
|
||||
|
||||
|
||||
class TestBackpackProgressive(SVTestBase):
|
||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive}
|
||||
|
||||
def test_backpack_is_in_pool_2_times(self):
|
||||
item_names = [item.name for item in self.multiworld.get_items()]
|
||||
self.assertEqual(item_names.count("Progressive Backpack"), 2)
|
||||
def test_backpack(self):
|
||||
with self.subTest(check="has items"):
|
||||
item_names = [item.name for item in self.multiworld.get_items()]
|
||||
self.assertEqual(item_names.count("Progressive Backpack"), 2)
|
||||
|
||||
def test_2_backpack_locations(self):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertIn("Large Pack", location_names)
|
||||
self.assertIn("Deluxe Pack", location_names)
|
||||
with self.subTest(check="has locations"):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertIn("Large Pack", location_names)
|
||||
self.assertIn("Deluxe Pack", location_names)
|
||||
|
||||
|
||||
class TestBackpackEarlyProgressive(SVTestBase):
|
||||
class TestBackpackEarlyProgressive(TestBackpackProgressive):
|
||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_early_progressive}
|
||||
|
||||
def test_backpack_is_in_pool_2_times(self):
|
||||
item_names = [item.name for item in self.multiworld.get_items()]
|
||||
self.assertEqual(item_names.count("Progressive Backpack"), 2)
|
||||
@property
|
||||
def run_default_tests(self) -> bool:
|
||||
# EarlyProgressive is default
|
||||
return False
|
||||
|
||||
def test_2_backpack_locations(self):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertIn("Large Pack", location_names)
|
||||
self.assertIn("Deluxe Pack", location_names)
|
||||
def test_backpack(self):
|
||||
super().test_backpack()
|
||||
|
||||
def test_progressive_backpack_is_in_early_pool(self):
|
||||
self.assertIn("Progressive Backpack", self.multiworld.early_items[1])
|
||||
with self.subTest(check="is early"):
|
||||
self.assertIn("Progressive Backpack", self.multiworld.early_items[1])
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import typing
|
||||
|
||||
from BaseClasses import ItemClassification, MultiWorld
|
||||
from . import setup_solo_multiworld, SVTestBase
|
||||
from . import setup_solo_multiworld, SVTestBase, SVTestCase, allsanity_options_with_mods, \
|
||||
allsanity_options_without_mods, minimal_locations_maximal_items
|
||||
from .. import locations, items, location_table, options
|
||||
from ..data.villagers_data import all_villagers_by_name, all_villagers_by_mod_by_name
|
||||
from ..items import items_by_group, Group
|
||||
|
@ -7,11 +10,11 @@ from ..locations import LocationTags
|
|||
from ..mods.mod_data import ModNames
|
||||
|
||||
|
||||
def get_real_locations(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def get_real_locations(tester: typing.Union[SVTestBase, SVTestCase], multiworld: MultiWorld):
|
||||
return [location for location in multiworld.get_locations(tester.player) if not location.event]
|
||||
|
||||
|
||||
def get_real_location_names(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def get_real_location_names(tester: typing.Union[SVTestBase, SVTestCase], multiworld: MultiWorld):
|
||||
return [location.name for location in multiworld.get_locations(tester.player) if not location.event]
|
||||
|
||||
|
||||
|
@ -115,21 +118,6 @@ class TestNoGingerIslandItemGeneration(SVTestBase):
|
|||
self.assertTrue(count == 0 or count == 2)
|
||||
|
||||
|
||||
class TestGivenProgressiveBackpack(SVTestBase):
|
||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive}
|
||||
|
||||
def test_when_generate_world_then_two_progressive_backpack_are_added(self):
|
||||
self.assertEqual(self.multiworld.itempool.count(self.world.create_item("Progressive Backpack")), 2)
|
||||
|
||||
def test_when_generate_world_then_backpack_locations_are_added(self):
|
||||
created_locations = {location.name for location in self.multiworld.get_locations(1)}
|
||||
backpacks_exist = [location.name in created_locations
|
||||
for location in locations.locations_by_tag[LocationTags.BACKPACK]
|
||||
if location.name != "Premium Pack"]
|
||||
all_exist = all(backpacks_exist)
|
||||
self.assertTrue(all_exist)
|
||||
|
||||
|
||||
class TestRemixedMineRewards(SVTestBase):
|
||||
def test_when_generate_world_then_one_reward_is_added_per_chest(self):
|
||||
# assert self.world.create_item("Rusty Sword") in self.multiworld.itempool
|
||||
|
@ -205,17 +193,17 @@ class TestLocationGeneration(SVTestBase):
|
|||
self.assertIn(location.name, location_table)
|
||||
|
||||
|
||||
class TestLocationAndItemCount(SVTestBase):
|
||||
class TestLocationAndItemCount(SVTestCase):
|
||||
|
||||
def test_minimal_location_maximal_items_still_valid(self):
|
||||
min_max_options = self.minimal_locations_maximal_items()
|
||||
min_max_options = minimal_locations_maximal_items()
|
||||
multiworld = setup_solo_multiworld(min_max_options)
|
||||
valid_locations = get_real_locations(self, multiworld)
|
||||
self.assertGreaterEqual(len(valid_locations), len(multiworld.itempool))
|
||||
|
||||
def test_allsanity_without_mods_has_at_least_locations(self):
|
||||
expected_locations = 994
|
||||
allsanity_options = self.allsanity_options_without_mods()
|
||||
allsanity_options = allsanity_options_without_mods()
|
||||
multiworld = setup_solo_multiworld(allsanity_options)
|
||||
number_locations = len(get_real_locations(self, multiworld))
|
||||
self.assertGreaterEqual(number_locations, expected_locations)
|
||||
|
@ -228,7 +216,7 @@ class TestLocationAndItemCount(SVTestBase):
|
|||
|
||||
def test_allsanity_with_mods_has_at_least_locations(self):
|
||||
expected_locations = 1246
|
||||
allsanity_options = self.allsanity_options_with_mods()
|
||||
allsanity_options = allsanity_options_with_mods()
|
||||
multiworld = setup_solo_multiworld(allsanity_options)
|
||||
number_locations = len(get_real_locations(self, multiworld))
|
||||
self.assertGreaterEqual(number_locations, expected_locations)
|
||||
|
@ -245,6 +233,11 @@ class TestFriendsanityNone(SVTestBase):
|
|||
options.Friendsanity.internal_name: options.Friendsanity.option_none,
|
||||
}
|
||||
|
||||
@property
|
||||
def run_default_tests(self) -> bool:
|
||||
# None is default
|
||||
return False
|
||||
|
||||
def test_no_friendsanity_items(self):
|
||||
for item in self.multiworld.itempool:
|
||||
self.assertFalse(item.name.endswith(" <3"))
|
||||
|
@ -416,6 +409,7 @@ class TestFriendsanityAllNpcsWithMarriage(SVTestBase):
|
|||
self.assertLessEqual(int(hearts), 10)
|
||||
|
||||
|
||||
""" # Assuming math is correct if we check 2 points
|
||||
class TestFriendsanityAllNpcsWithMarriageHeartSize2(SVTestBase):
|
||||
options = {
|
||||
options.Friendsanity.internal_name: options.Friendsanity.option_all_with_marriage,
|
||||
|
@ -528,6 +522,7 @@ class TestFriendsanityAllNpcsWithMarriageHeartSize4(SVTestBase):
|
|||
self.assertTrue(hearts == 4 or hearts == 8 or hearts == 12 or hearts == 14)
|
||||
else:
|
||||
self.assertTrue(hearts == 4 or hearts == 8 or hearts == 10)
|
||||
"""
|
||||
|
||||
|
||||
class TestFriendsanityAllNpcsWithMarriageHeartSize5(SVTestBase):
|
||||
|
|
|
@ -6,12 +6,12 @@ import random
|
|||
from typing import Set
|
||||
|
||||
from BaseClasses import ItemClassification, MultiWorld
|
||||
from . import setup_solo_multiworld, SVTestBase
|
||||
from . import setup_solo_multiworld, SVTestCase, allsanity_options_without_mods
|
||||
from .. import ItemData, StardewValleyWorld
|
||||
from ..items import Group, item_table
|
||||
|
||||
|
||||
class TestItems(SVTestBase):
|
||||
class TestItems(SVTestCase):
|
||||
def test_can_create_item_of_resource_pack(self):
|
||||
item_name = "Resource Pack: 500 Money"
|
||||
|
||||
|
@ -46,7 +46,7 @@ class TestItems(SVTestBase):
|
|||
|
||||
def test_correct_number_of_stardrops(self):
|
||||
seed = random.randrange(sys.maxsize)
|
||||
allsanity_options = self.allsanity_options_without_mods()
|
||||
allsanity_options = allsanity_options_without_mods()
|
||||
multiworld = setup_solo_multiworld(allsanity_options, seed=seed)
|
||||
stardrop_items = [item for item in multiworld.get_items() if "Stardrop" in item.name]
|
||||
self.assertEqual(len(stardrop_items), 5)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import itertools
|
||||
import unittest
|
||||
from random import random
|
||||
from typing import Dict
|
||||
|
||||
from BaseClasses import ItemClassification, MultiWorld
|
||||
from Options import SpecialRange
|
||||
from . import setup_solo_multiworld, SVTestBase
|
||||
from . import setup_solo_multiworld, SVTestBase, SVTestCase, allsanity_options_without_mods, allsanity_options_with_mods
|
||||
from .. import StardewItem, items_by_group, Group, StardewValleyWorld
|
||||
from ..locations import locations_by_tag, LocationTags, location_table
|
||||
from ..options import ExcludeGingerIsland, ToolProgression, Goal, SeasonRandomization, TrapItems, SpecialOrderLocations, ArcadeMachineLocations
|
||||
|
@ -17,21 +18,21 @@ SEASONS = {Season.spring, Season.summer, Season.fall, Season.winter}
|
|||
TOOLS = {"Hoe", "Pickaxe", "Axe", "Watering Can", "Trash Can", "Fishing Rod"}
|
||||
|
||||
|
||||
def assert_can_win(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def assert_can_win(tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
for item in multiworld.get_items():
|
||||
multiworld.state.collect(item)
|
||||
|
||||
tester.assertTrue(multiworld.find_item("Victory", 1).can_reach(multiworld.state))
|
||||
|
||||
|
||||
def basic_checks(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def basic_checks(tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
tester.assertIn(StardewItem("Victory", ItemClassification.progression, None, 1), multiworld.get_items())
|
||||
assert_can_win(tester, multiworld)
|
||||
non_event_locations = [location for location in multiworld.get_locations() if not location.event]
|
||||
tester.assertEqual(len(multiworld.itempool), len(non_event_locations))
|
||||
|
||||
|
||||
def check_no_ginger_island(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def check_no_ginger_island(tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
ginger_island_items = [item_data.name for item_data in items_by_group[Group.GINGER_ISLAND]]
|
||||
ginger_island_locations = [location_data.name for location_data in locations_by_tag[LocationTags.GINGER_ISLAND]]
|
||||
for item in multiworld.get_items():
|
||||
|
@ -48,9 +49,9 @@ def get_option_choices(option) -> Dict[str, int]:
|
|||
return {}
|
||||
|
||||
|
||||
class TestGenerateDynamicOptions(SVTestBase):
|
||||
class TestGenerateDynamicOptions(SVTestCase):
|
||||
def test_given_special_range_when_generate_then_basic_checks(self):
|
||||
options = self.world.options_dataclass.type_hints
|
||||
options = StardewValleyWorld.options_dataclass.type_hints
|
||||
for option_name, option in options.items():
|
||||
if not isinstance(option, SpecialRange):
|
||||
continue
|
||||
|
@ -62,7 +63,7 @@ class TestGenerateDynamicOptions(SVTestBase):
|
|||
|
||||
def test_given_choice_when_generate_then_basic_checks(self):
|
||||
seed = int(random() * pow(10, 18) - 1)
|
||||
options = self.world.options_dataclass.type_hints
|
||||
options = StardewValleyWorld.options_dataclass.type_hints
|
||||
for option_name, option in options.items():
|
||||
if not option.options:
|
||||
continue
|
||||
|
@ -73,7 +74,7 @@ class TestGenerateDynamicOptions(SVTestBase):
|
|||
basic_checks(self, multiworld)
|
||||
|
||||
|
||||
class TestGoal(SVTestBase):
|
||||
class TestGoal(SVTestCase):
|
||||
def test_given_goal_when_generate_then_victory_is_in_correct_location(self):
|
||||
for goal, location in [("community_center", GoalName.community_center),
|
||||
("grandpa_evaluation", GoalName.grandpa_evaluation),
|
||||
|
@ -90,7 +91,7 @@ class TestGoal(SVTestBase):
|
|||
self.assertEqual(victory.name, location)
|
||||
|
||||
|
||||
class TestSeasonRandomization(SVTestBase):
|
||||
class TestSeasonRandomization(SVTestCase):
|
||||
def test_given_disabled_when_generate_then_all_seasons_are_precollected(self):
|
||||
world_options = {SeasonRandomization.internal_name: SeasonRandomization.option_disabled}
|
||||
multi_world = setup_solo_multiworld(world_options)
|
||||
|
@ -114,7 +115,7 @@ class TestSeasonRandomization(SVTestBase):
|
|||
self.assertEqual(items.count(Season.progressive), 3)
|
||||
|
||||
|
||||
class TestToolProgression(SVTestBase):
|
||||
class TestToolProgression(SVTestCase):
|
||||
def test_given_vanilla_when_generate_then_no_tool_in_pool(self):
|
||||
world_options = {ToolProgression.internal_name: ToolProgression.option_vanilla}
|
||||
multi_world = setup_solo_multiworld(world_options)
|
||||
|
@ -147,9 +148,9 @@ class TestToolProgression(SVTestBase):
|
|||
self.assertIn("Purchase Iridium Rod", locations)
|
||||
|
||||
|
||||
class TestGenerateAllOptionsWithExcludeGingerIsland(SVTestBase):
|
||||
class TestGenerateAllOptionsWithExcludeGingerIsland(SVTestCase):
|
||||
def test_given_special_range_when_generate_exclude_ginger_island(self):
|
||||
options = self.world.options_dataclass.type_hints
|
||||
options = StardewValleyWorld.options_dataclass.type_hints
|
||||
for option_name, option in options.items():
|
||||
if not isinstance(option, SpecialRange) or option_name == ExcludeGingerIsland.internal_name:
|
||||
continue
|
||||
|
@ -162,7 +163,7 @@ class TestGenerateAllOptionsWithExcludeGingerIsland(SVTestBase):
|
|||
|
||||
def test_given_choice_when_generate_exclude_ginger_island(self):
|
||||
seed = int(random() * pow(10, 18) - 1)
|
||||
options = self.world.options_dataclass.type_hints
|
||||
options = StardewValleyWorld.options_dataclass.type_hints
|
||||
for option_name, option in options.items():
|
||||
if not option.options or option_name == ExcludeGingerIsland.internal_name:
|
||||
continue
|
||||
|
@ -191,9 +192,9 @@ class TestGenerateAllOptionsWithExcludeGingerIsland(SVTestBase):
|
|||
basic_checks(self, multiworld)
|
||||
|
||||
|
||||
class TestTraps(SVTestBase):
|
||||
class TestTraps(SVTestCase):
|
||||
def test_given_no_traps_when_generate_then_no_trap_in_pool(self):
|
||||
world_options = self.allsanity_options_without_mods()
|
||||
world_options = allsanity_options_without_mods()
|
||||
world_options.update({TrapItems.internal_name: TrapItems.option_no_traps})
|
||||
multi_world = setup_solo_multiworld(world_options)
|
||||
|
||||
|
@ -209,7 +210,7 @@ class TestTraps(SVTestBase):
|
|||
for value in trap_option.options:
|
||||
if value == "no_traps":
|
||||
continue
|
||||
world_options = self.allsanity_options_with_mods()
|
||||
world_options = allsanity_options_with_mods()
|
||||
world_options.update({TrapItems.internal_name: trap_option.options[value]})
|
||||
multi_world = setup_solo_multiworld(world_options)
|
||||
trap_items = [item_data.name for item_data in items_by_group[Group.TRAP] if Group.DEPRECATED not in item_data.groups and item_data.mod_name is None]
|
||||
|
@ -219,7 +220,7 @@ class TestTraps(SVTestBase):
|
|||
self.assertIn(item, multiworld_items)
|
||||
|
||||
|
||||
class TestSpecialOrders(SVTestBase):
|
||||
class TestSpecialOrders(SVTestCase):
|
||||
def test_given_disabled_then_no_order_in_pool(self):
|
||||
world_options = {SpecialOrderLocations.internal_name: SpecialOrderLocations.option_disabled}
|
||||
multi_world = setup_solo_multiworld(world_options)
|
||||
|
|
|
@ -2,7 +2,7 @@ import random
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
from . import SVTestBase, setup_solo_multiworld
|
||||
from . import SVTestCase, setup_solo_multiworld
|
||||
from .. import options, StardewValleyWorld, StardewValleyOptions
|
||||
from ..options import EntranceRandomization, ExcludeGingerIsland
|
||||
from ..regions import vanilla_regions, vanilla_connections, randomize_connections, RandomizationFlag
|
||||
|
@ -88,7 +88,7 @@ class TestEntranceRando(unittest.TestCase):
|
|||
f"Connections are duplicated in randomization. Seed = {seed}")
|
||||
|
||||
|
||||
class TestEntranceClassifications(SVTestBase):
|
||||
class TestEntranceClassifications(SVTestCase):
|
||||
|
||||
def test_non_progression_are_all_accessible_with_empty_inventory(self):
|
||||
for option, flag in [(options.EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN),
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import os
|
||||
import unittest
|
||||
from argparse import Namespace
|
||||
from typing import Dict, FrozenSet, Tuple, Any, ClassVar
|
||||
|
||||
from BaseClasses import MultiWorld
|
||||
from Utils import cache_argsless
|
||||
from test.TestBase import WorldTestBase
|
||||
from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld
|
||||
from .. import StardewValleyWorld
|
||||
|
@ -13,11 +15,17 @@ from ..options import Cropsanity, SkillProgression, SpecialOrderLocations, Frien
|
|||
BundleRandomization, BundlePrice, FestivalLocations, FriendsanityHeartSize, ExcludeGingerIsland, TrapItems, Goal, Mods
|
||||
|
||||
|
||||
class SVTestBase(WorldTestBase):
|
||||
class SVTestCase(unittest.TestCase):
|
||||
player: ClassVar[int] = 1
|
||||
"""Set to False to not skip some 'extra' tests"""
|
||||
skip_extra_tests: bool = True
|
||||
"""Set to False to run tests that take long"""
|
||||
skip_long_tests: bool = True
|
||||
|
||||
|
||||
class SVTestBase(WorldTestBase, SVTestCase):
|
||||
game = "Stardew Valley"
|
||||
world: StardewValleyWorld
|
||||
player: ClassVar[int] = 1
|
||||
skip_long_tests: bool = True
|
||||
|
||||
def world_setup(self, *args, **kwargs):
|
||||
super().world_setup(*args, **kwargs)
|
||||
|
@ -34,66 +42,73 @@ class SVTestBase(WorldTestBase):
|
|||
should_run_default_tests = is_not_stardew_test and super().run_default_tests
|
||||
return should_run_default_tests
|
||||
|
||||
def minimal_locations_maximal_items(self):
|
||||
min_max_options = {
|
||||
SeasonRandomization.internal_name: SeasonRandomization.option_randomized,
|
||||
Cropsanity.internal_name: Cropsanity.option_shuffled,
|
||||
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
|
||||
|
||||
def allsanity_options_without_mods(self):
|
||||
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,
|
||||
Cropsanity.internal_name: Cropsanity.option_shuffled,
|
||||
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 minimal_locations_maximal_items():
|
||||
min_max_options = {
|
||||
SeasonRandomization.internal_name: SeasonRandomization.option_randomized,
|
||||
Cropsanity.internal_name: Cropsanity.option_shuffled,
|
||||
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,
|
||||
Cropsanity.internal_name: Cropsanity.option_shuffled,
|
||||
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
|
||||
|
||||
def allsanity_options_with_mods(self):
|
||||
allsanity = {}
|
||||
allsanity.update(self.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
|
||||
|
||||
pre_generated_worlds = {}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import unittest
|
||||
from typing import List
|
||||
|
||||
from BaseClasses import MultiWorld, ItemClassification
|
||||
from ... import StardewItem
|
||||
from .. import SVTestBase
|
||||
|
||||
|
||||
def get_all_item_names(multiworld: MultiWorld) -> List[str]:
|
||||
|
@ -13,21 +13,21 @@ def get_all_location_names(multiworld: MultiWorld) -> List[str]:
|
|||
return [location.name for location in multiworld.get_locations() if not location.event]
|
||||
|
||||
|
||||
def assert_victory_exists(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def assert_victory_exists(tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
tester.assertIn(StardewItem("Victory", ItemClassification.progression, None, 1), multiworld.get_items())
|
||||
|
||||
|
||||
def collect_all_then_assert_can_win(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def collect_all_then_assert_can_win(tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
for item in multiworld.get_items():
|
||||
multiworld.state.collect(item)
|
||||
tester.assertTrue(multiworld.find_item("Victory", 1).can_reach(multiworld.state))
|
||||
|
||||
|
||||
def assert_can_win(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def assert_can_win(tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
assert_victory_exists(tester, multiworld)
|
||||
collect_all_then_assert_can_win(tester, multiworld)
|
||||
|
||||
|
||||
def assert_same_number_items_locations(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def assert_same_number_items_locations(tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
non_event_locations = [location for location in multiworld.get_locations() if not location.event]
|
||||
tester.assertEqual(len(multiworld.itempool), len(non_event_locations))
|
|
@ -1,23 +1,17 @@
|
|||
import unittest
|
||||
from typing import List, Union
|
||||
|
||||
from BaseClasses import MultiWorld
|
||||
from worlds.stardew_valley.mods.mod_data import ModNames
|
||||
from worlds.stardew_valley.mods.mod_data import all_mods
|
||||
from worlds.stardew_valley.test import setup_solo_multiworld
|
||||
from worlds.stardew_valley.test.TestOptions import basic_checks, SVTestBase
|
||||
from worlds.stardew_valley.test.TestOptions import basic_checks, SVTestCase
|
||||
from worlds.stardew_valley.items import item_table
|
||||
from worlds.stardew_valley.locations import location_table
|
||||
from worlds.stardew_valley.options import Mods
|
||||
from .option_names import options_to_include
|
||||
|
||||
all_mods = frozenset({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})
|
||||
|
||||
|
||||
def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: SVTestBase, multiworld: MultiWorld):
|
||||
def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
if isinstance(chosen_mods, str):
|
||||
chosen_mods = [chosen_mods]
|
||||
for multiworld_item in multiworld.get_items():
|
||||
|
@ -30,7 +24,7 @@ def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: SVTestBase
|
|||
tester.assertTrue(location.mod_name is None or location.mod_name in chosen_mods)
|
||||
|
||||
|
||||
class TestGenerateModsOptions(SVTestBase):
|
||||
class TestGenerateModsOptions(SVTestCase):
|
||||
|
||||
def test_given_mod_pairs_when_generate_then_basic_checks(self):
|
||||
if self.skip_long_tests:
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import unittest
|
||||
from typing import Dict
|
||||
|
||||
from BaseClasses import MultiWorld
|
||||
from Options import SpecialRange
|
||||
from .option_names import options_to_include
|
||||
from worlds.stardew_valley.test.checks.world_checks import assert_can_win, assert_same_number_items_locations
|
||||
from .. import setup_solo_multiworld, SVTestBase
|
||||
from .. import setup_solo_multiworld, SVTestCase
|
||||
|
||||
|
||||
def basic_checks(tester: SVTestBase, multiworld: MultiWorld):
|
||||
def basic_checks(tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
assert_can_win(tester, multiworld)
|
||||
assert_same_number_items_locations(tester, multiworld)
|
||||
|
||||
|
@ -20,7 +21,7 @@ def get_option_choices(option) -> Dict[str, int]:
|
|||
return {}
|
||||
|
||||
|
||||
class TestGenerateDynamicOptions(SVTestBase):
|
||||
class TestGenerateDynamicOptions(SVTestCase):
|
||||
def test_given_option_pair_when_generate_then_basic_checks(self):
|
||||
if self.skip_long_tests:
|
||||
return
|
||||
|
|
|
@ -4,7 +4,7 @@ import random
|
|||
from BaseClasses import MultiWorld
|
||||
from Options import SpecialRange, Range
|
||||
from .option_names import options_to_include
|
||||
from .. import setup_solo_multiworld, SVTestBase
|
||||
from .. import setup_solo_multiworld, SVTestCase
|
||||
from ..checks.goal_checks import assert_perfection_world_is_valid, assert_goal_world_is_valid
|
||||
from ..checks.option_checks import assert_can_reach_island_if_should, assert_cropsanity_same_number_items_and_locations, \
|
||||
assert_festivals_give_access_to_deluxe_scarecrow
|
||||
|
@ -72,14 +72,14 @@ def generate_many_worlds(number_worlds: int, start_index: int) -> Dict[int, Mult
|
|||
return multiworlds
|
||||
|
||||
|
||||
def check_every_multiworld_is_valid(tester: SVTestBase, multiworlds: Dict[int, MultiWorld]):
|
||||
def check_every_multiworld_is_valid(tester: SVTestCase, multiworlds: Dict[int, MultiWorld]):
|
||||
for multiworld_id in multiworlds:
|
||||
multiworld = multiworlds[multiworld_id]
|
||||
with tester.subTest(f"Checking validity of world {multiworld_id}"):
|
||||
check_multiworld_is_valid(tester, multiworld_id, multiworld)
|
||||
|
||||
|
||||
def check_multiworld_is_valid(tester: SVTestBase, multiworld_id: int, multiworld: MultiWorld):
|
||||
def check_multiworld_is_valid(tester: SVTestCase, multiworld_id: int, multiworld: MultiWorld):
|
||||
assert_victory_exists(tester, multiworld)
|
||||
assert_same_number_items_locations(tester, multiworld)
|
||||
assert_goal_world_is_valid(tester, multiworld)
|
||||
|
@ -88,7 +88,7 @@ def check_multiworld_is_valid(tester: SVTestBase, multiworld_id: int, multiworld
|
|||
assert_festivals_give_access_to_deluxe_scarecrow(tester, multiworld)
|
||||
|
||||
|
||||
class TestGenerateManyWorlds(SVTestBase):
|
||||
class TestGenerateManyWorlds(SVTestCase):
|
||||
def test_generate_many_worlds_then_check_results(self):
|
||||
if self.skip_long_tests:
|
||||
return
|
||||
|
|
|
@ -7,45 +7,40 @@ class TestBiggerBackpackVanilla(SVTestBase):
|
|||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_vanilla,
|
||||
options.Mods.internal_name: ModNames.big_backpack}
|
||||
|
||||
def test_no_backpack_in_pool(self):
|
||||
item_names = {item.name for item in self.multiworld.get_items()}
|
||||
self.assertNotIn("Progressive Backpack", item_names)
|
||||
def test_no_backpack(self):
|
||||
with self.subTest(check="no items"):
|
||||
item_names = {item.name for item in self.multiworld.get_items()}
|
||||
self.assertNotIn("Progressive Backpack", item_names)
|
||||
|
||||
def test_no_backpack_locations(self):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertNotIn("Large Pack", location_names)
|
||||
self.assertNotIn("Deluxe Pack", location_names)
|
||||
self.assertNotIn("Premium Pack", location_names)
|
||||
with self.subTest(check="no locations"):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertNotIn("Large Pack", location_names)
|
||||
self.assertNotIn("Deluxe Pack", location_names)
|
||||
self.assertNotIn("Premium Pack", location_names)
|
||||
|
||||
|
||||
class TestBiggerBackpackProgressive(SVTestBase):
|
||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive,
|
||||
options.Mods.internal_name: ModNames.big_backpack}
|
||||
|
||||
def test_backpack_is_in_pool_3_times(self):
|
||||
item_names = [item.name for item in self.multiworld.get_items()]
|
||||
self.assertEqual(item_names.count("Progressive Backpack"), 3)
|
||||
def test_backpack(self):
|
||||
with self.subTest(check="has items"):
|
||||
item_names = [item.name for item in self.multiworld.get_items()]
|
||||
self.assertEqual(item_names.count("Progressive Backpack"), 3)
|
||||
|
||||
def test_3_backpack_locations(self):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertIn("Large Pack", location_names)
|
||||
self.assertIn("Deluxe Pack", location_names)
|
||||
self.assertIn("Premium Pack", location_names)
|
||||
with self.subTest(check="has locations"):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertIn("Large Pack", location_names)
|
||||
self.assertIn("Deluxe Pack", location_names)
|
||||
self.assertIn("Premium Pack", location_names)
|
||||
|
||||
|
||||
class TestBiggerBackpackEarlyProgressive(SVTestBase):
|
||||
class TestBiggerBackpackEarlyProgressive(TestBiggerBackpackProgressive):
|
||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_early_progressive,
|
||||
options.Mods.internal_name: ModNames.big_backpack}
|
||||
|
||||
def test_backpack_is_in_pool_3_times(self):
|
||||
item_names = [item.name for item in self.multiworld.get_items()]
|
||||
self.assertEqual(item_names.count("Progressive Backpack"), 3)
|
||||
def test_backpack(self):
|
||||
super().test_backpack()
|
||||
|
||||
def test_3_backpack_locations(self):
|
||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||
self.assertIn("Large Pack", location_names)
|
||||
self.assertIn("Deluxe Pack", location_names)
|
||||
self.assertIn("Premium Pack", location_names)
|
||||
|
||||
def test_progressive_backpack_is_in_early_pool(self):
|
||||
self.assertIn("Progressive Backpack", self.multiworld.early_items[1])
|
||||
with self.subTest(check="is early"):
|
||||
self.assertIn("Progressive Backpack", self.multiworld.early_items[1])
|
||||
|
|
|
@ -4,24 +4,17 @@ import random
|
|||
import sys
|
||||
|
||||
from BaseClasses import MultiWorld
|
||||
from ...mods.mod_data import ModNames
|
||||
from .. import setup_solo_multiworld
|
||||
from ..TestOptions import basic_checks, SVTestBase
|
||||
from ...mods.mod_data import all_mods
|
||||
from .. import setup_solo_multiworld, SVTestBase, SVTestCase, allsanity_options_without_mods
|
||||
from ..TestOptions import basic_checks
|
||||
from ... import items, Group, ItemClassification
|
||||
from ...regions import RandomizationFlag, create_final_connections, randomize_connections, create_final_regions
|
||||
from ...items import item_table, items_by_group
|
||||
from ...locations import location_table
|
||||
from ...options import Mods, EntranceRandomization, Friendsanity, SeasonRandomization, SpecialOrderLocations, ExcludeGingerIsland, TrapItems
|
||||
|
||||
all_mods = frozenset({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})
|
||||
|
||||
|
||||
def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: SVTestBase, multiworld: MultiWorld):
|
||||
def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: unittest.TestCase, multiworld: MultiWorld):
|
||||
if isinstance(chosen_mods, str):
|
||||
chosen_mods = [chosen_mods]
|
||||
for multiworld_item in multiworld.get_items():
|
||||
|
@ -34,7 +27,7 @@ def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: SVTestBase
|
|||
tester.assertTrue(location.mod_name is None or location.mod_name in chosen_mods)
|
||||
|
||||
|
||||
class TestGenerateModsOptions(SVTestBase):
|
||||
class TestGenerateModsOptions(SVTestCase):
|
||||
|
||||
def test_given_single_mods_when_generate_then_basic_checks(self):
|
||||
for mod in all_mods:
|
||||
|
@ -50,6 +43,8 @@ class TestGenerateModsOptions(SVTestBase):
|
|||
multiworld = setup_solo_multiworld({EntranceRandomization.internal_name: option, Mods: mod})
|
||||
basic_checks(self, multiworld)
|
||||
check_stray_mod_items(mod, self, multiworld)
|
||||
if self.skip_extra_tests:
|
||||
return # assume the rest will work as well
|
||||
|
||||
|
||||
class TestBaseItemGeneration(SVTestBase):
|
||||
|
@ -103,7 +98,7 @@ class TestNoGingerIslandModItemGeneration(SVTestBase):
|
|||
self.assertIn(progression_item.name, all_created_items)
|
||||
|
||||
|
||||
class TestModEntranceRando(unittest.TestCase):
|
||||
class TestModEntranceRando(SVTestCase):
|
||||
|
||||
def test_mod_entrance_randomization(self):
|
||||
|
||||
|
@ -137,12 +132,12 @@ class TestModEntranceRando(unittest.TestCase):
|
|||
f"Connections are duplicated in randomization. Seed = {seed}")
|
||||
|
||||
|
||||
class TestModTraps(SVTestBase):
|
||||
class TestModTraps(SVTestCase):
|
||||
def test_given_traps_when_generate_then_all_traps_in_pool(self):
|
||||
for value in TrapItems.options:
|
||||
if value == "no_traps":
|
||||
continue
|
||||
world_options = self.allsanity_options_without_mods()
|
||||
world_options = allsanity_options_without_mods()
|
||||
world_options.update({TrapItems.internal_name: TrapItems.options[value], Mods: "Magic"})
|
||||
multi_world = setup_solo_multiworld(world_options)
|
||||
trap_items = [item_data.name for item_data in items_by_group[Group.TRAP] if Group.DEPRECATED not in item_data.groups]
|
||||
|
|
Loading…
Reference in New Issue