#include "test_utils.h"
#include "../runtime/fastframe.h"
UnittestTestResult_t* test_init(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_init");
rava_fastframe_init();
UNITTEST_ASSERT_EQUAL(_unittest_result, 0, rava_fastframe_get_depth(), "initial depth should be 0");
UNITTEST_ASSERT_NULL(_unittest_result, rava_fastframe_current(), "current frame should be NULL");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_push_pop(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_push_pop");
rava_fastframe_init();
FastFrame_t* frame = rava_fastframe_push(NULL, 4);
UNITTEST_ASSERT_NOT_NULL(_unittest_result, frame, "pushed frame should not be NULL");
UNITTEST_ASSERT_EQUAL(_unittest_result, 1, rava_fastframe_get_depth(), "depth should be 1");
UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_current() == frame, "current should match pushed frame");
rava_fastframe_pop();
UNITTEST_ASSERT_EQUAL(_unittest_result, 0, rava_fastframe_get_depth(), "depth should be 0 after pop");
UNITTEST_ASSERT_NULL(_unittest_result, rava_fastframe_current(), "current should be NULL after pop");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_nested_frames(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_nested_frames");
rava_fastframe_init();
FastFrame_t* f1 = rava_fastframe_push(NULL, 2);
FastFrame_t* f2 = rava_fastframe_push(NULL, 2);
FastFrame_t* f3 = rava_fastframe_push(NULL, 2);
UNITTEST_ASSERT_EQUAL(_unittest_result, 3, rava_fastframe_get_depth(), "depth should be 3");
UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_current() == f3, "current should be f3");
rava_fastframe_pop();
UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_current() == f2, "current should be f2");
rava_fastframe_pop();
UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_current() == f1, "current should be f1");
rava_fastframe_pop();
UNITTEST_ASSERT_NULL(_unittest_result, rava_fastframe_current(), "current should be NULL");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_stack_operations(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_stack_operations");
rava_fastframe_init();
FastFrame_t* frame = rava_fastframe_push(NULL, 4);
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(20));
rava_fastframe_stack_push(frame, rava_nanbox_int(30));
UNITTEST_ASSERT_FALSE(_unittest_result, rava_fastframe_stack_is_empty(frame), "stack should not be empty");
UNITTEST_ASSERT_EQUAL(_unittest_result, 3, frame->stack_top, "stack top should be 3");
RavaNanboxValue_t top = rava_fastframe_stack_peek(frame);
UNITTEST_ASSERT_EQUAL(_unittest_result, 30, rava_nanbox_as_int(top), "peek should return 30");
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 v2 = rava_fastframe_stack_pop(frame);
RavaNanboxValue_t v3 = rava_fastframe_stack_pop(frame);
UNITTEST_ASSERT_EQUAL(_unittest_result, 30, rava_nanbox_as_int(v1), "first pop should return 30");
UNITTEST_ASSERT_EQUAL(_unittest_result, 20, rava_nanbox_as_int(v2), "second pop should return 20");
UNITTEST_ASSERT_EQUAL(_unittest_result, 10, rava_nanbox_as_int(v3), "third pop should return 10");
UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_stack_is_empty(frame), "stack should be empty after pops");
rava_fastframe_reset();
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_locals(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_locals");
rava_fastframe_init();
FastFrame_t* frame = rava_fastframe_push(NULL, 8);
frame->locals[0] = rava_nanbox_int(100);
frame->locals[1] = rava_nanbox_int(200);
frame->locals[2] = rava_nanbox_bool(true);
UNITTEST_ASSERT_EQUAL(_unittest_result, 100, rava_nanbox_as_int(frame->locals[0]), "local 0 should be 100");
UNITTEST_ASSERT_EQUAL(_unittest_result, 200, rava_nanbox_as_int(frame->locals[1]), "local 1 should be 200");
UNITTEST_ASSERT_TRUE(_unittest_result, rava_nanbox_as_bool(frame->locals[2]), "local 2 should be true");
rava_fastframe_reset();
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_reset(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_reset");
rava_fastframe_init();
rava_fastframe_push(NULL, 2);
rava_fastframe_push(NULL, 2);
rava_fastframe_push(NULL, 2);
UNITTEST_ASSERT_EQUAL(_unittest_result, 3, rava_fastframe_get_depth(), "depth should be 3");
rava_fastframe_reset();
UNITTEST_ASSERT_EQUAL(_unittest_result, 0, rava_fastframe_get_depth(), "depth should be 0 after reset");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_stack_clear(void) {
UNITTEST_BEGIN_TEST("TestFastFrame", "test_stack_clear");
rava_fastframe_init();
FastFrame_t* frame = rava_fastframe_push(NULL, 4);
rava_fastframe_stack_push(frame, rava_nanbox_int(1));
rava_fastframe_stack_push(frame, rava_nanbox_int(2));
rava_fastframe_stack_push(frame, rava_nanbox_int(3));
UNITTEST_ASSERT_EQUAL(_unittest_result, 3, frame->stack_top, "stack top should be 3");
rava_fastframe_stack_clear(frame);
UNITTEST_ASSERT_EQUAL(_unittest_result, 0, frame->stack_top, "stack top should be 0 after clear");
UNITTEST_ASSERT_TRUE(_unittest_result, rava_fastframe_stack_is_empty(frame), "stack should be empty after clear");
rava_fastframe_reset();
UNITTEST_END_TEST();
}
int main(int argc, char **argv) {
UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
if (argc > 1 && strcmp(argv[1], "--json") == 0) {
config->output_format = UNITTEST_FORMAT_JSON;
config->use_colors = false;
}
UnittestTestSuite_t *suite = unittest_test_suite_create("Fast Frame Tests");
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;
}