155 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Python
		
	
	
	
import itertools
 | 
						|
import unittest
 | 
						|
 | 
						|
from BaseClasses import ItemClassification, MultiWorld
 | 
						|
from Options import SpecialRange
 | 
						|
from . import setup_solo_multiworld, SVTestBase
 | 
						|
from .. import StardewItem, options
 | 
						|
from ..options import StardewOption, stardew_valley_option_classes
 | 
						|
 | 
						|
SEASONS = {"Spring", "Summer", "Fall", "Winter"}
 | 
						|
TOOLS = {"Hoe", "Pickaxe", "Axe", "Watering Can", "Trash Can", "Fishing Rod"}
 | 
						|
 | 
						|
 | 
						|
def assert_can_win(multiworld: MultiWorld):
 | 
						|
    for item in multiworld.get_items():
 | 
						|
        multiworld.state.collect(item)
 | 
						|
 | 
						|
    assert multiworld.find_item("Victory", 1).can_reach(multiworld.state)
 | 
						|
 | 
						|
 | 
						|
def basic_checks(multiworld: MultiWorld):
 | 
						|
    assert StardewItem("Victory", ItemClassification.progression, None, 1) in multiworld.get_items()
 | 
						|
    assert_can_win(multiworld)
 | 
						|
    assert len(multiworld.itempool) == len(
 | 
						|
        [location for location in multiworld.get_locations() if not location.event])
 | 
						|
 | 
						|
 | 
						|
class TestGenerateDynamicOptions(SVTestBase):
 | 
						|
    def test_given_special_range_when_generate_then_basic_checks(self):
 | 
						|
        for option in stardew_valley_option_classes:
 | 
						|
            if not issubclass(option, SpecialRange):
 | 
						|
                continue
 | 
						|
            with self.subTest(msg=option.internal_name):
 | 
						|
                for value in option.special_range_names:
 | 
						|
                    multiworld = setup_solo_multiworld({option.internal_name: option.special_range_names[value]})
 | 
						|
                    basic_checks(multiworld)
 | 
						|
 | 
						|
    def test_given_choice_when_generate_then_basic_checks(self):
 | 
						|
        for option in stardew_valley_option_classes:
 | 
						|
            if not option.options:
 | 
						|
                continue
 | 
						|
            with self.subTest(msg=option.internal_name):
 | 
						|
                for value in option.options:
 | 
						|
                    multiworld = setup_solo_multiworld({option.internal_name: option.options[value]})
 | 
						|
                    basic_checks(multiworld)
 | 
						|
 | 
						|
    def test_given_option_combination_when_generate_then_basic_checks(self):
 | 
						|
        option_combinations = [{options.Goal.internal_name: options.Goal.option_master_angler,
 | 
						|
                               options.ToolProgression.internal_name: options.ToolProgression.option_vanilla}]
 | 
						|
        ids = ["Master Angler + Vanilla tools"]
 | 
						|
 | 
						|
        for i in range(0, len(option_combinations)):
 | 
						|
            option_combination = option_combinations[i]
 | 
						|
            id = ids[i]
 | 
						|
            with self.subTest(msg=f"{id}"):
 | 
						|
                multi_world = setup_solo_multiworld(option_combination)
 | 
						|
                basic_checks(multi_world)
 | 
						|
 | 
						|
 | 
						|
class TestGoal(SVTestBase):
 | 
						|
    def test_given_goal_when_generate_then_victory_is_in_correct_location(self):
 | 
						|
        for goal, location in [("community_center", "Complete Community Center"),
 | 
						|
                                               ("grandpa_evaluation", "Succeed Grandpa's Evaluation"),
 | 
						|
                                               ("bottom_of_the_mines", "Reach the Bottom of The Mines"),
 | 
						|
                                               ("cryptic_note", "Complete Quest Cryptic Note"),
 | 
						|
                                               ("master_angler", "Catch Every Fish")]:
 | 
						|
            with self.subTest(msg=f"Goal: {goal}, Location: {location}"):
 | 
						|
                world_options = {options.Goal.internal_name: options.Goal.options[goal]}
 | 
						|
                multi_world = setup_solo_multiworld(world_options)
 | 
						|
                victory = multi_world.find_item("Victory", 1)
 | 
						|
                assert victory.name == location
 | 
						|
 | 
						|
 | 
						|
