From 0cbcb2c2eba08c5869406f11a58b43022312f0ec Mon Sep 17 00:00:00 2001 From: Silvio Tomatis Date: Thu, 3 Aug 2023 19:26:42 +0200 Subject: [PATCH 1/5] Add tests for object pickup --- test/test_transitions.py | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 test/test_transitions.py diff --git a/test/test_transitions.py b/test/test_transitions.py new file mode 100644 index 00000000..8ebc9d65 --- /dev/null +++ b/test/test_transitions.py @@ -0,0 +1,64 @@ +import pytest + + +class TestTransitions(object): + messages = [] + + @pytest.fixture(scope="function") + def mocked_exp(self, exp): + def publish(error_msg): + self.messages.append(error_msg) + exp.publish = publish + yield exp + self.messages[:] = [] + + @pytest.fixture + def item(self, exp): + item = self.create_item() + exp.grid.item_locations[(0, 0)] = item + return item + + def create_item(self): + from dlgr.griduniverse.experiment import Item + + return Item({ + "item_id": 9, + "calories": 5, + "crossable": True, + "interactive": True, + "maturation_speed": 1, + "maturation_threshold": 0.0, + "n_uses": 3, + "name": "Food", + "plantable": False, + "planting_cost": 1, + "portable": True, + "spawn_rate": 0.1, + "sprite": "#8a9b0f,#7a6b54", + }) + + @pytest.fixture + def participant(self, exp, a): + participant = a.participant() + participant.current_item = None + exp.grid.players[participant.id] = participant + return participant + + def test_consume_item_success(self, item, exp, participant): + exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 0)}) + assert not exp.grid.item_locations # The item is no longer there + assert participant.current_item == item # The item is now in the player's inventory + + def test_consume_item_full_hands_error(self, item, mocked_exp, participant): + participant.current_item = self.create_item() + + mocked_exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 0)}) + assert list(mocked_exp.grid.item_locations.keys()) == [(0, 0)] # The item is still there + assert participant.current_item != item # The item is not in the player's inventory + assert len(self.messages) == 1 + + def test_consume_item_no_item_error(self, item, mocked_exp, participant): + mocked_exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 1)}) + assert list(mocked_exp.grid.item_locations.keys()) == [(0, 0)] # The item is still there + assert participant.current_item != item # The item is not in the player's inventory + assert len(self.messages) == 1 From fbf58582a4b8e1638ba4d45399599d9964b4f668 Mon Sep 17 00:00:00 2001 From: Silvio Tomatis Date: Thu, 3 Aug 2023 20:11:32 +0200 Subject: [PATCH 2/5] Add tests for object drop --- test/test_transitions.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/test_transitions.py b/test/test_transitions.py index 8ebc9d65..9cc273af 100644 --- a/test/test_transitions.py +++ b/test/test_transitions.py @@ -62,3 +62,21 @@ def test_consume_item_no_item_error(self, item, mocked_exp, participant): assert list(mocked_exp.grid.item_locations.keys()) == [(0, 0)] # The item is still there assert participant.current_item != item # The item is not in the player's inventory assert len(self.messages) == 1 + + def test_drop_item_success(self, exp, participant): + participant.current_item = item = self.create_item() + + exp.handle_item_drop(msg={"player_id": participant.id, "position": (3, 3)}) + assert list(exp.grid.item_locations.keys()) == [(3, 3)] + assert item.position == (3, 3) + + def test_drop_item_cant_drop_error(self, mocked_exp, participant, item): + """The user tries to drop an item over an exiting item. + """ + assert item # The `item` fixture places it at (0, 0) + participant.current_item = self.create_item() # The participant has an item in their hands + + mocked_exp.handle_item_drop(msg={"player_id": participant.id, "position": (0, 0)}) + # Dropping failed, so the item is still in the player's hands + assert participant.current_item + assert len(self.messages) == 1 # and we get an error message From 5fed0b0c23de2ab2113a00d1e78cd0b471e17ffe Mon Sep 17 00:00:00 2001 From: Silvio Tomatis Date: Fri, 4 Aug 2023 15:41:46 +0200 Subject: [PATCH 3/5] Add trasition test --- test/test_transitions.py | 80 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/test/test_transitions.py b/test/test_transitions.py index 9cc273af..284b1f2a 100644 --- a/test/test_transitions.py +++ b/test/test_transitions.py @@ -1,7 +1,7 @@ import pytest -class TestTransitions(object): +class TestPickupDrop(object): messages = [] @pytest.fixture(scope="function") @@ -44,12 +44,12 @@ def participant(self, exp, a): exp.grid.players[participant.id] = participant return participant - def test_consume_item_success(self, item, exp, participant): + def test_pickup_item_success(self, item, exp, participant): exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 0)}) assert not exp.grid.item_locations # The item is no longer there assert participant.current_item == item # The item is now in the player's inventory - def test_consume_item_full_hands_error(self, item, mocked_exp, participant): + def test_pickup_item_full_hands_error(self, item, mocked_exp, participant): participant.current_item = self.create_item() mocked_exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 0)}) @@ -57,7 +57,7 @@ def test_consume_item_full_hands_error(self, item, mocked_exp, participant): assert participant.current_item != item # The item is not in the player's inventory assert len(self.messages) == 1 - def test_consume_item_no_item_error(self, item, mocked_exp, participant): + def test_pickup_item_no_item_error(self, item, mocked_exp, participant): mocked_exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 1)}) assert list(mocked_exp.grid.item_locations.keys()) == [(0, 0)] # The item is still there assert participant.current_item != item # The item is not in the player's inventory @@ -80,3 +80,75 @@ def test_drop_item_cant_drop_error(self, mocked_exp, participant, item): # Dropping failed, so the item is still in the player's hands assert participant.current_item assert len(self.messages) == 1 # and we get an error message + + +class TestHandleItemTransition(object): + messages = [] + + @pytest.fixture(scope="function") + def mocked_exp(self, exp): + def publish(error_msg): + self.messages.append(error_msg) + exp.publish = publish + exp.transition_config = { + ('last', 2, 3): { + 'actor_end': 5, + 'actor_start': 2, + 'last_use': False, + 'modify_uses': [0, 0], + 'target_end': 3, + 'target_start': 3, + 'visible': 'always' + }, + } + yield exp + self.messages[:] = [] + + @pytest.fixture + def item(self, exp): + item = self.create_item() + exp.grid.item_locations[(0, 0)] = item + return item + + @pytest.fixture + def participant(self, exp, a): + participant = a.participant() + participant.current_item = None + exp.grid.players[participant.id] = participant + return participant + + def create_item(self, **kwargs): + from dlgr.griduniverse.experiment import Item + + item_data = { + "item_id": 9, + "calories": 5, + "crossable": True, + "interactive": True, + "maturation_speed": 1, + "maturation_threshold": 0.0, + "n_uses": 3, + "name": "Food", + "plantable": False, + "planting_cost": 1, + "portable": True, + "spawn_rate": 0.1, + "sprite": "#8a9b0f,#7a6b54", + } + item_data.update(kwargs) + return Item(item_data) + + def test_handle_item_transition_combine_items(self, mocked_exp, participant): + big_hard_rock = self.create_item(**mocked_exp.item_config[3]) + stone = self.create_item(**mocked_exp.item_config[2]) + assert stone.name == "Stone" + assert big_hard_rock.name == "Big Hard Rock" + mocked_exp.grid.item_locations[(0, 0)] = big_hard_rock + participant.current_item = stone + mocked_exp.handle_item_transition(msg={"player_id": participant.id, "position": (0, 0)}) + # The Sone has been consumed, and a Sharp Stone has been created. + # The Big Hard Rock is still there. + assert participant.current_item.name == "Sharp Stone" + assert len(mocked_exp.grid.items_consumed) == 1 + assert len(mocked_exp.grid.item_locations) == 1 + list(mocked_exp.grid.item_locations.values())[0].name == "Big Hard Rock" From 4e4cb464c5ce5efbef12ec04a71f29eaea843509 Mon Sep 17 00:00:00 2001 From: Silvio Tomatis Date: Fri, 4 Aug 2023 17:35:53 +0200 Subject: [PATCH 4/5] Refactor test fixtures --- .pre-commit-config.yaml | 2 +- test/test_transitions.py | 174 +++++++++++++++++++-------------------- 2 files changed, 84 insertions(+), 92 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0668b0aa..2b26ce46 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ - files: ^(tests|dlgr|demos)/|setup.py + files: ^(test|dlgr|demos)/|setup.py - repo: https://github.com/PyCQA/flake8 rev: '6.0.0' diff --git a/test/test_transitions.py b/test/test_transitions.py index 284b1f2a..f935a866 100644 --- a/test/test_transitions.py +++ b/test/test_transitions.py @@ -8,75 +8,61 @@ class TestPickupDrop(object): def mocked_exp(self, exp): def publish(error_msg): self.messages.append(error_msg) + exp.publish = publish yield exp self.messages[:] = [] - @pytest.fixture - def item(self, exp): - item = self.create_item() - exp.grid.item_locations[(0, 0)] = item - return item - - def create_item(self): - from dlgr.griduniverse.experiment import Item - - return Item({ - "item_id": 9, - "calories": 5, - "crossable": True, - "interactive": True, - "maturation_speed": 1, - "maturation_threshold": 0.0, - "n_uses": 3, - "name": "Food", - "plantable": False, - "planting_cost": 1, - "portable": True, - "spawn_rate": 0.1, - "sprite": "#8a9b0f,#7a6b54", - }) - - @pytest.fixture - def participant(self, exp, a): - participant = a.participant() - participant.current_item = None - exp.grid.players[participant.id] = participant - return participant - def test_pickup_item_success(self, item, exp, participant): exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 0)}) assert not exp.grid.item_locations # The item is no longer there - assert participant.current_item == item # The item is now in the player's inventory + assert ( + participant.current_item == item + ) # The item is now in the player's inventory def test_pickup_item_full_hands_error(self, item, mocked_exp, participant): - participant.current_item = self.create_item() - - mocked_exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 0)}) - assert list(mocked_exp.grid.item_locations.keys()) == [(0, 0)] # The item is still there - assert participant.current_item != item # The item is not in the player's inventory + participant.current_item = create_item() + + mocked_exp.handle_item_pick_up( + msg={"player_id": participant.id, "position": (0, 0)} + ) + assert list(mocked_exp.grid.item_locations.keys()) == [ + (0, 0) + ] # The item is still there + assert ( + participant.current_item != item + ) # The item is not in the player's inventory assert len(self.messages) == 1 def test_pickup_item_no_item_error(self, item, mocked_exp, participant): - mocked_exp.handle_item_pick_up(msg={"player_id": participant.id, "position": (0, 1)}) - assert list(mocked_exp.grid.item_locations.keys()) == [(0, 0)] # The item is still there - assert participant.current_item != item # The item is not in the player's inventory + mocked_exp.handle_item_pick_up( + msg={"player_id": participant.id, "position": (0, 1)} + ) + assert list(mocked_exp.grid.item_locations.keys()) == [ + (0, 0) + ] # The item is still there + assert ( + participant.current_item != item + ) # The item is not in the player's inventory assert len(self.messages) == 1 def test_drop_item_success(self, exp, participant): - participant.current_item = item = self.create_item() + participant.current_item = item = create_item() exp.handle_item_drop(msg={"player_id": participant.id, "position": (3, 3)}) assert list(exp.grid.item_locations.keys()) == [(3, 3)] assert item.position == (3, 3) def test_drop_item_cant_drop_error(self, mocked_exp, participant, item): - """The user tries to drop an item over an exiting item. - """ + """The user tries to drop an item over an exiting item.""" assert item # The `item` fixture places it at (0, 0) - participant.current_item = self.create_item() # The participant has an item in their hands + participant.current_item = ( + create_item() + ) # The participant has an item in their hands - mocked_exp.handle_item_drop(msg={"player_id": participant.id, "position": (0, 0)}) + mocked_exp.handle_item_drop( + msg={"player_id": participant.id, "position": (0, 0)} + ) # Dropping failed, so the item is still in the player's hands assert participant.current_item assert len(self.messages) == 1 # and we get an error message @@ -89,66 +75,72 @@ class TestHandleItemTransition(object): def mocked_exp(self, exp): def publish(error_msg): self.messages.append(error_msg) + exp.publish = publish exp.transition_config = { - ('last', 2, 3): { - 'actor_end': 5, - 'actor_start': 2, - 'last_use': False, - 'modify_uses': [0, 0], - 'target_end': 3, - 'target_start': 3, - 'visible': 'always' + ("last", 2, 3): { + "actor_end": 5, + "actor_start": 2, + "last_use": False, + "modify_uses": [0, 0], + "target_end": 3, + "target_start": 3, + "visible": "always", }, } yield exp self.messages[:] = [] - @pytest.fixture - def item(self, exp): - item = self.create_item() - exp.grid.item_locations[(0, 0)] = item - return item - - @pytest.fixture - def participant(self, exp, a): - participant = a.participant() - participant.current_item = None - exp.grid.players[participant.id] = participant - return participant - - def create_item(self, **kwargs): - from dlgr.griduniverse.experiment import Item - - item_data = { - "item_id": 9, - "calories": 5, - "crossable": True, - "interactive": True, - "maturation_speed": 1, - "maturation_threshold": 0.0, - "n_uses": 3, - "name": "Food", - "plantable": False, - "planting_cost": 1, - "portable": True, - "spawn_rate": 0.1, - "sprite": "#8a9b0f,#7a6b54", - } - item_data.update(kwargs) - return Item(item_data) - def test_handle_item_transition_combine_items(self, mocked_exp, participant): - big_hard_rock = self.create_item(**mocked_exp.item_config[3]) - stone = self.create_item(**mocked_exp.item_config[2]) + big_hard_rock = create_item(**mocked_exp.item_config[3]) + stone = create_item(**mocked_exp.item_config[2]) assert stone.name == "Stone" assert big_hard_rock.name == "Big Hard Rock" mocked_exp.grid.item_locations[(0, 0)] = big_hard_rock participant.current_item = stone - mocked_exp.handle_item_transition(msg={"player_id": participant.id, "position": (0, 0)}) + mocked_exp.handle_item_transition( + msg={"player_id": participant.id, "position": (0, 0)} + ) # The Sone has been consumed, and a Sharp Stone has been created. # The Big Hard Rock is still there. assert participant.current_item.name == "Sharp Stone" assert len(mocked_exp.grid.items_consumed) == 1 assert len(mocked_exp.grid.item_locations) == 1 list(mocked_exp.grid.item_locations.values())[0].name == "Big Hard Rock" + + +@pytest.fixture +def item(exp): + item = create_item() + exp.grid.item_locations[(0, 0)] = item + return item + + +@pytest.fixture +def participant(exp, a): + participant = a.participant() + participant.current_item = None + exp.grid.players[participant.id] = participant + return participant + + +def create_item(**kwargs): + from dlgr.griduniverse.experiment import Item + + item_data = { + "item_id": 9, + "calories": 5, + "crossable": True, + "interactive": True, + "maturation_speed": 1, + "maturation_threshold": 0.0, + "n_uses": 3, + "name": "Food", + "plantable": False, + "planting_cost": 1, + "portable": True, + "spawn_rate": 0.1, + "sprite": "#8a9b0f,#7a6b54", + } + item_data.update(kwargs) + return Item(item_data) From 23e6beb68b5b11c8ab4ab2f7fc6f4623d51aa16d Mon Sep 17 00:00:00 2001 From: Alec Mitchell Date: Fri, 4 Aug 2023 11:33:08 -0700 Subject: [PATCH 5/5] Fix linting error. --- test/test_griduniverse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_griduniverse.py b/test/test_griduniverse.py index cdc07a35..7aa2a38d 100755 --- a/test/test_griduniverse.py +++ b/test/test_griduniverse.py @@ -96,7 +96,7 @@ def test_type_properties_cannot_by_shadowed(self, item_config): def test_remaining_uses_default(self, item_config): item = self.subject(item_config) - assert item.remaining_uses == item_config['n_uses'] + assert item.remaining_uses == item_config["n_uses"] def test_remaining_uses_in_constructor(self, item_config): item = self.subject(item_config, remaining_uses=1)