395 lines
13 KiB
C
395 lines
13 KiB
C
/**
|
|
* Copyright (c) 2026 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "dusktest.h"
|
|
#include "item/inventory.h"
|
|
|
|
static void test_inventoryInit(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[5];
|
|
inventory_t inventory;
|
|
|
|
inventoryInit(&inventory, storage, 5);
|
|
|
|
// Should setup struct
|
|
assert_non_null(inventory.storage);
|
|
assert_int_equal(inventory.storageSize, 5);
|
|
|
|
// Should zero the item ids.
|
|
for(size_t i = 0; i < inventory.storageSize; i++) {
|
|
assert_int_equal(inventory.storage[i].item, ITEM_ID_NULL);
|
|
assert_int_equal(inventory.storage[i].quantity, 0);
|
|
}
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventoryInit(NULL, storage, 5));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
expect_assert_failure(inventoryInit(&inventory, NULL, 5));
|
|
|
|
// Should fail when given zero storage size
|
|
expect_assert_failure(inventoryInit(&inventory, storage, 0));
|
|
}
|
|
|
|
static void test_inventoryItemExists(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[5];
|
|
inventory_t inventory;
|
|
inventoryInit(&inventory, storage, 5);
|
|
|
|
// Initially should not exist
|
|
assert_false(inventoryItemExists(&inventory, ITEM_ID_POTION));
|
|
|
|
// Add item
|
|
inventorySet(&inventory, ITEM_ID_POTION, 3);
|
|
assert_true(inventoryItemExists(&inventory, ITEM_ID_POTION));
|
|
|
|
// Remove item
|
|
inventorySet(&inventory, ITEM_ID_POTION, 0);
|
|
assert_false(inventoryItemExists(&inventory, ITEM_ID_POTION));
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventoryItemExists(NULL, ITEM_ID_POTION));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
inventory.storage = NULL;
|
|
expect_assert_failure(inventoryItemExists(&inventory, ITEM_ID_POTION));
|
|
inventory.storage = storage;
|
|
|
|
// Should fail when given zero storage size
|
|
inventory.storageSize = 0;
|
|
expect_assert_failure(inventoryItemExists(&inventory, ITEM_ID_POTION));
|
|
inventory.storageSize = 5;
|
|
|
|
// Should fail when given ITEM_ID_NULL
|
|
expect_assert_failure(inventoryItemExists(&inventory, ITEM_ID_NULL));
|
|
|
|
// Should fail if item has zero quantity somehow
|
|
inventorySet(&inventory, ITEM_ID_POTION, 3);
|
|
inventory.storage[0].quantity = 0;
|
|
expect_assert_failure(inventoryItemExists(&inventory, ITEM_ID_POTION));
|
|
}
|
|
|
|
static void test_inventorySet(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[5];
|
|
inventory_t inventory;
|
|
inventoryInit(&inventory, storage, 5);
|
|
|
|
// Set item quantity
|
|
inventorySet(&inventory, ITEM_ID_POTION, 4);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[0].quantity, 4);
|
|
|
|
// Update item quantity
|
|
inventorySet(&inventory, ITEM_ID_POTION, 2);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[0].quantity, 2);
|
|
|
|
// Remove item by setting quantity to 0
|
|
inventorySet(&inventory, ITEM_ID_POTION, 0);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_NULL);
|
|
|
|
// Setting multiple items should not cause issues
|
|
inventorySet(&inventory, ITEM_ID_POTION, 1);
|
|
inventorySet(&inventory, ITEM_ID_POTATO, 5);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[0].quantity, 1);
|
|
assert_int_equal(inventory.storage[1].item, ITEM_ID_POTATO);
|
|
assert_int_equal(inventory.storage[1].quantity, 5);
|
|
assert_int_equal(inventory.storage[2].item, ITEM_ID_NULL);
|
|
|
|
// Setting early item to 0 should shift others down
|
|
inventorySet(&inventory, ITEM_ID_POTION, 0);// Item 0 removed
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_POTATO);
|
|
assert_int_equal(inventory.storage[0].quantity, 5);
|
|
assert_int_equal(inventory.storage[1].item, ITEM_ID_NULL);
|
|
|
|
// Setting non-existing item should add it
|
|
inventorySet(&inventory, ITEM_ID_POTION, 3);
|
|
assert_int_equal(inventory.storage[1].item, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[1].quantity, 3);
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventorySet(NULL, ITEM_ID_POTION, 3));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
inventory.storage = NULL;
|
|
expect_assert_failure(inventorySet(&inventory, ITEM_ID_POTION, 3));
|
|
inventory.storage = storage;
|
|
|
|
// Should fail when given zero storage size
|
|
inventory.storageSize = 0;
|
|
expect_assert_failure(inventorySet(&inventory, ITEM_ID_POTION, 3));
|
|
inventory.storageSize = 5;
|
|
|
|
// Should fail when given ITEM_ID_NULL
|
|
expect_assert_failure(inventorySet(&inventory, ITEM_ID_NULL, 3));
|
|
}
|
|
|
|
static void test_inventoryAdd(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[5];
|
|
inventory_t inventory;
|
|
inventoryInit(&inventory, storage, 5);
|
|
|
|
// Add item quantity
|
|
inventoryAdd(&inventory, ITEM_ID_POTION, 4);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[0].quantity, 4);
|
|
|
|
// Add more to existing item
|
|
inventoryAdd(&inventory, ITEM_ID_POTION, 3);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[0].quantity, 7);
|
|
|
|
// Adding item that would overflow should assert
|
|
expect_assert_failure(inventoryAdd(&inventory, ITEM_ID_POTION, 250));
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventoryAdd(NULL, ITEM_ID_POTION, 3));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
inventory.storage = NULL;
|
|
expect_assert_failure(inventoryAdd(&inventory, ITEM_ID_POTION, 3));
|
|
inventory.storage = storage;
|
|
|
|
// Should fail when given zero storage size
|
|
inventory.storageSize = 0;
|
|
expect_assert_failure(inventoryAdd(&inventory, ITEM_ID_POTION, 3));
|
|
inventory.storageSize = 5;
|
|
|
|
// Should fail when given ITEM_ID_NULL
|
|
expect_assert_failure(inventoryAdd(&inventory, ITEM_ID_NULL, 3));
|
|
}
|
|
|
|
static void test_inventoryRemove(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[5];
|
|
inventory_t inventory;
|
|
inventoryInit(&inventory, storage, 5);
|
|
|
|
// Add item and then remove it
|
|
inventorySet(&inventory, ITEM_ID_POTION, 5);
|
|
inventoryRemove(&inventory, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_NULL);
|
|
|
|
// Removing non-existing item should do nothing
|
|
inventoryRemove(&inventory, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_NULL);
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventoryRemove(NULL, ITEM_ID_POTION));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
inventory.storage = NULL;
|
|
expect_assert_failure(inventoryRemove(&inventory, ITEM_ID_POTION));
|
|
inventory.storage = storage;
|
|
|
|
// Should fail when given zero storage size
|
|
inventory.storageSize = 0;
|
|
expect_assert_failure(inventoryRemove(&inventory, ITEM_ID_POTION));
|
|
inventory.storageSize = 5;
|
|
|
|
// Should fail when given ITEM_ID_NULL
|
|
expect_assert_failure(inventoryRemove(&inventory, ITEM_ID_NULL));
|
|
}
|
|
|
|
static void test_inventoryGetCount(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[5];
|
|
inventory_t inventory;
|
|
inventoryInit(&inventory, storage, 5);
|
|
|
|
// Initially should be zero
|
|
assert_int_equal(inventoryGetCount(&inventory, ITEM_ID_POTION), 0);
|
|
|
|
// Add item and check count
|
|
inventorySet(&inventory, ITEM_ID_POTION, 4);
|
|
assert_int_equal(inventoryGetCount(&inventory, ITEM_ID_POTION), 4);
|
|
|
|
// Update item quantity and check count
|
|
inventorySet(&inventory, ITEM_ID_POTION, 2);
|
|
assert_int_equal(inventoryGetCount(&inventory, ITEM_ID_POTION), 2);
|
|
|
|
// Remove item and check count
|
|
inventorySet(&inventory, ITEM_ID_POTION, 0);
|
|
assert_int_equal(inventoryGetCount(&inventory, ITEM_ID_POTION), 0);
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventoryGetCount(NULL, ITEM_ID_POTION));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
inventory.storage = NULL;
|
|
expect_assert_failure(inventoryGetCount(&inventory, ITEM_ID_POTION));
|
|
inventory.storage = storage;
|
|
|
|
// Should fail when given zero storage size
|
|
inventory.storageSize = 0;
|
|
expect_assert_failure(inventoryGetCount(&inventory, ITEM_ID_POTION));
|
|
inventory.storageSize = 5;
|
|
|
|
// Should fail when given ITEM_ID_NULL
|
|
expect_assert_failure(inventoryGetCount(&inventory, ITEM_ID_NULL));
|
|
}
|
|
|
|
static void test_inventoryIsFull(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[2];
|
|
inventory_t inventory;
|
|
inventoryInit(&inventory, storage, 2);
|
|
|
|
// Initially should not be full
|
|
assert_false(inventoryIsFull(&inventory));
|
|
|
|
// Fill inventory
|
|
inventorySet(&inventory, ITEM_ID_POTION, 1);
|
|
inventorySet(&inventory, ITEM_ID_POTATO, 1);
|
|
assert_true(inventoryIsFull(&inventory));
|
|
|
|
// Remove one item
|
|
inventoryRemove(&inventory, ITEM_ID_POTION);
|
|
assert_false(inventoryIsFull(&inventory));
|
|
|
|
// Add one item back
|
|
inventorySet(&inventory, ITEM_ID_POTION, 1);
|
|
assert_true(inventoryIsFull(&inventory));
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventoryIsFull(NULL));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
inventory.storage = NULL;
|
|
expect_assert_failure(inventoryIsFull(&inventory));
|
|
inventory.storage = storage;
|
|
|
|
// Should fail when given zero storage size
|
|
inventory.storageSize = 0;
|
|
expect_assert_failure(inventoryIsFull(&inventory));
|
|
inventory.storageSize = 2;
|
|
}
|
|
|
|
static void test_inventoryItemFull(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[2];
|
|
inventory_t inventory;
|
|
inventoryInit(&inventory, storage, 2);
|
|
|
|
// Initially should not be full
|
|
assert_false(inventoryItemFull(&inventory, ITEM_ID_POTION));
|
|
|
|
// Add some potions, but not too many.
|
|
inventorySet(&inventory, ITEM_ID_POTION, 100);
|
|
assert_false(inventoryItemFull(&inventory, ITEM_ID_POTION));
|
|
|
|
// Fill with potions
|
|
inventorySet(&inventory, ITEM_ID_POTION, ITEM_STACK_QUANTITY_MAX);
|
|
assert_true(inventoryItemFull(&inventory, ITEM_ID_POTION));
|
|
|
|
// Add potatoes, should not affect potions
|
|
inventorySet(&inventory, ITEM_ID_POTATO, 50);
|
|
assert_true(inventoryItemFull(&inventory, ITEM_ID_POTION));
|
|
assert_false(inventoryItemFull(&inventory, ITEM_ID_POTATO));
|
|
|
|
// Remove some potions
|
|
inventorySet(&inventory, ITEM_ID_POTION, 200);
|
|
assert_false(inventoryItemFull(&inventory, ITEM_ID_POTION));
|
|
|
|
// Fill with potatoes
|
|
inventorySet(&inventory, ITEM_ID_POTATO, ITEM_STACK_QUANTITY_MAX);
|
|
assert_false(inventoryItemFull(&inventory, ITEM_ID_POTION));
|
|
assert_true(inventoryItemFull(&inventory, ITEM_ID_POTATO));
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventoryItemFull(NULL, ITEM_ID_POTION));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
inventory.storage = NULL;
|
|
expect_assert_failure(inventoryItemFull(&inventory, ITEM_ID_POTION));
|
|
inventory.storage = storage;
|
|
|
|
// Should fail when given zero storage size
|
|
inventory.storageSize = 0;
|
|
expect_assert_failure(inventoryItemFull(&inventory, ITEM_ID_POTION));
|
|
inventory.storageSize = 2;
|
|
}
|
|
|
|
static void test_inventorySort(void **state) {
|
|
(void)state;
|
|
|
|
inventorystack_t storage[5];
|
|
inventory_t inventory;
|
|
inventoryInit(&inventory, storage, 5);
|
|
|
|
// Add items out of order
|
|
inventorySet(&inventory, ITEM_ID_POTATO, 3);
|
|
inventorySet(&inventory, ITEM_ID_APPLE, 5);
|
|
inventorySet(&inventory, ITEM_ID_POTION, 2);
|
|
|
|
// Sort by ID
|
|
inventorySort(&inventory, INVENTORY_SORT_BY_ID, false);
|
|
|
|
// Check order
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[1].item, ITEM_ID_POTATO);
|
|
assert_int_equal(inventory.storage[2].item, ITEM_ID_APPLE);
|
|
|
|
// Sort by ID reverse
|
|
inventorySort(&inventory, INVENTORY_SORT_BY_ID, true);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_APPLE);
|
|
assert_int_equal(inventory.storage[1].item, ITEM_ID_POTATO);
|
|
assert_int_equal(inventory.storage[2].item, ITEM_ID_POTION);
|
|
|
|
// Sort by type
|
|
inventorySort(&inventory, INVENTORY_SORT_BY_ID, false);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION);
|
|
assert_int_equal(inventory.storage[1].item, ITEM_ID_POTATO);
|
|
assert_int_equal(inventory.storage[2].item, ITEM_ID_APPLE);
|
|
|
|
// Sort by type reverse
|
|
inventorySort(&inventory, INVENTORY_SORT_BY_ID, true);
|
|
assert_int_equal(inventory.storage[0].item, ITEM_ID_APPLE);
|
|
assert_int_equal(inventory.storage[1].item, ITEM_ID_POTATO);
|
|
assert_int_equal(inventory.storage[2].item, ITEM_ID_POTION);
|
|
|
|
// Should fail when given NULL inventory pointer
|
|
expect_assert_failure(inventorySort(NULL, INVENTORY_SORT_BY_ID, false));
|
|
|
|
// Should fail when given NULL storage pointer
|
|
inventory.storage = NULL;
|
|
expect_assert_failure(inventorySort(&inventory, INVENTORY_SORT_BY_ID, false));
|
|
inventory.storage = storage;
|
|
|
|
// Should fail when given zero storage size
|
|
inventory.storageSize = 0;
|
|
expect_assert_failure(inventorySort(&inventory, INVENTORY_SORT_BY_ID, false));
|
|
inventory.storageSize = 5;
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
const struct CMUnitTest tests[] = {
|
|
cmocka_unit_test(test_inventoryInit),
|
|
cmocka_unit_test(test_inventoryItemExists),
|
|
cmocka_unit_test(test_inventorySet),
|
|
cmocka_unit_test(test_inventoryAdd),
|
|
cmocka_unit_test(test_inventoryRemove),
|
|
cmocka_unit_test(test_inventoryGetCount),
|
|
cmocka_unit_test(test_inventoryIsFull),
|
|
cmocka_unit_test(test_inventoryItemFull),
|
|
cmocka_unit_test(test_inventorySort),
|
|
};
|
|
|
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
|
} |