tests/test_iterator.c

Sun, 15 Dec 2024 11:11:16 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 15 Dec 2024 11:11:16 +0100
changeset 1011
838b096c1d08
parent 951
8f6d6556380a
permissions
-rw-r--r--

and changelog entry for issue #523

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#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);
    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.c == 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);
    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.c == 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);
    CX_TEST_DO {
        unsigned expected = 0;
        cx_foreach(unsigned *, e, iter) {
            CX_TEST_ASSERT(iter.index == expected);
            CX_TEST_ASSERT(*e == expected);
            CX_TEST_ASSERT(iter.elem_size == sizeof(unsigned));
            CX_TEST_ASSERT(iter.elem_count == size);
            CX_TEST_ASSERT(iter.src_handle.c == array);
            CX_TEST_ASSERT(iter.elem_handle == &array[expected]);
            expected++;
        }
        CX_TEST_ASSERT(expected == 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 = cxMutIterator(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.m == 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 = cxMutIterator(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.m == 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_with_slow_remove);
    cx_test_register(suite, test_iterator_with_fast_remove);

    return suite;
}

mercurial