diff --git a/Makefile b/Makefile index 53496ff..d5169d9 100644 --- a/Makefile +++ b/Makefile @@ -116,13 +116,22 @@ TEST_INHERITANCE_OBJECTS = $(TEST_INHERITANCE_SOURCES:.c=.o) TEST_BREAK_SOURCES = tests/test_break.c TEST_BREAK_OBJECTS = $(TEST_BREAK_SOURCES:.c=.o) +TEST_ELSEIF_SOURCES = tests/test_elseif.c +TEST_ELSEIF_OBJECTS = $(TEST_ELSEIF_SOURCES:.c=.o) + +TEST_FORLOOP_SOURCES = tests/test_forloop.c +TEST_FORLOOP_OBJECTS = $(TEST_FORLOOP_SOURCES:.c=.o) + +TEST_PRINTLN_SOURCES = tests/test_println.c +TEST_PRINTLN_OBJECTS = $(TEST_PRINTLN_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 test_super test_inheritance test_break +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_elseif test_forloop test_println test_lexer: $(LEXER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_LEXER_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) @@ -217,6 +226,15 @@ test_inheritance: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC test_break: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_BREAK_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) +test_elseif: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ELSEIF_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_forloop: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_FORLOOP_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_println: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_PRINTLN_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + test_unittest_demo: $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) @@ -285,8 +303,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_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_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_ELSEIF_OBJECTS) $(TEST_FORLOOP_OBJECTS) $(TEST_PRINTLN_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_elseif test_forloop test_println 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 @@ -300,4 +318,5 @@ test: all ./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_elseif && ./test_forloop && ./test_println && \ echo "" && echo "=== All Tests Passed ===" diff --git a/tests/test_elseif.c b/tests/test_elseif.c index 72e7706..e3bf89e 100644 --- a/tests/test_elseif.c +++ b/tests/test_elseif.c @@ -1,77 +1,128 @@ -#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_elseif_example(void) { + UNITTEST_BEGIN_TEST("TestElseIf", "test_elseif_example"); + + RAVA_TEST_FILE_EXECUTES(_unittest_result, + "examples/18_ElseIf.java", + "ElseIf", "main", + "else-if example should execute successfully"); + + UNITTEST_END_TEST(); } -int main() { - char *source = read_file("examples/18_ElseIf.java"); - if (!source) { - printf("Failed to read file\n"); - return 1; - } +UnittestTestResult_t* test_elseif_first_branch(void) { + UNITTEST_BEGIN_TEST("TestElseIf", "test_elseif_first_branch"); - 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, + "public class Test {\n" + " public static int main() {\n" + " int x = 10;\n" + " if (x > 5) {\n" + " return 1;\n" + " } else if (x > 0) {\n" + " return 2;\n" + " } else {\n" + " return 3;\n" + " }\n" + " }\n" + "}\n", + "Test", "main", 1, "should take first branch when x > 5"); - 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, "ElseIf", "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_elseif_second_branch(void) { + UNITTEST_BEGIN_TEST("TestElseIf", "test_elseif_second_branch"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int x = 3;\n" + " if (x > 5) {\n" + " return 1;\n" + " } else if (x > 0) {\n" + " return 2;\n" + " } else {\n" + " return 3;\n" + " }\n" + " }\n" + "}\n", + "Test", "main", 2, "should take else-if branch when 0 < x <= 5"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_elseif_else_branch(void) { + UNITTEST_BEGIN_TEST("TestElseIf", "test_elseif_else_branch"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int x = -5;\n" + " if (x > 5) {\n" + " return 1;\n" + " } else if (x > 0) {\n" + " return 2;\n" + " } else {\n" + " return 3;\n" + " }\n" + " }\n" + "}\n", + "Test", "main", 3, "should take else branch when x <= 0"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_elseif_chain(void) { + UNITTEST_BEGIN_TEST("TestElseIf", "test_elseif_chain"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int x = 75;\n" + " if (x >= 90) {\n" + " return 1;\n" + " } else if (x >= 80) {\n" + " return 2;\n" + " } else if (x >= 70) {\n" + " return 3;\n" + " } else if (x >= 60) {\n" + " return 4;\n" + " } else {\n" + " return 5;\n" + " }\n" + " }\n" + "}\n", + "Test", "main", 3, "should take third branch for grade C"); + + 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("Else-If Tests"); + + UnittestTestCase_t *tc = unittest_test_case_create("TestElseIf"); + unittest_test_case_add_result(tc, test_elseif_example()); + unittest_test_case_add_result(tc, test_elseif_first_branch()); + unittest_test_case_add_result(tc, test_elseif_second_branch()); + unittest_test_case_add_result(tc, test_elseif_else_branch()); + unittest_test_case_add_result(tc, test_elseif_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; } diff --git a/tests/test_forloop.c b/tests/test_forloop.c index e46be99..d7cc8d3 100644 --- a/tests/test_forloop.c +++ b/tests/test_forloop.c @@ -1,77 +1,133 @@ -#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_forloop_example(void) { + UNITTEST_BEGIN_TEST("TestForLoop", "test_forloop_example"); + + RAVA_TEST_FILE_EXECUTES(_unittest_result, + "examples/16_ForLoop.java", + "ForLoop", "main", + "for loop example should execute successfully"); + + UNITTEST_END_TEST(); } -int main() { - char *source = read_file("examples/16_ForLoop.java"); - if (!source) { - printf("Failed to read file\n"); - return 1; - } +UnittestTestResult_t* test_forloop_sum(void) { + UNITTEST_BEGIN_TEST("TestForLoop", "test_forloop_sum"); - 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, + "public class Test {\n" + " public static int main() {\n" + " int sum = 0;\n" + " for (int i = 1; i <= 10; i++) {\n" + " sum = sum + i;\n" + " }\n" + " return sum;\n" + " }\n" + "}\n", + "Test", "main", 55, "sum 1 to 10 should equal 55"); - 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, "ForLoop", "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_forloop_countdown(void) { + UNITTEST_BEGIN_TEST("TestForLoop", "test_forloop_countdown"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int count = 0;\n" + " for (int i = 10; i > 0; i--) {\n" + " count = count + 1;\n" + " }\n" + " return count;\n" + " }\n" + "}\n", + "Test", "main", 10, "countdown from 10 should iterate 10 times"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_forloop_nested(void) { + UNITTEST_BEGIN_TEST("TestForLoop", "test_forloop_nested"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int count = 0;\n" + " for (int i = 0; i < 3; i++) {\n" + " for (int j = 0; j < 4; j++) {\n" + " count = count + 1;\n" + " }\n" + " }\n" + " return count;\n" + " }\n" + "}\n", + "Test", "main", 12, "3x4 nested loops should count 12"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_forloop_step_by_two(void) { + UNITTEST_BEGIN_TEST("TestForLoop", "test_forloop_step_by_two"); + + 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 = i + 2) {\n" + " sum = sum + i;\n" + " }\n" + " return sum;\n" + " }\n" + "}\n", + "Test", "main", 20, "sum even numbers 0-8 should equal 20"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_forloop_zero_iterations(void) { + UNITTEST_BEGIN_TEST("TestForLoop", "test_forloop_zero_iterations"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " int count = 0;\n" + " for (int i = 0; i < 0; i++) {\n" + " count = count + 1;\n" + " }\n" + " return count;\n" + " }\n" + "}\n", + "Test", "main", 0, "loop with false condition should not execute"); + + 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("For Loop Tests"); + + UnittestTestCase_t *tc = unittest_test_case_create("TestForLoop"); + unittest_test_case_add_result(tc, test_forloop_example()); + unittest_test_case_add_result(tc, test_forloop_sum()); + unittest_test_case_add_result(tc, test_forloop_countdown()); + unittest_test_case_add_result(tc, test_forloop_nested()); + unittest_test_case_add_result(tc, test_forloop_step_by_two()); + unittest_test_case_add_result(tc, test_forloop_zero_iterations()); + 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_println.c b/tests/test_println.c index 08dc115..b54e5db 100644 --- a/tests/test_println.c +++ b/tests/test_println.c @@ -1,72 +1,92 @@ -#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" -int main() { - const char *source = +UnittestTestResult_t* test_println_int(void) { + UNITTEST_BEGIN_TEST("TestPrintln", "test_println_int"); + + RAVA_TEST_RUN(_unittest_result, "public class Test {\n" " public static int main() {\n" " System.out.println(42);\n" - " System.out.println(100);\n" + " return 42;\n" + " }\n" + "}\n", + "Test", "main", 42, "println should execute and return value"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_println_expression(void) { + UNITTEST_BEGIN_TEST("TestPrintln", "test_println_expression"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" " int x = 10;\n" " int y = 20;\n" " System.out.println(x + y);\n" - " return 0;\n" + " return x + y;\n" " }\n" - "}\n"; + "}\n", + "Test", "main", 30, "println with expression should work"); - printf("Source:\n%s\n", source); - - RavaLexer_t *lexer = rava_lexer_create(source); - RavaParser_t *parser = rava_parser_create(lexer); - RavaASTNode_t *ast = rava_parser_parse(parser); - - if (parser->had_error) { - printf("Parse error: %s\n", parser->error_message); - return 1; - } - - RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create(); - if (!rava_semantic_analyze(analyzer, ast)) { - printf("Semantic error: %s\n", analyzer->error_message); - return 1; - } - - 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"); - return 1; - } - - printf("\nGenerated IR:\n"); - rava_ir_print(program); - - RavaVM_t *vm = rava_vm_create(program); - printf("\nExecuting Test.main()...\n"); - printf("Output:\n"); - - if (!rava_vm_execute(vm, "Test", "main")) { - printf("Runtime error: %s\n", vm->error_message); - rava_vm_destroy(vm); - return 1; - } - - printf("\n✅ Execution completed successfully!\n"); - - 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 0; + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_println_multiple(void) { + UNITTEST_BEGIN_TEST("TestPrintln", "test_println_multiple"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " System.out.println(1);\n" + " System.out.println(2);\n" + " System.out.println(3);\n" + " return 6;\n" + " }\n" + "}\n", + "Test", "main", 6, "multiple println calls should work"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_print_no_newline(void) { + UNITTEST_BEGIN_TEST("TestPrintln", "test_print_no_newline"); + + RAVA_TEST_RUN(_unittest_result, + "public class Test {\n" + " public static int main() {\n" + " System.out.print(42);\n" + " return 42;\n" + " }\n" + "}\n", + "Test", "main", 42, "print without newline should work"); + + 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("Print/Println Tests"); + + UnittestTestCase_t *tc = unittest_test_case_create("TestPrintln"); + unittest_test_case_add_result(tc, test_println_int()); + unittest_test_case_add_result(tc, test_println_expression()); + unittest_test_case_add_result(tc, test_println_multiple()); + unittest_test_case_add_result(tc, test_print_no_newline()); + 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; }