static void test1(const char *pcszDesc, T3 paTestData[], size_t cTestItems)
{
    RTTestISubF("%s with size of %u (items=%u)", pcszDesc, sizeof(T1), cTestItems);

    /*
     * Construction
     */

    /* Create a test list */
    L<T1, T2> testList;

    const size_t defCap = L<T1, T2>::kDefaultCapacity;
    RTTESTI_CHECK(testList.isEmpty());
    RTTESTI_CHECK(testList.size()     == 0);
    RTTESTI_CHECK(testList.capacity() == defCap);

    /*
     * Adding
     */

    /* Add the second half of the test data */
    size_t cAdded = 1;

    /* Start adding the second half of our test list */
    for (size_t i = cTestItems / 2; i < cTestItems; ++i, ++cAdded)
    {
        testList.append(paTestData[i]);
        RTTESTI_CHECK_RETV(testList.size()    == cAdded);
        RTTESTI_CHECK(testList.at(0)          == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList[0]             == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList.first()        == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[i]);
        RTTESTI_CHECK(testList[cAdded - 1]    == paTestData[i]);
        RTTESTI_CHECK(testList.last()         == paTestData[i]);
    }

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList.size()        == cTestItems / 2);
    RTTESTI_CHECK_RETV(testList.isEmpty()     == false);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Start prepending the first half of our test list. Iterate reverse to get
     * the correct sorting back. */
    for (size_t i = cTestItems / 2; i > 0; --i, ++cAdded)
    {
        testList.prepend(paTestData[i - 1]);
        RTTESTI_CHECK_RETV(testList.size()    == cAdded);
        RTTESTI_CHECK(testList.at(0)          == paTestData[i - 1]);
        RTTESTI_CHECK(testList[0]             == paTestData[i - 1]);
        RTTESTI_CHECK(testList.first()        == paTestData[i - 1]);
        RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[cTestItems - 1]);
        RTTESTI_CHECK(testList[cAdded - 1]    == paTestData[cTestItems - 1]);
        RTTESTI_CHECK(testList.last()         == paTestData[cTestItems - 1]);
    }

    /* Check that all is correctly prepended. */
    RTTESTI_CHECK_RETV(testList.size()        == cTestItems);
    RTTESTI_CHECK_RETV(testList.isEmpty()     == false);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[i]);

    /*
     * Contains
     */
    L<T1, T2> testList2;

    /* Check full list. */
    RTTESTI_CHECK( testList.contains(paTestData[0]));
    RTTESTI_CHECK( testList.contains(paTestData[cTestItems / 2]));
    RTTESTI_CHECK( testList.contains(paTestData[cTestItems - 1]));
    RTTESTI_CHECK(!testList.contains(T1()));
    /* Check empty list. */
    RTTESTI_CHECK(!testList2.contains(paTestData[0]));
    RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems / 2]));
    RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems - 1]));
    RTTESTI_CHECK(!testList2.contains(T1()));

    /*
     * Copy operator
     */
    L<T1, T2> testList3(testList);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i]);

    /*
     * "=" operator
     */
    L<T1, T2> testList4;
    testList4 = testList;

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList4.size() == cTestItems);
    for (size_t i = 0; i < testList4.size(); ++i)
        RTTESTI_CHECK(testList4.at(i) == paTestData[i]);

    /*
     * Append list
     */
    testList3.append(testList4);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /*
     * Prepend list
     */
    testList3.prepend(testList4);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 3);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /*
     * "value" method
     */
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.value(i)       == paTestData[i % cTestItems]);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.value(i, T1()) == paTestData[i % cTestItems]);
    RTTESTI_CHECK(testList3.value(testList3.size() + 1) == T1());       /* Invalid index */
    RTTESTI_CHECK(testList3.value(testList3.size() + 1, T1()) == T1()); /* Invalid index */

    /*
     * operator[] (reading)
     */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[i]);

    /*
     * operator[] (writing)
     *
     * Replace with inverted array.
     */
    for (size_t i = 0; i < cTestItems; ++i)
        testList[i] = paTestData[cTestItems - i - 1];
    RTTESTI_CHECK_RETV(testList.size() == cTestItems);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[cTestItems - i - 1]);

    /*
     * Replace
     *
     * Replace with inverted array (Must be original array when finished).
     */
    for (size_t i = 0; i < cTestItems; ++i)
        testList.replace(i, paTestData[i]);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[i]);

    /*
     * Removing
     */

    /* Remove Range */
    testList3.removeRange(cTestItems, cTestItems * 2);
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /* Remove the first half (reverse) */
    size_t cRemoved = 1;
    for (size_t i = cTestItems / 2; i > 0; --i, ++cRemoved)
    {
        testList.removeAt(i - 1);
        RTTESTI_CHECK_RETV(testList.size() == cTestItems - cRemoved);
    }
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);

    /* Check that all is correctly removed and only the second part of the list
     * is still there. */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /*
     * setCapacitiy
     */
    testList.setCapacity(cTestItems * 5);
    RTTESTI_CHECK(testList.capacity()  == cTestItems * 5);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);

    /* As the capacity just increased, we should still have all entries from
     * the previous list. */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Decrease the capacity so it will be smaller than the count of items in
     * the list. The list should be shrink automatically, but the remaining
     * items should be still valid. */
    testList.setCapacity(cTestItems / 4);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 4);
    RTTESTI_CHECK(testList.capacity()  == cTestItems / 4);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Clear all */
    testList.clear();
    RTTESTI_CHECK_RETV(testList.isEmpty());
    RTTESTI_CHECK_RETV(testList.size() == 0);
    RTTESTI_CHECK(testList.capacity()  == defCap);


    /* Copy empty lists. */
    L<T1, T2> testList5(testList);
    RTTESTI_CHECK_RETV(testList5.isEmpty());
    RTTESTI_CHECK_RETV(testList5.size() == 0);
    RTTESTI_CHECK(testList5.capacity()  == 0);

    testList5.append(paTestData[0]);
    testList5 = testList;
    RTTESTI_CHECK_RETV(testList5.isEmpty());
    RTTESTI_CHECK_RETV(testList5.size() == 0);
    RTTESTI_CHECK(testList5.capacity()  == 0);

    /*
     * Negative testing.
     */
    bool fMayPanic = RTAssertMayPanic();
    bool fQuiet    = RTAssertAreQuiet();
    RTAssertSetMayPanic(false);
    RTAssertSetQuiet(true);

    L<T1, T2> testList6;
    for (size_t i = 0; i < cTestItems; ++i)
        testList6.insert(i, paTestData[i]);
    RTTESTI_CHECK(testList6.size() == cTestItems);

    /* Insertion beyond the end of the array ends up at the end. */
    size_t cBefore = testList6.size();
    testList6.insert(cBefore + 3, paTestData[0]);
    RTTESTI_CHECK(testList6.size() == cBefore + 1);
    RTTESTI_CHECK(testList6.at(cBefore) == paTestData[0]);

    cBefore = testList6.size();
    L<T1, T2> testList7(testList6);
    testList6.insert(testList6.size() + 42, testList7);
    RTTESTI_CHECK(testList6.size() == cBefore + testList7.size());

    /* Inserting, appending or prepending a list to itself is not supported. */
    cBefore = testList6.size();
    testList6.insert(3, testList6);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.append(testList6);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.prepend(testList6);
    RTTESTI_CHECK(testList6.size() == cBefore);

    /* Replace does nothing if the index is bad. */
    cBefore = testList6.size();
    testList6.replace(cBefore, testList6[6]);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.replace(cBefore + 64, testList6[6]);
    RTTESTI_CHECK(testList6.size() == cBefore);

    /* Indexing beyond the array returns the last element. */
    cBefore = testList6.size();
    RTTESTI_CHECK(testList6[cBefore] == testList6.last());
    RTTESTI_CHECK(testList6[cBefore + 42] == testList6.last());

    RTTESTI_CHECK(&testList6[cBefore]      == &testList6[cBefore - 1]);
    RTTESTI_CHECK(&testList6[cBefore + 42] == &testList6[cBefore - 1]);

    /* removeAt does nothing if the index is bad. */
    cBefore = testList6.size();
    testList6.removeAt(cBefore);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.removeAt(cBefore + 42);
    RTTESTI_CHECK(testList6.size() == cBefore);

    L<T1, T2> testListEmpty1; RTTESTI_CHECK(!testListEmpty1.size());
    testListEmpty1.removeFirst();
    RTTESTI_CHECK(!testListEmpty1.size());

    testListEmpty1.removeLast();
    RTTESTI_CHECK(!testListEmpty1.size());

    testListEmpty1.removeAt(128);
    RTTESTI_CHECK(!testListEmpty1.size());

    /* removeRange interprets indexes beyond the end as the end of array (asserted). */
    testListEmpty1.removeRange(42, 128);
    RTTESTI_CHECK(!testListEmpty1.size());

    cBefore = testList6.size();
    testList6.removeRange(cBefore, cBefore);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.removeRange(cBefore + 12, cBefore + 128);
    RTTESTI_CHECK(testList6.size() == cBefore);

    /* If end is less or equal to the start, nothing is done. */
    testListEmpty1.removeRange(128, 0);
    RTTESTI_CHECK(!testListEmpty1.size());

    cBefore = testList6.size();
    testList6.removeRange(cBefore, 0);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.removeRange(0, 0);
    RTTESTI_CHECK(testList6.size() == cBefore);

    cBefore = testList6.size();
    testList6.removeRange(0, 0);
    RTTESTI_CHECK(testList6.size() == cBefore);

    RTAssertSetQuiet(fQuiet);
    RTAssertSetMayPanic(fMayPanic);
}
Ejemplo n.º 2
0
static void test1(const char *pcszDesc, T3 paTestData[], size_t cTestItems)
{
    RTTestISubF("%s with size of %u (items=%u)", pcszDesc, sizeof(T1), cTestItems);

    /*
     * Construction
     */

    /* Create a test list */
    L<T1, T2> testList;

    const size_t defCap = L<T1, T2>::DefaultCapacity;
    RTTESTI_CHECK(testList.isEmpty());
    RTTESTI_CHECK(testList.size()     == 0);
    RTTESTI_CHECK(testList.capacity() == defCap);

    /*
     * Adding
     */

    /* Add the second half of the test data */
    size_t cAdded = 1;

    /* Start adding the second half of our test list */
    for (size_t i = cTestItems / 2; i < cTestItems; ++i, ++cAdded)
    {
        testList.append(paTestData[i]);
        RTTESTI_CHECK_RETV(testList.size()    == cAdded);
        RTTESTI_CHECK(testList.at(0)          == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList[0]             == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList.first()        == paTestData[cTestItems / 2]);
        RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[i]);
        RTTESTI_CHECK(testList[cAdded - 1]    == paTestData[i]);
        RTTESTI_CHECK(testList.last()         == paTestData[i]);
    }

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList.size()        == cTestItems / 2);
    RTTESTI_CHECK_RETV(testList.isEmpty()     == false);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Start prepending the first half of our test list. Iterate reverse to get
     * the correct sorting back. */
    for (size_t i = cTestItems / 2; i > 0; --i, ++cAdded)
    {
        testList.prepend(paTestData[i - 1]);
        RTTESTI_CHECK_RETV(testList.size()    == cAdded);
        RTTESTI_CHECK(testList.at(0)          == paTestData[i - 1]);
        RTTESTI_CHECK(testList[0]             == paTestData[i - 1]);
        RTTESTI_CHECK(testList.first()        == paTestData[i - 1]);
        RTTESTI_CHECK(testList.at(cAdded - 1) == paTestData[cTestItems - 1]);
        RTTESTI_CHECK(testList[cAdded - 1]    == paTestData[cTestItems - 1]);
        RTTESTI_CHECK(testList.last()         == paTestData[cTestItems - 1]);
    }

    /* Check that all is correctly prepended. */
    RTTESTI_CHECK_RETV(testList.size()        == cTestItems);
    RTTESTI_CHECK_RETV(testList.isEmpty()     == false);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[i]);

    /*
     * Contains
     */
    L<T1, T2> testList2;

    /* Check full list. */
    RTTESTI_CHECK( testList.contains(paTestData[0]));
    RTTESTI_CHECK( testList.contains(paTestData[cTestItems / 2]));
    RTTESTI_CHECK( testList.contains(paTestData[cTestItems - 1]));
    RTTESTI_CHECK(!testList.contains(T1()));
    /* Check empty list. */
    RTTESTI_CHECK(!testList2.contains(paTestData[0]));
    RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems / 2]));
    RTTESTI_CHECK(!testList2.contains(paTestData[cTestItems - 1]));
    RTTESTI_CHECK(!testList2.contains(T1()));

    /*
     * Copy operator
     */
    L<T1, T2> testList3(testList);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i]);

    /*
     * "=" operator
     */
    L<T1, T2> testList4;
    testList4 = testList;

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList4.size() == cTestItems);
    for (size_t i = 0; i < testList4.size(); ++i)
        RTTESTI_CHECK(testList4.at(i) == paTestData[i]);

    /*
     * Append list
     */
    testList3.append(testList4);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /*
     * Prepend list
     */
    testList3.prepend(testList4);

    /* Check that all is correctly appended. */
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 3);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /*
     * "value" method
     */
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.value(i)       == paTestData[i % cTestItems]);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.value(i, T1()) == paTestData[i % cTestItems]);
    RTTESTI_CHECK(testList3.value(testList3.size() + 1) == T1());       /* Invalid index */
    RTTESTI_CHECK(testList3.value(testList3.size() + 1, T1()) == T1()); /* Invalid index */

    /*
     * operator[] (reading)
     */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[i]);

    /*
     * operator[] (writing)
     *
     * Replace with inverted array.
     */
    for (size_t i = 0; i < cTestItems; ++i)
        testList[i] = paTestData[cTestItems - i - 1];
    RTTESTI_CHECK_RETV(testList.size() == cTestItems);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[cTestItems - i - 1]);

    /*
     * Replace
     *
     * Replace with inverted array (Must be original array when finished).
     */
    for (size_t i = 0; i < cTestItems; ++i)
        testList.replace(i, paTestData[i]);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList[i] == paTestData[i]);

    /*
     * Removing
     */

    /* Remove Range */
    testList3.removeRange(cTestItems, cTestItems * 2);
    RTTESTI_CHECK_RETV(testList3.size() == cTestItems * 2);
    for (size_t i = 0; i < testList3.size(); ++i)
        RTTESTI_CHECK(testList3.at(i) == paTestData[i % cTestItems]);

    /* Remove the first half (reverse) */
    size_t cRemoved = 1;
    for (size_t i = cTestItems / 2; i > 0; --i, ++cRemoved)
    {
        testList.removeAt(i - 1);
        RTTESTI_CHECK_RETV(testList.size() == cTestItems - cRemoved);
    }
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);

    /* Check that all is correctly removed and only the second part of the list
     * is still there. */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /*
     * setCapacitiy
     */
    testList.setCapacity(cTestItems * 5);
    RTTESTI_CHECK(testList.capacity()  == cTestItems * 5);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 2);

    /* As the capacity just increased, we should still have all entries from
     * the previous list. */
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Decrease the capacity so it will be smaller than the count of items in
     * the list. The list should be shrink automatically, but the remaining
     * items should be still valid. */
    testList.setCapacity(cTestItems / 4);
    RTTESTI_CHECK_RETV(testList.size() == cTestItems / 4);
    RTTESTI_CHECK(testList.capacity()  == cTestItems / 4);
    for (size_t i = 0; i < testList.size(); ++i)
        RTTESTI_CHECK(testList.at(i) == paTestData[cTestItems / 2 + i]);

    /* Clear all */
    testList.clear();
    RTTESTI_CHECK_RETV(testList.isEmpty());
    RTTESTI_CHECK_RETV(testList.size() == 0);
    RTTESTI_CHECK(testList.capacity()  == defCap);


    /* Copy empty lists. */
    L<T1, T2> testList5(testList);
    RTTESTI_CHECK_RETV(testList5.isEmpty());
    RTTESTI_CHECK_RETV(testList5.size() == 0);
    RTTESTI_CHECK(testList5.capacity()  == 0);

    testList5.append(paTestData[0]);
    testList5 = testList;
    RTTESTI_CHECK_RETV(testList5.isEmpty());
    RTTESTI_CHECK_RETV(testList5.size() == 0);
    RTTESTI_CHECK(testList5.capacity()  == 0);

}