summaryrefslogtreecommitdiff
path: root/tests/std/test_vec.zc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/std/test_vec.zc')
-rw-r--r--tests/std/test_vec.zc168
1 files changed, 168 insertions, 0 deletions
diff --git a/tests/std/test_vec.zc b/tests/std/test_vec.zc
new file mode 100644
index 0000000..4787e06
--- /dev/null
+++ b/tests/std/test_vec.zc
@@ -0,0 +1,168 @@
+import "std/vec.zc"
+import "std/io.zc"
+
+// Helper for assertions
+fn assert_true(cond: bool, msg: char*) {
+ if (!cond) {
+ print "Assertion failed: {msg}\n";
+ exit(1);
+ }
+}
+
+fn assert_eq(a: int, b: int, msg: char*) {
+ if (a != b) {
+ print "Assertion failed: {msg} (Expected {a}, Got {b})\n";
+ exit(1);
+ }
+}
+
+@derive(Eq, Clone)
+struct Point {
+ x: int;
+ y: int;
+}
+
+test "Vec Basics (Construction, Push, Pop, Access)" {
+ print "Testing Vec basics...\n";
+ var v = Vec<int>::new();
+ assert_eq(v.len, 0, "Initial len");
+ assert_eq(v.cap, 0, "Initial cap");
+
+ v.push(10);
+ v.push(20);
+ v.push(30);
+
+ assert_eq(v.len, 3, "Len after push");
+ assert_eq(v.get(0), 10, "get(0)");
+ assert_eq(v.get(1), 20, "get(1)");
+ assert_eq(v.get(2), 30, "get(2)");
+ assert_eq(v.last(), 30, "last()");
+ assert_eq(v.first(), 10, "first()");
+
+ assert_eq(v.pop(), 30, "pop()");
+ assert_eq(v.len, 2, "Len after pop");
+
+ v.set(0, 99);
+ assert_eq(v.get(0), 99, "set()");
+
+ // Explicit clean up check (safe idempotent free)
+ v.free();
+ assert_eq(v.len, 0, "Len after free");
+}
+
+test "Vec Capacity and Allocation" {
+ print "Testing Vec capacity...\n";
+ // with_capacity
+ var v1 = Vec<int>::with_capacity(10);
+ assert_eq(v1.len, 0, "with_capacity len");
+ assert_eq(v1.cap, 10, "with_capacity cap");
+ v1.push(1);
+ assert_eq(v1.cap, 10, "Cap should not change yet");
+
+ // Implicit grow
+ var v2 = Vec<int>::new();
+ // Force grow logic: 0 -> 8 -> 16...
+ var i = 0;
+ while i < 9 {
+ v2.push(i);
+ i = i + 1;
+ }
+ assert_true(v2.cap >= 9, "Capacity grew to hold 9 items");
+ // Expected strategy: 0 -> 8 -> 16
+ assert_eq(v2.cap, 16, "Growth strategy check (8->16)");
+}
+
+test "Vec Modification (Insert, Remove, Clear)" {
+ print "Testing Vec modification...\n";
+ var v = Vec<int>::new();
+ v.push(1);
+ v.push(3);
+
+ v.insert(1, 2); // [1, 2, 3]
+ assert_eq(v.get(1), 2, "insert middle");
+ assert_eq(v.len, 3, "insert len");
+
+ var val = v.remove(0); // [2, 3]
+ assert_eq(val, 1, "remove return");
+ assert_eq(v.get(0), 2, "remove shift");
+ assert_eq(v.len, 2, "remove len");
+
+ v.clear();
+ assert_eq(v.len, 0, "clear len");
+ assert_true(v.is_empty(), "is_empty");
+}
+
+test "Vec Extensions (pop_opt)" {
+ print "Testing Vec extensions...\n";
+ var v = Vec<int>::new();
+ v.push(42);
+
+ var opt = v.pop_opt();
+ assert_true(!opt.is_none(), "pop_opt some");
+ assert_eq(opt.unwrap(), 42, "pop_opt val");
+
+ var empty = v.pop_opt();
+ assert_true(empty.is_none(), "pop_opt none");
+}
+
+test "Vec Iteration (Reference and Value)" {
+ print "Testing Vec iteration...\n";
+ var v = Vec<Point>::new();
+ v.push(Point { x: 10, y: 10 });
+ v.push(Point { x: 20, y: 20 });
+
+ // 1. Value Iteration
+ var sum_val = 0;
+ for p in v {
+ sum_val = sum_val + p.x;
+ }
+ assert_eq(sum_val, 30, "Value iteration sum");
+
+ // 2. Reference Iteration (Sugar &v) - In-place modification
+ for p in &v {
+ (*p).x = (*p).x + 1;
+ }
+ assert_eq(v.get(0).x, 11, "Ref iter mod 0");
+ assert_eq(v.get(1).x, 21, "Ref iter mod 1");
+
+ // 3. Explicit iter_ref()
+ for p in v.iter_ref() {
+ (*p).y = (*p).y + 2;
+ }
+ assert_eq(v.get(0).y, 12, "Explicit ref iter mod 0");
+ assert_eq(v.get(1).y, 22, "Explicit ref iter mod 1");
+}
+
+test "Vec Clone and Drop" {
+ print "Testing Vec clone and drop...\n";
+ var v = Vec<int>::new();
+ v.push(100);
+ v.push(200);
+
+ var v2 = v.clone();
+ assert_eq(v2.len, 2, "Clone len");
+ assert_eq(v2.get(0), 100, "Clone val 0");
+
+ v.set(0, 999);
+ assert_eq(v.get(0), 999, "Original mod");
+ assert_eq(v2.get(0), 100, "Clone independent");
+
+ // Drop is implicit at end of scope.
+ // We trust valgrind/previous verification for actual memory free.
+ // This test ensures no double-free crashes or logic errors.
+}
+
+test "Vec Utils (Reverse, Contains)" {
+ print "Testing Vec utils...\n";
+ var v = Vec<int>::new();
+ v.push(1);
+ v.push(2);
+ v.push(3);
+
+ v.reverse(); // [3, 2, 1]
+ assert_eq(v.get(0), 3, "Reverse 0");
+ assert_eq(v.get(2), 1, "Reverse 2");
+
+ assert_true(v.contains(2), "Contains true");
+ assert_true(!v.contains(99), "Contains false");
+}