Skip to content

Commit

Permalink
Merge pull request #266 from melvio/262-support-graceful-degradation-…
Browse files Browse the repository at this point in the history
…for-new-pets-and-new-potions-hopla-feed-all

262 support graceful degradation for new pets and new potions hopla feed all
  • Loading branch information
melvio authored Sep 23, 2024
2 parents 4fa8615 + ad374b1 commit d54a630
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 11 deletions.
5 changes: 3 additions & 2 deletions src/hopla/cli/feed_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __get_feed_plan_or_exit() -> Union[NoReturn, FeedPlan]:
"""Get the user and build the feed plan"""
user: HabiticaUser = HabiticaUserRequest().request_user_data_or_exit()
stockpile: FoodStockpile = FoodStockpileBuilder().user(user).build()
zoo: Zoo = ZooBuilder(user).build()
zoo: Zoo = ZooBuilder(user).build(skip_unsupported_pets=True)

algorithm = FeedAlgorithm(zoo=zoo, stockpile=stockpile)
return algorithm.make_plan()
Expand Down Expand Up @@ -100,7 +100,8 @@ def feed_all(no_interactive: bool) -> None:
click.echo(
"The feed plan is empty. Reasons for this could be:\n"
"1. There is insufficient food available to turn pets into mounts.\n"
"2. You don't have any feedable pets."
"2. You don't have any feedable pets\n"
"3. You do have feedable pets, but they are not supported yet by hopla\n"
)
sys.exit(0)

Expand Down
2 changes: 1 addition & 1 deletion src/hopla/hoplalib/hoplaversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

MAJOR_VERSION: Final[int] = 0
MINOR_VERSION: Final[int] = 0
PATCH_VERSION: Final[int] = 43
PATCH_VERSION: Final[int] = 44
PRE_RELEASE: Final[Optional[str]] = "alpha"


Expand Down
15 changes: 12 additions & 3 deletions src/hopla/hoplalib/zoo/zoomodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
"""
Module with models for collections of pets and mounts.
"""
import logging
from typing import Callable, Dict
from dataclasses import dataclass

from hopla.cli.groupcmds.get_user import HabiticaUser
from hopla.hoplalib.zoo.foodmodels import FeedStatus
from hopla.hoplalib.zoo.petdata import PetData
from hopla.hoplalib.zoo.petmodels import Mount, Pet, PetMountPair

Zoo = Dict[str, PetMountPair]
Expand Down Expand Up @@ -73,13 +75,20 @@ def __init__(self, user: HabiticaUser):
def __repr__(self):
return self.__class__.__name__ + f"({self.__dict__})"

def build(self) -> Zoo:
"""Create the Zoo. Return the Zoo in case of success"""
def build(self, skip_unsupported_pets: bool = False) -> Zoo:
""" Build the Zoo.
:param skip_unsupported_pets: if True, skip unsupported pets (excludes mounts)
:return: the Zoo in case of success
"""

# loop through the pets
for pet_name, feed_status in self.pets.items():
pet = Pet(pet_name, feed_status=FeedStatus(feed_status))
if skip_unsupported_pets and (pet_name not in PetData.pet_names):
logging.error(f"{pet_name=} not supported yet: skipped {pet_name}")
continue

pet = Pet(pet_name, feed_status=FeedStatus(feed_status))
if self.mounts.get(pet_name) is not None:
mount = Mount(
mount_name=pet_name,
Expand Down
4 changes: 3 additions & 1 deletion src/tests/cli/test_feed_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ def test_feed_released_pets(self, mock_user_request: MagicMock,

expected_msg = ("The feed plan is empty. Reasons for this could be:\n"
"1. There is insufficient food available to turn pets into mounts.\n"
"2. You don't have any feedable pets.")
"2. You don't have any feedable pets\n"
"3. You do have feedable pets, but they are not supported yet by hopla\n")

assert expected_msg in result.stdout

@pytest.fixture
Expand Down
33 changes: 29 additions & 4 deletions src/tests/hoplalib/zoo/test_zoomodels.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env python3
import pytest

from hopla.cli.groupcmds.get_user import HabiticaUser
from hopla.hoplalib.zoo.foodmodels import FeedStatus
from hopla.hoplalib.zoo.petmodels import Pet, PetMountPair
from hopla.hoplalib.zoo.petmodels import Pet, PetMountPair, InvalidPet
from hopla.hoplalib.zoo.zoomodels import Zoo, ZooBuilder, ZooHelper
from tests.testutils.user_test_utils import UserTestUtil

Expand Down Expand Up @@ -39,9 +41,6 @@ def test_build_empty_zoo(self):

assert zoo == {}

def test_build_released_zoo(self):
pass

def test_build_raised_pets(self):
animal_name = "BearCub-Shadow"
feed_status = -1 # i.e. No pet, just mount
Expand Down Expand Up @@ -84,6 +83,32 @@ def test_build_yes_pet_no_mount(self):
assert result_pair.mount_available() is False
assert result_pair.pet_available()

def test_build_not_supported_pets_fails(self):
animal_name_supported = "Dragon-Skeleton"
animal_name_not_supported = "Dragon-NOTSUPPORTED"
user = UserTestUtil.user_with_zoo(pets={animal_name_supported: 5, animal_name_not_supported: 5})

with pytest.raises(InvalidPet) as exc:
ZooBuilder(user).build()

assert animal_name_not_supported in str(exc.value)
assert animal_name_supported not in str(exc.value)

def test_build_not_supported_pets_success(self):
animal_name_supported = "Dragon-Skeleton"
animal_name_not_supported = "Dragon-NOTSUPPORTED"
feed_status = 5
user = UserTestUtil.user_with_zoo(pets={animal_name_supported: feed_status,
animal_name_not_supported: feed_status})

zoo: Zoo = ZooBuilder(user).build(skip_unsupported_pets=True)

assert len(zoo) == 1
result_pair: PetMountPair = zoo[animal_name_supported]
assert result_pair.pet.name == animal_name_supported
assert result_pair.pet.feed_status == FeedStatus(feed_status)
assert result_pair.mount_available() is False


class TestZooHelper:
def test_filter_on_pet_mount_pair(self):
Expand Down

0 comments on commit d54a630

Please sign in to comment.