160 lines
5.6 KiB
Python
160 lines
5.6 KiB
Python
import unittest
|
|
from collections import Counter
|
|
from typing import ClassVar, Set
|
|
|
|
from . import SVTestBase
|
|
from ..content.feature import friendsanity
|
|
from ..options import Friendsanity, FriendsanityHeartSize
|
|
|
|
all_vanilla_bachelor = {
|
|
"Harvey", "Elliott", "Sam", "Alex", "Shane", "Sebastian", "Emily", "Haley", "Leah", "Abigail", "Penny", "Maru"
|
|
}
|
|
|
|
all_vanilla_starting_npc = {
|
|
"Alex", "Elliott", "Harvey", "Sam", "Sebastian", "Shane", "Abigail", "Emily", "Haley", "Leah", "Maru", "Penny", "Caroline", "Clint", "Demetrius", "Evelyn",
|
|
"George", "Gus", "Jas", "Jodi", "Lewis", "Linus", "Marnie", "Pam", "Pierre", "Robin", "Vincent", "Willy", "Wizard", "Pet",
|
|
}
|
|
|
|
all_vanilla_npc = {
|
|
"Alex", "Elliott", "Harvey", "Sam", "Sebastian", "Shane", "Abigail", "Emily", "Haley", "Leah", "Maru", "Penny", "Caroline", "Clint", "Demetrius", "Evelyn",
|
|
"George", "Gus", "Jas", "Jodi", "Lewis", "Linus", "Marnie", "Pam", "Pierre", "Robin", "Vincent", "Willy", "Wizard", "Pet", "Sandy", "Dwarf", "Kent", "Leo",
|
|
"Krobus"
|
|
}
|
|
|
|
|
|
class SVFriendsanityTestBase(SVTestBase):
|
|
expected_npcs: ClassVar[Set[str]] = set()
|
|
expected_pet_heart_size: ClassVar[Set[str]] = set()
|
|
expected_bachelor_heart_size: ClassVar[Set[str]] = set()
|
|
expected_other_heart_size: ClassVar[Set[str]] = set()
|
|
|
|
@classmethod
|
|
def setUpClass(cls) -> None:
|
|
if cls is SVFriendsanityTestBase:
|
|
raise unittest.SkipTest("Base tests disabled")
|
|
|
|
super().setUpClass()
|
|
|
|
def test_friendsanity(self):
|
|
with self.subTest("Items are valid"):
|
|
self.check_all_items_match_expected_npcs()
|
|
with self.subTest("Correct number of items"):
|
|
self.check_correct_number_of_items()
|
|
with self.subTest("Locations are valid"):
|
|
self.check_all_locations_match_expected_npcs()
|
|
with self.subTest("Locations heart size are valid"):
|
|
self.check_all_locations_match_heart_size()
|
|
|
|
def check_all_items_match_expected_npcs(self):
|
|
npc_names = {
|
|
name
|
|
for item in self.multiworld.itempool
|
|
if (name := friendsanity.extract_npc_from_item_name(item.name)) is not None
|
|
}
|
|
|
|
self.assertEqual(npc_names, self.expected_npcs)
|
|
|
|
def check_correct_number_of_items(self):
|
|
item_by_npc = Counter()
|
|
for item in self.multiworld.itempool:
|
|
name = friendsanity.extract_npc_from_item_name(item.name)
|
|
if name is None:
|
|
continue
|
|
|
|
item_by_npc[name] += 1
|
|
|
|
for name, count in item_by_npc.items():
|
|
|
|
if name == "Pet":
|
|
self.assertEqual(count, len(self.expected_pet_heart_size))
|
|
elif self.world.content.villagers[name].bachelor:
|
|
self.assertEqual(count, len(self.expected_bachelor_heart_size))
|
|
else:
|
|
self.assertEqual(count, len(self.expected_other_heart_size))
|
|
|
|
def check_all_locations_match_expected_npcs(self):
|
|
npc_names = {
|
|
name_and_heart[0]
|
|
for location_name in self.get_real_location_names()
|
|
if (name_and_heart := friendsanity.extract_npc_from_location_name(location_name))[0] is not None
|
|
}
|
|
|
|
self.assertEqual(npc_names, self.expected_npcs)
|
|
|
|
def check_all_locations_match_heart_size(self):
|
|
for location_name in self.get_real_location_names():
|
|
name, heart_size = friendsanity.extract_npc_from_location_name(location_name)
|
|
if name is None:
|
|
continue
|
|
|
|
if name == "Pet":
|
|
self.assertIn(heart_size, self.expected_pet_heart_size)
|
|
elif self.world.content.villagers[name].bachelor:
|
|
self.assertIn(heart_size, self.expected_bachelor_heart_size)
|
|
else:
|
|
self.assertIn(heart_size, self.expected_other_heart_size)
|
|
|
|
|
|
class TestFriendsanityNone(SVFriendsanityTestBase):
|
|
options = {
|
|
Friendsanity: Friendsanity.option_none,
|
|
}
|
|
|
|
@property
|
|
def run_default_tests(self) -> bool:
|
|
# None is default
|
|
return False
|
|
|
|
|
|
class TestFriendsanityBachelors(SVFriendsanityTestBase):
|
|
options = {
|
|
Friendsanity: Friendsanity.option_bachelors,
|
|
FriendsanityHeartSize: 1,
|
|
}
|
|
expected_npcs = all_vanilla_bachelor
|
|
expected_bachelor_heart_size = {1, 2, 3, 4, 5, 6, 7, 8}
|
|
|
|
|
|
class TestFriendsanityStartingNpcs(SVFriendsanityTestBase):
|
|
options = {
|
|
Friendsanity: Friendsanity.option_starting_npcs,
|
|
FriendsanityHeartSize: 1,
|
|
}
|
|
expected_npcs = all_vanilla_starting_npc
|
|
expected_pet_heart_size = {1, 2, 3, 4, 5}
|
|
expected_bachelor_heart_size = {1, 2, 3, 4, 5, 6, 7, 8}
|
|
expected_other_heart_size = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
|
|
|
|
|
class TestFriendsanityAllNpcs(SVFriendsanityTestBase):
|
|
options = {
|
|
Friendsanity: Friendsanity.option_all,
|
|
FriendsanityHeartSize: 4,
|
|
}
|
|
expected_npcs = all_vanilla_npc
|
|
expected_pet_heart_size = {4, 5}
|
|
expected_bachelor_heart_size = {4, 8}
|
|
expected_other_heart_size = {4, 8, 10}
|
|
|
|
|
|
class TestFriendsanityHeartSize3(SVFriendsanityTestBase):
|
|
options = {
|
|
Friendsanity: Friendsanity.option_all_with_marriage,
|
|
FriendsanityHeartSize: 3,
|
|
}
|
|
expected_npcs = all_vanilla_npc
|
|
expected_pet_heart_size = {3, 5}
|
|
expected_bachelor_heart_size = {3, 6, 9, 12, 14}
|
|
expected_other_heart_size = {3, 6, 9, 10}
|
|
|
|
|
|
class TestFriendsanityHeartSize5(SVFriendsanityTestBase):
|
|
options = {
|
|
Friendsanity: Friendsanity.option_all_with_marriage,
|
|
FriendsanityHeartSize: 5,
|
|
}
|
|
expected_npcs = all_vanilla_npc
|
|
expected_pet_heart_size = {5}
|
|
expected_bachelor_heart_size = {5, 10, 14}
|
|
expected_other_heart_size = {5, 10}
|