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