
void TestArena() {
    Arena arena = {};

    {
        void *value = PushSize(&arena, sizeof(int));
        Assert(value == 0);
    }

    InitArena(&arena, MiB(256) + PAGE_SIZE);
    Assert(arena.data && arena.reserve);

    {
        uint8_t *data       = (uint8_t *)PushSize(&arena, sizeof(uint8_t));
        *data               = 10;
        data[PAGE_SIZE - 1] = 0;
        // data[PAGE_SIZE] = 0;

        Assert(*data == 10);
        Assert(arena.len == 1);
        Assert(arena.commit == PAGE_SIZE);

        uint8_t *d2 = (uint8_t *)PushSize(&arena, sizeof(uint8_t));
        *d2         = 20;
        Assert(arena.len == 9);
    }

    {
        int *alot_of_data = (int *)PushSize(&arena, MiB(256));

        for (int i = 0; i < 1024 * 1024 * 1; i += 1) {
            alot_of_data[i] = i;
        }
        for (int i = 0; i < 1024 * 1024 * 1; i += 1) {
            Assert(alot_of_data[i] == i);
        }
        Assert(arena.len == 16 + MiB(256));
        Assert(arena.commit == AlignUp(16 + MiB(256), PAGE_SIZE));
    }

    {
        void *result = PushSize(&arena, PAGE_SIZE - 16);
        Assert(result);
        Assert(arena.commit == arena.reserve);
        Assert(arena.commit == arena.len);

        void *v = PushSize(&arena, 2423);
        Assert(v == NULL);
    }

    Release(&arena);

    {
        Arena *arena = AllocArena();
        int   *a     = (int *)PushSize(arena, 1024);
        for (int i = 0; i < 64; i += 1) a[i] = 0;
        Clear(arena);
        a = (int *)PushSize(arena, 1024);
        for (int i = 0; i < 64; i += 1) a[i] = 0;
        Release(arena);
    }
}

void TestArray() {
    Array<int> arr = {};
    defer { arr.dealloc(); };

    for (int i = 0; i < 32; i += 1) arr.add(i);

    int i = 31;
    For(arr.reverse_iter()) {
        defer { arr.unordered_remove(it); };
        Assert(i-- == it);
    }
}

void RunTests() {
    TestArena();
    TestArray();
}