Tests: now autoload tests from /worlds/*/test (#1318)

Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
This commit is contained in:
Fabian Dill 2022-12-11 13:15:23 +01:00 committed by GitHub
parent ec45479c52
commit 2dcfbff751
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
81 changed files with 715 additions and 683 deletions

View File

@ -37,4 +37,4 @@ jobs:
python ModuleUpdate.py --yes --force --append "WebHostLib/requirements.txt" python ModuleUpdate.py --yes --force --append "WebHostLib/requirements.txt"
- name: Unittests - name: Unittests
run: | run: |
pytest test pytest

View File

@ -99,7 +99,7 @@ def local_path(*path: str) -> str:
local_path.cached_path = os.path.dirname(os.path.abspath(sys.argv[0])) local_path.cached_path = os.path.dirname(os.path.abspath(sys.argv[0]))
else: else:
import __main__ import __main__
if hasattr(__main__, "__file__"): if hasattr(__main__, "__file__") and os.path.isfile(__main__.__file__):
# we are running in a normal Python environment # we are running in a normal Python environment
local_path.cached_path = os.path.dirname(os.path.abspath(__main__.__file__)) local_path.cached_path = os.path.dirname(os.path.abspath(__main__.__file__))
else: else:

View File

@ -1,12 +1,17 @@
import typing
import unittest import unittest
import pathlib import pathlib
from argparse import Namespace
import Utils import Utils
from test.general import gen_steps
from worlds import AutoWorld
from worlds.AutoWorld import call_all
file_path = pathlib.Path(__file__).parent.parent file_path = pathlib.Path(__file__).parent.parent
Utils.local_path.cached_path = file_path Utils.local_path.cached_path = file_path
from BaseClasses import MultiWorld, CollectionState, ItemClassification from BaseClasses import MultiWorld, CollectionState, ItemClassification, Item
from worlds.alttp.Items import ItemFactory from worlds.alttp.Items import ItemFactory
@ -92,3 +97,94 @@ class TestBase(unittest.TestCase):
new_items.remove(missing_item) new_items.remove(missing_item)
items = ItemFactory(new_items, 1) items = ItemFactory(new_items, 1)
return self.get_state(items) return self.get_state(items)
class WorldTestBase(unittest.TestCase):
options: typing.Dict[str, typing.Any] = {}
multiworld: MultiWorld
game: typing.ClassVar[str] # define game name in subclass, example "Secret of Evermore"
auto_construct: typing.ClassVar[bool] = True
""" automatically set up a world for each test in this class """
def setUp(self) -> None:
if self.auto_construct:
self.world_setup()
def world_setup(self, seed: typing.Optional[int] = None) -> None:
if not hasattr(self, "game"):
raise NotImplementedError("didn't define game name")
self.multiworld = MultiWorld(1)
self.multiworld.game[1] = self.game
self.multiworld.player_name = {1: "Tester"}
self.multiworld.set_seed(seed)
args = Namespace()
for name, option in AutoWorld.AutoWorldRegister.world_types[self.game].option_definitions.items():
setattr(args, name, {
1: option.from_any(self.options.get(name, getattr(option, "default")))
})
self.multiworld.set_options(args)
self.multiworld.set_default_common_options()
for step in gen_steps:
call_all(self.multiworld, step)
def collect_all_but(self, item_names: typing.Union[str, typing.Iterable[str]]) -> None:
if isinstance(item_names, str):
item_names = (item_names,)
for item in self.multiworld.get_items():
if item.name not in item_names:
self.multiworld.state.collect(item)
def get_item_by_name(self, item_name: str) -> Item:
for item in self.multiworld.get_items():
if item.name == item_name:
return item
raise ValueError("No such item")
def get_items_by_name(self, item_names: typing.Union[str, typing.Iterable[str]]) -> typing.List[Item]:
if isinstance(item_names, str):
item_names = (item_names,)
return [item for item in self.multiworld.itempool if item.name in item_names]
def collect_by_name(self, item_names: typing.Union[str, typing.Iterable[str]]) -> typing.List[Item]:
""" collect all of the items in the item pool that have the given names """
items = self.get_items_by_name(item_names)
self.collect(items)
return items
def collect(self, items: typing.Union[Item, typing.Iterable[Item]]) -> None:
if isinstance(items, Item):
items = (items,)
for item in items:
self.multiworld.state.collect(item)
def remove(self, items: typing.Union[Item, typing.Iterable[Item]]) -> None:
if isinstance(items, Item):
items = (items,)
for item in items:
if item.location and item.location.event and item.location in self.multiworld.state.events:
self.multiworld.state.events.remove(item.location)
self.multiworld.state.remove(item)
def can_reach_location(self, location: str) -> bool:
return self.multiworld.state.can_reach(location, "Location", 1)
def count(self, item_name: str) -> int:
return self.multiworld.state.count(item_name, 1)
def assertAccessDependency(self,
locations: typing.List[str],
possible_items: typing.Iterable[typing.Iterable[str]]) -> None:
all_items = [item_name for item_names in possible_items for item_name in item_names]
self.collect_all_but(all_items)
for location in self.multiworld.get_locations():
self.assertEqual(self.multiworld.state.can_reach(location), location.name not in locations)
for item_names in possible_items:
items = self.collect_by_name(item_names)
for location in locations:
self.assertTrue(self.can_reach_location(location))
self.remove(items)
def assertBeatable(self, beatable: bool):
self.assertEqual(self.multiworld.can_beat_game(self.multiworld.state), beatable)

View File

@ -1,2 +1,3 @@
import warnings import warnings
warnings.simplefilter("always") warnings.simplefilter("always")

View File

@ -9,14 +9,13 @@ import os
import ModuleUpdate import ModuleUpdate
ModuleUpdate.update_ran = True # don't upgrade ModuleUpdate.update_ran = True # don't upgrade
import Generate import Generate
import Utils
class TestGenerateMain(unittest.TestCase): class TestGenerateMain(unittest.TestCase):
"""This tests Generate.py (ArchipelagoGenerate.exe) main""" """This tests Generate.py (ArchipelagoGenerate.exe) main"""
generate_dir = Path(Generate.__file__).parent generate_dir = Path(Generate.__file__).parent
run_dir = generate_dir / 'test' # reproducible cwd that's neither __file__ nor Generate.__file__ run_dir = generate_dir / "test" # reproducible cwd that's neither __file__ nor Generate.__file__
abs_input_dir = Path(__file__).parent / 'data' / 'OnePlayer' abs_input_dir = Path(__file__).parent / 'data' / 'OnePlayer'
rel_input_dir = abs_input_dir.relative_to(run_dir) # directly supplied relative paths are relative to cwd rel_input_dir = abs_input_dir.relative_to(run_dir) # directly supplied relative paths are relative to cwd
yaml_input_dir = abs_input_dir.relative_to(generate_dir) # yaml paths are relative to user_path yaml_input_dir = abs_input_dir.relative_to(generate_dir) # yaml paths are relative to user_path
@ -30,12 +29,29 @@ class TestGenerateMain(unittest.TestCase):
f"{list(output_path.glob('*'))}") f"{list(output_path.glob('*'))}")
def setUp(self): def setUp(self):
Utils.local_path.cached_path = str(self.generate_dir) self.original_argv = sys.argv.copy()
self.original_cwd = os.getcwd()
self.original_local_path = Generate.Utils.local_path.cached_path
self.original_user_path = Generate.Utils.user_path.cached_path
# Force both user_path and local_path to a specific path. They have independent caches.
Generate.Utils.user_path.cached_path = Generate.Utils.local_path.cached_path = str(self.generate_dir)
os.chdir(self.run_dir) os.chdir(self.run_dir)
self.output_tempdir = TemporaryDirectory(prefix='AP_out_') self.output_tempdir = TemporaryDirectory(prefix='AP_out_')
def tearDown(self): def tearDown(self):
self.output_tempdir.cleanup() self.output_tempdir.cleanup()
os.chdir(self.original_cwd)
sys.argv = self.original_argv
Generate.Utils.local_path.cached_path = self.original_local_path
Generate.Utils.user_path.cached_path = self.original_user_path
def test_paths(self):
self.assertTrue(os.path.exists(self.generate_dir))
self.assertTrue(os.path.exists(self.run_dir))
self.assertTrue(os.path.exists(self.abs_input_dir))
self.assertTrue(os.path.exists(self.rel_input_dir))
self.assertFalse(os.path.exists(self.yaml_input_dir)) # relative to user_path, not cwd
def test_generate_absolute(self): def test_generate_absolute(self):
sys.argv = [sys.argv[0], '--seed', '0', sys.argv = [sys.argv[0], '--seed', '0',
@ -57,7 +73,7 @@ class TestGenerateMain(unittest.TestCase):
def test_generate_yaml(self): def test_generate_yaml(self):
# override host.yaml # override host.yaml
defaults = Utils.get_options()["generator"] defaults = Generate.Utils.get_options()["generator"]
defaults["player_files_path"] = str(self.yaml_input_dir) defaults["player_files_path"] = str(self.yaml_input_dir)
defaults["players"] = 0 defaults["players"] = 0

View File

@ -0,0 +1,14 @@
def load_tests(loader, standard_tests, pattern):
import os
import unittest
from ..TestBase import file_path
from worlds.AutoWorld import AutoWorldRegister
suite = unittest.TestSuite()
suite.addTests(standard_tests)
folders = [os.path.join(os.path.split(world.__file__)[0], "test")
for world in AutoWorldRegister.world_types.values()]
for folder in folders:
if os.path.exists(folder):
suite.addTests(loader.discover(folder, top_level_dir=file_path))
return suite

View File

@ -1,98 +0,0 @@
import typing
import unittest
from argparse import Namespace
from test.general import gen_steps
from BaseClasses import MultiWorld, Item
from worlds import AutoWorld
from worlds.AutoWorld import call_all
class WorldTestBase(unittest.TestCase):
options: typing.Dict[str, typing.Any] = {}
multiworld: MultiWorld
game: typing.ClassVar[str] # define game name in subclass, example "Secret of Evermore"
auto_construct: typing.ClassVar[bool] = True
""" automatically set up a world for each test in this class """
def setUp(self) -> None:
if self.auto_construct:
self.world_setup()
def world_setup(self, seed: typing.Optional[int] = None) -> None:
if not hasattr(self, "game"):
raise NotImplementedError("didn't define game name")
self.multiworld = MultiWorld(1)
self.multiworld.game[1] = self.game
self.multiworld.player_name = {1: "Tester"}
self.multiworld.set_seed(seed)
args = Namespace()
for name, option in AutoWorld.AutoWorldRegister.world_types[self.game].option_definitions.items():
setattr(args, name, {
1: option.from_any(self.options.get(name, getattr(option, "default")))
})
self.multiworld.set_options(args)
self.multiworld.set_default_common_options()
for step in gen_steps:
call_all(self.multiworld, step)
def collect_all_but(self, item_names: typing.Union[str, typing.Iterable[str]]) -> None:
if isinstance(item_names, str):
item_names = (item_names,)
for item in self.multiworld.get_items():
if item.name not in item_names:
self.multiworld.state.collect(item)
def get_item_by_name(self, item_name: str) -> Item:
for item in self.multiworld.get_items():
if item.name == item_name:
return item
raise ValueError("No such item")
def get_items_by_name(self, item_names: typing.Union[str, typing.Iterable[str]]) -> typing.List[Item]:
if isinstance(item_names, str):
item_names = (item_names,)
return [item for item in self.multiworld.itempool if item.name in item_names]
def collect_by_name(self, item_names: typing.Union[str, typing.Iterable[str]]) -> typing.List[Item]:
""" collect all of the items in the item pool that have the given names """
items = self.get_items_by_name(item_names)
self.collect(items)
return items
def collect(self, items: typing.Union[Item, typing.Iterable[Item]]) -> None:
if isinstance(items, Item):
items = (items,)
for item in items:
self.multiworld.state.collect(item)
def remove(self, items: typing.Union[Item, typing.Iterable[Item]]) -> None:
if isinstance(items, Item):
items = (items,)
for item in items:
if item.location and item.location.event and item.location in self.multiworld.state.events:
self.multiworld.state.events.remove(item.location)
self.multiworld.state.remove(item)
def can_reach_location(self, location: str) -> bool:
return self.multiworld.state.can_reach(location, "Location", 1)
def count(self, item_name: str) -> int:
return self.multiworld.state.count(item_name, 1)
def assertAccessDependency(self,
locations: typing.List[str],
possible_items: typing.Iterable[typing.Iterable[str]]) -> None:
all_items = [item_name for item_names in possible_items for item_name in item_names]
self.collect_all_but(all_items)
for location in self.multiworld.get_locations():
self.assertEqual(self.multiworld.state.can_reach(location), location.name not in locations)
for item_names in possible_items:
items = self.collect_by_name(item_names)
for location in locations:
self.assertTrue(self.can_reach_location(location))
self.remove(items)
def assertBeatable(self, beatable: bool):
self.assertEqual(self.multiworld.can_beat_game(self.multiworld.state), beatable)

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestAgahnimsTower(TestDungeon): class TestAgahnimsTower(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestDarkPalace(TestDungeon): class TestDarkPalace(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestDesertPalace(TestDungeon): class TestDesertPalace(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestEasternPalace(TestDungeon): class TestEasternPalace(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestGanonsTower(TestDungeon): class TestGanonsTower(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestIcePalace(TestDungeon): class TestIcePalace(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestMiseryMire(TestDungeon): class TestMiseryMire(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestSkullWoods(TestDungeon): class TestSkullWoods(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestSwampPalace(TestDungeon): class TestSwampPalace(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestThievesTown(TestDungeon): class TestThievesTown(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.dungeons.TestDungeon import TestDungeon from .TestDungeon import TestDungeon
class TestTowerOfHera(TestDungeon): class TestTowerOfHera(TestDungeon):

View File

@ -1,4 +1,4 @@
from test.inverted.TestInverted import TestInverted from .TestInverted import TestInverted
class TestInvertedDarkWorld(TestInverted): class TestInvertedDarkWorld(TestInverted):

View File

@ -1,4 +1,4 @@
from test.inverted.TestInverted import TestInverted from .TestInverted import TestInverted
class TestInvertedDeathMountain(TestInverted): class TestInvertedDeathMountain(TestInverted):

View File

@ -1,4 +1,4 @@
from test.inverted.TestInverted import TestInverted from .TestInverted import TestInverted
class TestEntrances(TestInverted): class TestEntrances(TestInverted):

View File

@ -1,4 +1,4 @@
from test.inverted.TestInverted import TestInverted from .TestInverted import TestInverted
class TestInvertedLightWorld(TestInverted): class TestInvertedLightWorld(TestInverted):

View File

@ -1,4 +1,4 @@
from test.inverted.TestInverted import TestInverted from .TestInverted import TestInverted
class TestInvertedTurtleRock(TestInverted): class TestInvertedTurtleRock(TestInverted):

View File

@ -1,4 +1,4 @@
from test.inverted_minor_glitches.TestInvertedMinor import TestInvertedMinor from .TestInvertedMinor import TestInvertedMinor
class TestInvertedDarkWorld(TestInvertedMinor): class TestInvertedDarkWorld(TestInvertedMinor):

View File

@ -1,4 +1,4 @@
from test.inverted_minor_glitches.TestInvertedMinor import TestInvertedMinor from .TestInvertedMinor import TestInvertedMinor
class TestInvertedDeathMountain(TestInvertedMinor): class TestInvertedDeathMountain(TestInvertedMinor):

View File

@ -1,4 +1,4 @@
from test.inverted_minor_glitches.TestInvertedMinor import TestInvertedMinor from .TestInvertedMinor import TestInvertedMinor
class TestEntrances(TestInvertedMinor): class TestEntrances(TestInvertedMinor):

View File

@ -1,4 +1,4 @@
from test.inverted_minor_glitches.TestInvertedMinor import TestInvertedMinor from .TestInvertedMinor import TestInvertedMinor
class TestInvertedLightWorld(TestInvertedMinor): class TestInvertedLightWorld(TestInvertedMinor):

View File

@ -1,4 +1,4 @@
from test.inverted_minor_glitches.TestInvertedMinor import TestInvertedMinor from .TestInvertedMinor import TestInvertedMinor
class TestInvertedTurtleRock(TestInvertedMinor): class TestInvertedTurtleRock(TestInvertedMinor):

View File

@ -1,4 +1,4 @@
from test.inverted_owg.TestInvertedOWG import TestInvertedOWG from .TestInvertedOWG import TestInvertedOWG
class TestDarkWorld(TestInvertedOWG): class TestDarkWorld(TestInvertedOWG):

View File

@ -1,4 +1,4 @@
from test.inverted_owg.TestInvertedOWG import TestInvertedOWG from .TestInvertedOWG import TestInvertedOWG
class TestDeathMountain(TestInvertedOWG): class TestDeathMountain(TestInvertedOWG):

View File

@ -1,4 +1,5 @@
from test.inverted_owg.TestInvertedOWG import TestInvertedOWG from .TestInvertedOWG import TestInvertedOWG
class TestDungeons(TestInvertedOWG): class TestDungeons(TestInvertedOWG):

View File

@ -1,4 +1,4 @@
from test.inverted_owg.TestInvertedOWG import TestInvertedOWG from .TestInvertedOWG import TestInvertedOWG
class TestLightWorld(TestInvertedOWG): class TestLightWorld(TestInvertedOWG):

View File

@ -1,4 +1,4 @@
from test.minor_glitches.TestMinor import TestMinor from .TestMinor import TestMinor
class TestDarkWorld(TestMinor): class TestDarkWorld(TestMinor):

View File

@ -1,4 +1,4 @@
from test.minor_glitches.TestMinor import TestMinor from .TestMinor import TestMinor
class TestDeathMountain(TestMinor): class TestDeathMountain(TestMinor):

View File

@ -1,4 +1,4 @@
from test.minor_glitches.TestMinor import TestMinor from .TestMinor import TestMinor
class TestEntrances(TestMinor): class TestEntrances(TestMinor):

View File

@ -1,4 +1,4 @@
from test.minor_glitches.TestMinor import TestMinor from .TestMinor import TestMinor
class TestLightWorld(TestMinor): class TestLightWorld(TestMinor):

View File

@ -1,4 +1,4 @@
from test.owg.TestVanillaOWG import TestVanillaOWG from .TestVanillaOWG import TestVanillaOWG
class TestDarkWorld(TestVanillaOWG): class TestDarkWorld(TestVanillaOWG):

View File

@ -1,4 +1,4 @@
from test.owg.TestVanillaOWG import TestVanillaOWG from .TestVanillaOWG import TestVanillaOWG
class TestDeathMountain(TestVanillaOWG): class TestDeathMountain(TestVanillaOWG):

View File

@ -1,4 +1,4 @@
from test.owg.TestVanillaOWG import TestVanillaOWG from .TestVanillaOWG import TestVanillaOWG
class TestDungeons(TestVanillaOWG): class TestDungeons(TestVanillaOWG):

View File

@ -1,4 +1,4 @@
from test.owg.TestVanillaOWG import TestVanillaOWG from .TestVanillaOWG import TestVanillaOWG
class TestLightWorld(TestVanillaOWG): class TestLightWorld(TestVanillaOWG):

View File

@ -1,4 +1,4 @@
from test.vanilla.TestVanilla import TestVanilla from .TestVanilla import TestVanilla
class TestDarkWorld(TestVanilla): class TestDarkWorld(TestVanilla):

View File

@ -1,4 +1,4 @@
from test.vanilla.TestVanilla import TestVanilla from .TestVanilla import TestVanilla
class TestDeathMountain(TestVanilla): class TestDeathMountain(TestVanilla):

View File

@ -1,4 +1,4 @@
from test.vanilla.TestVanilla import TestVanilla from .TestVanilla import TestVanilla
class TestEntrances(TestVanilla): class TestEntrances(TestVanilla):

View File

@ -1,4 +1,4 @@
from test.vanilla.TestVanilla import TestVanilla from .TestVanilla import TestVanilla
class TestLightWorld(TestVanilla): class TestLightWorld(TestVanilla):

View File

@ -1,4 +1,5 @@
from test.minecraft.TestMinecraft import TestMinecraft from .TestMinecraft import TestMinecraft
# Format: # Format:
# [location, expected_result, given_items, [excluded_items]] # [location, expected_result, given_items, [excluded_items]]

View File

@ -1,4 +1,5 @@
from test.minecraft.TestMinecraft import TestMinecraft from .TestMinecraft import TestMinecraft
class TestEntrances(TestMinecraft): class TestEntrances(TestMinecraft):

View File

@ -1,11 +1,12 @@
import worlds.minecraft.Options
from test.TestBase import TestBase from test.TestBase import TestBase
from BaseClasses import MultiWorld, ItemClassification from BaseClasses import MultiWorld, ItemClassification
from worlds import AutoWorld from worlds import AutoWorld
from worlds.minecraft import MinecraftWorld from worlds.minecraft import MinecraftWorld
from worlds.minecraft.Items import MinecraftItem, item_table from worlds.minecraft.Items import MinecraftItem, item_table
from worlds.minecraft.Options import * from Options import Toggle
from Options import Toggle, Range from worlds.minecraft.Options import AdvancementGoal, EggShardsRequired, EggShardsAvailable, BossGoal, BeeTraps, \
ShuffleStructures, CombatDifficulty
# Converts the name of an item into an item object # Converts the name of an item into an item object
def MCItemFactory(items, player: int): def MCItemFactory(items, player: int):
@ -27,6 +28,7 @@ def MCItemFactory(items, player: int):
return ret[0] return ret[0]
return ret return ret
class TestMinecraft(TestBase): class TestMinecraft(TestBase):
def setUp(self): def setUp(self):
@ -39,10 +41,10 @@ class TestMinecraft(TestBase):
setattr(self.multiworld, "advancement_goal", {1: AdvancementGoal(30)}) setattr(self.multiworld, "advancement_goal", {1: AdvancementGoal(30)})
setattr(self.multiworld, "egg_shards_required", {1: EggShardsRequired(0)}) setattr(self.multiworld, "egg_shards_required", {1: EggShardsRequired(0)})
setattr(self.multiworld, "egg_shards_available", {1: EggShardsAvailable(0)}) setattr(self.multiworld, "egg_shards_available", {1: EggShardsAvailable(0)})
setattr(self.multiworld, "required_bosses", {1: BossGoal(1)}) # ender dragon setattr(self.multiworld, "required_bosses", {1: BossGoal(1)}) # ender dragon
setattr(self.multiworld, "shuffle_structures", {1: ShuffleStructures(False)}) setattr(self.multiworld, "shuffle_structures", {1: ShuffleStructures(False)})
setattr(self.multiworld, "bee_traps", {1: BeeTraps(0)}) setattr(self.multiworld, "bee_traps", {1: BeeTraps(0)})
setattr(self.multiworld, "combat_difficulty", {1: CombatDifficulty(1)}) # normal setattr(self.multiworld, "combat_difficulty", {1: CombatDifficulty(1)}) # normal
setattr(self.multiworld, "structure_compasses", {1: Toggle(False)}) setattr(self.multiworld, "structure_compasses", {1: Toggle(False)})
setattr(self.multiworld, "death_link", {1: Toggle(False)}) setattr(self.multiworld, "death_link", {1: Toggle(False)})
AutoWorld.call_single(self.multiworld, "create_regions", 1) AutoWorld.call_single(self.multiworld, "create_regions", 1)
@ -64,4 +66,3 @@ class TestMinecraft(TestBase):
new_items.remove(missing_item) new_items.remove(missing_item)
items = MCItemFactory(new_items, 1) items = MCItemFactory(new_items, 1)
return self.get_state(items) return self.get_state(items)

View File

@ -1,5 +1,4 @@
import unittest import unittest
import json
from random import Random from random import Random

View File

View File

@ -1,4 +1,4 @@
from test.worlds.test_base import WorldTestBase from test.TestBase import WorldTestBase
class RLTestBase(WorldTestBase): class RLTestBase(WorldTestBase):

View File

@ -1,4 +1,4 @@
from test.worlds.test_base import WorldTestBase from test.TestBase import WorldTestBase
class SoETestBase(WorldTestBase): class SoETestBase(WorldTestBase):

View File

@ -1,4 +1,4 @@
from test.worlds.zillion import ZillionTestBase from . import ZillionTestBase
from worlds.zillion.options import ZillionJumpLevels, ZillionGunLevels, validate from worlds.zillion.options import ZillionJumpLevels, ZillionGunLevels, validate
from zilliandomizer.options import VBLR_CHOICES from zilliandomizer.options import VBLR_CHOICES

View File

@ -1,5 +1,5 @@
from typing import cast from typing import cast
from test.worlds.zillion import ZillionTestBase from . import ZillionTestBase
from worlds.zillion import ZillionWorld from worlds.zillion import ZillionWorld

View File

@ -1,5 +1,5 @@
from typing import cast from typing import cast
from test.worlds.test_base import WorldTestBase from test.TestBase import WorldTestBase
from worlds.zillion import ZillionWorld from worlds.zillion import ZillionWorld