This commit is contained in:
retoor 2025-12-04 23:00:10 +01:00
parent f58f42a4a2
commit 5b5d2e1009
6 changed files with 401 additions and 242 deletions

View File

@ -260,17 +260,17 @@ benchmark: test_benchmark
@python3 examples/benchmark.py @python3 examples/benchmark.py
@echo "" @echo ""
test_nanbox: tests/test_nanbox.c runtime/nanbox.h test_nanbox: tests/test_nanbox.c runtime/nanbox.h $(UNITTEST_OBJECTS)
$(CC) $(CFLAGS) -o $@ tests/test_nanbox.c $(LDFLAGS) $(CC) $(CFLAGS) -o $@ tests/test_nanbox.c $(UNITTEST_OBJECTS) $(LDFLAGS)
test_fastframe: tests/test_fastframe.c runtime/fastframe.c runtime/nanbox.h runtime/fastframe.h test_fastframe: tests/test_fastframe.c runtime/fastframe.c runtime/nanbox.h runtime/fastframe.h $(UNITTEST_OBJECTS)
$(CC) $(CFLAGS) -o $@ tests/test_fastframe.c runtime/fastframe.c $(LDFLAGS) $(CC) $(CFLAGS) -o $@ tests/test_fastframe.c runtime/fastframe.c $(UNITTEST_OBJECTS) $(LDFLAGS)
test_labeltable: tests/test_labeltable.c runtime/labeltable.c $(IR_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) test_labeltable: tests/test_labeltable.c runtime/labeltable.c $(IR_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(UNITTEST_OBJECTS)
$(CC) $(CFLAGS) -o $@ tests/test_labeltable.c runtime/labeltable.c $(IR_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(LDFLAGS) $(CC) $(CFLAGS) -o $@ tests/test_labeltable.c runtime/labeltable.c $(IR_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(UNITTEST_OBJECTS) $(LDFLAGS)
test_methodcache: tests/test_methodcache.c runtime/methodcache.c runtime/methodcache.h test_methodcache: tests/test_methodcache.c runtime/methodcache.c runtime/methodcache.h $(UNITTEST_OBJECTS)
$(CC) $(CFLAGS) -o $@ tests/test_methodcache.c runtime/methodcache.c $(LDFLAGS) $(CC) $(CFLAGS) -o $@ tests/test_methodcache.c runtime/methodcache.c $(UNITTEST_OBJECTS) $(LDFLAGS)
test_phase0: test_nanbox test_fastframe test_labeltable test_methodcache test_phase0: test_nanbox test_fastframe test_labeltable test_methodcache
@echo "=== Running Phase 0 Tests ===" @echo "=== Running Phase 0 Tests ==="

View File

@ -1,86 +1,93 @@
#include <stdio.h> #include "test_utils.h"
#include <assert.h>
#include "../runtime/fastframe.h" #include "../runtime/fastframe.h"
static int tests_passed = 0; UnittestTestResult_t* test_init(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_init");
#define TEST(name) static void test_##name(void)
#define RUN_TEST(name) do { \
printf("Running %s... ", #name); \
test_##name(); \
printf("PASSED\n"); \
tests_passed++; \
} while(0)
TEST(init) {
rava_fastframe_init(); rava_fastframe_init();
assert(rava_fastframe_get_depth() == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, rava_fastframe_get_depth(), "initial depth should be 0");
assert(rava_fastframe_current() == NULL); UNITTEST_ASSERT_NULL(_unittest_result, rava_fastframe_current(), "current frame should be NULL");
UNITTEST_END_TEST();
} }
TEST(push_pop) { UnittestTestResult_t* test_push_pop(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_push_pop");
rava_fastframe_init(); rava_fastframe_init();
FastFrame_t* frame = rava_fastframe_push(NULL, 4); FastFrame_t* frame = rava_fastframe_push(NULL, 4);
assert(frame != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, frame, "pushed frame should not be NULL");
assert(rava_fastframe_get_depth() == 1); UNITTEST_ASSERT_EQUAL(_unittest_result, 1, rava_fastframe_get_depth(), "depth should be 1");
assert(rava_fastframe_current() == frame); UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_current() == frame, "current should match pushed frame");
rava_fastframe_pop(); rava_fastframe_pop();
assert(rava_fastframe_get_depth() == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, rava_fastframe_get_depth(), "depth should be 0 after pop");
assert(rava_fastframe_current() == NULL); UNITTEST_ASSERT_NULL(_unittest_result, rava_fastframe_current(), "current should be NULL after pop");
UNITTEST_END_TEST();
} }
TEST(nested_frames) { UnittestTestResult_t* test_nested_frames(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_nested_frames");
rava_fastframe_init(); rava_fastframe_init();
FastFrame_t* f1 = rava_fastframe_push(NULL, 2); FastFrame_t* f1 = rava_fastframe_push(NULL, 2);
FastFrame_t* f2 = rava_fastframe_push(NULL, 2); FastFrame_t* f2 = rava_fastframe_push(NULL, 2);
FastFrame_t* f3 = rava_fastframe_push(NULL, 2); FastFrame_t* f3 = rava_fastframe_push(NULL, 2);
assert(rava_fastframe_get_depth() == 3); UNITTEST_ASSERT_EQUAL(_unittest_result, 3, rava_fastframe_get_depth(), "depth should be 3");
assert(rava_fastframe_current() == f3); UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_current() == f3, "current should be f3");
rava_fastframe_pop(); rava_fastframe_pop();
assert(rava_fastframe_current() == f2); UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_current() == f2, "current should be f2");
rava_fastframe_pop(); rava_fastframe_pop();
assert(rava_fastframe_current() == f1); UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_current() == f1, "current should be f1");
rava_fastframe_pop(); rava_fastframe_pop();
assert(rava_fastframe_current() == NULL); UNITTEST_ASSERT_NULL(_unittest_result, rava_fastframe_current(), "current should be NULL");
UNITTEST_END_TEST();
} }
TEST(stack_operations) { UnittestTestResult_t* test_stack_operations(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_stack_operations");
rava_fastframe_init(); rava_fastframe_init();
FastFrame_t* frame = rava_fastframe_push(NULL, 4); FastFrame_t* frame = rava_fastframe_push(NULL, 4);
assert(rava_fastframe_stack_is_empty(frame)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_stack_is_empty(frame), "stack should be empty");
rava_fastframe_stack_push(frame, rava_nanbox_int(10)); rava_fastframe_stack_push(frame, rava_nanbox_int(10));
rava_fastframe_stack_push(frame, rava_nanbox_int(20)); rava_fastframe_stack_push(frame, rava_nanbox_int(20));
rava_fastframe_stack_push(frame, rava_nanbox_int(30)); rava_fastframe_stack_push(frame, rava_nanbox_int(30));
assert(!rava_fastframe_stack_is_empty(frame)); UNITTEST_ASSERT_FALSE(_unittest_result, rava_fastframe_stack_is_empty(frame), "stack should not be empty");
assert(frame->stack_top == 3); UNITTEST_ASSERT_EQUAL(_unittest_result, 3, frame->stack_top, "stack top should be 3");
RavaNanboxValue_t top = rava_fastframe_stack_peek(frame); RavaNanboxValue_t top = rava_fastframe_stack_peek(frame);
assert(rava_nanbox_as_int(top) == 30); UNITTEST_ASSERT_EQUAL(_unittest_result, 30, rava_nanbox_as_int(top), "peek should return 30");
assert(frame->stack_top == 3); UNITTEST_ASSERT_EQUAL(_unittest_result, 3, frame->stack_top, "peek should not change stack top");
RavaNanboxValue_t v1 = rava_fastframe_stack_pop(frame); RavaNanboxValue_t v1 = rava_fastframe_stack_pop(frame);
RavaNanboxValue_t v2 = rava_fastframe_stack_pop(frame); RavaNanboxValue_t v2 = rava_fastframe_stack_pop(frame);
RavaNanboxValue_t v3 = rava_fastframe_stack_pop(frame); RavaNanboxValue_t v3 = rava_fastframe_stack_pop(frame);
assert(rava_nanbox_as_int(v1) == 30); UNITTEST_ASSERT_EQUAL(_unittest_result, 30, rava_nanbox_as_int(v1), "first pop should return 30");
assert(rava_nanbox_as_int(v2) == 20); UNITTEST_ASSERT_EQUAL(_unittest_result, 20, rava_nanbox_as_int(v2), "second pop should return 20");
assert(rava_nanbox_as_int(v3) == 10); UNITTEST_ASSERT_EQUAL(_unittest_result, 10, rava_nanbox_as_int(v3), "third pop should return 10");
assert(rava_fastframe_stack_is_empty(frame)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_stack_is_empty(frame), "stack should be empty after pops");
rava_fastframe_reset(); rava_fastframe_reset();
UNITTEST_END_TEST();
} }
TEST(locals) { UnittestTestResult_t* test_locals(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_locals");
rava_fastframe_init(); rava_fastframe_init();
FastFrame_t* frame = rava_fastframe_push(NULL, 8); FastFrame_t* frame = rava_fastframe_push(NULL, 8);
@ -89,27 +96,35 @@ TEST(locals) {
frame->locals[1] = rava_nanbox_int(200); frame->locals[1] = rava_nanbox_int(200);
frame->locals[2] = rava_nanbox_bool(true); frame->locals[2] = rava_nanbox_bool(true);
assert(rava_nanbox_as_int(frame->locals[0]) == 100); UNITTEST_ASSERT_EQUAL(_unittest_result, 100, rava_nanbox_as_int(frame->locals[0]), "local 0 should be 100");
assert(rava_nanbox_as_int(frame->locals[1]) == 200); UNITTEST_ASSERT_EQUAL(_unittest_result, 200, rava_nanbox_as_int(frame->locals[1]), "local 1 should be 200");
assert(rava_nanbox_as_bool(frame->locals[2]) == true); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_as_bool(frame->locals[2]), "local 2 should be true");
rava_fastframe_reset(); rava_fastframe_reset();
UNITTEST_END_TEST();
} }
TEST(reset) { UnittestTestResult_t* test_reset(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_reset");
rava_fastframe_init(); rava_fastframe_init();
rava_fastframe_push(NULL, 2); rava_fastframe_push(NULL, 2);
rava_fastframe_push(NULL, 2); rava_fastframe_push(NULL, 2);
rava_fastframe_push(NULL, 2); rava_fastframe_push(NULL, 2);
assert(rava_fastframe_get_depth() == 3); UNITTEST_ASSERT_EQUAL(_unittest_result, 3, rava_fastframe_get_depth(), "depth should be 3");
rava_fastframe_reset(); rava_fastframe_reset();
assert(rava_fastframe_get_depth() == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, rava_fastframe_get_depth(), "depth should be 0 after reset");
UNITTEST_END_TEST();
} }
TEST(stack_clear) { UnittestTestResult_t* test_stack_clear(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_stack_clear");
rava_fastframe_init(); rava_fastframe_init();
FastFrame_t* frame = rava_fastframe_push(NULL, 4); FastFrame_t* frame = rava_fastframe_push(NULL, 4);
@ -117,26 +132,43 @@ TEST(stack_clear) {
rava_fastframe_stack_push(frame, rava_nanbox_int(2)); rava_fastframe_stack_push(frame, rava_nanbox_int(2));
rava_fastframe_stack_push(frame, rava_nanbox_int(3)); rava_fastframe_stack_push(frame, rava_nanbox_int(3));
assert(frame->stack_top == 3); UNITTEST_ASSERT_EQUAL(_unittest_result, 3, frame->stack_top, "stack top should be 3");
rava_fastframe_stack_clear(frame); rava_fastframe_stack_clear(frame);
assert(frame->stack_top == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, frame->stack_top, "stack top should be 0 after clear");
assert(rava_fastframe_stack_is_empty(frame)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_stack_is_empty(frame), "stack should be empty after clear");
rava_fastframe_reset(); rava_fastframe_reset();
UNITTEST_END_TEST();
} }
int main(void) { int main(int argc, char **argv) {
printf("=== Fast Frame Unit Tests ===\n\n"); UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
RUN_TEST(init); if (argc > 1 && strcmp(argv[1], "--json") == 0) {
RUN_TEST(push_pop); config->output_format = UNITTEST_FORMAT_JSON;
RUN_TEST(nested_frames); config->use_colors = false;
RUN_TEST(stack_operations); }
RUN_TEST(locals);
RUN_TEST(reset);
RUN_TEST(stack_clear);
printf("\n=== Results: %d tests passed ===\n", tests_passed); UnittestTestSuite_t *suite = unittest_test_suite_create("Fast Frame Tests");
return 0;
UnittestTestCase_t *tc = unittest_test_case_create("TestFastFrame");
unittest_test_case_add_result(tc, test_init());
unittest_test_case_add_result(tc, test_push_pop());
unittest_test_case_add_result(tc, test_nested_frames());
unittest_test_case_add_result(tc, test_stack_operations());
unittest_test_case_add_result(tc, test_locals());
unittest_test_case_add_result(tc, test_reset());
unittest_test_case_add_result(tc, test_stack_clear());
unittest_test_suite_add_test_case(suite, tc);
unittest_generate_report(suite, config);
int failures = suite->total_failed + suite->total_errors;
unittest_test_suite_destroy(suite);
unittest_config_destroy(config);
return failures > 0 ? 1 : 0;
} }

View File

@ -1,33 +1,31 @@
#include <stdio.h> #include "test_utils.h"
#include <assert.h>
#include <stdlib.h>
#include "../ir/ir.h" #include "../ir/ir.h"
#include "../runtime/labeltable.h" #include "../runtime/labeltable.h"
static int tests_passed = 0; UnittestTestResult_t* test_create_empty(void) {
UNITTEST_BEGIN_TEST("TestLabelTable", "test_create_empty");
#define TEST(name) static void test_##name(void)
#define RUN_TEST(name) do { \
printf("Running %s... ", #name); \
test_##name(); \
printf("PASSED\n"); \
tests_passed++; \
} while(0)
TEST(create_empty) {
RavaInstructionList_t* list = rava_instruction_list_create(); RavaInstructionList_t* list = rava_instruction_list_create();
LabelTable_t* table = rava_labeltable_create(list); LabelTable_t* table = rava_labeltable_create(list);
assert(table != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, table, "table should not be NULL");
rava_labeltable_destroy(table); rava_labeltable_destroy(table);
rava_instruction_list_destroy(list); rava_instruction_list_destroy(list);
UNITTEST_END_TEST();
} }
TEST(create_null) { UnittestTestResult_t* test_create_null(void) {
UNITTEST_BEGIN_TEST("TestLabelTable", "test_create_null");
LabelTable_t* table = rava_labeltable_create(NULL); LabelTable_t* table = rava_labeltable_create(NULL);
assert(table == NULL); UNITTEST_ASSERT_NULL(_unittest_result, table, "table should be NULL for NULL input");
UNITTEST_END_TEST();
} }
TEST(single_label) { UnittestTestResult_t* test_single_label(void) {
UNITTEST_BEGIN_TEST("TestLabelTable", "test_single_label");
RavaInstructionList_t* list = rava_instruction_list_create(); RavaInstructionList_t* list = rava_instruction_list_create();
RavaInstruction_t instr1 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 10}; RavaInstruction_t instr1 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 10};
@ -39,16 +37,20 @@ TEST(single_label) {
rava_instruction_list_add(list, instr3); rava_instruction_list_add(list, instr3);
LabelTable_t* table = rava_labeltable_create(list); LabelTable_t* table = rava_labeltable_create(list);
assert(table != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, table, "table should not be NULL");
size_t pc = rava_labeltable_lookup(table, 0); size_t pc = rava_labeltable_lookup(table, 0);
assert(pc == 2); UNITTEST_ASSERT_EQUAL(_unittest_result, 2, (int)pc, "label 0 should point to PC 2");
rava_labeltable_destroy(table); rava_labeltable_destroy(table);
rava_instruction_list_destroy(list); rava_instruction_list_destroy(list);
UNITTEST_END_TEST();
} }
TEST(multiple_labels) { UnittestTestResult_t* test_multiple_labels(void) {
UNITTEST_BEGIN_TEST("TestLabelTable", "test_multiple_labels");
RavaInstructionList_t* list = rava_instruction_list_create(); RavaInstructionList_t* list = rava_instruction_list_create();
RavaInstruction_t instr0 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 0}; RavaInstruction_t instr0 = {.opcode = RAVA_OP_LOAD_CONST, .operand.int_value = 0};
@ -66,59 +68,84 @@ TEST(multiple_labels) {
rava_instruction_list_add(list, label2); rava_instruction_list_add(list, label2);
LabelTable_t* table = rava_labeltable_create(list); LabelTable_t* table = rava_labeltable_create(list);
assert(table != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, table, "table should not be NULL");
assert(rava_labeltable_lookup(table, 0) == 2); UNITTEST_ASSERT_EQUAL(_unittest_result, 2, (int)rava_labeltable_lookup(table, 0), "label 0 should point to PC 2");
assert(rava_labeltable_lookup(table, 1) == 4); UNITTEST_ASSERT_EQUAL(_unittest_result, 4, (int)rava_labeltable_lookup(table, 1), "label 1 should point to PC 4");
assert(rava_labeltable_lookup(table, 2) == 6); UNITTEST_ASSERT_EQUAL(_unittest_result, 6, (int)rava_labeltable_lookup(table, 2), "label 2 should point to PC 6");
rava_labeltable_destroy(table); rava_labeltable_destroy(table);
rava_instruction_list_destroy(list); rava_instruction_list_destroy(list);
UNITTEST_END_TEST();
} }
TEST(missing_label) { UnittestTestResult_t* test_missing_label(void) {
UNITTEST_BEGIN_TEST("TestLabelTable", "test_missing_label");
RavaInstructionList_t* list = rava_instruction_list_create(); RavaInstructionList_t* list = rava_instruction_list_create();
RavaInstruction_t label = {.opcode = RAVA_OP_LABEL, .operand.label_id = 5}; RavaInstruction_t label = {.opcode = RAVA_OP_LABEL, .operand.label_id = 5};
rava_instruction_list_add(list, label); rava_instruction_list_add(list, label);
LabelTable_t* table = rava_labeltable_create(list); LabelTable_t* table = rava_labeltable_create(list);
assert(table != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, table, "table should not be NULL");
assert(rava_labeltable_lookup(table, 0) == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, (int)rava_labeltable_lookup(table, 0), "missing label 0 should return 0");
assert(rava_labeltable_lookup(table, 1) == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, (int)rava_labeltable_lookup(table, 1), "missing label 1 should return 0");
assert(rava_labeltable_lookup(table, 5) == 1); UNITTEST_ASSERT_EQUAL(_unittest_result, 1, (int)rava_labeltable_lookup(table, 5), "label 5 should point to PC 1");
rava_labeltable_destroy(table); rava_labeltable_destroy(table);
rava_instruction_list_destroy(list); rava_instruction_list_destroy(list);
UNITTEST_END_TEST();
} }
TEST(out_of_range) { UnittestTestResult_t* test_out_of_range(void) {
UNITTEST_BEGIN_TEST("TestLabelTable", "test_out_of_range");
RavaInstructionList_t* list = rava_instruction_list_create(); RavaInstructionList_t* list = rava_instruction_list_create();
RavaInstruction_t label = {.opcode = RAVA_OP_LABEL, .operand.label_id = 2}; RavaInstruction_t label = {.opcode = RAVA_OP_LABEL, .operand.label_id = 2};
rava_instruction_list_add(list, label); rava_instruction_list_add(list, label);
LabelTable_t* table = rava_labeltable_create(list); LabelTable_t* table = rava_labeltable_create(list);
assert(table != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, table, "table should not be NULL");
assert(rava_labeltable_lookup(table, 100) == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, (int)rava_labeltable_lookup(table, 100), "out of range label should return 0");
assert(rava_labeltable_lookup(table, -1) == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, (int)rava_labeltable_lookup(table, -1), "negative label should return 0");
rava_labeltable_destroy(table); rava_labeltable_destroy(table);
rava_instruction_list_destroy(list); rava_instruction_list_destroy(list);
UNITTEST_END_TEST();
} }
int main(void) { int main(int argc, char **argv) {
printf("=== Label Table Unit Tests ===\n\n"); UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
RUN_TEST(create_empty); if (argc > 1 && strcmp(argv[1], "--json") == 0) {
RUN_TEST(create_null); config->output_format = UNITTEST_FORMAT_JSON;
RUN_TEST(single_label); config->use_colors = false;
RUN_TEST(multiple_labels); }
RUN_TEST(missing_label);
RUN_TEST(out_of_range);
printf("\n=== Results: %d tests passed ===\n", tests_passed); UnittestTestSuite_t *suite = unittest_test_suite_create("Label Table Tests");
return 0;
UnittestTestCase_t *tc = unittest_test_case_create("TestLabelTable");
unittest_test_case_add_result(tc, test_create_empty());
unittest_test_case_add_result(tc, test_create_null());
unittest_test_case_add_result(tc, test_single_label());
unittest_test_case_add_result(tc, test_multiple_labels());
unittest_test_case_add_result(tc, test_missing_label());
unittest_test_case_add_result(tc, test_out_of_range());
unittest_test_suite_add_test_case(suite, tc);
unittest_generate_report(suite, config);
int failures = suite->total_failed + suite->total_errors;
unittest_test_suite_destroy(suite);
unittest_config_destroy(config);
return failures > 0 ? 1 : 0;
} }

