From b61cd8cd758d58de7336137b6dad8818b7024fdb Mon Sep 17 00:00:00 2001 From: Daniel Bingham Date: Sat, 13 Jan 2024 13:15:02 -0500 Subject: [PATCH] Tests for Harvest and Status. --- data/characters/gird.json | 51 ++- game/commands/crafting.py | 3 +- game/store/models/item.py | 4 +- tests/game/commands/test_crafting.py | 399 +++++++++++++++++++++++- tests/game/commands/test_information.py | 144 +++++++++ 5 files changed, 595 insertions(+), 6 deletions(-) create mode 100644 tests/game/commands/test_information.py diff --git a/data/characters/gird.json b/data/characters/gird.json index 8497a5f3..5e8c1141 100644 --- a/data/characters/gird.json +++ b/data/characters/gird.json @@ -1 +1,50 @@ -{"name": "gird", "description": "", "details": "", "sex": "male", "position": "standing", "speed": "walking", "attributes": {"strength": 10, "maxStrength": 10, "stamina": 10, "maxStamina": 10, "constitution": 10, "maxConstitution": 10}, "reserves": {"calories": 1934, "maxCalories": 2400, "thirst": 3414, "maxThirst": 4000, "sleep": 12, "maxSleep": 16}, "bodyType": "bipedal", "body": {"wounds": {}, "worn": {}}, "inventory": ["pile of serviceberries", "pile of serviceberries", "handful of serviceberries", "handful of serviceberries", "handful of serviceberries", "handful of serviceberries", "handful of serviceberries", "handful of serviceberries", "handful of serviceberries", "handful of serviceberries", "handful of serviceberries", "handful of serviceberries", "pile of serviceberries", "pile of serviceberries", "pile of serviceberries", "pile of serviceberries", "pile of serviceberries", "pile of serviceberries"], "room": 5166} \ No newline at end of file +{ + "attributes": { + "constitution": 10, + "maxConstitution": 10, + "maxStamina": 10, + "maxStrength": 10, + "stamina": 10, + "strength": 10 + }, + "body": { + "worn": {}, + "wounds": {} + }, + "bodyType": "bipedal", + "description": "", + "details": "", + "inventory": [ + "pile of serviceberries", + "pile of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "handful of serviceberries", + "pile of serviceberries", + "pile of serviceberries", + "pile of serviceberries", + "pile of serviceberries", + "pile of serviceberries", + "pile of serviceberries" + ], + "name": "gird", + "position": "standing", + "reserves": { + "calories": 1934, + "maxCalories": 2400, + "maxSleep": 16, + "maxThirst": 4000, + "sleep": 12, + "thirst": 3414 + }, + "room": 5166, + "sex": "male", + "speed": "walking" +} diff --git a/game/commands/crafting.py b/game/commands/crafting.py index 381feff6..f7b0019f 100644 --- a/game/commands/crafting.py +++ b/game/commands/crafting.py @@ -157,6 +157,7 @@ def finish(self, player, cancelled=False): player.write("\nYou didn't harvest long enough to produce anything.") return + if harvest.consumed: if in_inventory: player.character.inventory.remove(item) @@ -173,7 +174,7 @@ def finish(self, player, cancelled=False): else: harvest.harvested = True - player.write("\nYou " + harvest.action + " " + results + " from " + item.description + ".") + player.write("\nYou %s %s from %s." % (harvest.action, results, item.description)) self.library.room.writeToRoom(player.character, "%s %s from %s." % (player.character.name, harvest.action, item.description)) diff --git a/game/store/models/item.py b/game/store/models/item.py index b1a6e9e6..161d279d 100644 --- a/game/store/models/item.py +++ b/game/store/models/item.py @@ -83,8 +83,8 @@ def fromJson(self, data): self.consumed = data['consumed'] - if 'replaceWith' in data: - self.replace_with = data['replaceWith'] + if 'replacedWith' in data: + self.replaced_with = data['replacedWith'] self.calories = data['calories'] self.time = data['time'] diff --git a/tests/game/commands/test_crafting.py b/tests/game/commands/test_crafting.py index fd02162d..7afab8d3 100644 --- a/tests/game/commands/test_crafting.py +++ b/tests/game/commands/test_crafting.py @@ -592,9 +592,9 @@ def test_Harvest_target_already_harvested(): player.write.assert_called_once_with("a harvestable item has already been harvested. There's nothing left!") -def test_Harvest_successfully_started(): +def test_Harvest_successfully_started_from_item_in_room(): """ - Test a player successfully beginning a harvest. + Test a player successfully beginning to harvest an item in the room. """ store = Store('test', '') @@ -626,3 +626,398 @@ def test_Harvest_successfully_started(): assert player.character.action is harvest_command assert player.character.action_time == instance.traits["Harvestable"].time assert player.character.action_data == { "harvesting": instance, "in_inventory": False } + + +def test_Harvest_successfully_started_from_item_in_inventory(): + """ + Test a player successfully beginning to harvest an item in their inventory. + """ + + store = Store('test', '') + + harvestable = Item() + harvestable.fromJson(harvestable_json) + store.items.add(harvestable) + + library = Library(store) + + harvest_command = Harvest(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.player = player + + player.character.room = Room() + player.character.room.occupants.append(player.character) + + instance = store.items.instance(harvestable.getId()) + player.character.inventory.append(instance) + + harvest_command.execute(player, 'harvestable') + + player.write.assert_called_once_with("You begin to harvest a harvestable item.") + assert player.character.action is harvest_command + assert player.character.action_time == instance.traits["Harvestable"].time + assert player.character.action_data == { "harvesting": instance, "in_inventory": True } + +def test_Harvest_step(): + """ + Test a harvest step. + """ + + store = Store('test', '') + + harvestable = Item() + harvestable.fromJson(harvestable_json) + store.items.add(harvestable) + + library = Library(store) + + harvest_command = Harvest(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.player = player + + player.character.room = Room() + player.character.room.occupants.append(player.character) + + instance = store.items.instance(harvestable.getId()) + player.character.action = harvest_command + player.character.action_time = instance.traits["Harvestable"].time + player.character.action_data = { "harvesting": instance, "in_inventory": False } + player.character.room.items.append(instance) + + harvest_command.step(player) + + assert player.character.reserves.calories == player.character.reserves.max_calories - 10 + +def test_Harvest_successfully_finished(): + """ + Test finishing a harvest. + """ + + store = Store('test', '') + + harvestable = Item() + harvestable.fromJson(harvestable_json) + store.items.add(harvestable) + + harvested = Item() + harvested.fromJson(harvested_item_json) + store.items.add(harvested) + + library = Library(store) + + harvest_command = Harvest(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.player = player + + room = Room() + player.character.room = room + player.character.room.occupants.append(player.character) + + instance = store.items.instance(harvestable.getId()) + player.character.room.items.append(instance) + + player.character.action = harvest_command + player.character.action_time = 0 + player.character.action_data = { "harvesting": instance, "in_inventory": False } + + harvest_command.finish(player) + + player.write.assert_called_once_with("\nYou harvest 1 harvested item from a harvestable item.") + assert len([ item for item in player.character.inventory if item.getId() == harvested.getId()]) == 1 + assert len([ item for item in room.items if item.getId() == harvestable.getId() ]) == 1 + assert instance.traits["Harvestable"].harvested is True + + +harvestable_consumed_json = { + "name": "harvestable", + "description": "a harvestable item", + "details": "An item that can be harvested.", + "keywords": ["harvestable"], + "length": 1, + "width": 1, + "height": 1, + "weight": 1, + "traits": { + "Harvestable": { + "products": [ + { + "product": "harvested item", + "amount": 1 + } + ], + "preDescription": "This item can be harvested.", + "postDescription": "This item has been harvested.", + "consumed": True, + "calories": 100, + "time": 10, + "action": "harvest", + "required_tools": [ ] + } + } +} + +def test_Harvest_successfully_finished_for_consumed_item(): + """ + Test finishing a harvest for an item that is consumed by harvesting. + """ + + store = Store('test', '') + + harvestable = Item() + harvestable.fromJson(harvestable_consumed_json) + store.items.add(harvestable) + + harvested = Item() + harvested.fromJson(harvested_item_json) + store.items.add(harvested) + + library = Library(store) + + harvest_command = Harvest(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.player = player + + room = Room() + player.character.room = room + player.character.room.occupants.append(player.character) + + instance = store.items.instance(harvestable.getId()) + player.character.room.items.append(instance) + + player.character.action = harvest_command + player.character.action_time = 0 + player.character.action_data = { "harvesting": instance, "in_inventory": False } + + harvest_command.finish(player) + + player.write.assert_called_once_with("\nYou harvest 1 harvested item from a harvestable item.") + assert len([ item for item in player.character.inventory if item.getId() == harvested.getId()]) == 1 + assert len([ item for item in room.items if item.getId() == harvestable.getId() ]) == 0 + + +harvestable_replaced_json = { + "name": "harvestable", + "description": "a harvestable item", + "details": "An item that can be harvested.", + "keywords": ["harvestable"], + "length": 1, + "width": 1, + "height": 1, + "weight": 1, + "traits": { + "Harvestable": { + "products": [ + { + "product": "harvested item", + "amount": 1 + } + ], + "preDescription": "This item can be harvested.", + "postDescription": "This item has been harvested.", + "consumed": False, + "replacedWith": "replacement", + "calories": 100, + "time": 10, + "action": "harvest", + "required_tools": [ ] + } + } +} + +replacement_json = { + "name": "replacement", + "description": "a replacement item", + "details": "An item that replaced a harvestable.", + "keywords": ["replacement"], + "length": 1, + "width": 1, + "height": 1, + "weight": 1, + "traits": { } +} + +def test_Harvest_successfully_finished_for_replaced_item(): + """ + Test finishing a harvest for an item that is replaced during harvesting. + """ + + store = Store('test', '') + + harvestable = Item() + harvestable.fromJson(harvestable_replaced_json) + store.items.add(harvestable) + + replacement = Item() + replacement.fromJson(replacement_json) + store.items.add(replacement) + + harvested = Item() + harvested.fromJson(harvested_item_json) + store.items.add(harvested) + + library = Library(store) + + harvest_command = Harvest(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.player = player + + room = Room() + player.character.room = room + player.character.room.occupants.append(player.character) + + instance = store.items.instance(harvestable.getId()) + player.character.room.items.append(instance) + + player.character.action = harvest_command + player.character.action_time = 0 + player.character.action_data = { "harvesting": instance, "in_inventory": False } + + harvest_command.finish(player) + + player.write.assert_called_once_with("\nYou harvest 1 harvested item from a harvestable item.") + assert len([ item for item in player.character.inventory if item.getId() == harvested.getId()]) == 1 + assert len([ item for item in room.items if item.getId() == harvestable.getId() ]) == 0 + assert len([ item for item in room.items if item.getId() == replacement.getId() ]) == 1 + + +harvestable_multiple_products_json = { + "name": "harvestable", + "description": "a harvestable item", + "details": "An item that can be harvested.", + "keywords": ["harvestable"], + "length": 1, + "width": 1, + "height": 1, + "weight": 1, + "traits": { + "Harvestable": { + "products": [ + { + "product": "harvested item", + "amount": 4 + } + ], + "preDescription": "This item can be harvested.", + "postDescription": "This item has been harvested.", + "consumed": False, + "calories": 100, + "time": 10, + "action": "harvest", + "required_tools": [ ] + } + } +} + +def test_Harvest_cancelled_partially_completed(): + """ + Test a harvest attempt that was cancelled while partially complete. + """ + + store = Store('test', '') + + harvestable = Item() + harvestable.fromJson(harvestable_multiple_products_json) + store.items.add(harvestable) + + harvested = Item() + harvested.fromJson(harvested_item_json) + store.items.add(harvested) + + library = Library(store) + + harvest_command = Harvest(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.player = player + + room = Room() + player.character.room = room + player.character.room.occupants.append(player.character) + + instance = store.items.instance(harvestable.getId()) + player.character.room.items.append(instance) + + player.character.action = harvest_command + player.character.action_time = 5 + player.character.action_data = { "harvesting": instance, "in_inventory": False } + + harvest_command.cancel(player) + + player.write.assert_called_once_with("\nYou harvest 2 harvested item from a harvestable item.") + assert len([ item for item in player.character.inventory if item.getId() == harvested.getId()]) == 2 + assert len([ item for item in room.items if item.getId() == harvestable.getId() ]) == 1 + assert instance.traits["Harvestable"].harvested is True + + +def test_Harvest_cancelled_incomplete(): + """ + Test a harvest attempt that was cancelled without going long enough to produce anything. + """ + + store = Store('test', '') + + harvestable = Item() + harvestable.fromJson(harvestable_multiple_products_json) + store.items.add(harvestable) + + harvested = Item() + harvested.fromJson(harvested_item_json) + store.items.add(harvested) + + library = Library(store) + + harvest_command = Harvest(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.player = player + + room = Room() + player.character.room = room + player.character.room.occupants.append(player.character) + + instance = store.items.instance(harvestable.getId()) + player.character.room.items.append(instance) + + player.character.action = harvest_command + player.character.action_time = 9 + player.character.action_data = { "harvesting": instance, "in_inventory": False } + + harvest_command.cancel(player) + + player.write.assert_called_once_with("\nYou didn't harvest long enough to produce anything.") + assert len([ item for item in player.character.inventory if item.getId() == harvested.getId()]) == 0 + assert len([ item for item in room.items if item.getId() == harvestable.getId() ]) == 1 + assert instance.traits["Harvestable"].harvested is False diff --git a/tests/game/commands/test_information.py b/tests/game/commands/test_information.py new file mode 100644 index 00000000..f86c66bc --- /dev/null +++ b/tests/game/commands/test_information.py @@ -0,0 +1,144 @@ +from unittest.mock import Mock, call + +from game.library.library import Library +from game.store.store import Store +from game.player import Player +from game.store.models.character import PlayerCharacter, Character +from game.store.models.room import Room + +from game.commands.information import Status + +character_json = { + "attributes": { + "constitution": 10, + "maxConstitution": 10, + "maxStamina": 10, + "maxStrength": 10, + "stamina": 10, + "strength": 10 + }, + "body": { + "worn": {}, + "wounds": {} + }, + "bodyType": "bipedal", + "description": "", + "details": "", + "inventory": [ ], + "name": "character", + "position": "standing", + "reserves": { + "calories": 2400, + "maxCalories": 2400, + "maxSleep": 16, + "maxThirst": 4000, + "sleep": 16, + "thirst": 4000 + }, + "room": 1, + "sex": "male", + "speed": "walking" +} + +def test_Status(): + """ + Test the Status command with a character with full reserves. + """ + + store = Store('test', '') + library = Library(store) + + status = Status(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.fromJson(character_json) + + room = Room() + player.character.room = room + room.occupants.append(player.character) + + status.execute(player, 'Hello') + + player.write.assert_has_calls([ + call("You are Character."), + call("You are standing and walking."), + call("You are sated, hydrated, and awake.\nYou are breathing calmly and rested.") + ]) + + +def test_Status_mid_reserves(): + """ + Test the Status command with a character with half used reserves. + """ + + store = Store('test', '') + library = Library(store) + + status = Status(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.fromJson(character_json) + + player.character.reserves.calories -= player.character.reserves.max_calories * 0.5 + player.character.reserves.thirst -= player.character.reserves.max_thirst * 0.5 + player.character.reserves.sleep -= player.character.reserves.max_sleep * 0.75 + player.character.reserves.wind -= player.character.reserves.max_wind * 0.5 + player.character.reserves.energy -= player.character.reserves.max_energy * 0.5 + + room = Room() + player.character.room = room + room.occupants.append(player.character) + + status.execute(player, 'Hello') + + player.write.assert_has_calls([ + call("You are Character."), + call("You are standing and walking."), + call("You are hungry, thirsty, and yawning.\nYou are huffing and tired.") + ]) + + +def test_Status_low_reserves(): + """ + Test the Status command with a character with three quarters used reserves. + """ + + store = Store('test', '') + library = Library(store) + + status = Status(library, store) + + socket = Mock() + player = Player(socket, None, None) + player.write = Mock() + + player.character = PlayerCharacter() + player.character.fromJson(character_json) + + player.character.reserves.calories -= player.character.reserves.max_calories * 0.75 + player.character.reserves.thirst -= player.character.reserves.max_thirst * 0.75 + player.character.reserves.sleep -= player.character.reserves.max_sleep + player.character.reserves.wind -= player.character.reserves.max_wind * 0.75 + player.character.reserves.energy -= player.character.reserves.max_energy * 0.75 + + room = Room() + player.character.room = room + room.occupants.append(player.character) + + status.execute(player, 'Hello') + + player.write.assert_has_calls([ + call("You are Character."), + call("You are standing and walking."), + call("You are ravenous, dehydrated, and drowsy.\nYou are winded and fatigued.") + ]) + +