Add tests

Add tests for `core:container/xar` and `core:container/handle_map` (static + dynamic).
This commit is contained in:
Jeroen van Rijn
2026-02-15 14:54:31 +01:00
parent c66059dd03
commit 03a8526cf0
4 changed files with 185 additions and 5 deletions

View File

@@ -386,7 +386,7 @@ Attempts to add the given element at the beginning.
This operation assumes that the small-array is not empty.
Note: Performing this operation will cause pointers obtained
through get_ptr(_save) to reference incorrect elements.
through get_ptr(_safe) to reference incorrect elements.
**Inputs**
- `a`: A pointer to the small-array
@@ -466,7 +466,7 @@ Removes and returns the first element of the small-array.
This operation assumes that the small-array is not empty.
Note: Performing this operation will cause pointers obtained
through get_ptr(_save) to reference incorrect elements.
through get_ptr(_safe) to reference incorrect elements.
**Inputs**
- `a`: A pointer to the small-array
@@ -542,7 +542,7 @@ Attempts to remove and return the first element of the small array.
Unlike `pop_front`, it does not assume that the array is non-empty.
Note: Performing this operation will cause pointers obtained
through get_ptr(_save) to reference incorrect elements.
through get_ptr(_safe) to reference incorrect elements.
**Inputs**
- `a`: A pointer to the small-array
@@ -616,7 +616,7 @@ consume :: proc "odin" (a: ^$A/Small_Array($N, $T), count: int, loc := #caller_l
Removes the element at the specified index while retaining order.
Note: Performing this operation will cause pointers obtained
through get_ptr(_save) to reference incorrect elements.
through get_ptr(_safe) to reference incorrect elements.
**Inputs**
- `a`: A pointer to the small-array
@@ -754,7 +754,7 @@ push_back_elems :: proc "contextless" (a: ^$A/Small_Array($N, $T), items: ..T) -
Tries to insert an element at the specified position.
Note: Performing this operation will cause pointers obtained
through get_ptr(_save) to reference incorrect elements.
through get_ptr(_safe) to reference incorrect elements.
**Inputs**
- `a`: A pointer to the small-array

View File

@@ -0,0 +1,141 @@
package test_core_container
import hm "core:container/handle_map"
import "core:container/xar"
import "core:testing"
Item :: struct {
v: int,
p: ^Item,
handle: hm.Handle32,
my_idx: u16,
}
@test
test_dynamic_handle_map :: proc(t: ^testing.T) {
dhm: hm.Dynamic_Handle_Map(Item, hm.Handle32)
hm.dynamic_init(&dhm, context.allocator)
defer hm.dynamic_destroy(&dhm)
items: [dynamic]Item
defer delete(items)
N :: 512
for i in 1..=N {
h, add_err := hm.dynamic_add(&dhm, Item{v = i * 10 + 1})
assert(add_err == nil)
item := hm.dynamic_get(&dhm, h)
item.handle = h
item.p = item
item.my_idx = h.idx
append(&items, item^)
}
testing.expect(t, hm.dynamic_len(dhm) == N)
testing.expect(t, hm.dynamic_cap(dhm) >= N)
for v in items {
item := hm.dynamic_get(&dhm, v.handle)
assert(item^ == v)
// Remove half of the items
if item.handle.idx & 1 == 0 {
found, found_err := hm.dynamic_remove(&dhm, v.handle)
assert(found && found_err == nil)
// These removed handles should no longer be valid
assert(!hm.dynamic_is_valid(&dhm, v.handle))
} else {
// Non-removed handles should still be valid
assert(hm.dynamic_is_valid(&dhm, v.handle))
}
}
testing.expect(t, hm.dynamic_len(dhm) == N / 2)
testing.expect(t, hm.dynamic_cap(dhm) >= N / 2)
testing.expect(t, xar.len(dhm.unused_items) == N / 2)
it := hm.dynamic_iterator_make(&dhm)
for v, handle in hm.iterate(&it) {
assert(v.handle.idx & 1 == 1)
assert(hm.dynamic_is_valid(&dhm, handle))
item := hm.dynamic_get(&dhm, handle)
assert(item.my_idx == v.handle.idx)
}
for i in 1..=N / 2 {
h, add_err := hm.dynamic_add(&dhm, Item{v = i * 10 + 1})
assert(add_err == nil)
assert(h.gen == 2)
}
hm.dynamic_clear(&dhm)
testing.expect(t, hm.dynamic_len(dhm) == 0)
testing.expect(t, hm.dynamic_cap(dhm) >= N)
}
test_static_handle_map :: proc(t: ^testing.T) {
N :: 512
shm: hm.Static_Handle_Map(N, Item, hm.Handle32)
items: [dynamic]Item
defer delete(items)
for i in 1..=N {
h, add_ok := hm.static_add(&shm, Item{v = i * 10 + 1})
assert(add_ok)
item := hm.static_get(&shm, h)
item.handle = h
item.p = item
item.my_idx = h.idx
append(&items, item^)
}
testing.expect(t, hm.static_len(shm) == N)
testing.expect(t, hm.static_cap(shm) >= N)
for v in items {
item := hm.static_get(&shm, v.handle)
assert(item^ == v)
// Remove half of the items
if item.handle.idx & 1 == 0 {
assert(hm.static_remove(&shm, v.handle))
// These removed handles should no longer be valid
assert(!hm.static_is_valid(shm, v.handle))
} else {
// Non-removed handles should still be valid
assert(hm.static_is_valid(shm, v.handle))
}
}
testing.expect(t, hm.static_len(shm) == N / 2)
testing.expect(t, hm.static_cap(shm) >= N / 2)
it := hm.static_iterator_make(&shm)
for v, handle in hm.iterate(&it) {
assert(v.handle.idx & 1 == 1)
assert(hm.static_is_valid(shm, handle))
item := hm.static_get(&shm, handle)
assert(item.my_idx == v.handle.idx)
}
for i in 1..=N / 2 {
h, add_ok := hm.static_add(&shm, Item{v = i * 10 + 1})
assert(add_ok)
assert(h.gen == 2)
}
hm.static_clear(&shm)
testing.expect(t, hm.static_len(shm) == 0)
testing.expect(t, hm.static_cap(shm) == N)
}

View File

@@ -0,0 +1,39 @@
package test_core_container
import "core:container/xar"
import "core:testing"
Value :: struct {
v: int,
p: ^int,
}
@test
test_xar_pointer_stability :: proc(t: ^testing.T) {
x: xar.Array(int, 4)
defer xar.destroy(&x)
values: [dynamic]Value
defer delete(values)
N :: 512
for i in 1..=N {
v := i * 10 + 1
xar.push_back(&x, v)
ptr := xar.get_ptr(&x, i - 1)
append(&values, Value{v = v, p = ptr})
}
assert(xar.len(x) == N)
assert(xar.cap(x) >= N)
for value, i in values {
ptr := xar.get_ptr(&x, i)
assert(ptr == value.p)
assert(ptr^ == value.v)
}
xar.clear(&x)
assert(xar.len(x) == 0)
assert(xar.cap(x) >= N)
}