View File

@ -1,26 +1,21 @@
#include <stdio.h> #include "test_utils.h"
#include <assert.h>
#include "../runtime/methodcache.h" #include "../runtime/methodcache.h"
static int tests_passed = 0; UnittestTestResult_t* test_create_destroy(void) {
UNITTEST_BEGIN_TEST("TestMethodCache", "test_create_destroy");
#define TEST(name) static void test_##name(void)
#define RUN_TEST(name) do { \
printf("Running %s... ", #name); \
test_##name(); \
printf("PASSED\n"); \
tests_passed++; \
} while(0)
TEST(create_destroy) {
MethodCache_t* cache = rava_methodcache_create(); MethodCache_t* cache = rava_methodcache_create();
assert(cache != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, cache, "cache should not be NULL");
rava_methodcache_destroy(cache); rava_methodcache_destroy(cache);
UNITTEST_END_TEST();
} }
TEST(insert_lookup) { UnittestTestResult_t* test_insert_lookup(void) {
UNITTEST_BEGIN_TEST("TestMethodCache", "test_insert_lookup");
MethodCache_t* cache = rava_methodcache_create(); MethodCache_t* cache = rava_methodcache_create();
assert(cache != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, cache, "cache should not be NULL");
int dummy_method = 42; int dummy_method = 42;
RavaMethod_t* method = (RavaMethod_t*)&dummy_method; RavaMethod_t* method = (RavaMethod_t*)&dummy_method;
@ -28,24 +23,32 @@ TEST(insert_lookup) {
rava_methodcache_insert(cache, "TestClass", "testMethod", method); rava_methodcache_insert(cache, "TestClass", "testMethod", method);
RavaMethod_t* found = rava_methodcache_lookup(cache, "TestClass", "testMethod"); RavaMethod_t* found = rava_methodcache_lookup(cache, "TestClass", "testMethod");
assert(found == method); UNITTEST_ASSERT_TRUE(_unittest_result, found == method, "found method should match inserted");
rava_methodcache_destroy(cache); rava_methodcache_destroy(cache);
UNITTEST_END_TEST();
} }
TEST(lookup_miss) { UnittestTestResult_t* test_lookup_miss(void) {
UNITTEST_BEGIN_TEST("TestMethodCache", "test_lookup_miss");
MethodCache_t* cache = rava_methodcache_create(); MethodCache_t* cache = rava_methodcache_create();
assert(cache != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, cache, "cache should not be NULL");
RavaMethod_t* found = rava_methodcache_lookup(cache, "NonExistent", "method"); RavaMethod_t* found = rava_methodcache_lookup(cache, "NonExistent", "method");
assert(found == NULL); UNITTEST_ASSERT_NULL(_unittest_result, found, "lookup miss should return NULL");
rava_methodcache_destroy(cache); rava_methodcache_destroy(cache);
UNITTEST_END_TEST();
} }
TEST(multiple_methods) { UnittestTestResult_t* test_multiple_methods(void) {
UNITTEST_BEGIN_TEST("TestMethodCache", "test_multiple_methods");
MethodCache_t* cache = rava_methodcache_create(); MethodCache_t* cache = rava_methodcache_create();
assert(cache != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, cache, "cache should not be NULL");
int m1 = 1, m2 = 2; int m1 = 1, m2 = 2;
RavaMethod_t* method1 = (RavaMethod_t*)&m1; RavaMethod_t* method1 = (RavaMethod_t*)&m1;
@ -53,67 +56,96 @@ TEST(multiple_methods) {
rava_methodcache_insert(cache, "TestClass", "methodA", method1); rava_methodcache_insert(cache, "TestClass", "methodA", method1);
RavaMethod_t* found1 = rava_methodcache_lookup(cache, "TestClass", "methodA"); RavaMethod_t* found1 = rava_methodcache_lookup(cache, "TestClass", "methodA");
assert(found1 == method1); UNITTEST_ASSERT_TRUE(_unittest_result, found1 == method1, "found1 should match method1");
rava_methodcache_insert(cache, "OtherClass", "methodB", method2); rava_methodcache_insert(cache, "OtherClass", "methodB", method2);
RavaMethod_t* found2 = rava_methodcache_lookup(cache, "OtherClass", "methodB"); RavaMethod_t* found2 = rava_methodcache_lookup(cache, "OtherClass", "methodB");
assert(found2 == method2); UNITTEST_ASSERT_TRUE(_unittest_result, found2 == method2, "found2 should match method2");
rava_methodcache_destroy(cache); rava_methodcache_destroy(cache);
UNITTEST_END_TEST();
} }
TEST(clear) { UnittestTestResult_t* test_clear(void) {
UNITTEST_BEGIN_TEST("TestMethodCache", "test_clear");
MethodCache_t* cache = rava_methodcache_create(); MethodCache_t* cache = rava_methodcache_create();
assert(cache != NULL); UNITTEST_ASSERT_NOT_NULL(_unittest_result, cache, "cache should not be NULL");
int dummy = 42; int dummy = 42;
RavaMethod_t* method = (RavaMethod_t*)&dummy; RavaMethod_t* method = (RavaMethod_t*)&dummy;
rava_methodcache_insert(cache, "TestClass", "testMethod", method); rava_methodcache_insert(cache, "TestClass", "testMethod", method);
assert(rava_methodcache_lookup(cache, "TestClass", "testMethod") == method); UNITTEST_ASSERT_TRUE(_unittest_result, rava_methodcache_lookup(cache, "TestClass", "testMethod") == method, "should find method before clear");
rava_methodcache_clear(cache); rava_methodcache_clear(cache);
assert(rava_methodcache_lookup(cache, "TestClass", "testMethod") == NULL); UNITTEST_ASSERT_NULL(_unittest_result, rava_methodcache_lookup(cache, "TestClass", "testMethod"), "should not find method after clear");
rava_methodcache_destroy(cache); rava_methodcache_destroy(cache);
UNITTEST_END_TEST();
} }
TEST(null_params) { UnittestTestResult_t* test_null_params(void) {
UNITTEST_BEGIN_TEST("TestMethodCache", "test_null_params");
MethodCache_t* cache = rava_methodcache_create(); MethodCache_t* cache = rava_methodcache_create();
rava_methodcache_insert(NULL, "Class", "method", NULL); rava_methodcache_insert(NULL, "Class", "method", NULL);
rava_methodcache_insert(cache, NULL, "method", NULL); rava_methodcache_insert(cache, NULL, "method", NULL);
rava_methodcache_insert(cache, "Class", NULL, NULL); rava_methodcache_insert(cache, "Class", NULL, NULL);
assert(rava_methodcache_lookup(NULL, "Class", "method") == NULL); UNITTEST_ASSERT_NULL(_unittest_result, rava_methodcache_lookup(NULL, "Class", "method"), "NULL cache should return NULL");
assert(rava_methodcache_lookup(cache, NULL, "method") == NULL); UNITTEST_ASSERT_NULL(_unittest_result, rava_methodcache_lookup(cache, NULL, "method"), "NULL class should return NULL");
assert(rava_methodcache_lookup(cache, "Class", NULL) == NULL); UNITTEST_ASSERT_NULL(_unittest_result, rava_methodcache_lookup(cache, "Class", NULL), "NULL method should return NULL");
rava_methodcache_destroy(cache); rava_methodcache_destroy(cache);
UNITTEST_END_TEST();
} }
TEST(hash_function) { UnittestTestResult_t* test_hash_function(void) {
UNITTEST_BEGIN_TEST("TestMethodCache", "test_hash_function");
uint32_t h1 = rava_methodcache_hash("hello"); uint32_t h1 = rava_methodcache_hash("hello");
uint32_t h2 = rava_methodcache_hash("hello"); uint32_t h2 = rava_methodcache_hash("hello");
uint32_t h3 = rava_methodcache_hash("world"); uint32_t h3 = rava_methodcache_hash("world");
assert(h1 == h2); UNITTEST_ASSERT_EQUAL(_unittest_result, h1, h2, "same string should produce same hash");
assert(h1 != h3); UNITTEST_ASSERT_TRUE(_unittest_result, h1 != h3, "different strings should produce different hashes");
assert(h1 != 0); UNITTEST_ASSERT_TRUE(_unittest_result, h1 != 0, "hash should not be 0");
assert(h3 != 0); UNITTEST_ASSERT_TRUE(_unittest_result, h3 != 0, "hash should not be 0");
UNITTEST_END_TEST();
} }
int main(void) { int main(int argc, char **argv) {
printf("=== Method Cache Unit Tests ===\n\n"); UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
RUN_TEST(create_destroy); if (argc > 1 && strcmp(argv[1], "--json") == 0) {
RUN_TEST(insert_lookup); config->output_format = UNITTEST_FORMAT_JSON;
RUN_TEST(lookup_miss); config->use_colors = false;
RUN_TEST(multiple_methods); }
RUN_TEST(clear);
RUN_TEST(null_params);
RUN_TEST(hash_function);
printf("\n=== Results: %d tests passed ===\n", tests_passed); UnittestTestSuite_t *suite = unittest_test_suite_create("Method Cache Tests");
return 0;
UnittestTestCase_t *tc = unittest_test_case_create("TestMethodCache");
unittest_test_case_add_result(tc, test_create_destroy());
unittest_test_case_add_result(tc, test_insert_lookup());
unittest_test_case_add_result(tc, test_lookup_miss());
unittest_test_case_add_result(tc, test_multiple_methods());
unittest_test_case_add_result(tc, test_clear());
unittest_test_case_add_result(tc, test_null_params());
unittest_test_case_add_result(tc, test_hash_function());
unittest_test_suite_add_test_case(suite, tc);
unittest_generate_report(suite, config);
int failures = suite->total_failed + suite->total_errors;
unittest_test_suite_destroy(suite);
unittest_config_destroy(config);
return failures > 0 ? 1 : 0;
} }

View File

@ -1,146 +1,211 @@
#include <stdio.h> #include "test_utils.h"
#include <assert.h>
#include <math.h> #include <math.h>
#include "../runtime/nanbox.h" #include "../runtime/nanbox.h"
static int tests_passed = 0; UnittestTestResult_t* test_int_basic(void) {
static int tests_failed = 0; UNITTEST_BEGIN_TEST("TestNanbox", "test_int_basic");
#define TEST(name) static void test_##name(void)
#define RUN_TEST(name) do { \
printf("Running %s... ", #name); \
test_##name(); \
printf("PASSED\n"); \
tests_passed++; \
} while(0)
TEST(int_basic) {
RavaNanboxValue_t val = rava_nanbox_int(42); RavaNanboxValue_t val = rava_nanbox_int(42);
assert(rava_nanbox_is_int(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_int(val), "should be int");
assert(!rava_nanbox_is_bool(val)); UNITTEST_ASSERT_FALSE(_unittest_result, rava_nanbox_is_bool(val), "should not be bool");
assert(!rava_nanbox_is_null(val)); UNITTEST_ASSERT_FALSE(_unittest_result, rava_nanbox_is_null(val), "should not be null");
assert(rava_nanbox_as_int(val) == 42); UNITTEST_ASSERT_EQUAL(_unittest_result, 42, rava_nanbox_as_int(val), "should equal 42");
UNITTEST_END_TEST();
} }
TEST(int_negative) { UnittestTestResult_t* test_int_negative(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_int_negative");
RavaNanboxValue_t val = rava_nanbox_int(-100); RavaNanboxValue_t val = rava_nanbox_int(-100);
assert(rava_nanbox_is_int(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_int(val), "should be int");
assert(rava_nanbox_as_int(val) == -100); UNITTEST_ASSERT_EQUAL(_unittest_result, -100, rava_nanbox_as_int(val), "should equal -100");
UNITTEST_END_TEST();
} }
TEST(int_zero) { UnittestTestResult_t* test_int_zero(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_int_zero");
RavaNanboxValue_t val = rava_nanbox_int(0); RavaNanboxValue_t val = rava_nanbox_int(0);
assert(rava_nanbox_is_int(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_int(val), "should be int");
assert(rava_nanbox_as_int(val) == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, rava_nanbox_as_int(val), "should equal 0");
UNITTEST_END_TEST();
} }
TEST(long_basic) { UnittestTestResult_t* test_long_basic(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_long_basic");
RavaNanboxValue_t val = rava_nanbox_long(1000000000000LL); RavaNanboxValue_t val = rava_nanbox_long(1000000000000LL);
assert(rava_nanbox_is_long(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_long(val), "should be long");
int64_t result = rava_nanbox_as_long(val);
(void)result; UNITTEST_END_TEST();
} }
TEST(bool_true) { UnittestTestResult_t* test_bool_true(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_bool_true");
RavaNanboxValue_t val = rava_nanbox_bool(true); RavaNanboxValue_t val = rava_nanbox_bool(true);
assert(rava_nanbox_is_bool(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_bool(val), "should be bool");
assert(rava_nanbox_as_bool(val) == true); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_as_bool(val), "should be true");
UNITTEST_END_TEST();
} }
TEST(bool_false) { UnittestTestResult_t* test_bool_false(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_bool_false");
RavaNanboxValue_t val = rava_nanbox_bool(false); RavaNanboxValue_t val = rava_nanbox_bool(false);
assert(rava_nanbox_is_bool(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_bool(val), "should be bool");
assert(rava_nanbox_as_bool(val) == false); UNITTEST_ASSERT_FALSE(_unittest_result, rava_nanbox_as_bool(val), "should be false");
UNITTEST_END_TEST();
} }
TEST(null) { UnittestTestResult_t* test_null(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_null");
RavaNanboxValue_t val = rava_nanbox_null(); RavaNanboxValue_t val = rava_nanbox_null();
assert(rava_nanbox_is_null(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_null(val), "should be null");
assert(!rava_nanbox_is_int(val)); UNITTEST_ASSERT_FALSE(_unittest_result, rava_nanbox_is_int(val), "should not be int");
assert(!rava_nanbox_is_bool(val)); UNITTEST_ASSERT_FALSE(_unittest_result, rava_nanbox_is_bool(val), "should not be bool");
UNITTEST_END_TEST();
} }
TEST(double_basic) { UnittestTestResult_t* test_double_basic(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_double_basic");
RavaNanboxValue_t val = rava_nanbox_double(3.14159); RavaNanboxValue_t val = rava_nanbox_double(3.14159);
assert(rava_nanbox_is_double(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_double(val), "should be double");
double d = rava_nanbox_as_double(val); double d = rava_nanbox_as_double(val);
assert(fabs(d - 3.14159) < 0.0001); UNITTEST_ASSERT_TRUE(_unittest_result, fabs(d - 3.14159) < 0.0001, "should equal 3.14159");
UNITTEST_END_TEST();
} }
TEST(double_negative) { UnittestTestResult_t* test_double_negative(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_double_negative");
RavaNanboxValue_t val = rava_nanbox_double(-123.456); RavaNanboxValue_t val = rava_nanbox_double(-123.456);
assert(rava_nanbox_is_double(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_double(val), "should be double");
double d = rava_nanbox_as_double(val); double d = rava_nanbox_as_double(val);
assert(fabs(d - (-123.456)) < 0.0001); UNITTEST_ASSERT_TRUE(_unittest_result, fabs(d - (-123.456)) < 0.0001, "should equal -123.456");
UNITTEST_END_TEST();
} }
TEST(conversion_int_to_long) { UnittestTestResult_t* test_conversion_int_to_long(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_conversion_int_to_long");
RavaNanboxValue_t val = rava_nanbox_int(42); RavaNanboxValue_t val = rava_nanbox_int(42);
assert(rava_nanbox_to_long(val) == 42); UNITTEST_ASSERT_EQUAL(_unittest_result, 42, (int)rava_nanbox_to_long(val), "int to long should equal 42");
UNITTEST_END_TEST();
} }
TEST(conversion_int_to_double) { UnittestTestResult_t* test_conversion_int_to_double(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_conversion_int_to_double");
RavaNanboxValue_t val = rava_nanbox_int(10); RavaNanboxValue_t val = rava_nanbox_int(10);
assert(fabs(rava_nanbox_to_double(val) - 10.0) < 0.0001); UNITTEST_ASSERT_TRUE(_unittest_result, fabs(rava_nanbox_to_double(val) - 10.0) < 0.0001, "int to double should equal 10.0");
UNITTEST_END_TEST();
} }
TEST(conversion_bool_to_int) { UnittestTestResult_t* test_conversion_bool_to_int(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_conversion_bool_to_int");
RavaNanboxValue_t t = rava_nanbox_bool(true); RavaNanboxValue_t t = rava_nanbox_bool(true);
RavaNanboxValue_t f = rava_nanbox_bool(false); RavaNanboxValue_t f = rava_nanbox_bool(false);
assert(rava_nanbox_to_int(t) == 1); UNITTEST_ASSERT_EQUAL(_unittest_result, 1, rava_nanbox_to_int(t), "true to int should equal 1");
assert(rava_nanbox_to_int(f) == 0); UNITTEST_ASSERT_EQUAL(_unittest_result, 0, rava_nanbox_to_int(f), "false to int should equal 0");
UNITTEST_END_TEST();
} }
TEST(to_bool) { UnittestTestResult_t* test_to_bool(void) {
assert(rava_nanbox_to_bool(rava_nanbox_null()) == false); UNITTEST_BEGIN_TEST("TestNanbox", "test_to_bool");
assert(rava_nanbox_to_bool(rava_nanbox_bool(true)) == true);
assert(rava_nanbox_to_bool(rava_nanbox_bool(false)) == false); UNITTEST_ASSERT_FALSE(_unittest_result, rava_nanbox_to_bool(rava_nanbox_null()), "null to bool should be false");
assert(rava_nanbox_to_bool(rava_nanbox_int(0)) == false); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_to_bool(rava_nanbox_bool(true)), "true to bool should be true");
assert(rava_nanbox_to_bool(rava_nanbox_int(1)) == true); UNITTEST_ASSERT_FALSE(_unittest_result, rava_nanbox_to_bool(rava_nanbox_bool(false)), "false to bool should be false");
assert(rava_nanbox_to_bool(rava_nanbox_int(-1)) == true); UNITTEST_ASSERT_FALSE(_unittest_result, rava_nanbox_to_bool(rava_nanbox_int(0)), "0 to bool should be false");
UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_to_bool(rava_nanbox_int(1)), "1 to bool should be true");
UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_to_bool(rava_nanbox_int(-1)), "-1 to bool should be true");
UNITTEST_END_TEST();
} }
TEST(object_pointer) { UnittestTestResult_t* test_object_pointer(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_object_pointer");
int dummy = 42; int dummy = 42;
RavaNanboxValue_t val = rava_nanbox_object(&dummy); RavaNanboxValue_t val = rava_nanbox_object(&dummy);
assert(rava_nanbox_is_object(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_object(val), "should be object");
assert(rava_nanbox_as_object(val) == &dummy); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_as_object(val) == &dummy, "pointer should match");
UNITTEST_END_TEST();
} }
TEST(string_pointer) { UnittestTestResult_t* test_string_pointer(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_string_pointer");
const char* str = "hello"; const char* str = "hello";
RavaNanboxValue_t val = rava_nanbox_string(str); RavaNanboxValue_t val = rava_nanbox_string(str);
assert(rava_nanbox_is_string(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_string(val), "should be string");
assert(rava_nanbox_as_string(val) == str); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_as_string(val) == str, "pointer should match");
UNITTEST_END_TEST();
} }
TEST(array_pointer) { UnittestTestResult_t* test_array_pointer(void) {
UNITTEST_BEGIN_TEST("TestNanbox", "test_array_pointer");
int arr[10]; int arr[10];
RavaNanboxValue_t val = rava_nanbox_array(arr); RavaNanboxValue_t val = rava_nanbox_array(arr);
assert(rava_nanbox_is_array(val)); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_is_array(val), "should be array");
assert(rava_nanbox_as_array(val) == arr); UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_as_array(val) == arr, "pointer should match");
UNITTEST_END_TEST();
} }
int main(void) { int main(int argc, char **argv) {
printf("=== NaN Boxing Unit Tests ===\n\n"); UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
RUN_TEST(int_basic); if (argc > 1 && strcmp(argv[1], "--json") == 0) {
RUN_TEST(int_negative); config->output_format = UNITTEST_FORMAT_JSON;
RUN_TEST(int_zero); config->use_colors = false;
RUN_TEST(long_basic); }
RUN_TEST(bool_true);
RUN_TEST(bool_false);
RUN_TEST(null);
RUN_TEST(double_basic);
RUN_TEST(double_negative);
RUN_TEST(conversion_int_to_long);
RUN_TEST(conversion_int_to_double);
RUN_TEST(conversion_bool_to_int);
RUN_TEST(to_bool);
RUN_TEST(object_pointer);
RUN_TEST(string_pointer);
RUN_TEST(array_pointer);
printf("\n=== Results: %d passed, %d failed ===\n", tests_passed, tests_failed); UnittestTestSuite_t *suite = unittest_test_suite_create("NaN Boxing Tests");
return tests_failed > 0 ? 1 : 0;
UnittestTestCase_t *tc = unittest_test_case_create("TestNanbox");
unittest_test_case_add_result(tc, test_int_basic());
unittest_test_case_add_result(tc, test_int_negative());
unittest_test_case_add_result(tc, test_int_zero());
unittest_test_case_add_result(tc, test_long_basic());
unittest_test_case_add_result(tc, test_bool_true());
unittest_test_case_add_result(tc, test_bool_false());
unittest_test_case_add_result(tc, test_null());
unittest_test_case_add_result(tc, test_double_basic());
unittest_test_case_add_result(tc, test_double_negative());
unittest_test_case_add_result(tc, test_conversion_int_to_long());
unittest_test_case_add_result(tc, test_conversion_int_to_double());
unittest_test_case_add_result(tc, test_conversion_bool_to_int());
unittest_test_case_add_result(tc, test_to_bool());
unittest_test_case_add_result(tc, test_object_pointer());
unittest_test_case_add_result(tc, test_string_pointer());
unittest_test_case_add_result(tc, test_array_pointer());
unittest_test_suite_add_test_case(suite, tc);
unittest_generate_report(suite, config);
int failures = suite->total_failed + suite->total_errors;
unittest_test_suite_destroy(suite);
unittest_config_destroy(config);
return failures > 0 ? 1 : 0;
} }

View File

@ -168,6 +168,9 @@ void _unittest_format_tap(UnittestTestSuite_t *suite, UnittestConfig_t *config,
double unittest_get_time_ms(void); double unittest_get_time_ms(void);
#define UNITTEST_ASSERT_EQUAL(result, expected, actual, msg) \
unittest_assert_int_equal((result), (expected), (actual), (msg), __LINE__, __FILE__)
#define UNITTEST_ASSERT_EQUAL_INT(result, expected, actual, msg) \ #define UNITTEST_ASSERT_EQUAL_INT(result, expected, actual, msg) \
unittest_assert_int_equal((result), (expected), (actual), (msg), __LINE__, __FILE__) unittest_assert_int_equal((result), (expected), (actual), (msg), __LINE__, __FILE__)