class TestSeasonRandomization(SVTestBase):
 | 
						|
    def test_given_disabled_when_generate_then_all_seasons_are_precollected(self):
 | 
						|
        world_options = {options.SeasonRandomization.internal_name: options.SeasonRandomization.option_disabled}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
 | 
						|
        precollected_items = {item.name for item in multi_world.precollected_items[1]}
 | 
						|
        assert all([season in precollected_items for season in SEASONS])
 | 
						|
 | 
						|
    def test_given_randomized_when_generate_then_all_seasons_are_in_the_pool_or_precollected(self):
 | 
						|
        world_options = {options.SeasonRandomization.internal_name: options.SeasonRandomization.option_randomized}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
        precollected_items = {item.name for item in multi_world.precollected_items[1]}
 | 
						|
        items = {item.name for item in multi_world.get_items()} | precollected_items
 | 
						|
        assert all([season in items for season in SEASONS])
 | 
						|
        assert len(SEASONS.intersection(precollected_items)) == 1
 | 
						|
 | 
						|
    def test_given_progressive_when_generate_then_3_progressive_seasons_are_in_the_pool(self):
 | 
						|
        world_options = {options.SeasonRandomization.internal_name: options.SeasonRandomization.option_progressive}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
 | 
						|
        items = [item.name for item in multi_world.get_items()]
 | 
						|
        assert items.count("Progressive Season") == 3
 | 
						|
 | 
						|
 | 
						|
class TestBackpackProgression(SVTestBase):
 | 
						|
    def test_given_vanilla_when_generate_then_no_backpack_in_pool(self):
 | 
						|
        world_options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_vanilla}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
 | 
						|
        assert "Progressive Backpack" not in {item.name for item in multi_world.get_items()}
 | 
						|
 | 
						|
    def test_given_progressive_when_generate_then_progressive_backpack_is_in_pool_two_times(self):
 | 
						|
        world_options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
        items = [item.name for item in multi_world.get_items()]
 | 
						|
        assert items.count("Progressive Backpack") == 2
 | 
						|
 | 
						|
    def test_given_progressive_when_generate_then_backpack_upgrades_are_locations(self):
 | 
						|
        world_options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
 | 
						|
        locations = {locations.name for locations in multi_world.get_locations(1)}
 | 
						|
        assert "Large Pack" in locations
 | 
						|
        assert "Deluxe Pack" in locations
 | 
						|
 | 
						|
    def test_given_early_progressive_when_generate_then_progressive_backpack_is_in_early_pool(self):
 | 
						|
        world_options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_early_progressive}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
 | 
						|
        assert "Progressive Backpack" in multi_world.early_items[1]
 | 
						|
 | 
						|
 | 
						|
class TestToolProgression(SVTestBase):
 | 
						|
    def test_given_vanilla_when_generate_then_no_tool_in_pool(self):
 | 
						|
        world_options = {options.ToolProgression.internal_name: options.ToolProgression.option_vanilla}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
 | 
						|
        items = {item.name for item in multi_world.get_items()}
 | 
						|
        for tool in TOOLS:
 | 
						|
            assert tool not in items
 | 
						|
 | 
						|
    def test_given_progressive_when_generate_then_progressive_tool_of_each_is_in_pool_four_times(self):
 | 
						|
        world_options = {options.ToolProgression.internal_name:options.ToolProgression.option_progressive}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
 | 
						|
        items = [item.name for item in multi_world.get_items()]
 | 
						|
        for tool in TOOLS:
 | 
						|
            assert items.count("Progressive " + tool) == 4
 | 
						|
 | 
						|
    def test_given_progressive_when_generate_then_tool_upgrades_are_locations(self):
 | 
						|
        world_options = {options.ToolProgression.internal_name: options.ToolProgression.option_progressive}
 | 
						|
        multi_world = setup_solo_multiworld(world_options)
 | 
						|
 | 
						|
        locations = {locations.name for locations in multi_world.get_locations(1)}
 | 
						|
        for material, tool in itertools.product(["Copper", "Iron", "Gold", "Iridium"],
 | 
						|
                                                ["Hoe", "Pickaxe", "Axe", "Watering Can", "Trash Can"]):
 | 
						|
            assert f"{material} {tool} Upgrade" in locations
 | 
						|
        assert "Purchase Training Rod" in locations
 | 
						|
        assert "Bamboo Pole Cutscene" in locations
 | 
						|
        assert "Purchase Fiberglass Rod" in locations
 | 
						|
        assert "Purchase Iridium Rod" in locations
 |