diff options
| author | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-14 23:59:54 +0000 |
|---|---|---|
| committer | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-14 23:59:54 +0000 |
| commit | dcfdc053cb5f9fb4d5eac0a2233c75126b7a8188 (patch) | |
| tree | f34f30b382fa22d6fd0af46875a5b4b26d00feff /tests/memory | |
| parent | a918df69269a39ef7350a645b5db025d66ecb18a (diff) | |
Added some of the tests.
Diffstat (limited to 'tests/memory')
| -rw-r--r-- | tests/memory/test_memory_safety.zc | 217 | ||||
| -rw-r--r-- | tests/memory/test_unsafe.zc | 56 |
2 files changed, 273 insertions, 0 deletions
diff --git a/tests/memory/test_memory_safety.zc b/tests/memory/test_memory_safety.zc new file mode 100644 index 0000000..5cec2db --- /dev/null +++ b/tests/memory/test_memory_safety.zc @@ -0,0 +1,217 @@ + +import "std/mem.zc" + +// --- Globals --- +var DROP_COUNT = 0; + +// --- Structs & Helpers --- + +trait Drop { + fn drop(self); +} + +struct Resource { + id: int; +} + +impl Drop for Resource { + fn drop(self) { + println "Dropping Resource {self.id}"; + DROP_COUNT = DROP_COUNT + 1; + } +} + +fn create_resource(id: int) { + var r = Resource{id: id}; + println "Created Resource {r.id}"; +} + +struct Point { + x: int; + y: int; +} + +fn distance(p1: Point, p2: Point) -> int { + var dx = p2.x - p1.x; + var dy = p2.y - p1.y; + return dx * dx + dy * dy; +} + +fn accumulate(start: int, count: int) -> int { + var mut sum = start; + var mut i = 0; + while (i < count) { + sum += i; + i++; + } + return sum; +} + +fn process_point(p: Point) -> Point { + var result = Point { x: p.x * 2, y: p.y * 2 }; + return result; +} + +fn counter_immut() { + var mut count = 0; + { + var mut inner = 10; + inner = inner + 5; + count = count + inner; + } +} + +struct Permissions { + mask: U8; +} + +impl Permissions { + fn new(m: U8) -> Permissions { + return Permissions { mask: m }; + } + fn bitor(self, other: Permissions) -> Permissions { + return Permissions { mask: self.mask | other.mask }; + } + fn has(self, flag: U8) -> U8 { + return (self.mask & flag) == flag; + } +} + +fn get_resource() -> int { + println "resource opened"; + return 42; +} + +fn release_resource(id: int) { + if (id == 42) println "resource 42 released"; + else println "resource released (unknown)"; +} + +fn test_defer_logic() { + println "start test"; + var x = get_resource() defer release_resource(it); + println "using resource {x}"; +} + + +test "test_alloc" { + "Testing alloc<T>..."; + + var p = alloc<int>(); + *p = 42; + f" alloc<int>(): {*p}"; + assert(*p == 42, "alloc failed"); + free(p); + + var arr = alloc_n<int>(5); + for var i = 0; i < 5; i++ { + arr[i] = i * 10; + } + f" alloc_n<int>(5): [{arr[0]}, {arr[1]}, {arr[2]}, {arr[3]}, {arr[4]}]"; + free(arr); + + " ✓ alloc works!"; +} + +test "test_box" { + "Testing Box<T>..."; + var b = Box<int>::new(); + *b.get() = 100; + var val = *b.get(); + f" Box value: {val}"; + assert(val == 100, "Box failed"); + b.free(); + " ✓ Box works!"; +} + +test "test_slice" { + "Testing Slice<T>..."; + var data: int[5] = [1, 2, 3, 4, 5]; + var s = Slice<int>::new(&data[0], 5); + f" Slice len: {(int)s.len}"; + var v2 = s.get(2); + f" Slice[2]: {v2}"; + assert(v2 == 3, "Slice get failed"); + s.set(0, 99); + var v0 = s.get(0); + f" After set: Slice[0] = {v0}"; + assert(v0 == 99, "Slice set failed"); + " ✓ Slice works!"; +} + +test "test_swap" { + "Testing swap<T>..."; + var a = 10; + var b = 20; + f" Before: a={a}, b={b}"; + swap<int>(&a, &b); + f" After: a={a}, b={b}"; + assert(a == 20 && b == 10, "swap failed"); + " ✓ swap works!"; +} + +test "test_autofree" { + println "Testing autofree..."; + { + autofree var p = malloc(1024); + if (p == NULL) { eprintln "Malloc failed!"; } + strcpy(p, "Auto-freed string"); + print f"Allocated: {p}"; println ""; + } + println "Exited block successfully (hopefully freed)"; + { + autofree var p1 = malloc(10); + autofree var p2 = malloc(20); + } +} + +test "test_raii_drop" { + DROP_COUNT = 0; + "Entering scope..."; + create_resource(1); + "Exited scope."; + assert(DROP_COUNT == 1, "Expected Drop to be called once"); + { + var r2 = Resource{id: 2}; + var r3 = Resource{id: 3}; + } + assert(DROP_COUNT == 3, "Expected 3 total drops"); +} + +test "test_immutable" { + var p1 = Point { x: 0, y: 0 }; + var p2 = Point { x: 3, y: 4 }; + var dist = distance(p1, p2); + "Distance: {dist}"; + var sum = accumulate(10, 5); + "Accumulate: {sum}"; + var p3 = process_point(p1); + "Processed: ({p3.x}, {p3.y})"; + counter_immut(); +} + +test "test_permissions" { + const READ : U8 = 0b100; + const WRITE : U8 = 0b010; + const EXEC : U8 = 0b001; + + var p1 = Permissions::new(READ); + "Start: {p1.mask} (Read)"; + + var p2 = Permissions::new(WRITE); + var p_rw = p1 | p2; + "Combined: {p_rw.mask} (Read + Write)"; + + if (p_rw.has(EXEC)) { " > Has Execute access"; } + else { " > No Execute access"; } + + if (p_rw.has(READ)) { " > Has Read access"; } + + var p_all = p_rw | Permissions::new(EXEC); + "Final: {p_all.mask} (All)"; +} + +test "test_value_defer" { + test_defer_logic(); + println "end test"; +} diff --git a/tests/memory/test_unsafe.zc b/tests/memory/test_unsafe.zc new file mode 100644 index 0000000..126404a --- /dev/null +++ b/tests/memory/test_unsafe.zc @@ -0,0 +1,56 @@ + +raw { + #define MY_C_CONST 12345 + int legacy_add(int a, int b) { + return a + b + MY_C_CONST; + } +} + +extern fn legacy_add(a: int, b: int) -> int; + +fn process_arrays(n: int, a: restrict int*, b: restrict int*, out: restrict int*) { + for (var i = 0; i < n; i = i + 1) { + out[i] = a[i] + b[i]; + } +} + +fn counter() -> int { + static var count = 0; + count = count + 1; + return count; +} + +test "test_raw" { + println "Testing Raw C Embedding..."; + var res = legacy_add(10, 20); + // Expected: 10 + 20 + 12345 = 12375 + assert(res == 12375, "Raw C Code failed"); + println " Raw C Code: Success (Result: {res})"; +} + +test "test_restrict" { + var a: int[10]; + var b: int[10]; + var c: int[10]; + + for (var i = 0; i < 10; i = i + 1) { + a[i] = i; + b[i] = i * 2; + } + + process_arrays(10, a, b, c); + + for (var i = 0; i < 10; i = i + 1) { + assert(c[i] == i * 3, "Restrict test failed"); + } +} + +test "test_static_local" { + var a = counter(); // 1 + var b = counter(); // 2 + var c = counter(); // 3 + + assert a == 1; + assert b == 2; + assert c == 3; +} |
