Tests: world test base class (#1116)
* world test base class * game not instance property * I would have guessed that this only collected 1. * game property * move SoE tests into worlds * don't force auto world setup
This commit is contained in:
parent
49ae79e5ce
commit
f12b73f487
|
@ -128,7 +128,7 @@ ipython_config.py
|
||||||
|
|
||||||
# Environments
|
# Environments
|
||||||
.env
|
.env
|
||||||
.venv
|
.venv*
|
||||||
env/
|
env/
|
||||||
venv/
|
venv/
|
||||||
ENV/
|
ENV/
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
from argparse import Namespace
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
from enum import unique, IntEnum, IntFlag
|
from enum import unique, IntEnum, IntFlag
|
||||||
|
@ -54,6 +55,7 @@ class MultiWorld():
|
||||||
indirect_connections: Dict[Region, Set[Entrance]]
|
indirect_connections: Dict[Region, Set[Entrance]]
|
||||||
exclude_locations: Dict[int, Options.ExcludeLocations]
|
exclude_locations: Dict[int, Options.ExcludeLocations]
|
||||||
|
|
||||||
|
game: Dict[int, str]
|
||||||
|
|
||||||
class AttributeProxy():
|
class AttributeProxy():
|
||||||
def __init__(self, rule):
|
def __init__(self, rule):
|
||||||
|
@ -200,7 +202,7 @@ class MultiWorld():
|
||||||
self.slot_seeds = {player: random.Random(self.random.getrandbits(64)) for player in
|
self.slot_seeds = {player: random.Random(self.random.getrandbits(64)) for player in
|
||||||
range(1, self.players + 1)}
|
range(1, self.players + 1)}
|
||||||
|
|
||||||
def set_options(self, args):
|
def set_options(self, args: Namespace) -> None:
|
||||||
for option_key in Options.common_options:
|
for option_key in Options.common_options:
|
||||||
setattr(self, option_key, getattr(args, option_key, {}))
|
setattr(self, option_key, getattr(args, option_key, {}))
|
||||||
for option_key in Options.per_game_common_options:
|
for option_key in Options.per_game_common_options:
|
||||||
|
|
|
@ -78,6 +78,9 @@ class AssembleOptions(abc.ABCMeta):
|
||||||
|
|
||||||
return super(AssembleOptions, mcs).__new__(mcs, name, bases, attrs)
|
return super(AssembleOptions, mcs).__new__(mcs, name, bases, attrs)
|
||||||
|
|
||||||
|
@abc.abstractclassmethod
|
||||||
|
def from_any(cls, value: typing.Any) -> "Option[typing.Any]": ...
|
||||||
|
|
||||||
|
|
||||||
T = typing.TypeVar('T')
|
T = typing.TypeVar('T')
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
from test.worlds.test_base import WorldTestBase
|
||||||
|
|
||||||
|
|
||||||
|
class SoETestBase(WorldTestBase):
|
||||||
|
game = "Secret of Evermore"
|
|
@ -7,54 +7,66 @@ from worlds import AutoWorld
|
||||||
from worlds.AutoWorld import call_all
|
from worlds.AutoWorld import call_all
|
||||||
|
|
||||||
|
|
||||||
class SoETestBase(unittest.TestCase):
|
class WorldTestBase(unittest.TestCase):
|
||||||
options: typing.Dict[str, typing.Any] = {}
|
options: typing.Dict[str, typing.Any] = {}
|
||||||
world: MultiWorld
|
world: MultiWorld
|
||||||
game = "Secret of Evermore"
|
|
||||||
|
|
||||||
def setUp(self):
|
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) -> None:
|
||||||
|
if not hasattr(self, "game"):
|
||||||
|
raise NotImplementedError("didn't define game name")
|
||||||
self.world = MultiWorld(1)
|
self.world = MultiWorld(1)
|
||||||
self.world.game[1] = self.game
|
self.world.game[1] = self.game
|
||||||
self.world.player_name = {1: "Tester"}
|
self.world.player_name = {1: "Tester"}
|
||||||
self.world.set_seed()
|
self.world.set_seed()
|
||||||
args = Namespace()
|
args = Namespace()
|
||||||
for name, option in AutoWorld.AutoWorldRegister.world_types[self.game].option_definitions.items():
|
for name, option in AutoWorld.AutoWorldRegister.world_types[self.game].option_definitions.items():
|
||||||
setattr(args, name, {1: option.from_any(self.options.get(name, option.default))})
|
setattr(args, name, {
|
||||||
|
1: option.from_any(self.options.get(name, getattr(option, "default")))
|
||||||
|
})
|
||||||
self.world.set_options(args)
|
self.world.set_options(args)
|
||||||
self.world.set_default_common_options()
|
self.world.set_default_common_options()
|
||||||
for step in gen_steps:
|
for step in gen_steps:
|
||||||
call_all(self.world, step)
|
call_all(self.world, step)
|
||||||
|
|
||||||
def collect_all_but(self, item_names: typing.Union[str, typing.Iterable[str]]):
|
def collect_all_but(self, item_names: typing.Union[str, typing.Iterable[str]]) -> None:
|
||||||
if isinstance(item_names, str):
|
if isinstance(item_names, str):
|
||||||
item_names = (item_names,)
|
item_names = (item_names,)
|
||||||
for item in self.world.get_items():
|
for item in self.world.get_items():
|
||||||
if item.name not in item_names:
|
if item.name not in item_names:
|
||||||
self.world.state.collect(item)
|
self.world.state.collect(item)
|
||||||
|
|
||||||
def get_item_by_name(self, item_name: str):
|
def get_item_by_name(self, item_name: str) -> Item:
|
||||||
for item in self.world.get_items():
|
for item in self.world.get_items():
|
||||||
if item.name == item_name:
|
if item.name == item_name:
|
||||||
return item
|
return item
|
||||||
raise ValueError("No such item")
|
raise ValueError("No such item")
|
||||||
|
|
||||||
def get_items_by_name(self, item_names: typing.Union[str, typing.Iterable[str]]):
|
def get_items_by_name(self, item_names: typing.Union[str, typing.Iterable[str]]) -> typing.List[Item]:
|
||||||
if isinstance(item_names, str):
|
if isinstance(item_names, str):
|
||||||
item_names = (item_names,)
|
item_names = (item_names,)
|
||||||
return [item for item in self.world.itempool if item.name in item_names]
|
return [item for item in self.world.itempool if item.name in item_names]
|
||||||
|
|
||||||
def collect_by_name(self, item_names: typing.Union[str, typing.Iterable[str]]):
|
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)
|
items = self.get_items_by_name(item_names)
|
||||||
self.collect(items)
|
self.collect(items)
|
||||||
return items
|
return items
|
||||||
|
|
||||||
def collect(self, items: typing.Union[Item, typing.Iterable[Item]]):
|
def collect(self, items: typing.Union[Item, typing.Iterable[Item]]) -> None:
|
||||||
if isinstance(items, Item):
|
if isinstance(items, Item):
|
||||||
items = (items,)
|
items = (items,)
|
||||||
for item in items:
|
for item in items:
|
||||||
self.world.state.collect(item)
|
self.world.state.collect(item)
|
||||||
|
|
||||||
def remove(self, items: typing.Union[Item, typing.Iterable[Item]]):
|
def remove(self, items: typing.Union[Item, typing.Iterable[Item]]) -> None:
|
||||||
if isinstance(items, Item):
|
if isinstance(items, Item):
|
||||||
items = (items,)
|
items = (items,)
|
||||||
for item in items:
|
for item in items:
|
||||||
|
@ -62,13 +74,15 @@ class SoETestBase(unittest.TestCase):
|
||||||
self.world.state.events.remove(item.location)
|
self.world.state.events.remove(item.location)
|
||||||
self.world.state.remove(item)
|
self.world.state.remove(item)
|
||||||
|
|
||||||
def can_reach_location(self, location):
|
def can_reach_location(self, location: str) -> bool:
|
||||||
return self.world.state.can_reach(location, "Location", 1)
|
return self.world.state.can_reach(location, "Location", 1)
|
||||||
|
|
||||||
def count(self, item_name):
|
def count(self, item_name: str) -> int:
|
||||||
return self.world.state.count(item_name, 1)
|
return self.world.state.count(item_name, 1)
|
||||||
|
|
||||||
def assertAccessDependency(self, locations, possible_items):
|
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]
|
all_items = [item_name for item_names in possible_items for item_name in item_names]
|
||||||
|
|
||||||
self.collect_all_but(all_items)
|
self.collect_all_but(all_items)
|
Loading…
Reference in New Issue