Code

Tests for svg-affine and svg-length (the latter is not much more than a stub) and...
authorjaspervdg <jaspervdg@users.sourceforge.net>
Thu, 3 Jul 2008 13:20:00 +0000 (13:20 +0000)
committerjaspervdg <jaspervdg@users.sourceforge.net>
Thu, 3 Jul 2008 13:20:00 +0000 (13:20 +0000)
build.xml
src/svg/svg-affine-test.h [new file with mode: 0644]
src/svg/svg-length-test.h [new file with mode: 0644]
src/util/list-container-test.h [new file with mode: 0644]

index 0355b98bc5049559d62f6adf5357b366b68fa25d..2ab7104e24a6e9a46397b262e13e303f0ff12203 100644 (file)
--- a/build.xml
+++ b/build.xml
         <fileset dir="${src}/svg">
             <include name="css-ostringstream-test.h"/>
             <include name="stringstream-test.h"/>
+            <include name="svg-affine-test.h"/>
             <include name="svg-color-test.h"/>
+            <include name="svg-length-test.h"/>
             <include name="svg-path-test.h"/>
         </fileset>
     </cxxtestpart>
+    <cxxtestpart command="python ${cxxtest}/cxxtestgen.py" 
+                 out="${src}/util/test-util.cpp">
+        <fileset dir="${src}/util">
+            <include name="list-container-test.h"/>
+        </fileset>
+    </cxxtestpart>
     <cxxtestpart command="python ${cxxtest}/cxxtestgen.py" 
                  out="${src}/xml/test-xml.cpp">
         <fileset dir="${src}/xml">
            <exclude name="obj/helper/test-helper.o"/>
            <exclude name="obj/libnr/test-nr.o"/>
            <exclude name="obj/svg/test-svg.o"/>
+           <exclude name="obj/util/test-util.o"/>
            <exclude name="obj/xml/test-xml.o"/>
        </fileset>
     </staticlib>
            <include name="obj/helper/test-helper.o"/>
            <include name="obj/libnr/test-nr.o"/>
            <include name="obj/svg/test-svg.o"/>
+           <include name="obj/util/test-util.o"/>
            <include name="obj/xml/test-xml.o"/>
            <include name="libinkscape.a"/>
        </fileset>
     <delete file="${src}/helper/test-helper.cpp"/>
     <delete file="${src}/libnr/test-nr.cpp"/>
     <delete file="${src}/svg/test-svg.cpp"/>
+    <delete file="${src}/util/test-util.cpp"/>
     <delete file="${src}/xml/test-xml.cpp"/>
 
   </target>
