From 2955dc5e50e2a7019d5c6b3f9f668f7c4773c0ae Mon Sep 17 00:00:00 2001 From: ultimateownsz Date: Thu, 22 May 2025 22:24:45 +0200 Subject: [PATCH 1/4] Refactor inventory unit tests Refactor inventory tests: migrate from unit test to `pytest` and update test structure Co-Authored-By: Anthony Em <139152052+AnSiChen@users.noreply.github.com> --- pyproject.toml | 9 ++ tests/test_inventory.py | 200 +++++++++++++++++++++------------------- 2 files changed, 114 insertions(+), 95 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 063326e..ece25c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,3 +12,12 @@ explicit_package_bases = true ["mypy-pygame.*"] ignore_missing_imports = true + +[tool.pytest.ini_options] +minversion = "6.0" +# -ra: Show extra test summary info for all tests. +# -q: Quiet mode, which reduces the verbosity of the output. +addopts = "-ra -q" +testpaths = [ + "tests", +] diff --git a/tests/test_inventory.py b/tests/test_inventory.py index 7fc7afb..f04679c 100644 --- a/tests/test_inventory.py +++ b/tests/test_inventory.py @@ -4,100 +4,110 @@ # Add the project root to sys.path to allow imports to work when running tests directly with `python`. sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) -import unittest - -from src.inventory import Chest, Inventory, Quest +import pytest -class TestInventory(unittest.TestCase): - def setUp(self): - """Set up a new Inventory object before each test.""" - self.inventory = Inventory() - - # Test add_item - def test_add_item_new(self): - """Test adding a new item.""" - result = self.inventory.add_item("Sword", 1) - self.assertEqual(self.inventory.items, {"Sword": 1}) - self.assertEqual(result, "Successfully added 1 Sword(s) to your inventory.") - - def test_add_item_existing(self): - """Test adding to an existing item.""" - self.inventory.add_item("Potion", 1) - result = self.inventory.add_item("Potion", 2) - self.assertEqual(self.inventory.items, {"Potion": 3}) - self.assertEqual(result, "Successfully added 2 Potion(s) to your inventory.") - - # Test remove_item - def test_remove_item_success(self): - """Test successfully removing an item.""" - self.inventory.add_item("Potion", 3) - result = self.inventory.remove_item("Potion", 2) - self.assertEqual(self.inventory.items, {"Potion": 1}) - self.assertEqual(result, "Successfully removed 2 Potion(s) from your inventory.") - - def test_remove_item_fail(self): - """Test failing to remove an item not in inventory or insufficient quantity.""" - result = self.inventory.remove_item("Sword", 1) - self.assertEqual(self.inventory.items, {}) - self.assertEqual(result, "Cannot remove 1 Sword(s), insufficient quantity.") - - # Test use_item - def test_use_item_success(self): - """Test using an item.""" - self.inventory.add_item("Potion", 1) - result = self.inventory.use_item("Potion") - self.assertEqual(self.inventory.items, {}) - self.assertEqual(result, "You used Potion.") - - def test_use_item_fail(self): - """Test failing to use an item.""" - result = self.inventory.use_item("Potion") - self.assertEqual(self.inventory.items, {}) - self.assertEqual(result, "You dont' have Potion in your inventory.") - - # Test add_chest - def test_add_chest(self): - """Test adding a chest.""" - chest = Chest("Gold Chest") - self.inventory.add_chest(chest) - self.assertEqual(len(self.inventory.chests), 1) - self.assertEqual(self.inventory.chests[0].name, "Gold Chest") - - # Test add_quest - def test_add_quest(self): - """Test adding a quest.""" - quest = Quest() - self.inventory.add_quest(quest) - self.assertEqual(len(self.inventory.quests), 1) - self.assertFalse(self.inventory.quests[0].completed) - - # Test get_items - def test_get_items(self): - """Test getting a copy of items.""" - self.inventory.add_item("Sword", 1) - items = self.inventory.get_items() - self.assertEqual(items, {"Sword": 1}) - self.assertIsNot(items, self.inventory.items) # Copy of items - - # Test get_chests - def test_get_chests(self): - """Test getting a copy of chests.""" - chest = Chest("Gold Chest") - self.inventory.add_chest(chest) - chests = self.inventory.get_chests() - self.assertEqual(len(chests), 1) - self.assertIsNot(chests, self.inventory.chests) # Copy of items - - # Test get_quests - def test_get_quests(self): - """Test getting a copy of quests.""" - quest = Quest() - self.inventory.add_quest(quest) - quests = self.inventory.get_quests() - self.assertEqual(len(quests), 1) - self.assertIsNot(quests, self.inventory.quests) # Copy of items - - -if __name__ == "__main__": - unittest.main() +from src.inventory import Chest, Inventory, Quest +from src.utils.messaging import get_message + +# Old way of writing tests using unittest +# class TestInventory(unittest.TestCase): +# def setUp(self): +# """Set up a new Inventory object before each test.""" +# self.inventory = Inventory() + +@pytest.fixture +def inventory(): + """Set up a new Inventory object before each test.""" + return Inventory() + +# Test add_item +def test_add_item_new(inventory): + """Test adding a new item.""" + result = inventory.add_item("Sword", 1) + expected = get_message("inventory", "add_success", item="Sword", quantity=1) + assert inventory.items == {"Sword": 1} + assert result == expected + +def test_add_item_existing(inventory): + """Test adding to an existing item.""" + result = inventory.add_item("Potion", 2) + expected = get_message("inventory", "add_success", item="Potion", quantity=2) + assert inventory.items == {"Potion": 2} + assert result == expected + +# Test remove_item +def test_remove_item_success(inventory): + """Test successfully removing an item.""" + inventory.add_item("Potion", 3) + result = inventory.remove_item("Potion", 2) + expected = get_message("inventory", "remove_success", item="Potion", quantity=2) + assert inventory.items == {"Potion": 1} + assert result == expected + + +def test_remove_item_fail(inventory): + """Test failing to remove an item not in inventory or insufficient quantity.""" + result = inventory.remove_item("Sword", 1) + expected = get_message("inventory", "remove_fail", item="Sword", quantity=1) + assert inventory.items == {} + assert result == expected + +# Test use_item +def test_use_item_success(inventory): + """Test using an item.""" + inventory.add_item("Potion", 1) + result = inventory.use_item("Potion") + expected = get_message("inventory", "use_success", item="Potion") + assert inventory.items == {} + assert result == expected + +def test_use_item_fail(inventory): + """Test failing to use an item.""" + result = inventory.use_item("Potion") + expected = get_message("inventory", "use_fail", item="Potion") + assert inventory.items == {} + assert result == expected + +# Test add_chest +def test_add_chest(inventory): + """Test adding a chest.""" + chest = Chest("Gold Chest") + inventory.add_chest(chest) + assert len(inventory.chests) == 1 + assert inventory.chests[0].name == "Gold Chest" + +# Test add_quest +def test_add_quest(inventory): + """Test adding a quest.""" + quest = Quest() + inventory.add_quest(quest) + assert len(inventory.quests) == 1 + assert inventory.quests[0].completed == False + +# Test get_items +def test_get_items(inventory): + """Test getting a copy of items.""" + inventory.add_item("Sword", 1) + items = inventory.get_items() + assert items == {"Sword": 1} + assert items is not inventory.items # Copy of items + +# Test get_chests +def test_get_chests(inventory): + """Test getting a copy of chests.""" + chest = Chest("Gold Chest") + inventory.add_chest(chest) + chests = inventory.get_chests() + assert len(chests) == 1 + assert chests[0].name == "Gold Chest" + assert chests is not inventory.chests # Copy of items + +# Test get_quests +def test_get_quests(inventory): + """Test getting a copy of quests.""" + quest = Quest() + inventory.add_quest(quest) + quests = inventory.get_quests() + assert len(quests) == 1 + assert quests is not inventory.quests # Copy of items From c910ef1e1fbe5afe1b2be376caa721cfc7734472 Mon Sep 17 00:00:00 2001 From: ultimateownsz Date: Thu, 22 May 2025 22:31:10 +0200 Subject: [PATCH 2/4] Create .gitattributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Developers on different OSes won’t accidentally introduce line ending changes, keeping the repository history clean. --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..eba1110 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto \ No newline at end of file From dac598d0fb7cacbc71d907791aadd4e7b2439a4b Mon Sep 17 00:00:00 2001 From: ultimateownsz Date: Thu, 22 May 2025 22:41:04 +0200 Subject: [PATCH 3/4] fix ruff issues fix unit test assert --- src/sprites/gui/inventory_gui.py | 1 - tests/test_inventory.py | 13 ++++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/sprites/gui/inventory_gui.py b/src/sprites/gui/inventory_gui.py index b929768..47e8bcc 100644 --- a/src/sprites/gui/inventory_gui.py +++ b/src/sprites/gui/inventory_gui.py @@ -117,7 +117,6 @@ def draw(self) -> None: # Reset button actions self.button_actions: dict[str, tuple[pygame.Rect, pygame.Rect]] = {} - # Draw the inventory items items: list = list(self.inventory.get_items().items()) visible_items: list = items[self.scroll_offset : self.scroll_offset + self.max_visible_items] diff --git a/tests/test_inventory.py b/tests/test_inventory.py index f04679c..bac7eda 100644 --- a/tests/test_inventory.py +++ b/tests/test_inventory.py @@ -16,11 +16,13 @@ # """Set up a new Inventory object before each test.""" # self.inventory = Inventory() + @pytest.fixture def inventory(): """Set up a new Inventory object before each test.""" return Inventory() + # Test add_item def test_add_item_new(inventory): """Test adding a new item.""" @@ -29,6 +31,7 @@ def test_add_item_new(inventory): assert inventory.items == {"Sword": 1} assert result == expected + def test_add_item_existing(inventory): """Test adding to an existing item.""" result = inventory.add_item("Potion", 2) @@ -36,6 +39,7 @@ def test_add_item_existing(inventory): assert inventory.items == {"Potion": 2} assert result == expected + # Test remove_item def test_remove_item_success(inventory): """Test successfully removing an item.""" @@ -53,6 +57,7 @@ def test_remove_item_fail(inventory): assert inventory.items == {} assert result == expected + # Test use_item def test_use_item_success(inventory): """Test using an item.""" @@ -62,6 +67,7 @@ def test_use_item_success(inventory): assert inventory.items == {} assert result == expected + def test_use_item_fail(inventory): """Test failing to use an item.""" result = inventory.use_item("Potion") @@ -69,6 +75,7 @@ def test_use_item_fail(inventory): assert inventory.items == {} assert result == expected + # Test add_chest def test_add_chest(inventory): """Test adding a chest.""" @@ -77,13 +84,15 @@ def test_add_chest(inventory): assert len(inventory.chests) == 1 assert inventory.chests[0].name == "Gold Chest" + # Test add_quest def test_add_quest(inventory): """Test adding a quest.""" quest = Quest() inventory.add_quest(quest) assert len(inventory.quests) == 1 - assert inventory.quests[0].completed == False + assert not inventory.quests[0].completed + # Test get_items def test_get_items(inventory): @@ -93,6 +102,7 @@ def test_get_items(inventory): assert items == {"Sword": 1} assert items is not inventory.items # Copy of items + # Test get_chests def test_get_chests(inventory): """Test getting a copy of chests.""" @@ -103,6 +113,7 @@ def test_get_chests(inventory): assert chests[0].name == "Gold Chest" assert chests is not inventory.chests # Copy of items + # Test get_quests def test_get_quests(inventory): """Test getting a copy of quests.""" From 68b393c328e305f57ffcbc06b5e90565a876ab81 Mon Sep 17 00:00:00 2001 From: ultimateownsz Date: Mon, 26 May 2025 00:42:51 +0200 Subject: [PATCH 4/4] fix ruff import check A long error in the terminal when you ran ruff, has now been fixed: `include I` keyword was not found in terminal ruff check --select I --fix . --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 968ab0b..7cecec3 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ We chose to use [Ruff](https://docs.astral.sh/ruff/) to automatically lint and f > > > ```sh -> ruff format . && ruff check --include I --fix . # this formats code and sort imports +> ruff format . && ruff check --select I --fix . # this formats code and sort imports > ruff check . # run linting and perform fixes > mypy main.py > ``` @@ -193,7 +193,7 @@ We chose to use [Ruff](https://docs.astral.sh/ruff/) to automatically lint and f > > ```powershell > ruff format .; -> ruff check --include I --fix .; +> ruff check --select I --fix .; > ruff check .; > mypy main.py > ```