xref: /third_party/node/test/cctest/test_util.cc (revision 1cb0ef41)
1#include "debug_utils-inl.h"
2#include "env-inl.h"
3#include "gtest/gtest.h"
4#include "simdutf.h"
5#include "util-inl.h"
6
7using node::Calloc;
8using node::Malloc;
9using node::MaybeStackBuffer;
10using node::SPrintF;
11using node::StringEqualNoCase;
12using node::StringEqualNoCaseN;
13using node::ToLower;
14using node::UncheckedCalloc;
15using node::UncheckedMalloc;
16
17TEST(UtilTest, ListHead) {
18  struct Item { node::ListNode<Item> node_; };
19  typedef node::ListHead<Item, &Item::node_> List;
20
21  List list;
22  EXPECT_TRUE(list.IsEmpty());
23
24  Item one;
25  EXPECT_TRUE(one.node_.IsEmpty());
26
27  list.PushBack(&one);
28  EXPECT_FALSE(list.IsEmpty());
29  EXPECT_FALSE(one.node_.IsEmpty());
30
31  {
32    List::Iterator it = list.begin();
33    EXPECT_NE(list.end(), it);
34    EXPECT_EQ(&one, *it);
35    ++it;
36    EXPECT_FALSE(it != list.end());  // Iterator only implements != operator.
37  }
38
39  Item two;
40  list.PushBack(&two);
41
42  {
43    List::Iterator it = list.begin();
44    EXPECT_NE(list.end(), it);
45    EXPECT_EQ(&one, *it);
46    ++it;
47    EXPECT_NE(list.end(), it);
48    EXPECT_EQ(&two, *it);
49    ++it;
50    EXPECT_FALSE(it != list.end());  // Iterator only implements != operator.
51  }
52
53  EXPECT_EQ(&one, list.PopFront());
54  EXPECT_TRUE(one.node_.IsEmpty());
55  EXPECT_FALSE(list.IsEmpty());
56
57  {
58    List::Iterator it = list.begin();
59    EXPECT_NE(list.end(), it);
60    EXPECT_EQ(&two, *it);
61    ++it;
62    EXPECT_FALSE(it != list.end());  // Iterator only implements != operator.
63  }
64
65  EXPECT_EQ(&two, list.PopFront());
66  EXPECT_TRUE(two.node_.IsEmpty());
67  EXPECT_TRUE(list.IsEmpty());
68  EXPECT_FALSE(list.begin() != list.end());
69}
70
71TEST(UtilTest, StringEqualNoCase) {
72  EXPECT_FALSE(StringEqualNoCase("a", "b"));
73  EXPECT_TRUE(StringEqualNoCase("", ""));
74  EXPECT_TRUE(StringEqualNoCase("equal", "equal"));
75  EXPECT_TRUE(StringEqualNoCase("equal", "EQUAL"));
76  EXPECT_TRUE(StringEqualNoCase("EQUAL", "EQUAL"));
77  EXPECT_FALSE(StringEqualNoCase("equal", "equals"));
78  EXPECT_FALSE(StringEqualNoCase("equals", "equal"));
79}
80
81TEST(UtilTest, StringEqualNoCaseN) {
82  EXPECT_FALSE(StringEqualNoCaseN("a", "b", strlen("a")));
83  EXPECT_TRUE(StringEqualNoCaseN("", "", strlen("")));
84  EXPECT_TRUE(StringEqualNoCaseN("equal", "equal", strlen("equal")));
85  EXPECT_TRUE(StringEqualNoCaseN("equal", "EQUAL", strlen("equal")));
86  EXPECT_TRUE(StringEqualNoCaseN("EQUAL", "EQUAL", strlen("equal")));
87  EXPECT_TRUE(StringEqualNoCaseN("equal", "equals", strlen("equal")));
88  EXPECT_FALSE(StringEqualNoCaseN("equal", "equals", strlen("equals")));
89  EXPECT_TRUE(StringEqualNoCaseN("equals", "equal", strlen("equal")));
90  EXPECT_FALSE(StringEqualNoCaseN("equals", "equal", strlen("equals")));
91  EXPECT_TRUE(StringEqualNoCaseN("abc\0abc", "abc\0efg", strlen("abcdefgh")));
92  EXPECT_FALSE(StringEqualNoCaseN("abc\0abc", "abcd\0efg", strlen("abcdefgh")));
93}
94
95TEST(UtilTest, ToLower) {
96  EXPECT_EQ('0', ToLower('0'));
97  EXPECT_EQ('a', ToLower('a'));
98  EXPECT_EQ('a', ToLower('A'));
99}
100
101#define TEST_AND_FREE(expression, size)                                        \
102  do {                                                                         \
103    auto pointer = expression(size);                                           \
104    EXPECT_EQ(pointer == nullptr, size == 0);                                  \
105    free(pointer);                                                             \
106  } while (0)
107
108TEST(UtilTest, Malloc) {
109  TEST_AND_FREE(Malloc<char>, 0);
110  TEST_AND_FREE(Malloc<char>, 1);
111  TEST_AND_FREE(Malloc, 0);
112  TEST_AND_FREE(Malloc, 1);
113}
114
115TEST(UtilTest, Calloc) {
116  TEST_AND_FREE(Calloc<char>, 0);
117  TEST_AND_FREE(Calloc<char>, 1);
118  TEST_AND_FREE(Calloc, 0);
119  TEST_AND_FREE(Calloc, 1);
120}
121
122TEST(UtilTest, UncheckedMalloc) {
123  TEST_AND_FREE(UncheckedMalloc<char>, 0);
124  TEST_AND_FREE(UncheckedMalloc<char>, 1);
125  TEST_AND_FREE(UncheckedMalloc, 0);
126  TEST_AND_FREE(UncheckedMalloc, 1);
127}
128
129TEST(UtilTest, UncheckedCalloc) {
130  TEST_AND_FREE(UncheckedCalloc<char>, 0);
131  TEST_AND_FREE(UncheckedCalloc<char>, 1);
132  TEST_AND_FREE(UncheckedCalloc, 0);
133  TEST_AND_FREE(UncheckedCalloc, 1);
134}
135
136template <typename T>
137static void MaybeStackBufferBasic() {
138  MaybeStackBuffer<T> buf;
139  size_t old_length;
140  size_t old_capacity;
141
142  // Default constructor.
143  EXPECT_EQ(0U, buf.length());
144  EXPECT_FALSE(buf.IsAllocated());
145  EXPECT_GT(buf.capacity(), buf.length());
146
147  // SetLength() expansion.
148  buf.SetLength(buf.capacity());
149  EXPECT_EQ(buf.capacity(), buf.length());
150  EXPECT_FALSE(buf.IsAllocated());
151
152  // Means of accessing raw buffer.
153  EXPECT_EQ(buf.out(), *buf);
154  EXPECT_EQ(&buf[0], *buf);
155
156  // Basic I/O.
157  for (size_t i = 0; i < buf.length(); i++)
158    buf[i] = static_cast<T>(i);
159  for (size_t i = 0; i < buf.length(); i++)
160    EXPECT_EQ(static_cast<T>(i), buf[i]);
161
162  // SetLengthAndZeroTerminate().
163  buf.SetLengthAndZeroTerminate(buf.capacity() - 1);
164  EXPECT_EQ(buf.capacity() - 1, buf.length());
165  for (size_t i = 0; i < buf.length(); i++)
166    EXPECT_EQ(static_cast<T>(i), buf[i]);
167  buf.SetLength(buf.capacity());
168  EXPECT_EQ(0, buf[buf.length() - 1]);
169
170  // Initial Realloc.
171  old_length = buf.length() - 1;
172  old_capacity = buf.capacity();
173  buf.AllocateSufficientStorage(buf.capacity() * 2);
174  EXPECT_EQ(buf.capacity(), buf.length());
175  EXPECT_TRUE(buf.IsAllocated());
176  for (size_t i = 0; i < old_length; i++)
177    EXPECT_EQ(static_cast<T>(i), buf[i]);
178  EXPECT_EQ(0, buf[old_length]);
179
180  // SetLength() reduction and expansion.
181  for (size_t i = 0; i < buf.length(); i++)
182    buf[i] = static_cast<T>(i);
183  buf.SetLength(10);
184  for (size_t i = 0; i < buf.length(); i++)
185    EXPECT_EQ(static_cast<T>(i), buf[i]);
186  buf.SetLength(buf.capacity());
187  for (size_t i = 0; i < buf.length(); i++)
188    EXPECT_EQ(static_cast<T>(i), buf[i]);
189
190  // Subsequent Realloc.
191  old_length = buf.length();
192  old_capacity = buf.capacity();
193  buf.AllocateSufficientStorage(old_capacity * 1.5);
194  EXPECT_EQ(buf.capacity(), buf.length());
195  EXPECT_EQ(static_cast<size_t>(old_capacity * 1.5), buf.length());
196  EXPECT_TRUE(buf.IsAllocated());
197  for (size_t i = 0; i < old_length; i++)
198    EXPECT_EQ(static_cast<T>(i), buf[i]);
199
200  // Basic I/O on Realloc'd buffer.
201  for (size_t i = 0; i < buf.length(); i++)
202    buf[i] = static_cast<T>(i);
203  for (size_t i = 0; i < buf.length(); i++)
204    EXPECT_EQ(static_cast<T>(i), buf[i]);
205
206  // Release().
207  T* rawbuf = buf.out();
208  buf.Release();
209  EXPECT_EQ(0U, buf.length());
210  EXPECT_FALSE(buf.IsAllocated());
211  EXPECT_GT(buf.capacity(), buf.length());
212  free(rawbuf);
213}
214
215TEST(UtilTest, MaybeStackBuffer) {
216  MaybeStackBufferBasic<uint8_t>();
217  MaybeStackBufferBasic<uint16_t>();
218
219  // Constructor with size parameter.
220  {
221    MaybeStackBuffer<unsigned char> buf(100);
222    EXPECT_EQ(100U, buf.length());
223    EXPECT_FALSE(buf.IsAllocated());
224    EXPECT_GT(buf.capacity(), buf.length());
225    buf.SetLength(buf.capacity());
226    EXPECT_EQ(buf.capacity(), buf.length());
227    EXPECT_FALSE(buf.IsAllocated());
228    for (size_t i = 0; i < buf.length(); i++)
229      buf[i] = static_cast<unsigned char>(i);
230    for (size_t i = 0; i < buf.length(); i++)
231      EXPECT_EQ(static_cast<unsigned char>(i), buf[i]);
232
233    MaybeStackBuffer<unsigned char> bigbuf(10000);
234    EXPECT_EQ(10000U, bigbuf.length());
235    EXPECT_TRUE(bigbuf.IsAllocated());
236    EXPECT_EQ(bigbuf.length(), bigbuf.capacity());
237    for (size_t i = 0; i < bigbuf.length(); i++)
238      bigbuf[i] = static_cast<unsigned char>(i);
239    for (size_t i = 0; i < bigbuf.length(); i++)
240      EXPECT_EQ(static_cast<unsigned char>(i), bigbuf[i]);
241  }
242
243  // Invalidated buffer.
244  {
245    MaybeStackBuffer<char> buf;
246    buf.Invalidate();
247    EXPECT_TRUE(buf.IsInvalidated());
248    EXPECT_FALSE(buf.IsAllocated());
249    EXPECT_EQ(0U, buf.length());
250    EXPECT_EQ(0U, buf.capacity());
251    buf.Invalidate();
252    EXPECT_TRUE(buf.IsInvalidated());
253  }
254}
255
256TEST(UtilTest, SPrintF) {
257  // %d, %u and %s all do the same thing. The actual C++ type is used to infer
258  // the right representation.
259  EXPECT_EQ(SPrintF("%s", false), "false");
260  EXPECT_EQ(SPrintF("%s", true), "true");
261  EXPECT_EQ(SPrintF("%d", true), "true");
262  EXPECT_EQ(SPrintF("%u", true), "true");
263  EXPECT_EQ(SPrintF("%d", 10000000000LL), "10000000000");
264  EXPECT_EQ(SPrintF("%d", -10000000000LL), "-10000000000");
265  EXPECT_EQ(SPrintF("%u", 10000000000LL), "10000000000");
266  EXPECT_EQ(SPrintF("%u", -10000000000LL), "-10000000000");
267  EXPECT_EQ(SPrintF("%i", 10), "10");
268  EXPECT_EQ(SPrintF("%d", 10), "10");
269  EXPECT_EQ(SPrintF("%x", 15), "f");
270  EXPECT_EQ(SPrintF("%x", 16), "10");
271  EXPECT_EQ(SPrintF("%X", 15), "F");
272  EXPECT_EQ(SPrintF("%X", 16), "10");
273  EXPECT_EQ(SPrintF("%o", 7), "7");
274  EXPECT_EQ(SPrintF("%o", 8), "10");
275
276  EXPECT_EQ(atof(SPrintF("%s", 0.5).c_str()), 0.5);
277  EXPECT_EQ(atof(SPrintF("%s", -0.5).c_str()), -0.5);
278
279  void (*fn)() = []() {};
280  void* p = reinterpret_cast<void*>(&fn);
281  EXPECT_GE(SPrintF("%p", fn).size(), 4u);
282  EXPECT_GE(SPrintF("%p", p).size(), 4u);
283
284  const std::string foo = "foo";
285  const char* bar = "bar";
286  EXPECT_EQ(SPrintF("%s %s", foo, "bar"), "foo bar");
287  EXPECT_EQ(SPrintF("%s %s", foo, bar), "foo bar");
288  EXPECT_EQ(SPrintF("%s", nullptr), "(null)");
289
290  EXPECT_EQ(SPrintF("[%% %s %%]", foo), "[% foo %]");
291
292  struct HasToString {
293    std::string ToString() const {
294      return "meow";
295    }
296  };
297  EXPECT_EQ(SPrintF("%s", HasToString{}), "meow");
298
299  const std::string with_zero = std::string("a") + '\0' + 'b';
300  EXPECT_EQ(SPrintF("%s", with_zero), with_zero);
301}
302