mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-06 06:38:20 +00:00
Add tests
Add tests for `core:container/xar` and `core:container/handle_map` (static + dynamic).
This commit is contained in:
@@ -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
|
||||
|
||||
141
tests/core/container/test_core_handle_map.odin
Normal file
141
tests/core/container/test_core_handle_map.odin
Normal 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)
|
||||
}
|
||||
39
tests/core/container/test_core_xar.odin
Normal file
39
tests/core/container/test_core_xar.odin
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user