Update.
This commit is contained in:
parent
56212ecef1
commit
cdcfdf375c
26
Makefile
26
Makefile
@ -107,13 +107,22 @@ TEST_ENUMS_OBJECTS = $(TEST_ENUMS_SOURCES:.c=.o)
|
|||||||
TEST_COLLECTIONS_SOURCES = tests/test_collections.c
|
TEST_COLLECTIONS_SOURCES = tests/test_collections.c
|
||||||
TEST_COLLECTIONS_OBJECTS = $(TEST_COLLECTIONS_SOURCES:.c=.o)
|
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_SOURCES = tests/unittest.c
|
||||||
UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o)
|
UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o)
|
||||||
|
|
||||||
TEST_UNITTEST_DEMO_SOURCES = tests/test_unittest_demo.c
|
TEST_UNITTEST_DEMO_SOURCES = tests/test_unittest_demo.c
|
||||||
TEST_UNITTEST_DEMO_OBJECTS = $(TEST_UNITTEST_DEMO_SOURCES:.c=.o)
|
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)
|
test_lexer: $(LEXER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_LEXER_OBJECTS)
|
||||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
$(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)
|
test_collections: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_COLLECTIONS_OBJECTS)
|
||||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
$(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)
|
test_unittest_demo: $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS)
|
||||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
@ -267,8 +285,8 @@ clean:
|
|||||||
$(PHASE0_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) \
|
$(PHASE0_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) \
|
||||||
$(TEST_LEXER_OBJECTS) $(TEST_PARSER_OBJECTS) $(TEST_SEMANTIC_OBJECTS) $(TEST_IR_OBJECTS) $(TEST_RUNTIME_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_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_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_benchmark \
|
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
|
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
|
.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_static && ./test_interfaces && ./test_exceptions && ./test_ternary && \
|
||||||
./test_bitwise && ./test_enhanced_for && ./test_array_init && ./test_instanceof && \
|
./test_bitwise && ./test_enhanced_for && ./test_array_init && ./test_instanceof && \
|
||||||
./test_shortcircuit && ./test_multidim_arrays && ./test_static_init && ./test_negative && \
|
./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 ==="
|
echo "" && echo "=== All Tests Passed ==="
|
||||||
|
|||||||
@ -1,42 +1,152 @@
|
|||||||
#include "../lexer/lexer.h"
|
#include "test_utils.h"
|
||||||
#include "../parser/parser.h"
|
|
||||||
#include "../semantic/semantic.h"
|
|
||||||
#include "../ir/ir.h"
|
|
||||||
#include "../ir/ir_gen.h"
|
|
||||||
#include "../runtime/runtime.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
static char* read_file(const char *filename) {
|
UnittestTestResult_t* test_break_continue_example(void) {
|
||||||
FILE *file = fopen(filename, "r");
|
UNITTEST_BEGIN_TEST("TestBreakContinue", "test_break_continue_example");
|
||||||
if (!file) return NULL;
|
|
||||||
fseek(file, 0, SEEK_END);
|
RAVA_TEST_FILE_EXECUTES(_unittest_result,
|
||||||
long size = ftell(file);
|
"examples/19_BreakContinue.java",
|
||||||
fseek(file, 0, SEEK_SET);
|
"BreakContinue", "main",
|
||||||
char *content = malloc(size + 1);
|
"break/continue example should execute successfully");
|
||||||
size_t read_bytes = fread(content, 1, size, file); (void)read_bytes;
|
|
||||||
content[size] = '\0';
|
UNITTEST_END_TEST();
|
||||||
fclose(file);
|
|
||||||
return content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
UnittestTestResult_t* test_break_in_for(void) {
|
||||||
char *source = read_file("examples/19_BreakContinue.java");
|
UNITTEST_BEGIN_TEST("TestBreakContinue", "test_break_in_for");
|
||||||
if (!source) { printf("Failed\n"); return 1; }
|
|
||||||
RavaLexer_t *l = rava_lexer_create(source);
|
RAVA_TEST_RUN(_unittest_result,
|
||||||
RavaParser_t *p = rava_parser_create(l);
|
"public class Test {\n"
|
||||||
RavaASTNode_t *ast = rava_parser_parse(p);
|
" public static int main() {\n"
|
||||||
if (p->had_error) { printf("Parse: %s\n", p->error_message); return 1; }
|
" int sum = 0;\n"
|
||||||
printf("Parse: OK\n");
|
" for (int i = 0; i < 10; i++) {\n"
|
||||||
RavaSemanticAnalyzer_t *a = rava_semantic_analyzer_create();
|
" if (i == 5) {\n"
|
||||||
if (!rava_semantic_analyze(a, ast)) { printf("Semantic: %s\n", a->error_message); return 1; }
|
" break;\n"
|
||||||
printf("Semantic: OK\n");
|
" }\n"
|
||||||
RavaIRGenerator_t *g = rava_ir_generator_create(a);
|
" sum = sum + i;\n"
|
||||||
RavaProgram_t *prog = rava_ir_generate(g, ast);
|
" }\n"
|
||||||
if (!prog) { printf("IR failed\n"); return 1; }
|
" return sum;\n"
|
||||||
printf("IR: OK\nOutput:\n");
|
" }\n"
|
||||||
RavaVM_t *vm = rava_vm_create(prog);
|
"}\n",
|
||||||
if (!rava_vm_execute(vm, "BreakContinue", "main")) { printf("Runtime: %s\n", vm->error_message); return 1; }
|
"Test", "main", 10, "break should exit for loop (0+1+2+3+4=10)");
|
||||||
printf("\nExecution: OK\n");
|
|
||||||
return 0;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,77 +1,111 @@
|
|||||||
#include "../lexer/lexer.h"
|
#include "test_utils.h"
|
||||||
#include "../parser/parser.h"
|
|
||||||
#include "../semantic/semantic.h"
|
|
||||||
#include "../ir/ir.h"
|
|
||||||
#include "../ir/ir_gen.h"
|
|
||||||
#include "../runtime/runtime.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static char* read_file(const char *filename) {
|
UnittestTestResult_t* test_inheritance_example(void) {
|
||||||
FILE *file = fopen(filename, "r");
|
UNITTEST_BEGIN_TEST("TestInheritance", "test_inheritance_example");
|
||||||
if (!file) return NULL;
|
|
||||||
fseek(file, 0, SEEK_END);
|
RAVA_TEST_FILE_EXECUTES(_unittest_result,
|
||||||
long size = ftell(file);
|
"examples/17_Inheritance.java",
|
||||||
fseek(file, 0, SEEK_SET);
|
"Inheritance", "main",
|
||||||
char *content = malloc(size + 1);
|
"inheritance example should execute successfully");
|
||||||
size_t read_bytes = fread(content, 1, size, file); (void)read_bytes;
|
|
||||||
content[size] = '\0';
|
UNITTEST_END_TEST();
|
||||||
fclose(file);
|
|
||||||
return content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
UnittestTestResult_t* test_simple_inheritance(void) {
|
||||||
char *source = read_file("examples/17_Inheritance.java");
|
UNITTEST_BEGIN_TEST("TestInheritance", "test_simple_inheritance");
|
||||||
if (!source) {
|
|
||||||
printf("Failed to read file\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
RavaLexer_t *lexer = rava_lexer_create(source);
|
RAVA_TEST_RUN(_unittest_result,
|
||||||
RavaParser_t *parser = rava_parser_create(lexer);
|
"class Animal {\n"
|
||||||
RavaASTNode_t *ast = rava_parser_parse(parser);
|
" 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) {
|
UNITTEST_END_TEST();
|
||||||
printf("Parse error: %s\n", parser->error_message);
|
}
|
||||||
free(source);
|
|
||||||
return 1;
|
UnittestTestResult_t* test_method_override(void) {
|
||||||
}
|
UNITTEST_BEGIN_TEST("TestInheritance", "test_method_override");
|
||||||
|
|
||||||
printf("Parse: OK\n");
|
RAVA_TEST_RUN(_unittest_result,
|
||||||
|
"class Parent {\n"
|
||||||
RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create();
|
" int getValue() {\n"
|
||||||
if (!rava_semantic_analyze(analyzer, ast)) {
|
" return 10;\n"
|
||||||
printf("Semantic error: %s\n", analyzer->error_message);
|
" }\n"
|
||||||
free(source);
|
"}\n"
|
||||||
return 1;
|
"class Child extends Parent {\n"
|
||||||
}
|
" int getValue() {\n"
|
||||||
|
" return 20;\n"
|
||||||
printf("Semantic: OK\n");
|
" }\n"
|
||||||
|
"}\n"
|
||||||
RavaIRGenerator_t *ir_gen = rava_ir_generator_create(analyzer);
|
"public class Test {\n"
|
||||||
RavaProgram_t *program = rava_ir_generate(ir_gen, ast);
|
" public static int main() {\n"
|
||||||
|
" Child c = new Child();\n"
|
||||||
if (!program) {
|
" return c.getValue();\n"
|
||||||
printf("IR generation failed\n");
|
" }\n"
|
||||||
free(source);
|
"}\n",
|
||||||
return 1;
|
"Test", "main", 20, "child method should override parent");
|
||||||
}
|
|
||||||
|
UNITTEST_END_TEST();
|
||||||
printf("IR Gen: OK\n");
|
}
|
||||||
printf("\nOutput:\n");
|
|
||||||
|
UnittestTestResult_t* test_inherited_method_with_value(void) {
|
||||||
RavaVM_t *vm = rava_vm_create(program);
|
UNITTEST_BEGIN_TEST("TestInheritance", "test_inherited_method_with_value");
|
||||||
if (!rava_vm_execute(vm, "Inheritance", "main")) {
|
|
||||||
printf("Runtime error: %s\n", vm->error_message);
|
RAVA_TEST_RUN(_unittest_result,
|
||||||
rava_vm_destroy(vm);
|
"class Parent {\n"
|
||||||
free(source);
|
" int getValue() {\n"
|
||||||
return 1;
|
" return 42;\n"
|
||||||
}
|
" }\n"
|
||||||
|
"}\n"
|
||||||
printf("\nExecution: OK\n");
|
"class Child extends Parent {\n"
|
||||||
|
"}\n"
|
||||||
rava_vm_destroy(vm);
|
"public class Test {\n"
|
||||||
free(source);
|
" public static int main() {\n"
|
||||||
return 0;
|
" 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,73 +1,9 @@
|
|||||||
#include "../lexer/lexer.h"
|
#include "test_utils.h"
|
||||||
#include "../parser/parser.h"
|
|
||||||
#include "../semantic/semantic.h"
|
|
||||||
#include "../ir/ir.h"
|
|
||||||
#include "../ir/ir_gen.h"
|
|
||||||
#include "../runtime/runtime.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static int test_count = 0;
|
UnittestTestResult_t* test_super_method_basic(void) {
|
||||||
static int pass_count = 0;
|
UNITTEST_BEGIN_TEST("TestSuper", "test_super_method_basic");
|
||||||
|
|
||||||
static void run_test_int(const char* name, const char* source, int expected) {
|
RAVA_TEST_RUN(_unittest_result,
|
||||||
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",
|
|
||||||
"class Parent {\n"
|
"class Parent {\n"
|
||||||
" int getValue() {\n"
|
" int getValue() {\n"
|
||||||
" return 10;\n"
|
" return 10;\n"
|
||||||
@ -83,9 +19,16 @@ int main(void) {
|
|||||||
" Child c = new Child();\n"
|
" Child c = new Child();\n"
|
||||||
" return c.getValue();\n"
|
" return c.getValue();\n"
|
||||||
" }\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"
|
"class Parent {\n"
|
||||||
" int add(int a, int b) {\n"
|
" int add(int a, int b) {\n"
|
||||||
" return a + b;\n"
|
" return a + b;\n"
|
||||||
@ -101,9 +44,16 @@ int main(void) {
|
|||||||
" Child c = new Child();\n"
|
" Child c = new Child();\n"
|
||||||
" return c.add(3, 4);\n"
|
" return c.add(3, 4);\n"
|
||||||
" }\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"
|
"class GrandParent {\n"
|
||||||
" int getValue() {\n"
|
" int getValue() {\n"
|
||||||
" return 100;\n"
|
" return 100;\n"
|
||||||
@ -124,9 +74,34 @@ int main(void) {
|
|||||||
" Child c = new Child();\n"
|
" Child c = new Child();\n"
|
||||||
" return c.getValue();\n"
|
" return c.getValue();\n"
|
||||||
" }\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);
|
UNITTEST_END_TEST();
|
||||||
|
}
|
||||||
return (pass_count == test_count) ? 0 : 1;
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user