Compare commits

...

3 Commits

Author SHA1 Message Date
b2f3c6e38d Update.
All checks were successful
CI / Optimization Infrastructure Tests (push) Successful in 19s
CI / Unit Tests (push) Successful in 20s
CI / Integration Tests (push) Successful in 1m22s
CI / Performance Benchmark (push) Successful in 3m5s
2025-12-09 20:47:37 +01:00
d431eb265c Optimization. 2025-12-09 20:47:28 +01:00
1f6ef54d3c Upgrade of tests. 2025-12-09 20:11:54 +01:00
5 changed files with 1131 additions and 6 deletions

701
examples/JavaKungFu.java Normal file
View File

@ -0,0 +1,701 @@
class Point {
int x;
int y;
}
class Rectangle {
int width;
int height;
int area;
Rectangle(int w, int h) {
this.width = w;
this.height = h;
this.area = w * h;
}
}
class Counter {
int count;
Counter() {
this.count = 0;
}
void increment() {
this.count = this.count + 1;
}
int getCount() {
return this.count;
}
}
class MathUtils {
int x;
}
class Animal {
int name;
int speak() {
return 0;
}
}
class Dog extends Animal {
int breed;
int speak() {
return 1;
}
}
class Cat extends Animal {
int indoor;
int speak() {
return 2;
}
}
interface Shape {
int getArea();
}
class Circle implements Shape {
int radius;
Circle(int r) {
this.radius = r;
}
int getArea() {
return (int)(3.14159 * this.radius * this.radius);
}
}
class Square implements Shape {
int side;
Square(int s) {
this.side = s;
}
int getArea() {
return this.side * this.side;
}
}
public class JavaKungFu {
static int staticCounter = 0;
static int fibCalls = 0;
int instanceValue;
JavaKungFu() {
this.instanceValue = 100;
}
JavaKungFu(int val) {
this.instanceValue = val;
}
int getValue() {
return this.instanceValue;
}
void setValue(int v) {
this.instanceValue = v;
}
int add(int x) {
return this.instanceValue + x;
}
public static int square(int x) {
return x * x;
}
public static int cube(int x) {
return x * x * x;
}
public static int fibonacci(int n) {
JavaKungFu.fibCalls = JavaKungFu.fibCalls + 1;
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
public static int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
public static boolean isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
int i = 5;
while (i * i <= n) {
if (n % i == 0 || n % (i + 2) == 0) return false;
i = i + 6;
}
return true;
}
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
public static boolean testPrimitiveTypes() {
int i = 42;
long l = 9876543210L;
double d = 3.14159;
boolean b = true;
char c = 'A';
if (i != 42) return false;
if (l != 9876543210L) return false;
if (d < 3.14 || d > 3.15) return false;
if (b != true) return false;
if (c != 'A') return false;
return true;
}
public static boolean testArithmeticOperators() {
int a = 20;
int b = 6;
if (a + b != 26) return false;
if (a - b != 14) return false;
if (a * b != 120) return false;
if (a / b != 3) return false;
if (a % b != 2) return false;
if (-a != -20) return false;
int x = 10;
x += 5;
if (x != 15) return false;
x -= 3;
if (x != 12) return false;
x *= 2;
if (x != 24) return false;
x /= 4;
if (x != 6) return false;
int y = 5;
if (++y != 6) return false;
if (--y != 5) return false;
return true;
}
public static boolean testBitwiseOperators() {
int a = 12;
int b = 10;
if ((a & b) != 8) return false;
if ((a | b) != 14) return false;
if ((a ^ b) != 6) return false;
int c = 1;
if ((c << 4) != 16) return false;
if ((16 >> 2) != 4) return false;
return true;
}
public static boolean testComparisonOperators() {
int a = 10;
int b = 20;
int c = 10;
if ((a == c) != true) return false;
if ((a != b) != true) return false;
if ((a < b) != true) return false;
if ((a <= c) != true) return false;
if ((b > a) != true) return false;
if ((b >= a) != true) return false;
return true;
}
public static boolean testLogicalOperators() {
boolean t = true;
boolean f = false;
if ((t && t) != true) return false;
if ((t && f) != false) return false;
if ((t || f) != true) return false;
if ((f || f) != false) return false;
if ((!t) != false) return false;
if ((!f) != true) return false;
return true;
}
public static boolean testTernaryOperator() {
int a = 10;
int b = 20;
int max = a > b ? a : b;
if (max != 20) return false;
int min = a < b ? a : b;
if (min != 10) return false;
int nested = a > 5 ? (a > 15 ? 2 : 1) : 0;
if (nested != 1) return false;
return true;
}
public static boolean testIfElse() {
int x = 15;
int result = 0;
if (x > 20) {
result = 1;
} else if (x > 10) {
result = 2;
} else if (x > 5) {
result = 3;
} else {
result = 4;
}
if (result != 2) return false;
return true;
}
public static boolean testWhileLoop() {
int sum = 0;
int i = 1;
while (i <= 10) {
sum = sum + i;
i = i + 1;
}
if (sum != 55) return false;
return true;
}
public static boolean testDoWhileLoop() {
int count = 0;
do {
count = count + 1;
} while (count < 5);
if (count != 5) return false;
return true;
}
public static boolean testForLoop() {
int sum = 0;
for (int a = 0; a < 10; a++) {
sum = sum + a;
}
if (sum != 45) return false;
int nested = 0;
for (int b = 0; b < 3; b++) {
for (int c = 0; c < 3; c++) {
nested = nested + 1;
}
}
if (nested != 9) return false;
return true;
}
public static boolean testBreakContinue() {
int sum = 0;
for (int a = 0; a < 100; a++) {
if (a >= 10) break;
sum = sum + a;
}
if (sum != 45) return false;
sum = 0;
for (int b = 0; b < 10; b++) {
if (b % 2 == 0) continue;
sum = sum + b;
}
if (sum != 25) return false;
return true;
}
public static boolean testSwitchStatement() {
int day = 3;
int result = 0;
switch (day) {
case 1: result = 10; break;
case 2: result = 20; break;
case 3: result = 30; break;
default: result = -1;
}
if (result != 30) return false;
return true;
}
public static boolean testArrays() {
int[] arr = new int[5];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
if (arr.length != 5) return false;
if (arr[2] != 30) return false;
int sum = 0;
for (int a = 0; a < arr.length; a++) {
sum = sum + arr[a];
}
if (sum != 150) return false;
return true;
}
public static boolean testEnhancedFor() {
int[] numbers = {1, 2, 3, 4, 5};
int sum = 0;
for (int n : numbers) {
sum = sum + n;
}
if (sum != 15) return false;
return true;
}
public static boolean testMultiDimArrays() {
int[][] matrix = new int[3][3];
for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {
matrix[a][b] = a * 3 + b;
}
}
if (matrix[0][0] != 0) return false;
if (matrix[1][1] != 4) return false;
if (matrix[2][2] != 8) return false;
return true;
}
public static boolean testObjectCreation() {
Point p1 = new Point();
p1.x = 10;
p1.y = 20;
if (p1.x != 10) return false;
if (p1.y != 20) return false;
Rectangle r = new Rectangle(4, 5);
if (r.width != 4) return false;
if (r.height != 5) return false;
if (r.area != 20) return false;
return true;
}
public static boolean testInstanceMethods() {
Rectangle r = new Rectangle(10, 5);
if (r.area != 50) return false;
if (r.width != 10) return false;
if (r.height != 5) return false;
return true;
}
public static boolean testStaticMembers() {
JavaKungFu.staticCounter = 0;
JavaKungFu.staticCounter = JavaKungFu.staticCounter + 1;
JavaKungFu.staticCounter = JavaKungFu.staticCounter + 1;
if (JavaKungFu.staticCounter != 2) return false;
int result = square(5);
if (result != 25) return false;
result = cube(3);
if (result != 27) return false;
return true;
}
public static boolean testInheritance() {
Dog dog = new Dog();
dog.name = 42;
dog.breed = 7;
if (dog.name != 42) return false;
if (dog.breed != 7) return false;
return true;
}
public static boolean testMethodOverride() {
Animal animal = new Animal();
if (animal.speak() != 0) return false;
Dog dog = new Dog();
if (dog.speak() != 1) return false;
Cat cat = new Cat();
if (cat.speak() != 2) return false;
return true;
}
public static boolean testInterfaces() {
Circle circle = new Circle(5);
int area = circle.getArea();
if (area < 75 || area > 79) return false;
Square square = new Square(4);
if (square.getArea() != 16) return false;
return true;
}
public static boolean testInstanceOf() {
Dog dog = new Dog();
boolean dogIsAnimal = dog instanceof Animal;
boolean dogIsDog = dog instanceof Dog;
if (dogIsAnimal != true) return false;
if (dogIsDog != true) return false;
return true;
}
public static boolean testRecursion() {
int fib10 = fibonacci(10);
if (fib10 != 55) return false;
int fact5 = factorial(5);
if (fact5 != 120) return false;
int gcdVal = gcd(48, 18);
if (gcdVal != 6) return false;
return true;
}
public static boolean testMathLibrary() {
if (Math.abs(-42) != 42) return false;
if (Math.min(10, 20) != 10) return false;
if (Math.max(10, 20) != 20) return false;
double sqrt = Math.sqrt(16.0);
if (sqrt < 3.99 || sqrt > 4.01) return false;
double pow = Math.pow(2.0, 10.0);
if (pow < 1023.0 || pow > 1025.0) return false;
return true;
}
public static boolean testStringOperations() {
String s = "Hello World";
if (s.length() != 11) return false;
if (s.charAt(0) != 'H') return false;
String sub = s.substring(0, 5);
if (sub.equals("Hello") == false) return false;
if (s.indexOf("World") != 6) return false;
if (s.contains("World") != true) return false;
if (s.startsWith("Hello") != true) return false;
if (s.endsWith("World") != true) return false;
String upper = s.toUpperCase();
if (upper.equals("HELLO WORLD") == false) return false;
String concat = "Hello" + " " + "World";
if (concat.equals("Hello World") == false) return false;
return true;
}
public static boolean testArrayList() {
ArrayList list = new ArrayList();
if (list.isEmpty() != true) return false;
list.add(10);
list.add(20);
list.add(30);
if (list.size() != 3) return false;
if ((int)list.get(0) != 10) return false;
if ((int)list.get(1) != 20) return false;
list.set(1, 25);
if ((int)list.get(1) != 25) return false;
list.clear();
if (list.size() != 0) return false;
return true;
}
public static boolean testHashMap() {
HashMap map = new HashMap();
map.put("one", 1);
map.put("two", 2);
map.put("three", 3);
if (map.size() != 3) return false;
if ((int)map.get("one") != 1) return false;
if ((int)map.get("two") != 2) return false;
if (map.containsKey("one") != true) return false;
if (map.containsKey("four") != false) return false;
map.put("two", 22);
if ((int)map.get("two") != 22) return false;
map.clear();
if (map.size() != 0) return false;
return true;
}
public static boolean testExceptions() {
int result = 0;
try {
throw 42;
} catch (Exception e) {
result = e;
}
if (result != 42) return false;
result = 0;
try {
result = 1;
} catch (Exception e) {
result = -1;
}
if (result != 1) return false;
return true;
}
public static boolean testAlgorithms() {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
bubbleSort(arr);
for (int a = 0; a < arr.length - 1; a++) {
if (arr[a] > arr[a + 1]) return false;
}
int[] sorted = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
int idx = binarySearch(sorted, 11);
if (idx != 5) return false;
idx = binarySearch(sorted, 10);
if (idx != -1) return false;
if (isPrime(17) == false) return false;
if (isPrime(18) == true) return false;
if (isPrime(2) == false) return false;
return true;
}
public static int main() {
System.out.println("=== JAVA KUNG-FU DEMONSTRATION ===");
System.out.println("");
int totalTests = 0;
int passedTests = 0;
totalTests = totalTests + 1;
if (testPrimitiveTypes() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Primitive Types"); }
else { System.out.println("[FAIL] Primitive Types"); }
totalTests = totalTests + 1;
if (testArithmeticOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Arithmetic Operators"); }
else { System.out.println("[FAIL] Arithmetic Operators"); }
totalTests = totalTests + 1;
if (testBitwiseOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Bitwise Operators"); }
else { System.out.println("[FAIL] Bitwise Operators"); }
totalTests = totalTests + 1;
if (testComparisonOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Comparison Operators"); }
else { System.out.println("[FAIL] Comparison Operators"); }
totalTests = totalTests + 1;
if (testLogicalOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Logical Operators"); }
else { System.out.println("[FAIL] Logical Operators"); }
totalTests = totalTests + 1;
if (testTernaryOperator() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Ternary Operator"); }
else { System.out.println("[FAIL] Ternary Operator"); }
totalTests = totalTests + 1;
if (testIfElse() == true) { passedTests = passedTests + 1; System.out.println("[PASS] If-Else Statements"); }
else { System.out.println("[FAIL] If-Else Statements"); }
totalTests = totalTests + 1;
if (testWhileLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] While Loop"); }
else { System.out.println("[FAIL] While Loop"); }
totalTests = totalTests + 1;
if (testDoWhileLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Do-While Loop"); }
else { System.out.println("[FAIL] Do-While Loop"); }
totalTests = totalTests + 1;
if (testForLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] For Loop"); }
else { System.out.println("[FAIL] For Loop"); }
totalTests = totalTests + 1;
if (testBreakContinue() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Break/Continue"); }
else { System.out.println("[FAIL] Break/Continue"); }
totalTests = totalTests + 1;
if (testSwitchStatement() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Switch Statement"); }
else { System.out.println("[FAIL] Switch Statement"); }
totalTests = totalTests + 1;
if (testArrays() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Arrays"); }
else { System.out.println("[FAIL] Arrays"); }
totalTests = totalTests + 1;
if (testEnhancedFor() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Enhanced For Loop"); }
else { System.out.println("[FAIL] Enhanced For Loop"); }
totalTests = totalTests + 1;
if (testMultiDimArrays() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Multi-Dimensional Arrays"); }
else { System.out.println("[FAIL] Multi-Dimensional Arrays"); }
totalTests = totalTests + 1;
if (testObjectCreation() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Object Creation"); }
else { System.out.println("[FAIL] Object Creation"); }
totalTests = totalTests + 1;
if (testInstanceMethods() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Instance Methods"); }
else { System.out.println("[FAIL] Instance Methods"); }
totalTests = totalTests + 1;
if (testStaticMembers() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Static Members"); }
else { System.out.println("[FAIL] Static Members"); }
totalTests = totalTests + 1;
if (testInheritance() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Inheritance"); }
else { System.out.println("[FAIL] Inheritance"); }
totalTests = totalTests + 1;
if (testMethodOverride() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Method Override"); }
else { System.out.println("[FAIL] Method Override"); }
totalTests = totalTests + 1;
if (testInterfaces() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Interfaces"); }
else { System.out.println("[FAIL] Interfaces"); }
totalTests = totalTests + 1;
if (testInstanceOf() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Instanceof"); }
else { System.out.println("[FAIL] Instanceof"); }
totalTests = totalTests + 1;
if (testRecursion() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Recursion"); }
else { System.out.println("[FAIL] Recursion"); }
totalTests = totalTests + 1;
if (testMathLibrary() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Math Library"); }
else { System.out.println("[FAIL] Math Library"); }
totalTests = totalTests + 1;
if (testStringOperations() == true) { passedTests = passedTests + 1; System.out.println("[PASS] String Operations"); }
else { System.out.println("[FAIL] String Operations"); }
totalTests = totalTests + 1;
if (testArrayList() == true) { passedTests = passedTests + 1; System.out.println("[PASS] ArrayList"); }
else { System.out.println("[FAIL] ArrayList"); }
totalTests = totalTests + 1;
if (testHashMap() == true) { passedTests = passedTests + 1; System.out.println("[PASS] HashMap"); }
else { System.out.println("[FAIL] HashMap"); }
totalTests = totalTests + 1;
if (testExceptions() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Exceptions"); }
else { System.out.println("[FAIL] Exceptions"); }
totalTests = totalTests + 1;
if (testAlgorithms() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Algorithms"); }
else { System.out.println("[FAIL] Algorithms"); }
System.out.println("");
System.out.println("=== RESULTS ===");
System.out.print("Passed: ");
System.out.print(passedTests);
System.out.print(" / ");
System.out.println(totalTests);
if (passedTests == totalTests) {
System.out.println("ALL TESTS PASSED!");
}
return passedTests == totalTests ? 0 : 1;
}
}

View File

@ -2730,7 +2730,7 @@ op_instanceof: {
RavaValue_t val = STACK_POP(stack);
bool result = false;
if (val.type == RAVA_VAL_OBJECT && val.data.object_val) {
result = strcmp(val.data.object_val->class_name, instr->operand.string_value) == 0;
result = _rava_vm_instanceof(vm, val.data.object_val->class_name, instr->operand.string_value);
}
STACK_PUSH(stack, rava_value_boolean(result));
DISPATCH();
@ -4364,7 +4364,7 @@ uf_instanceof: {
if (rava_nanbox_is_object(val)) {
RavaObject_t *obj = rava_nanbox_as_object(val);
if (obj) {
result = strcmp(obj->class_name, instr->operand.string_value) == 0;
result = _rava_vm_instanceof(vm, obj->class_name, instr->operand.string_value);
}
}
UF_PUSH(rava_nanbox_bool(result));

View File

@ -151,6 +151,7 @@ const char* _rava_intern_string(RavaVM_t *vm, const char *str);
void _rava_object_set_field_vm(RavaObject_t *obj, const char *name, RavaValue_t value, RavaVM_t *vm);
RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name);
bool _rava_vm_instanceof(RavaVM_t *vm, const char *object_class, const char *target_class);
RavaMethod_t* _rava_vm_find_method(RavaVM_t *vm, const char *class_name, const char *method_name);
RavaMethod_t* _rava_vm_find_method_cached(RavaVM_t *vm, const char *class_name, const char *method_name);
RavaMethod_t* _rava_vm_find_method_overload(RavaVM_t *vm, const char *class_name, const char *method_name, RavaValue_t *args, size_t arg_count);

View File

@ -19,6 +19,19 @@ RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name) {
return NULL;
}
bool _rava_vm_instanceof(RavaVM_t *vm, const char *object_class, const char *target_class) {
if (!object_class || !target_class) return false;
if (strcmp(object_class, target_class) == 0) return true;
const char *current = object_class;
while (current) {
RavaClass_t *cls = _rava_vm_find_class(vm, current);
if (!cls) break;
if (cls->superclass && strcmp(cls->superclass, target_class) == 0) return true;
current = cls->superclass;
}
return false;
}
static bool _rava_vm_method_signature_matches(RavaMethod_t *method, RavaValue_t *args, size_t arg_count) {
if (!method) return false;
if (method->param_count != arg_count) return false;

View File

@ -1,5 +1,355 @@
#include "test_utils.h"
UnittestTestResult_t* test_simple_object_creation(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_simple_object_creation");
const char *source =
"class Point { int x; int y; }\n"
"public class Test {\n"
" public static int main() {\n"
" Point p = new Point();\n"
" p.x = 10;\n"
" p.y = 20;\n"
" return p.x + p.y;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 30,
"Object creation and field access should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_multiple_objects(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_multiple_objects");
const char *source =
"class Point { int x; int y; }\n"
"public class Test {\n"
" public static int main() {\n"
" Point p1 = new Point();\n"
" Point p2 = new Point();\n"
" p1.x = 5;\n"
" p1.y = 10;\n"
" p2.x = 15;\n"
" p2.y = 20;\n"
" return p1.x + p1.y + p2.x + p2.y;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 50,
"Multiple objects should have independent fields");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_field_update(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_field_update");
const char *source =
"class Counter { int value; }\n"
"public class Test {\n"
" public static int main() {\n"
" Counter c = new Counter();\n"
" c.value = 0;\n"
" c.value = c.value + 1;\n"
" c.value = c.value + 1;\n"
" c.value = c.value + 1;\n"
" return c.value;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 3,
"Object field updates should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_constructor_basic(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_constructor_basic");
const char *source =
"class Box {\n"
" int width;\n"
" int height;\n"
" Box(int w, int h) {\n"
" this.width = w;\n"
" this.height = h;\n"
" }\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Box b = new Box(5, 10);\n"
" return b.width * b.height;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 50,
"Constructor with parameters should initialize fields");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_constructor_chained_operations(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_constructor_chained_operations");
const char *source =
"class Rectangle {\n"
" int width;\n"
" int height;\n"
" int area;\n"
" Rectangle(int w, int h) {\n"
" this.width = w;\n"
" this.height = h;\n"
" this.area = w * h;\n"
" }\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Rectangle r = new Rectangle(6, 7);\n"
" return r.area;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 42,
"Constructor should compute derived values");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_instance_method_on_main_class(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_instance_method_on_main_class");
const char *source =
"public class Test {\n"
" int value;\n"
" Test(int v) { this.value = v; }\n"
" int getValue() { return this.value; }\n"
" void setValue(int v) { this.value = v; }\n"
" public static int main() {\n"
" Test obj = new Test(42);\n"
" int v1 = obj.getValue();\n"
" obj.setValue(100);\n"
" int v2 = obj.getValue();\n"
" return v1 + v2;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 142,
"Instance methods on main class should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_single_instance_method(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_single_instance_method");
const char *source =
"class Counter {\n"
" int value;\n"
" int getValue() { return this.value; }\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Counter c = new Counter();\n"
" c.value = 42;\n"
" return c.getValue();\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 42,
"Single instance method should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_this_keyword_explicit(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_this_keyword_explicit");
const char *source =
"public class Test {\n"
" int x;\n"
" void setX(int x) { this.x = x; }\n"
" int getX() { return this.x; }\n"
" public static int main() {\n"
" Test v = new Test();\n"
" v.setX(99);\n"
" return v.getX();\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 99,
"this keyword should disambiguate field from parameter");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_passed_to_method(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_passed_to_method");
const char *source =
"class Point { int x; int y; }\n"
"public class Test {\n"
" public static int sumPoint(Point p) {\n"
" return p.x + p.y;\n"
" }\n"
" public static int main() {\n"
" Point p = new Point();\n"
" p.x = 15;\n"
" p.y = 25;\n"
" return sumPoint(p);\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 40,
"Objects should be passable to static methods");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_modified_by_method(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_modified_by_method");
const char *source =
"class Point { int x; int y; }\n"
"public class Test {\n"
" public static void doublePoint(Point p) {\n"
" p.x = p.x * 2;\n"
" p.y = p.y * 2;\n"
" }\n"
" public static int main() {\n"
" Point p = new Point();\n"
" p.x = 5;\n"
" p.y = 10;\n"
" doublePoint(p);\n"
" return p.x + p.y;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 30,
"Objects should be modifiable by methods (pass by reference)");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inheritance_field_access(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_inheritance_field_access");
const char *source =
"class Animal { int age; }\n"
"class Dog extends Animal { int barkCount; }\n"
"public class Test {\n"
" public static int main() {\n"
" Dog d = new Dog();\n"
" d.age = 5;\n"
" d.barkCount = 10;\n"
" return d.age + d.barkCount;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 15,
"Subclass should access inherited fields");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inheritance_method_override(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_inheritance_method_override");
const char *source =
"class Animal {\n"
" int speak() { return 1; }\n"
"}\n"
"class Dog extends Animal {\n"
" int speak() { return 2; }\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Dog d = new Dog();\n"
" return d.speak();\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 2,
"Subclass should override parent methods");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_multiple_int_fields(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_multiple_int_fields");
const char *source =
"class Tuple {\n"
" int a;\n"
" int b;\n"
" int c;\n"
" int d;\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Tuple t = new Tuple();\n"
" t.a = 1;\n"
" t.b = 2;\n"
" t.c = 3;\n"
" t.d = 4;\n"
" return t.a + t.b + t.c + t.d;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 10,
"Objects with multiple int fields should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_in_loop(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_in_loop");
const char *source =
"class Counter { int value; }\n"
"public class Test {\n"
" public static int main() {\n"
" Counter c = new Counter();\n"
" c.value = 0;\n"
" for (int i = 0; i < 10; i = i + 1) {\n"
" c.value = c.value + i;\n"
" }\n"
" return c.value;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 45,
"Object fields should be modifiable in loops");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_in_conditional(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_in_conditional");
const char *source =
"class Value { int x; }\n"
"public class Test {\n"
" public static int main() {\n"
" Value v = new Value();\n"
" v.x = 50;\n"
" int result = 0;\n"
" if (v.x > 25) {\n"
" result = v.x * 2;\n"
" } else {\n"
" result = v.x;\n"
" }\n"
" return result;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 100,
"Object fields should work in conditionals");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_simple_object_example(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_simple_object_example");
@ -11,6 +361,28 @@ UnittestTestResult_t* test_simple_object_example(void) {
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_instance_methods_example(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_instance_methods_example");
RAVA_TEST_FILE_EXECUTES(_unittest_result,
"examples/14_InstanceMethods.java",
"InstanceMethods", "main",
"14_InstanceMethods.java should execute successfully");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inheritance_example(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_inheritance_example");
RAVA_TEST_FILE_EXECUTES(_unittest_result,
"examples/17_Inheritance.java",
"Inheritance", "main",
"17_Inheritance.java should execute successfully");
UNITTEST_END_TEST();
}
int main(int argc, char **argv) {
UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
@ -20,11 +392,49 @@ int main(int argc, char **argv) {
config->use_colors = false;
}
UnittestTestSuite_t *suite = unittest_test_suite_create("Object Example Tests");
UnittestTestSuite_t *suite = unittest_test_suite_create("Object Tests");
UnittestTestCase_t *tc = unittest_test_case_create("TestObjects");
unittest_test_case_add_result(tc, test_simple_object_example());
unittest_test_suite_add_test_case(suite, tc);
UnittestTestCase_t *tc_basic = unittest_test_case_create("TestObjectBasics");
unittest_test_case_add_result(tc_basic, test_simple_object_creation());
unittest_test_case_add_result(tc_basic, test_multiple_objects());
unittest_test_case_add_result(tc_basic, test_object_field_update());
unittest_test_suite_add_test_case(suite, tc_basic);
UnittestTestCase_t *tc_constructor = unittest_test_case_create("TestConstructors");
unittest_test_case_add_result(tc_constructor, test_constructor_basic());
unittest_test_case_add_result(tc_constructor, test_constructor_chained_operations());
unittest_test_suite_add_test_case(suite, tc_constructor);
UnittestTestCase_t *tc_methods = unittest_test_case_create("TestInstanceMethods");
unittest_test_case_add_result(tc_methods, test_instance_method_on_main_class());
unittest_test_case_add_result(tc_methods, test_single_instance_method());
unittest_test_case_add_result(tc_methods, test_this_keyword_explicit());
unittest_test_suite_add_test_case(suite, tc_methods);
UnittestTestCase_t *tc_passing = unittest_test_case_create("TestObjectPassing");
unittest_test_case_add_result(tc_passing, test_object_passed_to_method());
unittest_test_case_add_result(tc_passing, test_object_modified_by_method());
unittest_test_suite_add_test_case(suite, tc_passing);
UnittestTestCase_t *tc_inheritance = unittest_test_case_create("TestInheritance");
unittest_test_case_add_result(tc_inheritance, test_inheritance_field_access());
unittest_test_case_add_result(tc_inheritance, test_inheritance_method_override());
unittest_test_suite_add_test_case(suite, tc_inheritance);
UnittestTestCase_t *tc_types = unittest_test_case_create("TestObjectTypes");
unittest_test_case_add_result(tc_types, test_multiple_int_fields());
unittest_test_suite_add_test_case(suite, tc_types);
UnittestTestCase_t *tc_advanced = unittest_test_case_create("TestAdvancedObjects");
unittest_test_case_add_result(tc_advanced, test_object_in_loop());
unittest_test_case_add_result(tc_advanced, test_object_in_conditional());
unittest_test_suite_add_test_case(suite, tc_advanced);
UnittestTestCase_t *tc_examples = unittest_test_case_create("TestExamples");
unittest_test_case_add_result(tc_examples, test_simple_object_example());
unittest_test_case_add_result(tc_examples, test_instance_methods_example());
unittest_test_case_add_result(tc_examples, test_inheritance_example());
unittest_test_suite_add_test_case(suite, tc_examples);
unittest_generate_report(suite, config);