/* slist_test.c
*
* Copyright 2025 Francois Techene
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include
#include
#include
#include "slist.h"
#ifndef bool
typedef Boolean bool;
#endif
typedef struct _MyObject {
char* text;
int num;
} MyObject;
MyObject* MyObject_new(char* text, int num)
{
MyObject* self = (MyObject*)malloc(sizeof(MyObject));
self->text = text;
self->num = num;
return self;
}
MyObject* obj1 = NULL;
MyObject* obj2 = NULL;
MyObject* obj3 = NULL;
SList* list = NULL;
bool found_error = false;
//////////////////////////////////////////////////////////
// Assert Functions
//
bool
ut_asser_ptr_equal(void* value_1, void* value_2, char* msg)
{
if (value_1 != value_2) {
printf(" FAILED: %s - Pointers do not match\n", msg);
found_error = true;
return 0;
}
return 1;
}
bool
ut_asser_null(void* value, char* msg)
{
if (value) {
printf(" FAILED: %s - Should be NULL\n", msg);
found_error = true;
return 0;
}
return 1;
}
bool
ut_asser_not_null(void* value, char* msg)
{
if (!value) {
printf(" FAILED: %s - Should not be NULL\n", msg);
found_error = true;
return 0;
}
return 1;
}
bool
ut_asser_true(bool value, char* msg)
{
if (!value) {
printf(" FAILED: %s - Should be true\n", msg);
found_error = true;
return 0;
}
return 1;
}
bool
ut_asser_false(bool value, char* msg)
{
if (value) {
printf(" FAILED: %s - Should be false\n", msg);
found_error = true;
return 0;
}
return 1;
}
bool
ut_asser_greater_int(int value_1, int value_2, char* msg)
{
if (value_1 > value_2) {
printf(" FAILED: %s - Should be greater than %d and is %d\n",
msg,
value_2,
value_1);
found_error = true;
return 0;
}
return 1;
}
bool
ut_asser_not_equal_int(int value_1, int value_2, char* msg)
{
if (value_1 == value_2) {
printf(" FAILED: %s - Should not equal %d\n", msg, value_2);
found_error = true;
return 0;
}
return 1;
}
bool
ut_asser_equal_int(int value_1, int value_2, char* msg)
{
if (value_1 != value_2) {
printf(" FAILED: %s - Value is %d, should be %d\n",
msg,
value_1,
value_2);
found_error = true;
return 0;
}
return 1;
}
//////////////////////////////////////////////////////////
// Unit Test
//
void
init_tests()
{
printf("Initializing Objects... \n");
obj1 = MyObject_new("Obj1", 1);
obj2 = MyObject_new("Obj2", 2);
obj3 = MyObject_new("Obj3", 3);
list = SList_new();
ut_asser_equal_int(obj1->num, 1,
"init_tests() - obj1->num");
ut_asser_equal_int(obj2->num, 2,
"init_tests() - obj2->num");
ut_asser_equal_int(obj3->num, 3,
"init_tests() - obj3->num");
ut_asser_null(list->head,
"init_tests() - list->head");
ut_asser_equal_int(list->count, 0,
"init_tests() - list->count");
}
void
test_append()
{
MyObject* obj = NULL;
SListItem* item = NULL;
int count = 0;
printf("Testing append... \n");
slist_append(list, obj1);
slist_append(list, obj2);
slist_append(list, obj3);
SL_FOREACH(item, list) {
count++;
obj = (MyObject*)item->data;
ut_asser_equal_int(obj->num, count,
"test_append() - obj->num");
}
ut_asser_equal_int(count, 3,
"test_append() - FOREACH count");
}
void
test_remove_item()
{
MyObject* obj = NULL;
SListItem* item = NULL;
int count = 0;
printf("Testing remove item...\n");
slist_remove_value(list, obj2);
SL_FOREACH(item, list) {
count++;
obj = (MyObject*)item->data;
if (count == 1) {
ut_asser_equal_int(obj->num, 1,
"test_remove_item() - obj->num");
}
if (count == 2) {
ut_asser_equal_int(obj->num, 3,
"test_remove_item() - obj->num");
}
}
ut_asser_equal_int(list->count, 2,
"test_remove_item() - list->count");
ut_asser_equal_int(count, 2,
"test_remove_item() - FOREACH count");
}
void
test_insert_at()
{
MyObject* obj = NULL;
SListItem* item = NULL;
int count = 0;
printf("Testing insert at... \n");
slist_insert_at(list, obj2, 1);
SL_FOREACH(item, list) {
count++;
obj = (MyObject*)item->data;
if (count == 1) {
ut_asser_equal_int(obj->num, 1,
"test_insert_at() - obj->num");
}
if (count == 2) {
ut_asser_equal_int(obj->num, 2,
"test_insert_at() - obj->num");
}
if (count == 3) {
ut_asser_equal_int(obj->num, 3,
"test_insert_at() - obj->num");
}
}
ut_asser_equal_int(list->count, 3,
"test_insert_at() - list->count");
ut_asser_equal_int(count, 3,
"test_insert_at() - FOREACH count");
}
void
test_remove_at()
{
MyObject* obj = NULL;
SListItem* item = NULL;
int count = 0;
printf("Testing remove first...\n");
slist_remove_at(list, 1);
SL_FOREACH(item, list) {
count++;
obj = (MyObject*)item->data;
if (count == 1) {
ut_asser_equal_int(obj->num, 1,
"test_remove_at() - obj->num");
}
if (count == 2) {
ut_asser_equal_int(obj->num, 3,
"test_remove_at() - obj->num");
}
}
ut_asser_equal_int(list->count, 2,
"test_remove_at() - list->count");
ut_asser_equal_int(count, 2,
"test_remove_at() - FOREACH count");
}
void
test_insert_after()
{
MyObject* obj = NULL;
SListItem* item = NULL;
int count = 0;
printf("Testing insert after... \n");
slist_insert_after(list, obj2, obj1);
SL_FOREACH(item, list) {
count++;
obj = (MyObject*)item->data;
if (count == 1) {
ut_asser_equal_int(obj->num, 1,
"test_insert_after()");
}
if (count == 2) {
ut_asser_equal_int(obj->num, 2,
"test_insert_after()");
}
if (count == 3) {
ut_asser_equal_int(obj->num, 3,
"test_insert_after()");
}
}
ut_asser_equal_int(list->count, 3,
"test_insert_after() - list->count");
ut_asser_equal_int(count, 3,
"test_insert_after() - FOREACH count");
}
void
test_remove_last()
{
MyObject* obj = NULL;
SListItem* item = NULL;
int count = 0;
printf("Testing remove last...\n");
slist_remove_last(list);
SL_FOREACH(item, list) {
count++;
obj = (MyObject*)item->data;
if (count == 1) {
ut_asser_equal_int(obj->num, 1,
"test_remove_last()");
}
if (count == 2) {
ut_asser_equal_int(obj->num, 2,
"test_remove_last()");
}
}
ut_asser_equal_int(list->count, 2,
"test_remove_last() - list->count");
ut_asser_equal_int(count, 2,
"test_remove_last() - FOREACH count");
}
void
test_empty_list()
{
MyObject* obj = NULL;
SListItem* item = NULL;
int count = 0;
printf("Testing empty list...\n");
slist_append(list, obj1);
slist_append(list, obj2);
ut_asser_not_equal_int(list->count, 0,
"test_empty_list() - list->count");
slist_empty(list);
SL_FOREACH(item, list) {
count++;
obj = (MyObject*)item->data;
}
ut_asser_equal_int(count, 0,
"test_empty_list() - FOREACH count");
ut_asser_equal_int(list->count, 0,
"test_empty_list() - list->count");
}
void test_memory()
{
long total_mem;
long mem_1;
long mem_2;
long mem_3;
long mem_4;
long mem_5;
long mem_empty;
printf("\nTesting memory...\n\n");
total_mem = FreeMem();
slist_append(list, obj1);
slist_append(list, obj2);
slist_append(list, obj3);
mem_1 = total_mem - FreeMem();
slist_remove_at(list, 0);
mem_2 = total_mem - FreeMem();
slist_remove_last(list);
mem_3 = total_mem - FreeMem();
slist_remove_value(list, obj2);
mem_4 = total_mem - FreeMem();
slist_append(list, obj1);
slist_append(list, obj2);
slist_append(list, obj3);
mem_5 = total_mem - FreeMem();
slist_empty(list);
mem_empty = total_mem - FreeMem();
printf("After appending 3 items: using %ld bytes\n", mem_1);
printf("After removing first: using %ld bytes\n", mem_2);
printf("After removing last: using %ld bytes\n", mem_3);
printf("After removing item: using %ld bytes\n", mem_4);
printf("After re-appending 3 items: using %ld bytes\n", mem_5);
printf("After emptying: using %ld bytes\n", mem_empty);
}
int
main(void)
{
MaxApplZone();
printf("+-----------------------------------+\n");
printf("| SList Unit Test |\n");
printf("+-----------------------------------+\n\n");
init_tests();
test_append();
test_remove_item();
test_insert_at();
test_remove_at();
test_insert_after();
test_remove_last();
test_empty_list();
test_memory();
if (!found_error) {
printf("\nSuccessful!\n");
}
else {
printf("\n** Errors were found **\n");
}
return 1;
}