diff --git a/tests/test_overloading.c b/tests/test_overloading.c new file mode 100644 index 0000000..d9c2277 --- /dev/null +++ b/tests/test_overloading.c @@ -0,0 +1,171 @@ +#include "unittest.h" +#include "../lexer/lexer.h" +#include "../parser/parser.h" +#include "../semantic/semantic.h" +#include "../ir/ir_gen.h" +#include "../runtime/runtime.h" + +UnittestTestResult_t* test_overloading_different_param_count(void) { + UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_different_param_count"); + + const char* source = + "public class Calculator {\n" + " public static int add(int a, int b) {\n" + " return a + b;\n" + " }\n" + "\n" + " public static int add(int a, int b, int c) {\n" + " return a + b + c;\n" + " }\n" + "}\n"; + + RavaLexer_t* lexer = rava_lexer_create(source); + UNITTEST_ASSERT_NOT_NULL(_unittest_result, lexer, "lexer should be created"); + + RavaParser_t* parser = rava_parser_create(lexer); + UNITTEST_ASSERT_NOT_NULL(_unittest_result, parser, "parser should be created"); + + RavaASTNode_t* ast = rava_parser_parse(parser); + UNITTEST_ASSERT_NOT_NULL(_unittest_result, ast, "AST should be created"); + + RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create(); + UNITTEST_ASSERT_NOT_NULL(_unittest_result, semantic, "semantic analyzer should be created"); + + bool success = rava_semantic_analyze(semantic, ast); + UNITTEST_ASSERT_TRUE(_unittest_result, success, "semantic analysis should accept overloaded methods with different param counts"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_overloading_different_param_types(void) { + UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_different_param_types"); + + const char* source = + "public class Calculator {\n" + " public static int add(int a, int b) {\n" + " return a + b;\n" + " }\n" + "\n" + " public static double add(double a, double b) {\n" + " return a + b;\n" + " }\n" + "}\n"; + + RavaLexer_t* lexer = rava_lexer_create(source); + RavaParser_t* parser = rava_parser_create(lexer); + RavaASTNode_t* ast = rava_parser_parse(parser); + RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create(); + + bool success = rava_semantic_analyze(semantic, ast); + UNITTEST_ASSERT_TRUE(_unittest_result, success, "semantic analysis should accept overloaded methods with different param types"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_overloading_reject_duplicate_signature(void) { + UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_reject_duplicate_signature"); + + const char* source = + "public class Calculator {\n" + " public static int add(int a, int b) {\n" + " return a + b;\n" + " }\n" + "\n" + " public static int add(int x, int y) {\n" + " return x + y;\n" + " }\n" + "}\n"; + + RavaLexer_t* lexer = rava_lexer_create(source); + RavaParser_t* parser = rava_parser_create(lexer); + RavaASTNode_t* ast = rava_parser_parse(parser); + RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create(); + + bool success = rava_semantic_analyze(semantic, ast); + UNITTEST_ASSERT_FALSE(_unittest_result, success, "semantic analysis should reject duplicate method signatures"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_overloading_mixed_param_types(void) { + UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_mixed_param_types"); + + const char* source = + "public class Calculator {\n" + " public static int add(int a, double b) {\n" + " return a + (int)b;\n" + " }\n" + "\n" + " public static double add(double a, int b) {\n" + " return a + (double)b;\n" + " }\n" + "}\n"; + + RavaLexer_t* lexer = rava_lexer_create(source); + RavaParser_t* parser = rava_parser_create(lexer); + RavaASTNode_t* ast = rava_parser_parse(parser); + RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create(); + + bool success = rava_semantic_analyze(semantic, ast); + UNITTEST_ASSERT_TRUE(_unittest_result, success, "semantic analysis should accept overloaded methods with mixed param types"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_overloading_three_overloads(void) { + UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_three_overloads"); + + const char* source = + "public class Math {\n" + " public static int max(int a, int b) {\n" + " return a > b ? a : b;\n" + " }\n" + "\n" + " public static double max(double a, double b) {\n" + " return a > b ? a : b;\n" + " }\n" + "\n" + " public static int max(int a, int b, int c) {\n" + " return a > b ? (a > c ? a : c) : (b > c ? b : c);\n" + " }\n" + "}\n"; + + RavaLexer_t* lexer = rava_lexer_create(source); + RavaParser_t* parser = rava_parser_create(lexer); + RavaASTNode_t* ast = rava_parser_parse(parser); + RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create(); + + bool success = rava_semantic_analyze(semantic, ast); + UNITTEST_ASSERT_TRUE(_unittest_result, success, "semantic analysis should accept three overloads of max()"); + + UNITTEST_END_TEST(); +} + +int main(int argc, char **argv) { + UnittestConfig_t *config = unittest_config_create(); + config->verbosity = 2; + config->track_execution_time = true; + + 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("Method Overloading Tests"); + + UnittestTestCase_t *tc = unittest_test_case_create("TestMethodOverloading"); + unittest_test_case_add_result(tc, test_overloading_different_param_count()); + unittest_test_case_add_result(tc, test_overloading_different_param_types()); + unittest_test_case_add_result(tc, test_overloading_reject_duplicate_signature()); + unittest_test_case_add_result(tc, test_overloading_mixed_param_types()); + unittest_test_case_add_result(tc, test_overloading_three_overloads()); + 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_overloading_runtime.c b/tests/test_overloading_runtime.c new file mode 100644 index 0000000..96a4f7e --- /dev/null +++ b/tests/test_overloading_runtime.c @@ -0,0 +1,100 @@ +#include "test_utils.h" + +UnittestTestResult_t* test_overloading_call_two_params(void) { + UNITTEST_BEGIN_TEST("TestOverloadingRuntime", "test_call_two_params"); + + const char* source = + "public class Calculator {\n" + " public static int add(int a, int b) {\n" + " return a + b;\n" + " }\n" + "\n" + " public static int add(int a, int b, int c) {\n" + " return a + b + c;\n" + " }\n" + "\n" + " public static int main() {\n" + " return add(10, 20);\n" + " }\n" + "}\n"; + + RAVA_TEST_RUN(_unittest_result, source, "Calculator", "main", 30, + "add(10, 20) should return 30"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_overloading_call_three_params(void) { + UNITTEST_BEGIN_TEST("TestOverloadingRuntime", "test_call_three_params"); + + const char* source = + "public class Calculator {\n" + " public static int add(int a, int b) {\n" + " return a + b;\n" + " }\n" + "\n" + " public static int add(int a, int b, int c) {\n" + " return a + b + c;\n" + " }\n" + "\n" + " public static int main() {\n" + " return add(10, 20, 30);\n" + " }\n" + "}\n"; + + RAVA_TEST_RUN(_unittest_result, source, "Calculator", "main", 60, + "add(10, 20, 30) should return 60"); + + UNITTEST_END_TEST(); +} + +UnittestTestResult_t* test_overloading_different_types(void) { + UNITTEST_BEGIN_TEST("TestOverloadingRuntime", "test_different_types"); + + const char* source = + "public class Math {\n" + " public static int max(int a, int b) {\n" + " return a > b ? a : b;\n" + " }\n" + "\n" + " public static double max(double a, double b) {\n" + " return a > b ? a : b;\n" + " }\n" + "\n" + " public static int main() {\n" + " return max(15, 25);\n" + " }\n" + "}\n"; + + RAVA_TEST_RUN(_unittest_result, source, "Math", "main", 25, + "max(15, 25) should return 25"); + + UNITTEST_END_TEST(); +} + +int main(int argc, char **argv) { + UnittestConfig_t *config = unittest_config_create(); + config->verbosity = 2; + config->track_execution_time = true; + + 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("Method Overloading Runtime Tests"); + + UnittestTestCase_t *tc = unittest_test_case_create("TestOverloadingRuntime"); + unittest_test_case_add_result(tc, test_overloading_call_two_params()); + unittest_test_case_add_result(tc, test_overloading_call_three_params()); + unittest_test_case_add_result(tc, test_overloading_different_types()); + 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; +}