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)"
|
ayeisha = "Ayeisha - The Postal Worker (Custom NPC)"
|
||||||
riley = "Custom NPC - Riley"
|
riley = "Custom NPC - Riley"
|
||||||
skull_cavern_elevator = "Skull Cavern Elevator"
|
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):
|
class TestBackpackVanilla(SVTestBase):
|
||||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_vanilla}
|
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_vanilla}
|
||||||
|
|
||||||
def test_no_backpack_in_pool(self):
|
def test_no_backpack(self):
|
||||||
item_names = {item.name for item in self.multiworld.get_items()}
|
with self.subTest("no items"):
|
||||||
self.assertNotIn("Progressive Backpack", item_names)
|
item_names = {item.name for item in self.multiworld.get_items()}
|
||||||
|
self.assertNotIn("Progressive Backpack", item_names)
|
||||||
|
|
||||||
def test_no_backpack_locations(self):
|
with self.subTest("no locations"):
|
||||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||||
self.assertNotIn("Large Pack", location_names)
|
self.assertNotIn("Large Pack", location_names)
|
||||||
self.assertNotIn("Deluxe Pack", location_names)
|
self.assertNotIn("Deluxe Pack", location_names)
|
||||||
|
|
||||||
|
|
||||||
class TestBackpackProgressive(SVTestBase):
|
class TestBackpackProgressive(SVTestBase):
|
||||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive}
|
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive}
|
||||||
|
|
||||||
def test_backpack_is_in_pool_2_times(self):
|
def test_backpack(self):
|
||||||
item_names = [item.name for item in self.multiworld.get_items()]
|
with self.subTest(check="has items"):
|
||||||
self.assertEqual(item_names.count("Progressive Backpack"), 2)
|
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):
|
with self.subTest(check="has locations"):
|
||||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||||
self.assertIn("Large Pack", location_names)
|
self.assertIn("Large Pack", location_names)
|
||||||
self.assertIn("Deluxe 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}
|
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_early_progressive}
|
||||||
|
|
||||||
def test_backpack_is_in_pool_2_times(self):
|
@property
|
||||||
item_names = [item.name for item in self.multiworld.get_items()]
|
def run_default_tests(self) -> bool:
|
||||||
self.assertEqual(item_names.count("Progressive Backpack"), 2)
|
# EarlyProgressive is default
|
||||||
|
return False
|
||||||
|
|
||||||
def test_2_backpack_locations(self):
|
def test_backpack(self):
|
||||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
super().test_backpack()
|
||||||
self.assertIn("Large Pack", location_names)
|
|
||||||
self.assertIn("Deluxe Pack", location_names)
|
|
||||||
|
|
||||||
def test_progressive_backpack_is_in_early_pool(self):
|
with self.subTest(check="is early"):
|
||||||
self.assertIn("Progressive Backpack", self.multiworld.early_items[1])
|
self.assertIn("Progressive Backpack", self.multiworld.early_items[1])
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
from BaseClasses import ItemClassification, MultiWorld
|
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 .. import locations, items, location_table, options
|
||||||
from ..data.villagers_data import all_villagers_by_name, all_villagers_by_mod_by_name
|
from ..data.villagers_data import all_villagers_by_name, all_villagers_by_mod_by_name
|
||||||
from ..items import items_by_group, Group
|
from ..items import items_by_group, Group
|
||||||
|
@ -7,11 +10,11 @@ from ..locations import LocationTags
|
||||||
from ..mods.mod_data import ModNames
|
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]
|
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]
|
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)
|
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):
|
class TestRemixedMineRewards(SVTestBase):
|
||||||
def test_when_generate_world_then_one_reward_is_added_per_chest(self):
|
def test_when_generate_world_then_one_reward_is_added_per_chest(self):
|
||||||
# assert self.world.create_item("Rusty Sword") in self.multiworld.itempool
|
# assert self.world.create_item("Rusty Sword") in self.multiworld.itempool
|
||||||
|
@ -205,17 +193,17 @@ class TestLocationGeneration(SVTestBase):
|
||||||
self.assertIn(location.name, location_table)
|
self.assertIn(location.name, location_table)
|
||||||
|
|
||||||
|
|
||||||
class TestLocationAndItemCount(SVTestBase):
|
class TestLocationAndItemCount(SVTestCase):
|
||||||
|
|
||||||
def test_minimal_location_maximal_items_still_valid(self):
|
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)
|
multiworld = setup_solo_multiworld(min_max_options)
|
||||||
valid_locations = get_real_locations(self, multiworld)
|
valid_locations = get_real_locations(self, multiworld)
|
||||||
self.assertGreaterEqual(len(valid_locations), len(multiworld.itempool))
|
self.assertGreaterEqual(len(valid_locations), len(multiworld.itempool))
|
||||||
|
|
||||||
def test_allsanity_without_mods_has_at_least_locations(self):
|
def test_allsanity_without_mods_has_at_least_locations(self):
|
||||||
expected_locations = 994
|
expected_locations = 994
|
||||||
allsanity_options = self.allsanity_options_without_mods()
|
allsanity_options = allsanity_options_without_mods()
|
||||||
multiworld = setup_solo_multiworld(allsanity_options)
|
multiworld = setup_solo_multiworld(allsanity_options)
|
||||||
number_locations = len(get_real_locations(self, multiworld))
|
number_locations = len(get_real_locations(self, multiworld))
|
||||||
self.assertGreaterEqual(number_locations, expected_locations)
|
self.assertGreaterEqual(number_locations, expected_locations)
|
||||||
|
@ -228,7 +216,7 @@ class TestLocationAndItemCount(SVTestBase):
|
||||||
|
|
||||||
def test_allsanity_with_mods_has_at_least_locations(self):
|
def test_allsanity_with_mods_has_at_least_locations(self):
|
||||||
expected_locations = 1246
|
expected_locations = 1246
|
||||||
allsanity_options = self.allsanity_options_with_mods()
|
allsanity_options = allsanity_options_with_mods()
|
||||||
multiworld = setup_solo_multiworld(allsanity_options)
|
multiworld = setup_solo_multiworld(allsanity_options)
|
||||||
number_locations = len(get_real_locations(self, multiworld))
|
number_locations = len(get_real_locations(self, multiworld))
|
||||||
self.assertGreaterEqual(number_locations, expected_locations)
|
self.assertGreaterEqual(number_locations, expected_locations)
|
||||||
|
@ -245,6 +233,11 @@ class TestFriendsanityNone(SVTestBase):
|
||||||
options.Friendsanity.internal_name: options.Friendsanity.option_none,
|
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):
|
def test_no_friendsanity_items(self):
|
||||||
for item in self.multiworld.itempool:
|
for item in self.multiworld.itempool:
|
||||||
self.assertFalse(item.name.endswith(" <3"))
|
self.assertFalse(item.name.endswith(" <3"))
|
||||||
|
@ -416,6 +409,7 @@ class TestFriendsanityAllNpcsWithMarriage(SVTestBase):
|
||||||
self.assertLessEqual(int(hearts), 10)
|
self.assertLessEqual(int(hearts), 10)
|
||||||
|
|
||||||
|
|
||||||
|
""" # Assuming math is correct if we check 2 points
|
||||||
class TestFriendsanityAllNpcsWithMarriageHeartSize2(SVTestBase):
|
class TestFriendsanityAllNpcsWithMarriageHeartSize2(SVTestBase):
|
||||||
options = {
|
options = {
|
||||||
options.Friendsanity.internal_name: options.Friendsanity.option_all_with_marriage,
|
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)
|
self.assertTrue(hearts == 4 or hearts == 8 or hearts == 12 or hearts == 14)
|
||||||
else:
|
else:
|
||||||
self.assertTrue(hearts == 4 or hearts == 8 or hearts == 10)
|
self.assertTrue(hearts == 4 or hearts == 8 or hearts == 10)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TestFriendsanityAllNpcsWithMarriageHeartSize5(SVTestBase):
|
class TestFriendsanityAllNpcsWithMarriageHeartSize5(SVTestBase):
|
||||||
|
|
|
@ -6,12 +6,12 @@ import random
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
from BaseClasses import ItemClassification, MultiWorld
|
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 .. import ItemData, StardewValleyWorld
|
||||||
from ..items import Group, item_table
|
from ..items import Group, item_table
|
||||||
|
|
||||||
|
|
||||||
class TestItems(SVTestBase):
|
class TestItems(SVTestCase):
|
||||||
def test_can_create_item_of_resource_pack(self):
|
def test_can_create_item_of_resource_pack(self):
|
||||||
item_name = "Resource Pack: 500 Money"
|
item_name = "Resource Pack: 500 Money"
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class TestItems(SVTestBase):
|
||||||
|
|
||||||
def test_correct_number_of_stardrops(self):
|
def test_correct_number_of_stardrops(self):
|
||||||
seed = random.randrange(sys.maxsize)
|
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)
|
multiworld = setup_solo_multiworld(allsanity_options, seed=seed)
|
||||||
stardrop_items = [item for item in multiworld.get_items() if "Stardrop" in item.name]
|
stardrop_items = [item for item in multiworld.get_items() if "Stardrop" in item.name]
|
||||||
self.assertEqual(len(stardrop_items), 5)
|
self.assertEqual(len(stardrop_items), 5)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import itertools
|
import itertools
|
||||||
|
import unittest
|
||||||
from random import random
|
from random import random
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from BaseClasses import ItemClassification, MultiWorld
|
from BaseClasses import ItemClassification, MultiWorld
|
||||||
from Options import SpecialRange
|
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 .. import StardewItem, items_by_group, Group, StardewValleyWorld
|
||||||
from ..locations import locations_by_tag, LocationTags, location_table
|
from ..locations import locations_by_tag, LocationTags, location_table
|
||||||
from ..options import ExcludeGingerIsland, ToolProgression, Goal, SeasonRandomization, TrapItems, SpecialOrderLocations, ArcadeMachineLocations
|
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"}
|
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():
|
for item in multiworld.get_items():
|
||||||
multiworld.state.collect(item)
|
multiworld.state.collect(item)
|
||||||
|
|
||||||
tester.assertTrue(multiworld.find_item("Victory", 1).can_reach(multiworld.state))
|
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())
|
tester.assertIn(StardewItem("Victory", ItemClassification.progression, None, 1), multiworld.get_items())
|
||||||
assert_can_win(tester, multiworld)
|
assert_can_win(tester, multiworld)
|
||||||
non_event_locations = [location for location in multiworld.get_locations() if not location.event]
|
non_event_locations = [location for location in multiworld.get_locations() if not location.event]
|
||||||
tester.assertEqual(len(multiworld.itempool), len(non_event_locations))
|
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_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]]
|
ginger_island_locations = [location_data.name for location_data in locations_by_tag[LocationTags.GINGER_ISLAND]]
|
||||||
for item in multiworld.get_items():
|
for item in multiworld.get_items():
|
||||||
|
@ -48,9 +49,9 @@ def get_option_choices(option) -> Dict[str, int]:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
class TestGenerateDynamicOptions(SVTestBase):
|
class TestGenerateDynamicOptions(SVTestCase):
|
||||||
def test_given_special_range_when_generate_then_basic_checks(self):
|
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():
|
for option_name, option in options.items():
|
||||||
if not isinstance(option, SpecialRange):
|
if not isinstance(option, SpecialRange):
|
||||||
continue
|
continue
|
||||||
|
@ -62,7 +63,7 @@ class TestGenerateDynamicOptions(SVTestBase):
|
||||||
|
|
||||||
def test_given_choice_when_generate_then_basic_checks(self):
|
def test_given_choice_when_generate_then_basic_checks(self):
|
||||||
seed = int(random() * pow(10, 18) - 1)
|
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():
|
for option_name, option in options.items():
|
||||||
if not option.options:
|
if not option.options:
|
||||||
continue
|
continue
|
||||||
|
@ -73,7 +74,7 @@ class TestGenerateDynamicOptions(SVTestBase):
|
||||||
basic_checks(self, multiworld)
|
basic_checks(self, multiworld)
|
||||||
|
|
||||||
|
|
||||||
class TestGoal(SVTestBase):
|
class TestGoal(SVTestCase):
|
||||||
def test_given_goal_when_generate_then_victory_is_in_correct_location(self):
|
def test_given_goal_when_generate_then_victory_is_in_correct_location(self):
|
||||||
for goal, location in [("community_center", GoalName.community_center),
|
for goal, location in [("community_center", GoalName.community_center),
|
||||||
("grandpa_evaluation", GoalName.grandpa_evaluation),
|
("grandpa_evaluation", GoalName.grandpa_evaluation),
|
||||||
|
@ -90,7 +91,7 @@ class TestGoal(SVTestBase):
|
||||||
self.assertEqual(victory.name, location)
|
self.assertEqual(victory.name, location)
|
||||||
|
|
||||||
|
|
||||||
class TestSeasonRandomization(SVTestBase):
|
class TestSeasonRandomization(SVTestCase):
|
||||||
def test_given_disabled_when_generate_then_all_seasons_are_precollected(self):
|
def test_given_disabled_when_generate_then_all_seasons_are_precollected(self):
|
||||||
world_options = {SeasonRandomization.internal_name: SeasonRandomization.option_disabled}
|
world_options = {SeasonRandomization.internal_name: SeasonRandomization.option_disabled}
|
||||||
multi_world = setup_solo_multiworld(world_options)
|
multi_world = setup_solo_multiworld(world_options)
|
||||||
|
@ -114,7 +115,7 @@ class TestSeasonRandomization(SVTestBase):
|
||||||
self.assertEqual(items.count(Season.progressive), 3)
|
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):
|
def test_given_vanilla_when_generate_then_no_tool_in_pool(self):
|
||||||
world_options = {ToolProgression.internal_name: ToolProgression.option_vanilla}
|
world_options = {ToolProgression.internal_name: ToolProgression.option_vanilla}
|
||||||
multi_world = setup_solo_multiworld(world_options)
|
multi_world = setup_solo_multiworld(world_options)
|
||||||
|
@ -147,9 +148,9 @@ class TestToolProgression(SVTestBase):
|
||||||
self.assertIn("Purchase Iridium Rod", locations)
|
self.assertIn("Purchase Iridium Rod", locations)
|
||||||
|
|
||||||
|
|
||||||
class TestGenerateAllOptionsWithExcludeGingerIsland(SVTestBase):
|
class TestGenerateAllOptionsWithExcludeGingerIsland(SVTestCase):
|
||||||
def test_given_special_range_when_generate_exclude_ginger_island(self):
|
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():
|
for option_name, option in options.items():
|
||||||
if not isinstance(option, SpecialRange) or option_name == ExcludeGingerIsland.internal_name:
|
if not isinstance(option, SpecialRange) or option_name == ExcludeGingerIsland.internal_name:
|
||||||
continue
|
continue
|
||||||
|
@ -162,7 +163,7 @@ class TestGenerateAllOptionsWithExcludeGingerIsland(SVTestBase):
|
||||||
|
|
||||||
def test_given_choice_when_generate_exclude_ginger_island(self):
|
def test_given_choice_when_generate_exclude_ginger_island(self):
|
||||||
seed = int(random() * pow(10, 18) - 1)
|
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():
|
for option_name, option in options.items():
|
||||||
if not option.options or option_name == ExcludeGingerIsland.internal_name:
|
if not option.options or option_name == ExcludeGingerIsland.internal_name:
|
||||||
continue
|
continue
|
||||||
|
@ -191,9 +192,9 @@ class TestGenerateAllOptionsWithExcludeGingerIsland(SVTestBase):
|
||||||
basic_checks(self, multiworld)
|
basic_checks(self, multiworld)
|
||||||
|
|
||||||
|
|
||||||
class TestTraps(SVTestBase):
|
class TestTraps(SVTestCase):
|
||||||
def test_given_no_traps_when_generate_then_no_trap_in_pool(self):
|
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})
|
world_options.update({TrapItems.internal_name: TrapItems.option_no_traps})
|
||||||
multi_world = setup_solo_multiworld(world_options)
|
multi_world = setup_solo_multiworld(world_options)
|
||||||
|
|
||||||
|
@ -209,7 +210,7 @@ class TestTraps(SVTestBase):
|
||||||
for value in trap_option.options:
|
for value in trap_option.options:
|
||||||
if value == "no_traps":
|
if value == "no_traps":
|
||||||
continue
|
continue
|
||||||
world_options = self.allsanity_options_with_mods()
|
world_options = allsanity_options_with_mods()
|
||||||
world_options.update({TrapItems.internal_name: trap_option.options[value]})
|
world_options.update({TrapItems.internal_name: trap_option.options[value]})
|
||||||
multi_world = setup_solo_multiworld(world_options)
|
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]
|
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)
|
self.assertIn(item, multiworld_items)
|
||||||
|
|
||||||
|
|
||||||
class TestSpecialOrders(SVTestBase):
|
class TestSpecialOrders(SVTestCase):
|
||||||
def test_given_disabled_then_no_order_in_pool(self):
|
def test_given_disabled_then_no_order_in_pool(self):
|
||||||
world_options = {SpecialOrderLocations.internal_name: SpecialOrderLocations.option_disabled}
|
world_options = {SpecialOrderLocations.internal_name: SpecialOrderLocations.option_disabled}
|
||||||
multi_world = setup_solo_multiworld(world_options)
|
multi_world = setup_solo_multiworld(world_options)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import random
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from . import SVTestBase, setup_solo_multiworld
|
from . import SVTestCase, setup_solo_multiworld
|
||||||
from .. import options, StardewValleyWorld, StardewValleyOptions
|
from .. import options, StardewValleyWorld, StardewValleyOptions
|
||||||
from ..options import EntranceRandomization, ExcludeGingerIsland
|
from ..options import EntranceRandomization, ExcludeGingerIsland
|
||||||
from ..regions import vanilla_regions, vanilla_connections, randomize_connections, RandomizationFlag
|
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}")
|
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):
|
def test_non_progression_are_all_accessible_with_empty_inventory(self):
|
||||||
for option, flag in [(options.EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN),
|
for option, flag in [(options.EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN),
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import os
|
import os
|
||||||
|
import unittest
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from typing import Dict, FrozenSet, Tuple, Any, ClassVar
|
from typing import Dict, FrozenSet, Tuple, Any, ClassVar
|
||||||
|
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
|
from Utils import cache_argsless
|
||||||
from test.TestBase import WorldTestBase
|
from test.TestBase import WorldTestBase
|
||||||
from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld
|
from test.general import gen_steps, setup_solo_multiworld as setup_base_solo_multiworld
|
||||||
from .. import StardewValleyWorld
|
from .. import StardewValleyWorld
|
||||||
|
@ -13,11 +15,17 @@ from ..options import Cropsanity, SkillProgression, SpecialOrderLocations, Frien
|
||||||
BundleRandomization, BundlePrice, FestivalLocations, FriendsanityHeartSize, ExcludeGingerIsland, TrapItems, Goal, Mods
|
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"
|
game = "Stardew Valley"
|
||||||
world: StardewValleyWorld
|
world: StardewValleyWorld
|
||||||
player: ClassVar[int] = 1
|
|
||||||
skip_long_tests: bool = True
|
|
||||||
|
|
||||||
def world_setup(self, *args, **kwargs):
|
def world_setup(self, *args, **kwargs):
|
||||||
super().world_setup(*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
|
should_run_default_tests = is_not_stardew_test and super().run_default_tests
|
||||||
return should_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):
|
@cache_argsless
|
||||||
allsanity = {
|
def minimal_locations_maximal_items():
|
||||||
Goal.internal_name: Goal.option_perfection,
|
min_max_options = {
|
||||||
BundleRandomization.internal_name: BundleRandomization.option_shuffled,
|
SeasonRandomization.internal_name: SeasonRandomization.option_randomized,
|
||||||
BundlePrice.internal_name: BundlePrice.option_expensive,
|
Cropsanity.internal_name: Cropsanity.option_shuffled,
|
||||||
SeasonRandomization.internal_name: SeasonRandomization.option_randomized,
|
BackpackProgression.internal_name: BackpackProgression.option_vanilla,
|
||||||
Cropsanity.internal_name: Cropsanity.option_shuffled,
|
ToolProgression.internal_name: ToolProgression.option_vanilla,
|
||||||
BackpackProgression.internal_name: BackpackProgression.option_progressive,
|
SkillProgression.internal_name: SkillProgression.option_vanilla,
|
||||||
ToolProgression.internal_name: ToolProgression.option_progressive,
|
BuildingProgression.internal_name: BuildingProgression.option_vanilla,
|
||||||
SkillProgression.internal_name: SkillProgression.option_progressive,
|
ElevatorProgression.internal_name: ElevatorProgression.option_vanilla,
|
||||||
BuildingProgression.internal_name: BuildingProgression.option_progressive,
|
ArcadeMachineLocations.internal_name: ArcadeMachineLocations.option_disabled,
|
||||||
FestivalLocations.internal_name: FestivalLocations.option_hard,
|
SpecialOrderLocations.internal_name: SpecialOrderLocations.option_disabled,
|
||||||
ElevatorProgression.internal_name: ElevatorProgression.option_progressive,
|
HelpWantedLocations.internal_name: 0,
|
||||||
ArcadeMachineLocations.internal_name: ArcadeMachineLocations.option_full_shuffling,
|
Fishsanity.internal_name: Fishsanity.option_none,
|
||||||
SpecialOrderLocations.internal_name: SpecialOrderLocations.option_board_qi,
|
Museumsanity.internal_name: Museumsanity.option_none,
|
||||||
HelpWantedLocations.internal_name: 56,
|
Friendsanity.internal_name: Friendsanity.option_none,
|
||||||
Fishsanity.internal_name: Fishsanity.option_all,
|
NumberOfMovementBuffs.internal_name: 12,
|
||||||
Museumsanity.internal_name: Museumsanity.option_all,
|
NumberOfLuckBuffs.internal_name: 12,
|
||||||
Friendsanity.internal_name: Friendsanity.option_all_with_marriage,
|
}
|
||||||
FriendsanityHeartSize.internal_name: 1,
|
return min_max_options
|
||||||
NumberOfMovementBuffs.internal_name: 12,
|
|
||||||
NumberOfLuckBuffs.internal_name: 12,
|
|
||||||
ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_false,
|
@cache_argsless
|
||||||
TrapItems.internal_name: TrapItems.option_nightmare,
|
def allsanity_options_without_mods():
|
||||||
}
|
allsanity = {
|
||||||
return 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 = {}
|
pre_generated_worlds = {}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
import unittest
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from BaseClasses import MultiWorld, ItemClassification
|
from BaseClasses import MultiWorld, ItemClassification
|
||||||
from ... import StardewItem
|
from ... import StardewItem
|
||||||
from .. import SVTestBase
|
|
||||||
|
|
||||||
|
|
||||||
def get_all_item_names(multiworld: MultiWorld) -> List[str]:
|
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]
|
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())
|
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():
|
for item in multiworld.get_items():
|
||||||
multiworld.state.collect(item)
|
multiworld.state.collect(item)
|
||||||
tester.assertTrue(multiworld.find_item("Victory", 1).can_reach(multiworld.state))
|
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)
|
assert_victory_exists(tester, multiworld)
|
||||||
collect_all_then_assert_can_win(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]
|
non_event_locations = [location for location in multiworld.get_locations() if not location.event]
|
||||||
tester.assertEqual(len(multiworld.itempool), len(non_event_locations))
|
tester.assertEqual(len(multiworld.itempool), len(non_event_locations))
|
|
@ -1,23 +1,17 @@
|
||||||
|
import unittest
|
||||||
from typing import List, Union
|
from typing import List, Union
|
||||||
|
|
||||||
from BaseClasses import MultiWorld
|
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 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.items import item_table
|
||||||
from worlds.stardew_valley.locations import location_table
|
from worlds.stardew_valley.locations import location_table
|
||||||
from worlds.stardew_valley.options import Mods
|
from worlds.stardew_valley.options import Mods
|
||||||
from .option_names import options_to_include
|
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: unittest.TestCase, multiworld: MultiWorld):
|
||||||
def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: SVTestBase, multiworld: MultiWorld):
|
|
||||||
if isinstance(chosen_mods, str):
|
if isinstance(chosen_mods, str):
|
||||||
chosen_mods = [chosen_mods]
|
chosen_mods = [chosen_mods]
|
||||||
for multiworld_item in multiworld.get_items():
|
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)
|
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):
|
def test_given_mod_pairs_when_generate_then_basic_checks(self):
|
||||||
if self.skip_long_tests:
|
if self.skip_long_tests:
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
|
import unittest
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from Options import SpecialRange
|
from Options import SpecialRange
|
||||||
from .option_names import options_to_include
|
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 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_can_win(tester, multiworld)
|
||||||
assert_same_number_items_locations(tester, multiworld)
|
assert_same_number_items_locations(tester, multiworld)
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ def get_option_choices(option) -> Dict[str, int]:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
class TestGenerateDynamicOptions(SVTestBase):
|
class TestGenerateDynamicOptions(SVTestCase):
|
||||||
def test_given_option_pair_when_generate_then_basic_checks(self):
|
def test_given_option_pair_when_generate_then_basic_checks(self):
|
||||||
if self.skip_long_tests:
|
if self.skip_long_tests:
|
||||||
return
|
return
|
||||||
|
|
|
@ -4,7 +4,7 @@ import random
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from Options import SpecialRange, Range
|
from Options import SpecialRange, Range
|
||||||
from .option_names import options_to_include
|
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.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, \
|
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
|
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
|
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:
|
for multiworld_id in multiworlds:
|
||||||
multiworld = multiworlds[multiworld_id]
|
multiworld = multiworlds[multiworld_id]
|
||||||
with tester.subTest(f"Checking validity of world {multiworld_id}"):
|
with tester.subTest(f"Checking validity of world {multiworld_id}"):
|
||||||
check_multiworld_is_valid(tester, multiworld_id, multiworld)
|
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_victory_exists(tester, multiworld)
|
||||||
assert_same_number_items_locations(tester, multiworld)
|
assert_same_number_items_locations(tester, multiworld)
|
||||||
assert_goal_world_is_valid(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)
|
assert_festivals_give_access_to_deluxe_scarecrow(tester, multiworld)
|
||||||
|
|
||||||
|
|
||||||
class TestGenerateManyWorlds(SVTestBase):
|
class TestGenerateManyWorlds(SVTestCase):
|
||||||
def test_generate_many_worlds_then_check_results(self):
|
def test_generate_many_worlds_then_check_results(self):
|
||||||
if self.skip_long_tests:
|
if self.skip_long_tests:
|
||||||
return
|
return
|
||||||
|
|
|
@ -7,45 +7,40 @@ class TestBiggerBackpackVanilla(SVTestBase):
|
||||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_vanilla,
|
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_vanilla,
|
||||||
options.Mods.internal_name: ModNames.big_backpack}
|
options.Mods.internal_name: ModNames.big_backpack}
|
||||||
|
|
||||||
def test_no_backpack_in_pool(self):
|
def test_no_backpack(self):
|
||||||
item_names = {item.name for item in self.multiworld.get_items()}
|
with self.subTest(check="no items"):
|
||||||
self.assertNotIn("Progressive Backpack", item_names)
|
item_names = {item.name for item in self.multiworld.get_items()}
|
||||||
|
self.assertNotIn("Progressive Backpack", item_names)
|
||||||
|
|
||||||
def test_no_backpack_locations(self):
|
with self.subTest(check="no locations"):
|
||||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||||
self.assertNotIn("Large Pack", location_names)
|
self.assertNotIn("Large Pack", location_names)
|
||||||
self.assertNotIn("Deluxe Pack", location_names)
|
self.assertNotIn("Deluxe Pack", location_names)
|
||||||
self.assertNotIn("Premium Pack", location_names)
|
self.assertNotIn("Premium Pack", location_names)
|
||||||
|
|
||||||
|
|
||||||
class TestBiggerBackpackProgressive(SVTestBase):
|
class TestBiggerBackpackProgressive(SVTestBase):
|
||||||
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive,
|
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive,
|
||||||
options.Mods.internal_name: ModNames.big_backpack}
|
options.Mods.internal_name: ModNames.big_backpack}
|
||||||
|
|
||||||
def test_backpack_is_in_pool_3_times(self):
|
def test_backpack(self):
|
||||||
item_names = [item.name for item in self.multiworld.get_items()]
|
with self.subTest(check="has items"):
|
||||||
self.assertEqual(item_names.count("Progressive Backpack"), 3)
|
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):
|
with self.subTest(check="has locations"):
|
||||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
location_names = {location.name for location in self.multiworld.get_locations()}
|
||||||
self.assertIn("Large Pack", location_names)
|
self.assertIn("Large Pack", location_names)
|
||||||
self.assertIn("Deluxe Pack", location_names)
|
self.assertIn("Deluxe Pack", location_names)
|
||||||
self.assertIn("Premium 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 = {options.BackpackProgression.internal_name: options.BackpackProgression.option_early_progressive,
|
||||||
options.Mods.internal_name: ModNames.big_backpack}
|
options.Mods.internal_name: ModNames.big_backpack}
|
||||||
|
|
||||||
def test_backpack_is_in_pool_3_times(self):
|
def test_backpack(self):
|
||||||
item_names = [item.name for item in self.multiworld.get_items()]
|
super().test_backpack()
|
||||||
self.assertEqual(item_names.count("Progressive Backpack"), 3)
|
|
||||||
|
|
||||||
def test_3_backpack_locations(self):
|
with self.subTest(check="is early"):
|
||||||
location_names = {location.name for location in self.multiworld.get_locations()}
|
self.assertIn("Progressive Backpack", self.multiworld.early_items[1])
|
||||||
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])
|
|
||||||
|
|
|
@ -4,24 +4,17 @@ import random
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from ...mods.mod_data import ModNames
|
from ...mods.mod_data import all_mods
|
||||||
from .. import setup_solo_multiworld
|
from .. import setup_solo_multiworld, SVTestBase, SVTestCase, allsanity_options_without_mods
|
||||||
from ..TestOptions import basic_checks, SVTestBase
|
from ..TestOptions import basic_checks
|
||||||
from ... import items, Group, ItemClassification
|
from ... import items, Group, ItemClassification
|
||||||
from ...regions import RandomizationFlag, create_final_connections, randomize_connections, create_final_regions
|
from ...regions import RandomizationFlag, create_final_connections, randomize_connections, create_final_regions
|
||||||
from ...items import item_table, items_by_group
|
from ...items import item_table, items_by_group
|
||||||
from ...locations import location_table
|
from ...locations import location_table
|
||||||
from ...options import Mods, EntranceRandomization, Friendsanity, SeasonRandomization, SpecialOrderLocations, ExcludeGingerIsland, TrapItems
|
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: unittest.TestCase, multiworld: MultiWorld):
|
||||||
def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: SVTestBase, multiworld: MultiWorld):
|
|
||||||
if isinstance(chosen_mods, str):
|
if isinstance(chosen_mods, str):
|
||||||
chosen_mods = [chosen_mods]
|
chosen_mods = [chosen_mods]
|
||||||
for multiworld_item in multiworld.get_items():
|
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)
|
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):
|
def test_given_single_mods_when_generate_then_basic_checks(self):
|
||||||
for mod in all_mods:
|
for mod in all_mods:
|
||||||
|
@ -50,6 +43,8 @@ class TestGenerateModsOptions(SVTestBase):
|
||||||
multiworld = setup_solo_multiworld({EntranceRandomization.internal_name: option, Mods: mod})
|
multiworld = setup_solo_multiworld({EntranceRandomization.internal_name: option, Mods: mod})
|
||||||
basic_checks(self, multiworld)
|
basic_checks(self, multiworld)
|
||||||
check_stray_mod_items(mod, 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):
|
class TestBaseItemGeneration(SVTestBase):
|
||||||
|
@ -103,7 +98,7 @@ class TestNoGingerIslandModItemGeneration(SVTestBase):
|
||||||
self.assertIn(progression_item.name, all_created_items)
|
self.assertIn(progression_item.name, all_created_items)
|
||||||
|
|
||||||
|
|
||||||
class TestModEntranceRando(unittest.TestCase):
|
class TestModEntranceRando(SVTestCase):
|
||||||
|
|
||||||
def test_mod_entrance_randomization(self):
|
def test_mod_entrance_randomization(self):
|
||||||
|
|
||||||
|
@ -137,12 +132,12 @@ class TestModEntranceRando(unittest.TestCase):
|
||||||
f"Connections are duplicated in randomization. Seed = {seed}")
|
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):
|
def test_given_traps_when_generate_then_all_traps_in_pool(self):
|
||||||
for value in TrapItems.options:
|
for value in TrapItems.options:
|
||||||
if value == "no_traps":
|
if value == "no_traps":
|
||||||
continue
|
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"})
|
world_options.update({TrapItems.internal_name: TrapItems.options[value], Mods: "Magic"})
|
||||||
multi_world = setup_solo_multiworld(world_options)
|
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]
|
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