#include "cx/test.h"
#include "cx/iterator.h"
CX_TEST(test_iterator_create) {
unsigned array[
20];
size_t size = cx_nmemb(array);
for (
unsigned i =
0 ; i < size ; i++) array[i] = i;
CxIterator iter = cxIterator(array,
sizeof(
unsigned), size, true);
CX_TEST_DO {
CX_TEST_ASSERT(iter.index ==
0);
CX_TEST_ASSERT(iter.elem_size ==
sizeof(
unsigned));
CX_TEST_ASSERT(iter.elem_count == size);
CX_TEST_ASSERT(iter.src_handle == array);
CX_TEST_ASSERT(iter.elem_handle == &array[
0]);
CX_TEST_ASSERT(cxIteratorValid(iter));
}
}
CX_TEST(test_iterator_create_null) {
CxIterator iter = cxIterator(
NULL,
sizeof(
unsigned),
47, true);
CX_TEST_DO {
CX_TEST_ASSERT(iter.index ==
0);
CX_TEST_ASSERT(iter.elem_size ==
sizeof(
unsigned));
CX_TEST_ASSERT(iter.elem_count ==
0);
CX_TEST_ASSERT(iter.src_handle ==
NULL);
CX_TEST_ASSERT(iter.elem_handle ==
NULL);
CX_TEST_ASSERT(!cxIteratorValid(iter));
}
}
CX_TEST(test_iterator_iterate) {
unsigned array[
20];
size_t size = cx_nmemb(array);
for (
unsigned i =
0 ; i < size ; i++) array[i] = i;
CxIterator iter = cxIterator(array,
sizeof(
unsigned), size, true);
CX_TEST_DO {
CX_TEST_ASSERT(iter.elem_size ==
sizeof(
unsigned));
CX_TEST_ASSERT(iter.elem_count == size);
CX_TEST_ASSERT(iter.src_handle == array);
unsigned expected =
0;
cx_foreach(
unsigned *, e, iter) {
CX_TEST_ASSERT(iter.index == expected);
CX_TEST_ASSERT(*e == expected);
CX_TEST_ASSERT(iter.elem_handle == &array[expected]);
expected++;
}
CX_TEST_ASSERT(expected == size);
}
}
CX_TEST(test_iterator_iterate_pointers) {
unsigned array[
20];
unsigned* ptr_array[
20];
size_t size = cx_nmemb(array);
for (
unsigned i =
0 ; i < size ; i++) {
array[i] =
3*i;
ptr_array[i] = &array[i];
}
CxIterator iter = cxIteratorPtr(ptr_array, size, true);
CX_TEST_DO {
CX_TEST_ASSERT(iter.elem_size ==
sizeof(
void*));
CX_TEST_ASSERT(iter.elem_count == size);
CX_TEST_ASSERT(iter.src_handle == ptr_array);
unsigned idx =
0;
cx_foreach(
unsigned *, e, iter) {
CX_TEST_ASSERT(iter.index == idx);
CX_TEST_ASSERT(*e == array[idx]);
CX_TEST_ASSERT(iter.elem_handle == &ptr_array[idx]);
idx++;
}
CX_TEST_ASSERT(idx == size);
}
}
CX_TEST(test_iterator_with_slow_remove) {
unsigned array[
20];
size_t size = cx_nmemb(array);
for (
unsigned i =
0 ; i < size ; i++) array[i] = i;
size_t elem_counts[] = {
20,
20,
19,
19,
18,
18,
17,
17,
16,
16,
15,
15,
14,
14,
13,
13,
12,
12,
11,
11
};
size_t indices[] = {
0,
1,
1,
2,
2,
3,
3,
4,
4,
5,
5,
6,
6,
7,
7,
8,
8,
9,
9,
10
};
unsigned expected_result[] = {
0,
2,
4,
6,
8,
10,
12,
14,
16,
18
};
CxIterator iter = cxIterator(array,
sizeof(
unsigned), size, true);
CX_TEST_DO {
unsigned expected =
0;
cx_foreach(
unsigned *, e, iter) {
CX_TEST_ASSERT(*e == expected);
CX_TEST_ASSERT(iter.index == indices[expected]);
CX_TEST_ASSERT(iter.elem_size ==
sizeof(
unsigned));
CX_TEST_ASSERT(iter.elem_count == elem_counts[expected]);
CX_TEST_ASSERT(iter.src_handle == array);
CX_TEST_ASSERT(iter.elem_handle == &array[indices[expected]]);
expected++;
if (expected %
2 ==
0) {
cxIteratorFlagRemoval(iter);
}
}
CX_TEST_ASSERT(expected ==
20);
CX_TEST_ASSERT(iter.index ==
10);
CX_TEST_ASSERT(iter.elem_count ==
10);
for (
unsigned i =
0 ; i <
9 ; i++) {
CX_TEST_ASSERT(array[i] == expected_result[i]);
}
}
}
CX_TEST(test_iterator_with_fast_remove) {
unsigned array[
20];
size_t size = cx_nmemb(array);
for (
unsigned i =
0 ; i < size ; i++) array[i] = i;
size_t elem_counts[] = {
20,
20,
19,
19,
18,
18,
17,
17,
16,
16,
15,
15,
14,
14,
13,
13,
12,
12,
11,
11
};
size_t indices[] = {
0,
1,
1,
2,
2,
3,
3,
4,
4,
5,
5,
6,
6,
7,
7,
8,
8,
9,
9,
10
};
unsigned expected_result[] = {
0,
19,
18,
17,
16,
15,
14,
13,
12,
11
};
unsigned expected_visits[] = {
0,
1,
19,
2,
18,
3,
17,
4,
16,
5,
15,
6,
14,
7,
13,
8,
12,
9,
11,
10
};
CxIterator iter = cxIterator(array,
sizeof(
unsigned), size, false);
CX_TEST_DO {
unsigned expected =
0;
cx_foreach(
unsigned *, e, iter) {
CX_TEST_ASSERT(*e == expected_visits[expected]);
CX_TEST_ASSERT(iter.index == indices[expected]);
CX_TEST_ASSERT(iter.elem_size ==
sizeof(
unsigned));
CX_TEST_ASSERT(iter.elem_count == elem_counts[expected]);
CX_TEST_ASSERT(iter.src_handle == array);
CX_TEST_ASSERT(iter.elem_handle == &array[indices[expected]]);
expected++;
if (expected %
2 ==
0) {
cxIteratorFlagRemoval(iter);
}
}
CX_TEST_ASSERT(expected ==
20);
CX_TEST_ASSERT(iter.index ==
10);
CX_TEST_ASSERT(iter.elem_count ==
10);
for (
unsigned i =
0 ; i <
9 ; i++) {
CX_TEST_ASSERT(array[i] == expected_result[i]);
}
}
}
CxTestSuite *cx_test_suite_iterator(
void) {
CxTestSuite *suite = cx_test_suite_new(
"iterator");
cx_test_register(suite, test_iterator_create);
cx_test_register(suite, test_iterator_iterate);
cx_test_register(suite, test_iterator_iterate_pointers);
cx_test_register(suite, test_iterator_with_slow_remove);
cx_test_register(suite, test_iterator_with_fast_remove);
return suite;
}