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
7 using node::Calloc;
8 using node::Malloc;
9 using node::MaybeStackBuffer;
10 using node::SPrintF;
11 using node::StringEqualNoCase;
12 using node::StringEqualNoCaseN;
13 using node::ToLower;
14 using node::UncheckedCalloc;
15 using node::UncheckedMalloc;
16
TEST(UtilTest,ListHead)17 TEST(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
TEST(UtilTest,StringEqualNoCase)71 TEST(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
TEST(UtilTest,StringEqualNoCaseN)81 TEST(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
TEST(UtilTest,ToLower)95 TEST(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
TEST(UtilTest,Malloc)108 TEST(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
TEST(UtilTest,Calloc)115 TEST(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
TEST(UtilTest,UncheckedMalloc)122 TEST(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
TEST(UtilTest,UncheckedCalloc)129 TEST(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
136 template <typename T>
MaybeStackBufferBasic()137 static 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
TEST(UtilTest,MaybeStackBuffer)215 TEST(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
TEST(UtilTest,SPrintF)256 TEST(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