diff --git a/Makefile b/Makefile index 0d50721..53496ff 100644 --- a/Makefile +++ b/Makefile @@ -107,13 +107,22 @@ TEST_ENUMS_OBJECTS = $(TEST_ENUMS_SOURCES:.c=.o) TEST_COLLECTIONS_SOURCES = tests/test_collections.c TEST_COLLECTIONS_OBJECTS = $(TEST_COLLECTIONS_SOURCES:.c=.o) +TEST_SUPER_SOURCES = tests/test_super.c +TEST_SUPER_OBJECTS = $(TEST_SUPER_SOURCES:.c=.o) + +TEST_INHERITANCE_SOURCES = tests/test_inheritance.c +TEST_INHERITANCE_OBJECTS = $(TEST_INHERITANCE_SOURCES:.c=.o) + +TEST_BREAK_SOURCES = tests/test_break.c +TEST_BREAK_OBJECTS = $(TEST_BREAK_SOURCES:.c=.o) + UNITTEST_SOURCES = tests/unittest.c UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o) TEST_UNITTEST_DEMO_SOURCES = tests/test_unittest_demo.c TEST_UNITTEST_DEMO_OBJECTS = $(TEST_UNITTEST_DEMO_SOURCES:.c=.o) -all: test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections +all: test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections test_super test_inheritance test_break test_lexer: $(LEXER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_LEXER_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) @@ -199,6 +208,15 @@ test_enums: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJEC test_collections: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_COLLECTIONS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) +test_super: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_SUPER_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_inheritance: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INHERITANCE_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_break: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_BREAK_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + test_unittest_demo: $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) @@ -267,8 +285,8 @@ clean: $(PHASE0_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) \ $(TEST_LEXER_OBJECTS) $(TEST_PARSER_OBJECTS) $(TEST_SEMANTIC_OBJECTS) $(TEST_IR_OBJECTS) $(TEST_RUNTIME_OBJECTS) \ $(TEST_STRINGS_OBJECTS) $(TEST_ARRAYS_OBJECTS) $(TEST_OBJECTS_OBJECTS) $(TEST_INSTANCE_OBJECTS) $(TEST_FILEIO_OBJECTS) \ - $(TEST_DOWHILE_OBJECTS) $(TEST_SWITCH_OBJECTS) $(TEST_MATH_OBJECTS) $(TEST_STRING_METHODS_OBJECTS) $(TEST_STATIC_OBJECTS) $(TEST_INTERFACES_OBJECTS) $(TEST_EXCEPTIONS_OBJECTS) $(TEST_TERNARY_OBJECTS) $(TEST_BITWISE_OBJECTS) $(TEST_ENHANCED_FOR_OBJECTS) $(TEST_ARRAY_INIT_OBJECTS) $(TEST_INSTANCEOF_OBJECTS) $(TEST_SHORTCIRCUIT_OBJECTS) $(TEST_MULTIDIM_ARRAYS_OBJECTS) $(TEST_STATIC_INIT_OBJECTS) $(TEST_NEGATIVE_OBJECTS) $(TEST_ENUMS_OBJECTS) $(TEST_COLLECTIONS_OBJECTS) $(TEST_BENCHMARK_OBJECTS) \ - test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections test_benchmark \ + $(TEST_DOWHILE_OBJECTS) $(TEST_SWITCH_OBJECTS) $(TEST_MATH_OBJECTS) $(TEST_STRING_METHODS_OBJECTS) $(TEST_STATIC_OBJECTS) $(TEST_INTERFACES_OBJECTS) $(TEST_EXCEPTIONS_OBJECTS) $(TEST_TERNARY_OBJECTS) $(TEST_BITWISE_OBJECTS) $(TEST_ENHANCED_FOR_OBJECTS) $(TEST_ARRAY_INIT_OBJECTS) $(TEST_INSTANCEOF_OBJECTS) $(TEST_SHORTCIRCUIT_OBJECTS) $(TEST_MULTIDIM_ARRAYS_OBJECTS) $(TEST_STATIC_INIT_OBJECTS) $(TEST_NEGATIVE_OBJECTS) $(TEST_ENUMS_OBJECTS) $(TEST_COLLECTIONS_OBJECTS) $(TEST_SUPER_OBJECTS) $(TEST_INHERITANCE_OBJECTS) $(TEST_BREAK_OBJECTS) $(TEST_BENCHMARK_OBJECTS) \ + test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections test_super test_inheritance test_break test_benchmark \ test_nanbox test_fastframe test_labeltable test_methodcache test_benchmark_pgo test_unittest_demo *.gcda */*.gcda .PHONY: all clean benchmark test_phase0 pgo test_benchmark_pgo_gen pgo_run test_benchmark_pgo test @@ -281,5 +299,5 @@ test: all ./test_static && ./test_interfaces && ./test_exceptions && ./test_ternary && \ ./test_bitwise && ./test_enhanced_for && ./test_array_init && ./test_instanceof && \ ./test_shortcircuit && ./test_multidim_arrays && ./test_static_init && ./test_negative && \ - ./test_enums && \ + ./test_enums && ./test_collections && ./test_super && ./test_inheritance && ./test_break && \ echo "" && echo "=== All Tests Passed ===" diff --git a/tests/test_break.c b/tests/test_break.c index ca783b0..47518c7 100644 --- a/tests/test_break.c +++ b/tests/test_break.c @@ -1,42 +1,152 @@ -#include "../lexer/lexer.h" -#include "../parser/parser.h" -#include "../semantic/semantic.h" -#include "../ir/ir.h" -#include "../ir/ir_gen.h" -#include "../runtime/runtime.h" -#include -#include +#include "test_utils.h" -static char* read_file(const char *filename) { - FILE *file = fopen(filename, "r"); - if (!file) return NULL; - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - char *content = malloc(size + 1); - size_t read_bytes = fread(content, 1, size, file); (void)read_bytes; - content[size] = '\0'; - fclose(file); - return content; +UnittestTestResult_t* test_break_continue_example(void) { + UNITTEST_BEGIN_TEST("TestBreakContinue", "test_break_continue_example"); + + RAVA_TEST_FILE_EXECUTES(_unittest_result, + "examples/19_BreakContinue.java", + "BreakContinue", "main", + "break/continue example should execute successfully"); + + UNITTEST_END_TEST(); } -int main() { - char *source = read_file("examples/19_BreakContinue.java"); - if (!source) { printf("Failed\n"); return 1; } - RavaLexer_t *l = rava_lexer_create(source); - RavaParser_t *p = rava_parser_create(l); - RavaASTNode_t *ast = rava_parser_parse(p); - if (p->had_error) { printf("Parse: %s\n", p->error_message); return 1; } - printf("Parse: OK\n"); - RavaSemanticAnalyzer_t *a = rava_semantic_analyzer_create(); - if (!rava_semantic_analyze(a, ast)) { printf("Semantic: %s\n", a->error_message); return 1; } - printf("Semantic: OK\n"); - RavaIRGenerator_t *g = rava_ir_generator_create(a); - RavaProgram_t *prog = rava_ir_generate(g, ast); - if (!prog) { printf("IR failed\n"); return 1; } - printf("IR: OK\nOutput:\n"); - RavaVM_t *vm = rava_vm_create(prog); - if (!rava_vm_execute(vm, "BreakContinue", "main")) { printf("Runtime: %s\n", vm->error_message); return 1; } - printf("\nExecution: OK\n"); - return 0; +UnittestTestResult_t* test_break_in_for(void) { + UNITTEST_BEGIN_TEST("TestBreakContinue", "test_break_in_for"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int sum = 0;\n" + " for (int i = 0; i < 10; i++) {\n" + " if (i == 5) {\n" + " break;\n" + " }\n" + " sum = sum + i;\n" + " }\n" + " return sum;\n" + " }\n" + "}\n", + "Test", "main", 10, "break should exit for loop (0+1+2+3+4=10)"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_break_in_while(void) { + UNITTEST_BEGIN_TEST("TestBreakContinue", "test_break_in_while"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int i = 0;\n" + " int sum = 0;\n" + " while (i < 100) {\n" + " if (i >= 5) {\n" + " break;\n" + " }\n" + " sum = sum + i;\n" + " i = i + 1;\n" + " }\n" + " return sum;\n" + " }\n" + "}\n", + "Test", "main", 10, "break should exit while loop"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_continue_in_for(void) { + UNITTEST_BEGIN_TEST("TestBreakContinue", "test_continue_in_for"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int sum = 0;\n" + " for (int i = 0; i < 10; i++) {\n" + " if (i % 2 == 0) {\n" + " continue;\n" + " }\n" + " sum = sum + i;\n" + " }\n" + " return sum;\n" + " }\n" + "}\n", + "Test", "main", 25, "continue should skip even numbers (1+3+5+7+9=25)"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_continue_in_while(void) { + UNITTEST_BEGIN_TEST("TestBreakContinue", "test_continue_in_while"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int i = 0;\n" + " int sum = 0;\n" + " while (i < 10) {\n" + " i = i + 1;\n" + " if (i % 2 == 0) {\n" + " continue;\n" + " }\n" + " sum = sum + i;\n" + " }\n" + " return sum;\n" + " }\n" + "}\n", + "Test", "main", 25, "continue in while should skip even iterations"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_nested_break(void) { + UNITTEST_BEGIN_TEST("TestBreakContinue", "test_nested_break"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int count = 0;\n" + " for (int i = 0; i < 5; i++) {\n" + " for (int j = 0; j < 5; j++) {\n" + " if (j == 2) {\n" + " break;\n" + " }\n" + " count = count + 1;\n" + " }\n" + " }\n" + " return count;\n" + " }\n" + "}\n", + "Test", "main", 10, "nested break exits inner loop only (5*2=10)"); + + 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("Break/Continue Tests"); + + UnittestTestCase_t *tc = unittest_test_case_create("TestBreakContinue"); + unittest_test_case_add_result(tc, test_break_continue_example()); + unittest_test_case_add_result(tc, test_break_in_for()); + unittest_test_case_add_result(tc, test_break_in_while()); + unittest_test_case_add_result(tc, test_continue_in_for()); + unittest_test_case_add_result(tc, test_continue_in_while()); + unittest_test_case_add_result(tc, test_nested_break()); + 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; } diff --git a/tests/test_inheritance.c b/tests/test_inheritance.c index 728284d..11697b6 100644 --- a/tests/test_inheritance.c +++ b/tests/test_inheritance.c @@ -1,77 +1,111 @@ -#include "../lexer/lexer.h" -#include "../parser/parser.h" -#include "../semantic/semantic.h" -#include "../ir/ir.h" -#include "../ir/ir_gen.h" -#include "../runtime/runtime.h" -#include -#include -#include +#include "test_utils.h" -static char* read_file(const char *filename) { - FILE *file = fopen(filename, "r"); - if (!file) return NULL; - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - char *content = malloc(size + 1); - size_t read_bytes = fread(content, 1, size, file); (void)read_bytes; - content[size] = '\0'; - fclose(file); - return content; +UnittestTestResult_t* test_inheritance_example(void) { + UNITTEST_BEGIN_TEST("TestInheritance", "test_inheritance_example"); + + RAVA_TEST_FILE_EXECUTES(_unittest_result, + "examples/17_Inheritance.java", + "Inheritance", "main", + "inheritance example should execute successfully"); + + UNITTEST_END_TEST(); } -int main() { - char *source = read_file("examples/17_Inheritance.java"); - if (!source) { - printf("Failed to read file\n"); - return 1; - } +UnittestTestResult_t* test_simple_inheritance(void) { + UNITTEST_BEGIN_TEST("TestInheritance", "test_simple_inheritance"); - RavaLexer_t *lexer = rava_lexer_create(source); - RavaParser_t *parser = rava_parser_create(lexer); - RavaASTNode_t *ast = rava_parser_parse(parser); + RAVA_TEST_RUN(_unittest_result, + "class Animal {\n" + " int getLegs() {\n" + " return 4;\n" + " }\n" + "}\n" + "class Dog extends Animal {\n" + " int bark() {\n" + " return 1;\n" + " }\n" + "}\n" + "public class Test {\n" + " public static int main() {\n" + " Dog d = new Dog();\n" + " return d.getLegs();\n" + " }\n" + "}\n", + "Test", "main", 4, "child should inherit parent methods"); - if (parser->had_error) { - printf("Parse error: %s\n", parser->error_message); - free(source); - return 1; - } - - printf("Parse: OK\n"); - - RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create(); - if (!rava_semantic_analyze(analyzer, ast)) { - printf("Semantic error: %s\n", analyzer->error_message); - free(source); - return 1; - } - - printf("Semantic: OK\n"); - - RavaIRGenerator_t *ir_gen = rava_ir_generator_create(analyzer); - RavaProgram_t *program = rava_ir_generate(ir_gen, ast); - - if (!program) { - printf("IR generation failed\n"); - free(source); - return 1; - } - - printf("IR Gen: OK\n"); - printf("\nOutput:\n"); - - RavaVM_t *vm = rava_vm_create(program); - if (!rava_vm_execute(vm, "Inheritance", "main")) { - printf("Runtime error: %s\n", vm->error_message); - rava_vm_destroy(vm); - free(source); - return 1; - } - - printf("\nExecution: OK\n"); - - rava_vm_destroy(vm); - free(source); - return 0; + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_method_override(void) { + UNITTEST_BEGIN_TEST("TestInheritance", "test_method_override"); + + RAVA_TEST_RUN(_unittest_result, + "class Parent {\n" + " int getValue() {\n" + " return 10;\n" + " }\n" + "}\n" + "class Child extends Parent {\n" + " int getValue() {\n" + " return 20;\n" + " }\n" + "}\n" + "public class Test {\n" + " public static int main() {\n" + " Child c = new Child();\n" + " return c.getValue();\n" + " }\n" + "}\n", + "Test", "main", 20, "child method should override parent"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_inherited_method_with_value(void) { + UNITTEST_BEGIN_TEST("TestInheritance", "test_inherited_method_with_value"); + + RAVA_TEST_RUN(_unittest_result, + "class Parent {\n" + " int getValue() {\n" + " return 42;\n" + " }\n" + "}\n" + "class Child extends Parent {\n" + "}\n" + "public class Test {\n" + " public static int main() {\n" + " Child c = new Child();\n" + " return c.getValue();\n" + " }\n" + "}\n", + "Test", "main", 42, "child should inherit parent method returning value"); + + 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("Inheritance Tests"); + + UnittestTestCase_t *tc = unittest_test_case_create("TestInheritance"); + unittest_test_case_add_result(tc, test_inheritance_example()); + unittest_test_case_add_result(tc, test_simple_inheritance()); + unittest_test_case_add_result(tc, test_method_override()); + unittest_test_case_add_result(tc, test_inherited_method_with_value()); + 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; } diff --git a/tests/test_super.c b/tests/test_super.c index 5a61309..bcbcfbb 100644 --- a/tests/test_super.c +++ b/tests/test_super.c @@ -1,73 +1,9 @@ -#include "../lexer/lexer.h" -#include "../parser/parser.h" -#include "../semantic/semantic.h" -#include "../ir/ir.h" -#include "../ir/ir_gen.h" -#include "../runtime/runtime.h" -#include -#include -#include +#include "test_utils.h" -static int test_count = 0; -static int pass_count = 0; +UnittestTestResult_t* test_super_method_basic(void) { + UNITTEST_BEGIN_TEST("TestSuper", "test_super_method_basic"); -static void run_test_int(const char* name, const char* source, int expected) { - test_count++; - - RavaLexer_t* lexer = rava_lexer_create(source); - RavaParser_t* parser = rava_parser_create(lexer); - RavaASTNode_t* ast = rava_parser_parse(parser); - - if (!ast || parser->had_error) { - printf("FAIL: %s - Parse error: %s\n", name, parser->error_message ? parser->error_message : "unknown"); - rava_parser_destroy(parser); - rava_lexer_destroy(lexer); - return; - } - - RavaSemanticAnalyzer_t* analyzer = rava_semantic_analyzer_create(); - rava_semantic_analyze(analyzer, ast); - - RavaIRGenerator_t* ir_gen = rava_ir_generator_create(analyzer); - RavaProgram_t* program = rava_ir_generate(ir_gen, ast); - - RavaVM_t* vm = rava_vm_create(program); - - if (!rava_vm_execute(vm, "Test", "main")) { - printf("FAIL: %s - Runtime error: %s\n", name, vm->error_message ? vm->error_message : "unknown"); - rava_vm_destroy(vm); - rava_program_destroy(program); - rava_ir_generator_destroy(ir_gen); - rava_semantic_analyzer_destroy(analyzer); - rava_ast_node_destroy(ast); - rava_parser_destroy(parser); - rava_lexer_destroy(lexer); - return; - } - - RavaValue_t result = rava_vm_get_result(vm); - int32_t result_int = rava_value_as_int(result); - - if (result_int == expected) { - printf("PASS: %s (result=%d)\n", name, result_int); - pass_count++; - } else { - printf("FAIL: %s (expected=%d, got=%d)\n", name, expected, result_int); - } - - rava_vm_destroy(vm); - rava_program_destroy(program); - rava_ir_generator_destroy(ir_gen); - rava_semantic_analyzer_destroy(analyzer); - rava_ast_node_destroy(ast); - rava_parser_destroy(parser); - rava_lexer_destroy(lexer); -} - -int main(void) { - printf("=== Super Keyword Tests ===\n\n"); - - run_test_int("super.method() basic", + RAVA_TEST_RUN(_unittest_result, "class Parent {\n" " int getValue() {\n" " return 10;\n" @@ -83,9 +19,16 @@ int main(void) { " Child c = new Child();\n" " return c.getValue();\n" " }\n" - "}\n", 15); + "}\n", + "Test", "main", 15, "super.method() should call parent method"); - run_test_int("super.method() with args", + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_super_method_with_args(void) { + UNITTEST_BEGIN_TEST("TestSuper", "test_super_method_with_args"); + + RAVA_TEST_RUN(_unittest_result, "class Parent {\n" " int add(int a, int b) {\n" " return a + b;\n" @@ -101,9 +44,16 @@ int main(void) { " Child c = new Child();\n" " return c.add(3, 4);\n" " }\n" - "}\n", 14); + "}\n", + "Test", "main", 14, "super.method(args) should pass arguments to parent"); - run_test_int("super.method() chain", + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_super_method_chain(void) { + UNITTEST_BEGIN_TEST("TestSuper", "test_super_method_chain"); + + RAVA_TEST_RUN(_unittest_result, "class GrandParent {\n" " int getValue() {\n" " return 100;\n" @@ -124,9 +74,34 @@ int main(void) { " Child c = new Child();\n" " return c.getValue();\n" " }\n" - "}\n", 111); + "}\n", + "Test", "main", 111, "super chain should accumulate values"); - printf("\n=== Results: %d/%d tests passed ===\n", pass_count, test_count); - - return (pass_count == test_count) ? 0 : 1; + 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("Super Keyword Tests"); + + UnittestTestCase_t *tc = unittest_test_case_create("TestSuper"); + unittest_test_case_add_result(tc, test_super_method_basic()); + unittest_test_case_add_result(tc, test_super_method_with_args()); + unittest_test_case_add_result(tc, test_super_method_chain()); + 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; }