diff --git a/src/svg/svg-affine-test.h b/src/svg/svg-affine-test.h
new file mode 100644 (file)
index 0000000..4180fcf
--- /dev/null
@@ -0,0 +1,219 @@
+#include <cxxtest/TestSuite.h>\r
+\r
+#include "svg/svg.h"\r
+#include <2geom/matrix.h>\r
+#include <algorithm>\r
+#include <glib.h>\r
+#include <iostream>\r
+#include <math.h>\r
+#include <utility>\r
+\r
+struct streq_free2 {\r
+    bool operator()(char const *exp, char const *got) const\r
+    {\r
+        bool const ret = (strcmp(exp, got) == 0);\r
+        g_free((void*)got);\r
+        return ret;\r
+    }\r
+};\r
+\r
+struct approx_equal {\r
+    bool operator()(Geom::Matrix const &ref, Geom::Matrix const &cm) const\r
+    {\r
+        double maxabsdiff = 0;\r
+        for(size_t i=0; i<6; i++) {\r
+            maxabsdiff = std::max(std::abs(ref[i]-cm[i]), maxabsdiff);\r
+        }\r
+        return maxabsdiff < 1e-14;\r
+    }\r
+};\r
+\r
+class SvgAffineTest : public CxxTest::TestSuite\r
+{\r
+private:\r
+    struct test_t {\r
+        char const * str;\r
+        Geom::Matrix matrix;\r
+    };\r
+    static test_t const read_matrix_tests[3];\r
+    static test_t const read_translate_tests[3];\r
+    static test_t const read_scale_tests[3];\r
+    static test_t const read_rotate_tests[4];\r
+    static test_t const read_skew_tests[3];\r
+    static test_t const write_matrix_tests[2];\r
+    static test_t const write_translate_tests[3];\r
+    static test_t const write_scale_tests[2];\r
+    static test_t const write_rotate_tests[2];\r
+    static test_t const write_skew_tests[3];\r
+public:\r
+    SvgAffineTest() {\r
+    }\r
+\r
+    void testReadIdentity()\r
+    {\r
+        char const* strs[] = {\r
+            //0,\r
+            "",\r
+            "matrix(1,0,0,1,0,0)",\r
+            "translate(0,0)",\r
+            "scale(1,1)",\r
+            "rotate(0,0,0)",\r
+            "skewX(0)",\r
+            "skewY(0)"};\r
+        size_t n = G_N_ELEMENTS(strs);\r
+        for(size_t i=0; i<n; i++) {\r
+            Geom::Matrix cm;\r
+            TSM_ASSERT(strs[i] , sp_svg_transform_read(strs[i], &cm));\r
+            TSM_ASSERT_EQUALS(strs[i] , Geom::identity() , cm);\r
+        }\r
+    }\r
+\r
+    void testWriteIdentity()\r
+    {\r
+        TS_ASSERT_EQUALS(sp_svg_transform_write(Geom::identity()) , (void*)0)\r
+    }\r
+\r
+    void testReadMatrix()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(read_matrix_tests); i++) {\r
+            Geom::Matrix cm;\r
+            TSM_ASSERT(read_matrix_tests[i].str , sp_svg_transform_read(read_matrix_tests[i].str, &cm));\r
+            TSM_ASSERT_RELATION(read_matrix_tests[i].str , approx_equal , read_matrix_tests[i].matrix , cm);\r
+        }\r
+    }\r
+\r
+    void testReadTranslate()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(read_translate_tests); i++) {\r
+            Geom::Matrix cm;\r
+            TSM_ASSERT(read_translate_tests[i].str , sp_svg_transform_read(read_translate_tests[i].str, &cm));\r
+            TSM_ASSERT_RELATION(read_translate_tests[i].str , approx_equal , read_translate_tests[i].matrix , cm);\r
+        }\r
+    }\r
+\r
+    void testReadScale()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(read_scale_tests); i++) {\r
+            Geom::Matrix cm;\r
+            TSM_ASSERT(read_scale_tests[i].str , sp_svg_transform_read(read_scale_tests[i].str, &cm));\r
+            TSM_ASSERT_RELATION(read_scale_tests[i].str , approx_equal , read_scale_tests[i].matrix , cm);\r
+        }\r
+    }\r
+\r
+    void testReadRotate()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(read_rotate_tests); i++) {\r
+            Geom::Matrix cm;\r
+            TSM_ASSERT(read_rotate_tests[i].str , sp_svg_transform_read(read_rotate_tests[i].str, &cm));\r
+            TSM_ASSERT_RELATION(read_rotate_tests[i].str , approx_equal , read_rotate_tests[i].matrix , cm);\r
+        }\r
+    }\r
+\r
+    void testReadSkew()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(read_skew_tests); i++) {\r
+            Geom::Matrix cm;\r
+            TSM_ASSERT(read_skew_tests[i].str , sp_svg_transform_read(read_skew_tests[i].str, &cm));\r
+            TSM_ASSERT_RELATION(read_skew_tests[i].str , approx_equal , read_skew_tests[i].matrix , cm);\r
+        }\r
+    }\r
+\r
+    void testWriteMatrix()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(write_matrix_tests); i++) {\r
+            TS_ASSERT_RELATION(streq_free2 , sp_svg_transform_write(write_matrix_tests[i].matrix) , write_matrix_tests[i].str);\r
+        }\r
+    }\r
+\r
+    void testWriteTranslate()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(write_translate_tests); i++) {\r
+            TS_ASSERT_RELATION(streq_free2 , sp_svg_transform_write(write_translate_tests[i].matrix) , write_translate_tests[i].str);\r
+        }\r
+    }\r
+\r
+    void testWriteScale()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(write_scale_tests); i++) {\r
+            TS_ASSERT_RELATION(streq_free2 , sp_svg_transform_write(write_scale_tests[i].matrix) , write_scale_tests[i].str);\r
+        }\r
+    }\r
+\r
+    void testWriteRotate()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(write_rotate_tests); i++) {\r
+            TS_ASSERT_RELATION(streq_free2 , sp_svg_transform_write(write_rotate_tests[i].matrix) , write_rotate_tests[i].str);\r
+        }\r
+    }\r
+\r
+    void testWriteSkew()\r
+    {\r
+        for(size_t i=0; i<G_N_ELEMENTS(write_skew_tests); i++) {\r
+            TS_ASSERT_RELATION(streq_free2 , sp_svg_transform_write(write_skew_tests[i].matrix) , write_skew_tests[i].str);\r
+        }\r
+    }\r
+\r
+    void testReadConcatenation()\r
+    {\r
+        char const * str = "skewY(17)skewX(9)translate(7,13)scale(2)rotate(13)translate(3,5)";\r
+        Geom::Matrix ref(2.0199976232558053, 1.0674773585906016, -0.14125199392774669, 1.9055550612095459, 14.412730624347654, 28.499820929377454); // Precomputed using Mathematica\r
+        Geom::Matrix cm;\r
+        TS_ASSERT(sp_svg_transform_read(str, &cm));\r
+        TS_ASSERT_RELATION(approx_equal , ref , cm);\r
+    }\r
+\r
+    // TODO: Perhaps check faulty transforms (like "translate(1,2,3)", or "matrix(1,2,3,4,5)", or ...)\r
+};\r
+\r
+static double const DEGREE = M_PI/180.;\r
+\r
+SvgAffineTest::test_t const SvgAffineTest::read_matrix_tests[3] = {\r
+    {"matrix(0,0,0,0,0,0)",Geom::Matrix(0,0,0,0,0,0)},\r
+    {"matrix(1,2,3,4,5,6)",Geom::Matrix(1,2,3,4,5,6)},\r
+    {"matrix(1 2 -3,-4,5e6,-6e-7)",Geom::Matrix(1,2,-3,-4,5e6,-6e-7)}};\r
+SvgAffineTest::test_t const SvgAffineTest::read_translate_tests[3] = {\r
+    {"translate(1)",Geom::Matrix(1,0,0,1,1,0)},\r
+    {"translate(1,1)",Geom::Matrix(1,0,0,1,1,1)},\r
+    {"translate(-1e3 .123e2)",Geom::Matrix(1,0,0,1,-1e3,.123e2)}};\r
+SvgAffineTest::test_t const SvgAffineTest::read_scale_tests[3] = {\r
+    {"scale(2)",Geom::Matrix(2,0,0,2,0,0)},\r
+    {"scale(2,3)",Geom::Matrix(2,0,0,3,0,0)},\r
+    {"scale(0.1e-2 -.475e0)",Geom::Matrix(0.1e-2,0,0,-.475e0,0,0)}};\r
+SvgAffineTest::test_t const SvgAffineTest::read_rotate_tests[4] = {\r
+    {"rotate(13 )",Geom::Matrix(cos(13.*DEGREE),sin(13.*DEGREE),-sin(13.*DEGREE),cos(13.*DEGREE),0,0)},\r
+    {"rotate(-13)",Geom::Matrix(cos(-13.*DEGREE),sin(-13.*DEGREE),-sin(-13.*DEGREE),cos(-13.*DEGREE),0,0)},\r
+    {"rotate(373)",Geom::Matrix(cos(13.*DEGREE),sin(13.*DEGREE),-sin(13.*DEGREE),cos(13.*DEGREE),0,0)},\r
+    {"rotate(13,7,11)",Geom::Matrix(cos(13.*DEGREE),sin(13.*DEGREE),-sin(13.*DEGREE),cos(13.*DEGREE),(1-cos(13.*DEGREE))*7+sin(13.*DEGREE)*11,(1-cos(13.*DEGREE))*11-sin(13.*DEGREE)*7)}};\r
+SvgAffineTest::test_t const SvgAffineTest::read_skew_tests[3] = {\r
+    {"skewX( 30)",Geom::Matrix(1,0,tan(30.*DEGREE),1,0,0)},\r
+    {"skewX(-30)",Geom::Matrix(1,0,tan(-30.*DEGREE),1,0,0)},\r
+    {"skewY(390)",Geom::Matrix(1,tan(30.*DEGREE),0,1,0,0)}};\r
+\r
+SvgAffineTest::test_t const SvgAffineTest::write_matrix_tests[2] = {\r
+    {"matrix(1,2,3,4,5,6)",Geom::Matrix(1,2,3,4,5,6)},\r
+    {"matrix(-1,2123,3,0.4,1e-8,1e20)",Geom::Matrix(-1,2.123e3,3+1e-14,0.4,1e-8,1e20)}};\r
+SvgAffineTest::test_t const SvgAffineTest::write_translate_tests[3] = {\r
+    {"translate(1,1)",Geom::Matrix(1,0,0,1,1,1)},\r
+    {"translate(1)",Geom::Matrix(1,0,0,1,1,0)},\r
+    {"translate(-1345,0.123)",Geom::Matrix(1,0,0,1,-1.345e3,.123)}};\r
+SvgAffineTest::test_t const SvgAffineTest::write_scale_tests[2] = {\r
+    {"scale(0)",Geom::Matrix(0,0,0,0,0,0)},\r
+    {"scale(2,3)",Geom::Matrix(2,0,0,3,0,0)}};\r
+SvgAffineTest::test_t const SvgAffineTest::write_rotate_tests[2] = {\r
+    {"rotate(13)",Geom::Matrix(cos(13.*DEGREE),sin(13.*DEGREE),-sin(13.*DEGREE),cos(13.*DEGREE),0,0)},\r
+    {"rotate(-13,7,11)",Geom::Matrix(cos(-13.*DEGREE),sin(-13.*DEGREE),-sin(-13.*DEGREE),cos(-13.*DEGREE),(1-cos(-13.*DEGREE))*7+sin(-13.*DEGREE)*11,(1-cos(-13.*DEGREE))*11-sin(-13.*DEGREE)*7)}};\r
+SvgAffineTest::test_t const SvgAffineTest::write_skew_tests[3] = {\r
+    {"skewX(30)",Geom::Matrix(1,0,tan(30.*DEGREE),1,0,0)},\r
+    {"skewX(-30)",Geom::Matrix(1,0,tan(-30.*DEGREE),1,0,0)},\r
+    {"skewY(390)",Geom::Matrix(1,tan(30.*DEGREE),0,1,0,0)}};\r
+\r
+/*\r
+  Local Variables:\r
+  mode:c++\r
+  c-file-style:"stroustrup"\r
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+  indent-tabs-mode:nil\r
+  fill-column:99\r
+  End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
diff --git a/src/svg/svg-length-test.h b/src/svg/svg-length-test.h
new file mode 100644 (file)
index 0000000..0f628ae
--- /dev/null
@@ -0,0 +1,46 @@
+#include <cxxtest/TestSuite.h>\r
+\r
+#include "svg/svg-length.h"\r
+#include <glib.h>\r
+#include <utility>\r
+\r
+class SvgLengthTest : public CxxTest::TestSuite\r
+{\r
+private:\r
+public:\r
+    SvgLengthTest() {\r
+    }\r
+\r
+    void testRead()\r
+    {\r
+        struct test_t {\r
+            char const* str; float computed;\r
+            test_t(char const* str, float computed) : str(str), computed(computed) {}\r
+        };\r
+        test_t tests[] = {\r
+            test_t("0",0),\r
+            test_t("1",1),\r
+            test_t("1.00001",1.00001),\r
+            test_t("1px",1),\r
+            test_t(".1px",0.1)};\r
+        size_t n = G_N_ELEMENTS(tests);\r
+        for(size_t i=0; i<n; i++) {\r
+            SVGLength l;\r
+            TSM_ASSERT(tests[i].str , l.read(tests[i].str));\r
+            TSM_ASSERT_EQUALS(tests[i].str , l.computed , tests[i].computed);\r
+        }\r
+    }\r
+\r
+    // TODO: More tests\r
+};\r
+\r
+/*\r
+  Local Variables:\r
+  mode:c++\r
+  c-file-style:"stroustrup"\r
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+  indent-tabs-mode:nil\r
+  fill-column:99\r
+  End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
diff --git a/src/util/list-container-test.h b/src/util/list-container-test.h
new file mode 100644 (file)
index 0000000..9d8507f
--- /dev/null
@@ -0,0 +1,245 @@
+#include <cxxtest/TestSuite.h>\r
+\r
+#include <stdarg.h>\r
+#include "util/list-container.h"\r
+\r
+using Inkscape::Util::ListContainer;\r
+\r
+#define ARRAY_RANGE(array) (array), (array)+sizeof((array))/sizeof((array)[0])\r
+\r
+static bool check_values(ListContainer<int> const &c, unsigned n_values, ...) {\r
+    bool ret = true;\r
+    va_list args;\r
+    va_start(args, n_values);\r
+    ListContainer<int>::const_iterator iter(c.begin());\r
+    while ( n_values && iter != c.end() ) {\r
+        int const value = va_arg(args, int);\r
+        if ( value != *iter ) {\r
+            ret = false;\r
+        }\r
+        if ( n_values == 1 && &c.back() != &*iter ) {\r
+            ret = false;\r
+        }\r
+        n_values--;\r
+        ++iter;\r
+    }\r
+    va_end(args);\r
+    return ret && n_values == 0 && iter == c.end();\r
+}\r
+\r
+class ListContainerTest : public CxxTest::TestSuite {\r
+public:\r
+    ListContainerTest()\r
+    {\r
+        Inkscape::GC::init();\r
+    }\r
+    virtual ~ListContainerTest() {}\r
+\r
+    void testRangeConstructor()\r
+    {\r
+        int const values[]={1,2,3,4};\r
+        int const * const values_end=values+4;\r
+        ListContainer<int> container(values, values_end);\r
+\r
+        ListContainer<int>::iterator container_iter=container.begin();\r
+        int const * values_iter=values;\r
+\r
+        while ( values_iter != values_end && container_iter != container.end() ) {\r
+            TS_ASSERT_EQUALS(*values_iter , *container_iter);\r
+            ++values_iter;\r
+            ++container_iter;\r
+        }\r
+\r
+        TS_ASSERT_EQUALS(values_iter , values_end);\r
+        TS_ASSERT_EQUALS(container_iter , container.end());\r
+    }\r
+\r
+    void testEqualityTests()\r
+    {\r
+        int const a[] = { 1, 2, 3, 4 };\r
+        int const b[] = { 1, 2, 3, 4 };\r
+        int const c[] = { 1, 2, 3 };\r
+        int const d[] = { 1, 2, 3, 5 };\r
+        ListContainer<int> c_a(ARRAY_RANGE(a));\r
+        ListContainer<int> c_b(ARRAY_RANGE(b));\r
+        ListContainer<int> c_c(ARRAY_RANGE(c));\r
+        ListContainer<int> c_d(ARRAY_RANGE(d));\r
+\r
+        TS_ASSERT(c_a == c_b);\r
+        TS_ASSERT(!( c_a != c_b ));\r
+        TS_ASSERT(!( c_a == c_c ));\r
+        TS_ASSERT(c_a != c_c);\r
+        TS_ASSERT(!( c_a == c_d ));\r
+        TS_ASSERT(c_a != c_d);\r
+    }\r
+\r
+    void testLessThan()\r
+    {\r
+        int const a[] = { 1, 2, 3, 4 };\r
+        int const b[] = { 1, 2, 2, 4 };\r
+        int const c[] = { 1, 2, 4, 4 };\r
+        int const d[] = { 1, 2, 3 };\r
+        ListContainer<int> c_a(ARRAY_RANGE(a));\r
+        ListContainer<int> c_b(ARRAY_RANGE(b));\r
+        ListContainer<int> c_c(ARRAY_RANGE(c));\r
+        ListContainer<int> c_d(ARRAY_RANGE(d));\r
+        TS_ASSERT(c_a >= c_b);\r
+        TS_ASSERT(!( c_a < c_b ));\r
+        TS_ASSERT(!( c_a >= c_c ));\r
+        TS_ASSERT(c_a < c_c);\r
+        TS_ASSERT(!( c_a < c_d ));\r
+        TS_ASSERT(c_a >= c_d);\r
+        TS_ASSERT(c_d < c_a);\r
+    }\r
+\r
+    void testAssignmentOperator()\r
+    {\r
+        int const a[] = { 1, 2, 3, 4 };\r
+        ListContainer<int> c_a(ARRAY_RANGE(a));\r
+        ListContainer<int> c_c;\r
+        TS_ASSERT(c_a != c_c);\r
+        c_c = c_a;\r
+        TS_ASSERT(c_a == c_c);\r
+        c_c = c_a;\r
+        TS_ASSERT(c_a == c_c);\r
+    }          \r
+\r
+    void testFillConstructor()\r
+    {\r
+        ListContainer<int> filled((std::size_t)3, 2);\r
+        TS_ASSERT(check_values(filled, 3, 2, 2, 2));\r
+    }\r
+\r
+    void testContainerSize()\r
+    {\r
+        ListContainer<int> empty;\r
+        TS_ASSERT(empty.empty());\r
+        TS_ASSERT_EQUALS(empty.size() , 0);\r
+        int const a[] = { 1, 2, 3 };\r
+        ListContainer<int> c_a(ARRAY_RANGE(a));\r
+        TS_ASSERT(!c_a.empty());\r
+        TS_ASSERT_EQUALS(c_a.size() , 3);\r
+\r
+        TS_ASSERT_LESS_THAN(0 , empty.max_size());\r
+    }\r
+\r
+    void testAppending()\r
+    {\r
+        ListContainer<int> c;\r
+        c.push_back(1);\r
+        TS_ASSERT(check_values(c, 1, 1));\r
+        c.push_back(2);\r
+        TS_ASSERT(check_values(c, 2, 1, 2));\r
+        c.push_back(3);\r
+        TS_ASSERT(check_values(c, 3, 1, 2, 3));\r
+    }\r
+\r
+    void testBulkAppending()\r
+    {\r
+        int const a[] = { 1, 2, 3, 4 };\r
+        int const b[] = { 5, 6, 7 };\r
+        ListContainer<int> c_a(ARRAY_RANGE(a));\r
+        ListContainer<int> c_b(ARRAY_RANGE(b));\r
+        c_a.insert(c_a.end(), c_b.begin(), c_b.end());\r
+        TS_ASSERT(check_values(c_a, 7, 1, 2, 3, 4, 5, 6, 7));\r
+    }\r
+\r
+    void testPrepending()\r
+    {\r
+        ListContainer<int> c;\r
+        c.push_front(1);\r
+        TS_ASSERT(check_values(c, 1, 1));\r
+        c.push_front(2);\r
+        TS_ASSERT(check_values(c, 2, 2, 1));\r
+        c.push_front(3);\r
+        TS_ASSERT(check_values(c, 3, 3, 2, 1));\r
+    }\r
+\r
+    void testSingleValueInsertion()\r
+    {\r
+        ListContainer<int> c;\r
+\r
+        c.insert(c.begin(), 1);\r
+        TS_ASSERT(check_values(c, 1, 1));\r
+\r
+        c.insert(c.end(), 2);\r
+        TS_ASSERT(check_values(c, 2, 1, 2));\r
+\r
+        c.insert(c.begin(), 3);\r
+        TS_ASSERT(check_values(c, 3, 3, 1, 2));\r
+\r
+        ListContainer<int>::iterator pos=c.begin();\r
+        ++pos;\r
+        c.insert(pos, 4);\r
+        TS_ASSERT(check_values(c, 4, 3, 4, 1, 2));\r
+    }\r
+\r
+    void testSingleValueErasure()\r
+    {\r
+        int const values[] = { 1, 2, 3, 4 };\r
+        ListContainer<int> c(ARRAY_RANGE(values));\r
+\r
+        c.erase(c.begin());\r
+        TS_ASSERT(check_values(c, 3, 2, 3, 4));\r
+\r
+        ListContainer<int>::iterator pos=c.begin();\r
+        ++pos;\r
+        c.erase(pos);\r
+        TS_ASSERT(check_values(c, 2, 2, 4));\r
+\r
+        pos=c.begin();\r
+        ++pos;\r
+        c.erase(pos);\r
+        TS_ASSERT(check_values(c, 1, 2));\r
+\r
+        c.erase(c.begin());\r
+        TS_ASSERT(check_values(c, 0));\r
+    }\r
+\r
+    void testPopFront()\r
+    {\r
+        int const full_ary[] = { 1, 2, 3 };\r
+        ListContainer<int> t(ARRAY_RANGE(full_ary));\r
+        TS_ASSERT(check_values(t, 3,  1, 2, 3));\r
+        TS_ASSERT_EQUALS(t.back() , 3);\r
+        t.pop_front();\r
+        TS_ASSERT(check_values(t, 2,  2, 3));\r
+        TS_ASSERT_EQUALS(t.back() , 3);\r
+        t.push_back(23);\r
+        TS_ASSERT(check_values(t, 3,  2, 3, 23));\r
+        TS_ASSERT_EQUALS(t.back() , 23);\r
+        t.pop_front();\r
+        TS_ASSERT(check_values(t, 2,  3, 23));\r
+        TS_ASSERT_EQUALS(t.back() , 23);\r
+        t.pop_front();\r
+        TS_ASSERT(check_values(t, 1,  23));\r
+        TS_ASSERT_EQUALS(t.back() , 23);\r
+        t.pop_front();\r
+        TS_ASSERT(check_values(t, 0));\r
+        t.push_back(42);\r
+        TS_ASSERT(check_values(t, 1,  42));\r
+        TS_ASSERT_EQUALS(t.back() , 42);\r
+    }\r
+\r
+    void testEraseAfter()\r
+    {\r
+        int const full_ary[] = { 1, 2, 3, 4 };\r
+        int const exp_ary[] = { 1, 3, 4 };\r
+        ListContainer<int> full_list(ARRAY_RANGE(full_ary));\r
+        ListContainer<int> exp_list(ARRAY_RANGE(exp_ary));\r
+        TS_ASSERT(full_list != exp_list);\r
+        full_list.erase_after(full_list.begin());\r
+        TS_ASSERT(full_list == exp_list);\r
+    }          \r
+};\r
+\r
+/*\r
+  Local Variables:\r
+  mode:c++\r
+  c-file-style:"stroustrup"\r
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+  indent-tabs-mode:nil\r
+  fill-column:99\r
+  End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r