tests/test_list.cpp

changeset 672
55d8fdd38ca4
parent 667
2f88a7c13a28
child 677
b09aae58bba4
equal deleted inserted replaced
671:d7a67375a7ac 672:55d8fdd38ca4
36 #include <array> 36 #include <array>
37 #include <vector> 37 #include <vector>
38 #include <unordered_set> 38 #include <unordered_set>
39 #include <algorithm> 39 #include <algorithm>
40 40
41 struct testdatastruct {
42 int x;
43 void *ptr;
44 };
45
46 static void free_testdatastruct(
47 void *a,
48 void *s
49 ) {
50 auto al = reinterpret_cast<CxTestingAllocator *>(a);
51 cxFree(al, reinterpret_cast<testdatastruct *>(s)->ptr);
52 }
53
54 struct node { 41 struct node {
55 node *next = nullptr; 42 node *next = nullptr;
56 node *prev = nullptr; 43 node *prev = nullptr;
57 int data = 0; 44 int data = 0;
58 }; 45 };
597 auto list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), testdata_len)); 584 auto list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), testdata_len));
598 cxListAddArray(list, testdata.data.data(), testdata_len); 585 cxListAddArray(list, testdata.data.data(), testdata_len);
599 return list; 586 return list;
600 } 587 }
601 588
602 void verifyCreate(CxList *list) const {
603 EXPECT_EQ(list->content_destructor_type, CX_DESTRUCTOR_NONE);
604 EXPECT_EQ(list->size, 0);
605 EXPECT_EQ(list->allocator, &testingAllocator);
606 EXPECT_EQ(list->cmpfunc, cx_cmp_int);
607 }
608
609 void verifyAdd( 589 void verifyAdd(
610 CxList *list, 590 CxList *list,
611 bool as_pointer 591 bool as_pointer
612 ) { 592 ) {
613 auto len = testdata_len; 593 auto len = testdata_len;
707 EXPECT_EQ(*(int *) cxListAt(list, 1), testdata.data[3]); 687 EXPECT_EQ(*(int *) cxListAt(list, 1), testdata.data[3]);
708 688
709 EXPECT_NE(cxListRemove(list, testdata_len), 0); 689 EXPECT_NE(cxListRemove(list, testdata_len), 0);
710 } 690 }
711 691
712 void verifyClear(CxList *list) { 692 static void verifyClear(CxList *list) {
713 // use the testing allocator for testing the destructor function 693 cxListClear(list);
694 EXPECT_EQ(0, list->size);
695 }
696
697 static unsigned destr_test_ctr;
698 static int destr_last_value;
699
700 static void simple_destr_test_fun(void *data) {
701 auto ptr = (int *) data;
702 destr_last_value = *ptr;
703 *ptr = destr_last_value + 1;
704 destr_test_ctr++;
705 }
706
707 static void advanced_destr_test_fun(
708 [[maybe_unused]] void *u,
709 void *data
710 ) {
711 simple_destr_test_fun(data);
712 }
713
714 void verifyAnyDestructor(CxList *list) {
715 int off = cxListIsStoringPointers(list) ? 1 : 0;
716
717 cxListRemove(list, 15);
718 EXPECT_EQ(1, destr_test_ctr);
719 EXPECT_EQ(testdata.data[15], destr_last_value + off);
720 EXPECT_EQ(testdata_len - destr_test_ctr, list->size);
721 cxListRemove(list, 47);
722 EXPECT_EQ(2, destr_test_ctr);
723 EXPECT_EQ(testdata.data[48], destr_last_value + off);
724 EXPECT_EQ(testdata_len - destr_test_ctr, list->size);
725
726 auto iter = cxListMutIteratorAt(list, 7);
727 cxIteratorNext(iter);
728 EXPECT_EQ(2, destr_test_ctr);
729 EXPECT_EQ(testdata.data[48], destr_last_value + off);
730 EXPECT_EQ(testdata_len - destr_test_ctr, list->size);
731 cxIteratorFlagRemoval(iter);
732 cxIteratorNext(iter);
733 EXPECT_EQ(3, destr_test_ctr);
734 EXPECT_EQ(testdata.data[8], destr_last_value + off);
735 EXPECT_EQ(testdata_len - destr_test_ctr, list->size);
736
737 iter = cxListMutBackwardsIteratorAt(list, 5);
738 cxIteratorNext(iter);
739 EXPECT_EQ(3, destr_test_ctr);
740 EXPECT_EQ(testdata.data[8], destr_last_value + off);
741 EXPECT_EQ(testdata_len - destr_test_ctr, list->size);
742 cxIteratorFlagRemoval(iter);
743 cxIteratorNext(iter);
744 EXPECT_EQ(4, destr_test_ctr);
745 EXPECT_EQ(testdata.data[4], destr_last_value + off);
746 EXPECT_EQ(testdata_len - destr_test_ctr, list->size);
747
748 cxListClear(list);
749 EXPECT_EQ(testdata_len, destr_test_ctr);
750 EXPECT_EQ(testdata.data[testdata_len - 1], destr_last_value + off);
751
752
753 }
754
755 void verifySimpleDestructor(CxList *list) {
756 destr_test_ctr = 0;
757 list->content_destructor_type = CX_DESTRUCTOR_SIMPLE;
758 list->simple_destructor = simple_destr_test_fun;
759 verifyAnyDestructor(list);
760 }
761
762 void verifyAdvancedDestructor(CxList *list) {
763 destr_test_ctr = 0;
714 list->content_destructor_type = CX_DESTRUCTOR_ADVANCED; 764 list->content_destructor_type = CX_DESTRUCTOR_ADVANCED;
715 list->advanced_destructor.func = free_testdatastruct; 765 list->advanced_destructor.func = advanced_destr_test_fun;
716 list->advanced_destructor.data = &testingAllocator; 766 verifyAnyDestructor(list);
717
718 testdatastruct s[10];
719 for (auto &t: s) {
720 t.ptr = cxMalloc(&testingAllocator, 16);
721 cxListAdd(list, &t);
722 }
723
724 cxListClear(list);
725 } 767 }
726 768
727 static void verifySwap(CxList *list) { 769 static void verifySwap(CxList *list) {
728 ASSERT_EQ(list->size, 0); 770 ASSERT_EQ(list->size, 0);
729 771
792 break; 834 break;
793 } 835 }
794 } 836 }
795 EXPECT_EQ(cxListFind(list, &val), exp); 837 EXPECT_EQ(cxListFind(list, &val), exp);
796 } 838 }
839
840 int notinlist = -1;
841 EXPECT_EQ(list->size, cxListFind(list, &notinlist));
797 } 842 }
798 843
799 void verifySort(CxList *list) const { 844 void verifySort(CxList *list) const {
800 std::array<int, testdata_len> expected{}; 845 std::array<int, testdata_len> expected{};
801 std::partial_sort_copy(testdata.data.begin(), testdata.data.end(), expected.begin(), expected.end()); 846 std::partial_sort_copy(testdata.data.begin(), testdata.data.end(), expected.begin(), expected.end());
909 *(int *) cxListAt(left, 15) = 10; 954 *(int *) cxListAt(left, 15) = 10;
910 EXPECT_EQ(cxListCompare(left, right), 0); 955 EXPECT_EQ(cxListCompare(left, right), 0);
911 } 956 }
912 }; 957 };
913 958
959 unsigned HighLevelTest::destr_test_ctr = 0;
960 int HighLevelTest::destr_last_value = 0;
961
914 class LinkedList : public HighLevelTest { 962 class LinkedList : public HighLevelTest {
915 }; 963 };
916 964
917 class PointerLinkedList : public HighLevelTest { 965 class PointerLinkedList : public HighLevelTest {
918 }; 966 };
930 EXPECT_TRUE(cxListIsStoringPointers(list)); 978 EXPECT_TRUE(cxListIsStoringPointers(list));
931 cxListStoreObjects(list); 979 cxListStoreObjects(list);
932 EXPECT_NE(list->cl, nullptr); 980 EXPECT_NE(list->cl, nullptr);
933 EXPECT_EQ(list->climpl, nullptr); 981 EXPECT_EQ(list->climpl, nullptr);
934 EXPECT_FALSE(cxListIsStoringPointers(list)); 982 EXPECT_FALSE(cxListIsStoringPointers(list));
935
936 list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, CX_STORE_POINTERS));
937 EXPECT_EQ(list->itemsize, sizeof(void *));
938 EXPECT_NE(list->cl, nullptr);
939 EXPECT_NE(list->climpl, nullptr);
940 EXPECT_TRUE(cxListIsStoringPointers(list));
941 } 983 }
942 984
943 TEST_F(LinkedList, cxLinkedListCreate) { 985 TEST_F(LinkedList, cxLinkedListCreate) {
944 CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int))); 986 CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int)));
945 ASSERT_NE(list, nullptr); 987 ASSERT_NE(list, nullptr);
946 EXPECT_EQ(list->itemsize, sizeof(int)); 988 EXPECT_EQ(list->itemsize, sizeof(int));
947 EXPECT_EQ(list->capacity, (size_t) -1); 989 EXPECT_EQ(list->capacity, (size_t) -1);
948 verifyCreate(list); 990 EXPECT_EQ(list->content_destructor_type, CX_DESTRUCTOR_NONE);
991 EXPECT_EQ(list->size, 0);
992 EXPECT_EQ(list->allocator, &testingAllocator);
993 EXPECT_EQ(list->cmpfunc, cx_cmp_int);
994 EXPECT_FALSE(cxListIsStoringPointers(list));
949 } 995 }
950 996
951 TEST_F(LinkedList, cxLinkedListCreateSimple) { 997 TEST_F(LinkedList, cxLinkedListCreateSimple) {
952 CxList *list = autofree(cxLinkedListCreateSimple(sizeof(int))); 998 CxList *list = autofree(cxLinkedListCreateSimple(sizeof(int)));
953 ASSERT_NE(list, nullptr); 999 ASSERT_NE(list, nullptr);
954 EXPECT_EQ(list->itemsize, sizeof(int)); 1000 EXPECT_EQ(list->itemsize, sizeof(int));
955 EXPECT_EQ(list->capacity, (size_t) -1); 1001 EXPECT_EQ(list->capacity, (size_t) -1);
956 EXPECT_EQ(list->cmpfunc, nullptr); 1002 EXPECT_EQ(list->cmpfunc, nullptr);
957 EXPECT_EQ(list->allocator, cxDefaultAllocator); 1003 EXPECT_EQ(list->allocator, cxDefaultAllocator);
1004 EXPECT_FALSE(cxListIsStoringPointers(list));
1005 }
1006
1007 TEST_F(LinkedList, cxLinkedListCreateSimpleForPointers) {
1008 CxList *list = autofree(cxLinkedListCreateSimple(CX_STORE_POINTERS));
1009 ASSERT_NE(list, nullptr);
1010 EXPECT_EQ(list->itemsize, sizeof(void *));
1011 EXPECT_EQ(list->capacity, (size_t) -1);
1012 EXPECT_EQ(list->cmpfunc, nullptr);
1013 EXPECT_EQ(list->allocator, cxDefaultAllocator);
1014 EXPECT_TRUE(cxListIsStoringPointers(list));
958 } 1015 }
959 1016
960 TEST_F(ArrayList, cxArrayListCreate) { 1017 TEST_F(ArrayList, cxArrayListCreate) {
961 CxList *list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 8)); 1018 CxList *list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 8));
962 ASSERT_NE(list, nullptr); 1019 ASSERT_NE(list, nullptr);
963 EXPECT_EQ(list->itemsize, sizeof(int)); 1020 EXPECT_EQ(list->itemsize, sizeof(int));
964 EXPECT_EQ(list->capacity, 8); 1021 EXPECT_EQ(list->capacity, 8);
965 verifyCreate(list); 1022 EXPECT_EQ(list->content_destructor_type, CX_DESTRUCTOR_NONE);
1023 EXPECT_EQ(list->size, 0);
1024 EXPECT_EQ(list->allocator, &testingAllocator);
1025 EXPECT_EQ(list->cmpfunc, cx_cmp_int);
1026 EXPECT_FALSE(cxListIsStoringPointers(list));
966 } 1027 }
967 1028
968 TEST_F(ArrayList, cxArrayListCreateSimple) { 1029 TEST_F(ArrayList, cxArrayListCreateSimple) {
969 CxList *list = autofree(cxArrayListCreateSimple(sizeof(int), 8)); 1030 CxList *list = autofree(cxArrayListCreateSimple(sizeof(int), 8));
970 ASSERT_NE(list, nullptr); 1031 ASSERT_NE(list, nullptr);
971 EXPECT_EQ(list->cmpfunc, nullptr); 1032 EXPECT_EQ(list->cmpfunc, nullptr);
972 EXPECT_EQ(list->allocator, cxDefaultAllocator); 1033 EXPECT_EQ(list->allocator, cxDefaultAllocator);
973 EXPECT_EQ(list->itemsize, sizeof(int)); 1034 EXPECT_EQ(list->itemsize, sizeof(int));
974 EXPECT_EQ(list->capacity, 8); 1035 EXPECT_EQ(list->capacity, 8);
1036 EXPECT_FALSE(cxListIsStoringPointers(list));
1037 }
1038
1039 TEST_F(ArrayList, cxArrayListCreateSimpleForPointers) {
1040 CxList *list = autofree(cxArrayListCreateSimple(CX_STORE_POINTERS, 8));
1041 ASSERT_NE(list, nullptr);
1042 EXPECT_EQ(list->cmpfunc, nullptr);
1043 EXPECT_EQ(list->allocator, cxDefaultAllocator);
1044 EXPECT_EQ(list->itemsize, sizeof(void *));
1045 EXPECT_EQ(list->capacity, 8);
1046 EXPECT_TRUE(cxListIsStoringPointers(list));
975 } 1047 }
976 1048
977 TEST_F(LinkedList, cxListAdd) { 1049 TEST_F(LinkedList, cxListAdd) {
978 auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int))); 1050 auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int)));
979 verifyAdd(list, false); 1051 verifyAdd(list, false);
1024 TEST_F(ArrayList, cxListRemove) { 1096 TEST_F(ArrayList, cxListRemove) {
1025 verifyRemove(arrayListFromTestData()); 1097 verifyRemove(arrayListFromTestData());
1026 } 1098 }
1027 1099
1028 TEST_F(LinkedList, cxListClear) { 1100 TEST_F(LinkedList, cxListClear) {
1029 verifyClear(autofree(cxLinkedListCreateSimple(sizeof(testdatastruct)))); 1101 verifyClear(linkedListFromTestData());
1030 } 1102 }
1031 1103
1032 TEST_F(PointerLinkedList, cxListClear) { 1104 TEST_F(PointerLinkedList, cxListClear) {
1033 verifyClear(cxLinkedListCreateSimple(CX_STORE_POINTERS)); 1105 verifyClear(pointerLinkedListFromTestData());
1034 } 1106 }
1035 1107
1036 TEST_F(ArrayList, cxListClear) { 1108 TEST_F(ArrayList, cxListClear) {
1037 verifyClear(autofree(cxArrayListCreateSimple(sizeof(testdatastruct), 8))); 1109 verifyClear(arrayListFromTestData());
1038 } 1110 }
1039 1111
1040 TEST_F(LinkedList, cxListSwap) { 1112 TEST_F(LinkedList, cxListSwap) {
1041 verifySwap(autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int)))); 1113 verifySwap(autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int))));
1042 } 1114 }
1201 auto left = arrayListFromTestData(); 1273 auto left = arrayListFromTestData();
1202 auto right = linkedListFromTestData(); 1274 auto right = linkedListFromTestData();
1203 verifyCompare(left, right); 1275 verifyCompare(left, right);
1204 } 1276 }
1205 1277
1206 TEST_F(PointerLinkedList, NoDestructor) { 1278 TEST_F(LinkedList, SimpleDestructor) {
1279 verifySimpleDestructor(linkedListFromTestData());
1280 }
1281
1282 TEST_F(PointerLinkedList, SimpleDestructor) {
1283 verifySimpleDestructor(pointerLinkedListFromTestData());
1284 }
1285
1286 TEST_F(ArrayList, SimpleDestructor) {
1287 verifySimpleDestructor(arrayListFromTestData());
1288 }
1289
1290 TEST_F(LinkedList, AdvancedDestructor) {
1291 verifyAdvancedDestructor(linkedListFromTestData());
1292 }
1293
1294 TEST_F(PointerLinkedList, AdvancedDestructor) {
1295 verifyAdvancedDestructor(pointerLinkedListFromTestData());
1296 }
1297
1298 TEST_F(ArrayList, AdvancedDestructor) {
1299 verifyAdvancedDestructor(arrayListFromTestData());
1300 }
1301
1302 TEST_F(PointerLinkedList, DestroyNoDestructor) {
1207 void *item = cxMalloc(&testingAllocator, sizeof(int)); 1303 void *item = cxMalloc(&testingAllocator, sizeof(int));
1208 auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 1304 auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
1209 cxListAdd(list, item); 1305 cxListAdd(list, item);
1210 ASSERT_FALSE(testingAllocator.verify()); 1306 ASSERT_FALSE(testingAllocator.verify());
1211 cxListDestroy(list); 1307 cxListDestroy(list);
1212 EXPECT_FALSE(testingAllocator.verify()); 1308 EXPECT_FALSE(testingAllocator.verify());
1213 cxFree(&testingAllocator, item); 1309 cxFree(&testingAllocator, item);
1214 EXPECT_TRUE(testingAllocator.verify()); 1310 EXPECT_TRUE(testingAllocator.verify());
1215 } 1311 }
1216 1312
1217 TEST_F(PointerLinkedList, SimpleDestructor) { 1313 TEST_F(PointerLinkedList, DestroySimpleDestructor) {
1218 int item = 0; 1314 int item = 0;
1219 auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 1315 auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
1220 list->content_destructor_type = CX_DESTRUCTOR_SIMPLE; 1316 list->content_destructor_type = CX_DESTRUCTOR_SIMPLE;
1221 list->simple_destructor = [](void *elem) { *(int *) elem = 42; }; 1317 list->simple_destructor = [](void *elem) { *(int *) elem = 42; };
1222 cxListAdd(list, &item); 1318 cxListAdd(list, &item);
1223 cxListDestroy(list); 1319 cxListDestroy(list);
1224 EXPECT_EQ(item, 42); 1320 EXPECT_EQ(item, 42);
1225 } 1321 }
1226 1322
1227 TEST_F(PointerLinkedList, AdvancedDestructor) { 1323 TEST_F(PointerLinkedList, DestroyAdvancedDestructor) {
1228 void *item = cxMalloc(&testingAllocator, sizeof(int)); 1324 void *item = cxMalloc(&testingAllocator, sizeof(int));
1229 auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 1325 auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
1230 list->content_destructor_type = CX_DESTRUCTOR_ADVANCED; 1326 list->content_destructor_type = CX_DESTRUCTOR_ADVANCED;
1231 list->advanced_destructor.data = &testingAllocator; 1327 list->advanced_destructor.data = &testingAllocator;
1232 list->advanced_destructor.func = (cx_destructor_func2) cxFree; 1328 list->advanced_destructor.func = (cx_destructor_func2) cxFree;

mercurial