1 #include <gtest/gtest.h>
2 #include <util/arr.h>
3 
4 class ArrTest : public ::testing::Test {};
5 
6 typedef struct Foo {
7   size_t x;
8   double y;
9 } Foo;
10 
TEST_F(ArrTest,testStruct)11 TEST_F(ArrTest, testStruct) {
12   Foo *arr = (Foo *)array_new(Foo, 8);
13 
14   for (size_t i = 0; i < 10; i++) {
15     arr = (Foo *)array_append(arr, (Foo){i});
16     ASSERT_EQ(i + 1, array_len(arr));
17   }
18 
19   for (size_t i = 0; i < 10; i++) {
20     ASSERT_EQ(i, arr[i].x);
21   }
22   // array_foreach(arr, elem, printf("%d\n", elem.x));
23   array_free(arr);
24 }
25 
TEST_F(ArrTest,testScalar)26 TEST_F(ArrTest, testScalar) {
27   int *ia = array_new(int, 8);
28   for (size_t i = 0; i < 100; i++) {
29     ia = array_append(ia, i);
30     ASSERT_EQ(i + 1, array_len(ia));
31     ASSERT_EQ(i, array_tail(ia));
32   }
33 
34   for (size_t i = 0; i < array_len(ia); i++) {
35     ASSERT_EQ(i, ia[i]);
36 
37     // printf("%d %zd\n", ia[i], array_len(ia));
38   }
39   array_free(ia);
40 }
41 
TEST_F(ArrTest,testStrings)42 TEST_F(ArrTest, testStrings) {
43   const char *strs[] = {"foo", "bar", "baz", NULL};
44   char **a = array_new(char *, 1);
45   size_t i = 0;
46   for (i = 0; strs[i] != NULL; i++) {
47     a = array_append(a, strdup(strs[i]));
48     ASSERT_EQ(i + 1, array_len(a));
49     ASSERT_STREQ(strs[i], array_tail(a));
50   }
51   for (size_t j = 0; j < i; j++) {
52     ASSERT_STREQ(strs[j], a[j]);
53 
54     // printf("%s\n", a[j]);
55   }
56   array_free_ex(a, free(*(void **)ptr));
57 }
58 
TEST_F(ArrTest,testTrimm)59 TEST_F(ArrTest, testTrimm) {
60   const char *strs[] = {"foo", "bar", "baz", NULL};
61   const char **a = array_new(const char *, 16);
62   size_t i = 0;
63   for (i = 0; strs[i] != NULL; i++) {
64     a = array_append(a, strs[i]);
65     ASSERT_EQ(i + 1, array_len(a));
66     ASSERT_STREQ(strs[i], array_tail(a));
67   }
68   a = array_trimm_cap(a, 2);
69   ASSERT_EQ(array_len(a), 2);
70   array_trimm_len(a, 1);
71   ASSERT_EQ(array_len(a), 1);
72   array_free(a);
73 }
74 
TEST_F(ArrTest,testEnsure)75 TEST_F(ArrTest, testEnsure) {
76   Foo *f = array_new(Foo, 1);
77   array_hdr_t *hdr = array_hdr(f);
78   Foo *tail = array_ensure_tail(&f, Foo);
79   // Make sure Valgrind does not complain!
80   tail->x = 0;
81   tail->y = 0;
82 
83   Foo *middle = array_ensure_at(&f, 5, Foo);
84   ASSERT_EQ(0, middle->x);
85   ASSERT_EQ(0, middle->y);
86 
87   for (size_t ii = 0; ii < array_len(f); ++ii) {
88     ASSERT_EQ(0, f[ii].x);
89     ASSERT_EQ(0, f[ii].y);
90   }
91 
92   // Try again with ensure_tail
93   tail = array_ensure_tail(&f, Foo);
94   f->x = 99;
95   f->y = 990;
96   tail->x = 100;
97   tail->y = 200;
98 
99   // ensure_append
100   Foo threeFoos[] = {{10, 11}, {20, 21}, {30, 31}};
101   size_t prevlen = array_len(f);
102   f = array_ensure_append(f, &threeFoos, 3, Foo);
103   ASSERT_EQ(10, f[prevlen].x);
104   ASSERT_EQ(20, f[prevlen + 1].x);
105   ASSERT_EQ(30, f[prevlen + 2].x);
106   array_free(f);
107 }
108 
TEST_F(ArrTest,testDelete)109 TEST_F(ArrTest, testDelete) {
110   int *a = array_new(int, 1);
111   a = array_append(a, 42);
112   a = array_del(a, 0);
113   ASSERT_EQ(0, array_len(a));
114 
115   // repopulate
116   for (size_t ii = 0; ii < 10; ++ii) {
117     a = array_append(a, ii);
118   }
119   ASSERT_EQ(10, array_len(a));
120   // Remove last element
121   for (ssize_t ii = 9; ii >= 0; --ii) {
122     ASSERT_LT(ii, array_len(a)) << ii;
123     a = array_del(a, ii);
124   }
125   ASSERT_EQ(0, array_len(a));
126   array_free(a);
127 
128   int tmp = 1;
129   a = NULL;
130   a = array_ensure_append(a, &tmp, 1, int);
131   ASSERT_EQ(1, array_len(a));
132   tmp = 2;
133   a = array_ensure_append(a, &tmp, 1, int);
134   ASSERT_EQ(2, array_len(a));
135   ASSERT_EQ(1, a[0]);
136   ASSERT_EQ(2, a[1]);
137 
138   a = array_del(a, 0);
139   ASSERT_EQ(1, array_len(a));
140   ASSERT_EQ(2, a[1]);
141   array_free(a);
142 }