Tests: datapackage and more multiworld renaming (#1454)

* Tests: add a test that created items and locations exist in the datapackage

* move FF validation to `assert_generate` and remove test exclusion

* test created location addresses are correct

* make the assertion proper and more verbose

* make item count test ~~a bit faster~~ a lot nicer

* 120 blaze it

* name test multiworld setup better and fix another over 120 line in FFR
This commit is contained in:
alwaysintreble 2023-02-15 15:46:10 -06:00 committed by GitHub
parent f078750b72
commit 8af7908cd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 32 deletions

View File

@ -1,24 +1,24 @@
import unittest
from worlds.AutoWorld import AutoWorldRegister
from . import setup_default_world
from . import setup_solo_multiworld
class TestImplemented(unittest.TestCase):
def testCompletionCondition(self):
"""Ensure a completion condition is set that has requirements."""
for game_name, world_type in AutoWorldRegister.world_types.items():
if not world_type.hidden and game_name not in {"ArchipIDLE", "Final Fantasy", "Sudoku"}:
if not world_type.hidden and game_name not in {"ArchipIDLE", "Sudoku"}:
with self.subTest(game_name):
multiworld = setup_default_world(world_type)
multiworld = setup_solo_multiworld(world_type)
self.assertFalse(multiworld.completion_condition[1](multiworld.state))
def testEntranceParents(self):
"""Tests that the parents of created Entrances match the exiting Region."""
for game_name, world_type in AutoWorldRegister.world_types.items():
if not world_type.hidden and game_name not in {"Final Fantasy"}:
if not world_type.hidden:
with self.subTest(game_name):
multiworld = setup_default_world(world_type)
multiworld = setup_solo_multiworld(world_type)
for region in multiworld.regions:
for exit in region.exits:
self.assertEqual(exit.parent_region, region)

View File

@ -1,6 +1,6 @@
import unittest
from worlds.AutoWorld import AutoWorldRegister
from . import setup_default_world
from . import setup_solo_multiworld
class TestBase(unittest.TestCase):
@ -43,14 +43,18 @@ class TestBase(unittest.TestCase):
def testItemCountGreaterEqualLocations(self):
for game_name, world_type in AutoWorldRegister.world_types.items():
if game_name in {"Final Fantasy"}:
continue
with self.subTest("Game", game=game_name):
world = setup_default_world(world_type)
location_count = sum(0 if location.event or location.item else 1 for location in world.get_locations())
multiworld = setup_solo_multiworld(world_type)
self.assertGreaterEqual(
len(world.itempool),
location_count,
f"{game_name} Item count MUST meet or exceede the number of locations",
len(multiworld.itempool),
len(multiworld.get_unfilled_locations()),
f"{game_name} Item count MUST meet or exceed the number of locations",
)
def testItemsInDatapackage(self):
"""Test that any created items in the itempool are in the datapackage"""
for game_name, world_type in AutoWorldRegister.world_types.items():
with self.subTest("Game", game=game_name):
multiworld = setup_solo_multiworld(world_type)
for item in multiworld.itempool:
self.assertIn(item.name, world_type.item_name_to_id)

View File

@ -1,16 +1,25 @@
import unittest
from collections import Counter
from worlds.AutoWorld import AutoWorldRegister
from . import setup_default_world
from . import setup_solo_multiworld
class TestBase(unittest.TestCase):
def testCreateDuplicateLocations(self):
"""Tests that no two Locations share a name."""
for game_name, world_type in AutoWorldRegister.world_types.items():
if game_name in {"Final Fantasy"}:
continue
multiworld = setup_default_world(world_type)
multiworld = setup_solo_multiworld(world_type)
locations = Counter(multiworld.get_locations())
if locations:
self.assertLessEqual(locations.most_common(1)[0][1], 1,
f"{world_type.game} has duplicate of location {locations.most_common(1)}")
def testLocationsInDatapackage(self):
"""Tests that created locations not filled before fill starts exist in the datapackage."""
for game_name, world_type in AutoWorldRegister.world_types.items():
with self.subTest("Game", game_name=game_name):
multiworld = setup_solo_multiworld(world_type)
locations = multiworld.get_unfilled_locations() # do unfilled locations to avoid Events
for location in locations:
self.assertIn(location.name, world_type.location_name_to_id)
self.assertEqual(location.address, world_type.location_name_to_id[location.name])

View File

@ -3,7 +3,7 @@ import unittest
from BaseClasses import CollectionState
from worlds.AutoWorld import AutoWorldRegister
from . import setup_default_world
from . import setup_solo_multiworld
class TestBase(unittest.TestCase):
@ -12,9 +12,9 @@ class TestBase(unittest.TestCase):
def testAllStateCanReachEverything(self):
for game_name, world_type in AutoWorldRegister.world_types.items():
# Final Fantasy logic is controlled by finalfantasyrandomizer.com
if game_name not in {"Ori and the Blind Forest", "Final Fantasy"}: # TODO: fix Ori Logic
if game_name not in {"Ori and the Blind Forest"}: # TODO: fix Ori Logic
with self.subTest("Game", game=game_name):
world = setup_default_world(world_type)
world = setup_solo_multiworld(world_type)
excluded = world.exclude_locations[1].value
state = world.get_all_state(False)
for location in world.get_locations():
@ -28,9 +28,9 @@ class TestBase(unittest.TestCase):
def testEmptyStateCanReachSomething(self):
for game_name, world_type in AutoWorldRegister.world_types.items():
# Final Fantasy logic is controlled by finalfantasyrandomizer.com
if game_name not in {"Archipelago", "Final Fantasy", "Sudoku"}:
if game_name not in {"Archipelago", "Sudoku"}:
with self.subTest("Game", game=game_name):
world = setup_default_world(world_type)
world = setup_solo_multiworld(world_type)
state = CollectionState(world)
locations = set()
for location in world.get_locations():

View File

@ -6,7 +6,7 @@ from worlds.AutoWorld import call_all
gen_steps = ["generate_early", "create_regions", "create_items", "set_rules", "generate_basic", "pre_fill"]
def setup_default_world(world_type) -> MultiWorld:
def setup_solo_multiworld(world_type) -> MultiWorld:
multiworld = MultiWorld(1)
multiworld.game[1] = world_type.game
multiworld.player_name = {1: "Tester"}

View File

@ -45,8 +45,14 @@ class FF1World(World):
self.locked_items = []
self.locked_locations = []
def generate_early(self):
return
@classmethod
def stage_assert_generate(cls, multiworld: MultiWorld) -> None:
# Fail generation if there are no items in the pool
for player in multiworld.get_game_players(cls.game):
options = get_options(multiworld, 'items', player)
assert options,\
f"FFR settings submitted with no key items ({multiworld.get_player_name(player)}). Please ensure you " \
f"generated the settings using finalfantasyrandomizer.com AND enabled the AP flag"
def create_regions(self):
locations = get_options(self.multiworld, 'locations', self.player)
@ -65,8 +71,8 @@ class FF1World(World):
terminated_event.access_rule = goal_rule_and_shards
if "MARK" in items.keys():
# Fail generation for Noverworld and provide link to old FFR website
raise Exception("FFR Noverworld seeds must be generated on an older version of FFR. Please ensure you generated the settings using "
"4-4-0.finalfantasyrandomizer.com")
raise Exception("FFR Noverworld seeds must be generated on an older version of FFR. Please ensure you "
"generated the settings using 4-4-0.finalfantasyrandomizer.com")
menu_region.locations.append(terminated_event)
self.multiworld.regions += [menu_region]
@ -85,10 +91,6 @@ class FF1World(World):
if possible_early_items:
progression_item = self.multiworld.random.choice(possible_early_items)
self._place_locked_item_in_sphere0(progression_item)
else:
# Fail generation if there are no items in the pool
raise Exception("FFR settings submitted with no key items. Please ensure you generated the settings using "
"finalfantasyrandomizer.com AND enabled the AP flag")
items = [self.create_item(name) for name, data in items.items() for x in range(data['count']) if name not in
self.locked_items]