229 lines
5.3 KiB
C
229 lines
5.3 KiB
C
#include "runner.h"
|
|
#include "../core.h"
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
|
|
UNIT_TEST(arrlen_macro) {
|
|
int array[5] = {1, 2, 3, 4, 5};
|
|
ASSERT(arrlen(array) == 5);
|
|
|
|
char str[] = "hello";
|
|
ASSERT(arrlen(str) == 6); // Including null terminator
|
|
}
|
|
|
|
UNIT_TEST(min_max_macros) {
|
|
ASSERT(MIN(5, 10) == 5);
|
|
ASSERT(MIN(-5, 10) == -5);
|
|
ASSERT(MIN(5.5, 10.1) == 5.5);
|
|
|
|
ASSERT(MAX(5, 10) == 10);
|
|
ASSERT(MAX(-5, 10) == 10);
|
|
ASSERT(MAX(5.5, 10.1) == 10.1);
|
|
}
|
|
|
|
UNIT_TEST(size_constants) {
|
|
ASSERT(KB(1) == 1024);
|
|
ASSERT(MB(1) == 1024 * 1024);
|
|
ASSERT(GB(1) == 1024 * 1024 * 1024);
|
|
ASSERT(TB(1) == 1024ULL * 1024ULL * 1024ULL * 1024ULL);
|
|
|
|
ASSERT(KB(2) == 2048);
|
|
ASSERT(MB(2) == 2 * 1024 * 1024);
|
|
}
|
|
|
|
UNIT_TEST(linked_list) {
|
|
// Define a simple node structure
|
|
typedef struct Node {
|
|
int value;
|
|
struct Node *next;
|
|
} Node;
|
|
|
|
// Create some nodes
|
|
Node n1 = {1, NULL};
|
|
Node n2 = {2, NULL};
|
|
Node n3 = {3, NULL};
|
|
|
|
// Initialize list
|
|
Node *list = NULL;
|
|
|
|
// Push nodes onto list
|
|
list_push(list, &n3);
|
|
list_push(list, &n2);
|
|
list_push(list, &n1);
|
|
|
|
// Check list order
|
|
ASSERT(list == &n1);
|
|
ASSERT(list->next == &n2);
|
|
ASSERT(list->next->next == &n3);
|
|
ASSERT(list->next->next->next == NULL);
|
|
|
|
// Pop from list
|
|
list_pop(list);
|
|
ASSERT(list == &n2);
|
|
ASSERT(list->next == &n3);
|
|
|
|
list_pop(list);
|
|
ASSERT(list == &n3);
|
|
|
|
list_pop(list);
|
|
ASSERT(list == NULL);
|
|
}
|
|
|
|
UNIT_TEST(double_linked_list) {
|
|
// Define a double linked node
|
|
typedef struct DNode {
|
|
int value;
|
|
struct DNode *next;
|
|
struct DNode *prev;
|
|
} DNode;
|
|
|
|
// Create some nodes
|
|
DNode n1 = {1, NULL, NULL};
|
|
DNode n2 = {2, NULL, NULL};
|
|
DNode n3 = {3, NULL, NULL};
|
|
|
|
// Initialize list
|
|
DNode *list = NULL;
|
|
|
|
// Push nodes
|
|
dlist_push(list, &n3);
|
|
dlist_push(list, &n2);
|
|
dlist_push(list, &n1);
|
|
|
|
// Check list structure
|
|
ASSERT(list == &n1);
|
|
ASSERT(list->next == &n2);
|
|
ASSERT(list->next->next == &n3);
|
|
ASSERT(list->prev == NULL);
|
|
ASSERT(list->next->prev == &n1);
|
|
ASSERT(list->next->next->prev == &n2);
|
|
|
|
// Pop middle node
|
|
dlist_pop(list, &n2);
|
|
|
|
// Check updated structure
|
|
ASSERT(list == &n1);
|
|
ASSERT(list->next == &n3);
|
|
ASSERT(list->next->prev == &n1);
|
|
|
|
// Pop first node
|
|
dlist_pop(list, &n1);
|
|
ASSERT(list == &n3);
|
|
ASSERT(list->prev == NULL);
|
|
}
|
|
|
|
UNIT_TEST(ordered_linked_list) {
|
|
// Define a simple node
|
|
typedef struct ONode {
|
|
int value;
|
|
struct ONode *next;
|
|
} ONode;
|
|
|
|
// Create nodes
|
|
ONode n1 = {1, NULL};
|
|
ONode n2 = {2, NULL};
|
|
ONode n3 = {3, NULL};
|
|
|
|
// Initialize head and tail
|
|
ONode *head = NULL;
|
|
ONode *tail = NULL;
|
|
|
|
// Push nodes in order
|
|
olist_push(head, tail, &n1);
|
|
ASSERT(head == &n1);
|
|
ASSERT(tail == &n1);
|
|
|
|
olist_push(head, tail, &n2);
|
|
ASSERT(head == &n1);
|
|
ASSERT(tail == &n2);
|
|
ASSERT(head->next == &n2);
|
|
|
|
olist_push(head, tail, &n3);
|
|
ASSERT(head == &n1);
|
|
ASSERT(tail == &n3);
|
|
ASSERT(head->next == &n2);
|
|
ASSERT(head->next->next == &n3);
|
|
}
|
|
|
|
UNIT_TEST(for_each_macro) {
|
|
// Define a simple node
|
|
typedef struct Node {
|
|
int value;
|
|
struct Node *next;
|
|
} Node;
|
|
|
|
// Create linked list
|
|
Node n1 = {1, NULL};
|
|
Node n2 = {2, NULL};
|
|
Node n3 = {3, NULL};
|
|
|
|
n1.next = &n2;
|
|
n2.next = &n3;
|
|
|
|
Node *list = &n1;
|
|
|
|
// Use for_each to sum values
|
|
int sum = 0;
|
|
for_each(it, list) {
|
|
sum += it->value;
|
|
}
|
|
|
|
ASSERT(sum == 6); // 1 + 2 + 3
|
|
}
|
|
|
|
UNIT_TEST(fmt_print) {
|
|
// This function outputs to stdout, so we can't easily test its output
|
|
// Just verify it doesn't crash and returns a positive value
|
|
int result = fmt_print("Test %d %s\n", 42, "hello");
|
|
ASSERT(result > 0);
|
|
}
|
|
|
|
UNIT_TEST(fmt_buffer) {
|
|
char buffer[128];
|
|
|
|
// Basic formatting
|
|
int result = fmt_buffer(buffer, sizeof(buffer), "Int: %d", 42);
|
|
ASSERT(result > 0);
|
|
ASSERT(strcmp(buffer, "Int: 42") == 0);
|
|
|
|
// Multiple arguments
|
|
result = fmt_buffer(buffer, sizeof(buffer), "%s %d %.2f", "Test", 123, 3.14159);
|
|
ASSERT(result > 0);
|
|
ASSERT(strcmp(buffer, "Test 123 3.14") == 0);
|
|
|
|
// Buffer size limiting
|
|
result = fmt_buffer(buffer, 5, "Long text that won't fit");
|
|
ASSERT(result == 24); // fmt_buffer returns the lenght if it did fit
|
|
ASSERT(strlen(buffer) == 4);
|
|
}
|
|
|
|
// Helper function to test variadic function
|
|
int test_fmt_printv(const char *fmt, ...) {
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
int result = fmt_printv(fmt, args);
|
|
va_end(args);
|
|
return result;
|
|
}
|
|
|
|
UNIT_TEST(fmt_printv) {
|
|
// Just verify it doesn't crash and returns positive value
|
|
int result = test_fmt_printv("Test %d %s\n", 42, "hello");
|
|
ASSERT(result > 0);
|
|
}
|
|
|
|
// Helper function to test variadic function
|
|
int test_fmt_bufferv(char *buf, usize len, const char *fmt, ...) {
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
int result = fmt_bufferv(buf, len, fmt, args);
|
|
va_end(args);
|
|
return result;
|
|
}
|
|
|
|
UNIT_TEST(fmt_bufferv) {
|
|
char buffer[128];
|
|
int result = test_fmt_bufferv(buffer, sizeof(buffer), "%d %s", 42, "test");
|
|
ASSERT(result > 0);
|
|
ASSERT(strcmp(buffer, "42 test") == 0);
|
|
}
|