diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000000000000000000000000000000000000..58c84c7994feb962663602fbd7150f06c6f312b7 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,4 @@ +[report] +exclude_lines = + if TYPE_CHECKING: + if __name__ == .__main__.: \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4a4f3ff04809f1a00e2621a8e8771a991b8f3873..d7fbaa1bf993c21c9d51759ebe9e56487eaabe6a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ pytest: - apt-get update -qy - apt-get install -y python3-dev python3-pip graphviz graphviz-dev - pip install '.[test]' - - pytest --cov --cov-report term-missing --cov-report xml:./coverage.xml --junitxml=./test.xml + - pytest --cov --cov-report term-missing --cov-report xml:./coverage.xml --junitxml=./test.xml --cov-config=.coveragerc coverage: '/^TOTAL .+?(\d+%)$/' artifacts: reports: diff --git a/cooperative_cuisine/configs/layouts/basic.layout b/cooperative_cuisine/configs/layouts/basic.layout index f3d0c2ec5af7857c4af42841d154a677fd31b21b..556080f3de7eccbc827bb77b3e74058b4ef55c64 100644 --- a/cooperative_cuisine/configs/layouts/basic.layout +++ b/cooperative_cuisine/configs/layouts/basic.layout @@ -1,5 +1,5 @@ #QU#FO#TNLB# -#__________M +@__________M |__________K $__________I #__A_____A_D diff --git a/tests/test_counter.py b/tests/test_counter.py new file mode 100644 index 0000000000000000000000000000000000000000..b0fb93a9bdd3f63d4d98f0377da8e9060fe3c88d --- /dev/null +++ b/tests/test_counter.py @@ -0,0 +1,101 @@ +import numpy as np + +from cooperative_cuisine.counters import ServingWindow, Dispenser +from cooperative_cuisine.game_items import Item, Plate, ItemInfo, ItemType +from cooperative_cuisine.hooks import Hooks +from cooperative_cuisine.utils import create_init_env_time + + +def test_serving_window(): + class DummyOrderManager: + def serve_meal(self, item, env_time, player) -> bool: + return (isinstance(item, str) and item == "Test123") or item.content_list[ + 0 + ].name == "TestMeal" + + class DummyPlateDispenser: + plate_received = False + + def update_plate_out_of_kitchen(self, env_time): + self.plate_received = True + + plate_dispenser = DummyPlateDispenser() + + serving_window = ServingWindow( + order_manager=DummyOrderManager(), + meals={"TestMeal", "TestMeal2"}, + env_time_func=create_init_env_time, + plate_dispenser=plate_dispenser, + pos=np.array([1.0, 1.0]), + hook=Hooks(None), + ) + + serving_window.drop_off(item="Test123") + assert ( + plate_dispenser.plate_received + ), "ServingWindow needs to update plate out of kitchen for ordered meal." + plate_dispenser.plate_received = False + plate = Plate(transitions={}, clean=True, item_info=None) + plate.content_list = [Item(name="TestMeal", item_info=None)] + assert serving_window.can_drop_off( + item=plate + ), "ServingWindow could drop off a known meal." + assert ( + serving_window.drop_off(item=plate) is None + ), "ServingWindow drop_off should return None for a served meal." + assert ( + plate_dispenser.plate_received + ), "ServingWindow needs to update plate out of kitchen for ordered meal." + plate_dispenser.plate_received = False + + plate.content_list = [Item(name="TestMeal2", item_info=None)] + assert serving_window.can_drop_off( + item=plate + ), "ServingWindow could drop off a known meal." + assert ( + serving_window.drop_off(item=plate) == plate + ), "ServingWindow should return the item for not ordered meals." + + assert ( + serving_window.pick_up() is None + ), "Player should not be able to pick something from the ServingWindow." + + +def test_dispenser(): + dispenser = Dispenser( + dispensing=ItemInfo( + type=ItemType.Ingredient, + name="MyIngredient", + seconds=0, + needs=["MySecondIngredient"], + equipment=None, + ), + pos=np.array([1.0, 1.0]), + hook=Hooks(None), + undo_dispenser_pickup=False, + ) + assert ( + dispenser.occupied_by.name == "MyIngredient" + ), "Initialized dispenser should be occupied by dispensing item" + assert ( + dispenser.pick_up().name == "MyIngredient" + ), "Picked up item should be the dispensing item" + assert ( + dispenser.occupied_by is not None + ), "After pickup a new occupied by should be generated" + assert ( + dispenser.occupied_by.name == "MyIngredient" + ), "After pick up a new occupied by item should be generated" + + assert not dispenser.can_drop_off( + dispenser.pick_up() + ), "Config undo_dispenser_pickup==False should stop the player to drop off picked up items" + + dispenser.undo_dispenser_pickup = True + assert dispenser.can_drop_off( + dispenser.pick_up() + ), "Config undo_dispenser_pickup==True should allow the player to drop off picked up items" + assert ( + dispenser.drop_off(dispenser.pick_up()) is None + ), "Config undo_dispenser_pickup==True should allow the player to drop off picked up items" + # check combine? diff --git a/tests/test_start.py b/tests/test_start.py index eb4746dfb41dc33db2a548ef5b675adfc46e9d7d..e69b1ac95c1590adff21abcaa9291f7352ddb8d6 100644 --- a/tests/test_start.py +++ b/tests/test_start.py @@ -12,7 +12,17 @@ from cooperative_cuisine.environment import ( InterActionData, ) from cooperative_cuisine.game_items import Item, ItemInfo, ItemType +from cooperative_cuisine.game_server import PlayerRequestType from cooperative_cuisine.hooks import Hooks +from cooperative_cuisine.server_results import ( + PlayerInfo, + CreateEnvResult, + PlayerRequestResult, +) +from cooperative_cuisine.state_representation import ( + StateRepresentation, + create_json_schema, +) from cooperative_cuisine.utils import create_init_env_time layouts_folder = ROOT_DIR / "configs" / "layouts" @@ -118,6 +128,10 @@ def test_player_movement_speed(env_config, layout_empty_config, item_info): np.linalg.norm(expected - env.players[player_name].pos), 0 ), "Performed movement do not move the player as expected." + assert StateRepresentation.model_validate_json( + json_data=env.get_json_state(player_id="1") + ), "json state does not match expected StateRepresentation." + def test_player_reach(env_config, layout_empty_config, item_info): env = Environment(env_config, layout_empty_config, item_info, as_files=False) @@ -281,3 +295,18 @@ def test_time_limit(): env.step(passed_time_2) assert env.game_ended, "Game has ended now." + + +def test_json_schema(): + assert isinstance(create_json_schema(), dict) + + +def test_server_result_definition(): + plater_info = PlayerInfo(client_id="123", player_hash="234567890", player_id="0") + CreateEnvResult(env_id="123344", player_info={"0": plater_info}, recipe_graphs=[]) + PlayerRequestResult( + request_type=PlayerRequestType.READY, + status=200, + msg="123", + player_hash="1234324", + )