402 lines · cpp
1//===- StringExtrasTest.cpp - Unit tests for String extras ----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/StringExtras.h"10#include "llvm/Support/raw_ostream.h"11#include "gmock/gmock.h"12#include "gtest/gtest.h"13 14using namespace llvm;15 16TEST(StringExtrasTest, isPrint) {17 EXPECT_FALSE(isPrint('\0'));18 EXPECT_FALSE(isPrint('\t'));19 EXPECT_TRUE(isPrint('0'));20 EXPECT_TRUE(isPrint('a'));21 EXPECT_TRUE(isPrint('A'));22 EXPECT_TRUE(isPrint(' '));23 EXPECT_TRUE(isPrint('~'));24 EXPECT_TRUE(isPrint('?'));25}26 27TEST(StringExtrasTest, isSpace) {28 EXPECT_TRUE(isSpace(' '));29 EXPECT_TRUE(isSpace('\t'));30 EXPECT_TRUE(isSpace('\n'));31 EXPECT_TRUE(isSpace('\v'));32 EXPECT_TRUE(isSpace('\f'));33 EXPECT_TRUE(isSpace('\v'));34 EXPECT_FALSE(isSpace('\0'));35 EXPECT_FALSE(isSpace('_'));36}37 38TEST(StringExtrasTest, isLower) {39 EXPECT_TRUE(isLower('a'));40 EXPECT_TRUE(isLower('b'));41 EXPECT_TRUE(isLower('z'));42 EXPECT_FALSE(isLower('A'));43 EXPECT_FALSE(isLower('B'));44 EXPECT_FALSE(isLower('Z'));45 EXPECT_FALSE(isLower('\0'));46 EXPECT_FALSE(isLower('\t'));47 EXPECT_FALSE(isLower('\?'));48}49 50TEST(StringExtrasTest, isUpper) {51 EXPECT_FALSE(isUpper('a'));52 EXPECT_FALSE(isUpper('b'));53 EXPECT_FALSE(isUpper('z'));54 EXPECT_TRUE(isUpper('A'));55 EXPECT_TRUE(isUpper('B'));56 EXPECT_TRUE(isUpper('Z'));57 EXPECT_FALSE(isUpper('\0'));58 EXPECT_FALSE(isUpper('\t'));59 EXPECT_FALSE(isUpper('\?'));60}61 62TEST(StringExtrasTest, isPunct) {63 EXPECT_FALSE(isPunct('a'));64 EXPECT_FALSE(isPunct('b'));65 EXPECT_FALSE(isPunct('z'));66 EXPECT_TRUE(isPunct('-'));67 EXPECT_TRUE(isPunct(';'));68 EXPECT_TRUE(isPunct('@'));69 EXPECT_FALSE(isPunct('0'));70 EXPECT_FALSE(isPunct('1'));71 EXPECT_FALSE(isPunct('x'));72}73 74template <class ContainerT> void testJoin() {75 ContainerT Items;76 EXPECT_EQ("", join(Items.begin(), Items.end(), " <sep> "));77 78 Items = {"foo"};79 EXPECT_EQ("foo", join(Items.begin(), Items.end(), " <sep> "));80 81 Items = {"foo", "bar"};82 EXPECT_EQ("foo <sep> bar", join(Items.begin(), Items.end(), " <sep> "));83 84 Items = {"foo", "bar", "baz"};85 EXPECT_EQ("foo <sep> bar <sep> baz",86 join(Items.begin(), Items.end(), " <sep> "));87}88 89TEST(StringExtrasTest, Join) {90 {91 SCOPED_TRACE("std::vector<std::string>");92 testJoin<std::vector<std::string>>();93 }94 {95 SCOPED_TRACE("std::vector<const char*>");96 testJoin<std::vector<const char *>>();97 }98}99 100TEST(StringExtrasTest, JoinItems) {101 const char *Foo = "foo";102 std::string Bar = "bar";103 llvm::StringRef Baz = "baz";104 char X = 'x';105 106 EXPECT_EQ("", join_items(" <sep> "));107 EXPECT_EQ("", join_items('/'));108 109 EXPECT_EQ("foo", join_items(" <sep> ", Foo));110 EXPECT_EQ("foo", join_items('/', Foo));111 112 EXPECT_EQ("foo <sep> bar", join_items(" <sep> ", Foo, Bar));113 EXPECT_EQ("foo/bar", join_items('/', Foo, Bar));114 115 EXPECT_EQ("foo <sep> bar <sep> baz", join_items(" <sep> ", Foo, Bar, Baz));116 EXPECT_EQ("foo/bar/baz", join_items('/', Foo, Bar, Baz));117 118 EXPECT_EQ("foo <sep> bar <sep> baz <sep> x",119 join_items(" <sep> ", Foo, Bar, Baz, X));120 121 EXPECT_EQ("foo/bar/baz/x", join_items('/', Foo, Bar, Baz, X));122}123 124TEST(StringExtrasTest, ToAndFromHex) {125 std::vector<uint8_t> OddBytes = {0x5, 0xBD, 0x0D, 0x3E, 0xCD};126 std::string OddStr = "05BD0D3ECD";127 StringRef OddData(reinterpret_cast<const char *>(OddBytes.data()),128 OddBytes.size());129 EXPECT_EQ(OddStr, toHex(OddData));130 EXPECT_EQ(OddData, fromHex(StringRef(OddStr).drop_front()));131 EXPECT_EQ(StringRef(OddStr).lower(), toHex(OddData, true));132 133 std::vector<uint8_t> EvenBytes = {0xA5, 0xBD, 0x0D, 0x3E, 0xCD};134 std::string EvenStr = "A5BD0D3ECD";135 StringRef EvenData(reinterpret_cast<const char *>(EvenBytes.data()),136 EvenBytes.size());137 EXPECT_EQ(EvenStr, toHex(EvenData));138 EXPECT_EQ(EvenData, fromHex(EvenStr));139 EXPECT_EQ(StringRef(EvenStr).lower(), toHex(EvenData, true));140 141 std::string InvalidStr = "A50\xFF";142 std::string IgnoredOutput;143 EXPECT_FALSE(tryGetFromHex(InvalidStr, IgnoredOutput));144}145 146TEST(StringExtrasTest, UINT64ToHex) {147 EXPECT_EQ(utohexstr(0x0u, false, 2), "00");148 EXPECT_EQ(utohexstr(0xA0u), "A0");149 EXPECT_EQ(utohexstr(0xA0u, false, 4), "00A0");150 EXPECT_EQ(utohexstr(0xA0u, false, 8), "000000A0");151}152 153TEST(StringExtrasTest, to_float) {154 float F;155 EXPECT_TRUE(to_float("4.7", F));156 EXPECT_FLOAT_EQ(4.7f, F);157 158 double D;159 EXPECT_TRUE(to_float("4.7", D));160 EXPECT_DOUBLE_EQ(4.7, D);161 162 long double LD;163 EXPECT_TRUE(to_float("4.7", LD));164 EXPECT_DOUBLE_EQ(4.7, LD);165 166 EXPECT_FALSE(to_float("foo", F));167 EXPECT_FALSE(to_float("7.4 foo", F));168 EXPECT_FLOAT_EQ(4.7f, F); // F should be unchanged169}170 171TEST(StringExtrasTest, printLowerCase) {172 std::string str;173 raw_string_ostream OS(str);174 printLowerCase("ABCdefg01234.,&!~`'}\"", OS);175 EXPECT_EQ("abcdefg01234.,&!~`'}\"", OS.str());176}177 178TEST(StringExtrasTest, printEscapedString) {179 std::string str;180 raw_string_ostream OS(str);181 printEscapedString("ABCdef123&<>\\\"'\t", OS);182 EXPECT_EQ("ABCdef123&<>\\\\\\22'\\09", OS.str());183}184 185TEST(StringExtrasTest, printHTMLEscaped) {186 std::string str;187 raw_string_ostream OS(str);188 printHTMLEscaped("ABCdef123&<>\"'", OS);189 EXPECT_EQ("ABCdef123&<>"'", OS.str());190}191 192TEST(StringExtrasTest, ConvertToSnakeFromCamelCase) {193 auto testConvertToSnakeCase = [](llvm::StringRef input,194 llvm::StringRef expected) {195 EXPECT_EQ(convertToSnakeFromCamelCase(input), expected.str());196 };197 198 testConvertToSnakeCase("OpName", "op_name");199 testConvertToSnakeCase("opName", "op_name");200 testConvertToSnakeCase("OPName", "op_name");201 testConvertToSnakeCase("Intel_OCL_BI", "intel_ocl_bi");202 testConvertToSnakeCase("I32Attr", "i32_attr");203 testConvertToSnakeCase("opNAME", "op_name");204 testConvertToSnakeCase("opNAMe", "op_na_me");205 testConvertToSnakeCase("opnameE", "opname_e");206 testConvertToSnakeCase("OPNameOPName", "op_name_op_name");207 testConvertToSnakeCase("_OpName", "_op_name");208 testConvertToSnakeCase("Op_Name", "op_name");209 testConvertToSnakeCase("", "");210 testConvertToSnakeCase("A", "a");211 testConvertToSnakeCase("_", "_");212 testConvertToSnakeCase("a", "a");213 testConvertToSnakeCase("op_name", "op_name");214 testConvertToSnakeCase("_op_name", "_op_name");215 testConvertToSnakeCase("__op_name", "__op_name");216 testConvertToSnakeCase("op__name", "op__name");217}218 219TEST(StringExtrasTest, ConvertToCamelFromSnakeCase) {220 auto testConvertToCamelCase = [](bool capitalizeFirst, llvm::StringRef input,221 llvm::StringRef expected) {222 EXPECT_EQ(convertToCamelFromSnakeCase(input, capitalizeFirst),223 expected.str());224 };225 226 testConvertToCamelCase(false, "op_name", "opName");227 testConvertToCamelCase(false, "_op_name", "_opName");228 testConvertToCamelCase(false, "__op_name", "_OpName");229 testConvertToCamelCase(false, "op__name", "op_Name");230 testConvertToCamelCase(false, "", "");231 testConvertToCamelCase(false, "A", "A");232 testConvertToCamelCase(false, "_", "_");233 testConvertToCamelCase(false, "a", "a");234 testConvertToCamelCase(false, "OpName", "OpName");235 testConvertToCamelCase(false, "opName", "opName");236 testConvertToCamelCase(false, "_OpName", "_OpName");237 testConvertToCamelCase(false, "Op_Name", "Op_Name");238 testConvertToCamelCase(true, "op_name", "OpName");239 testConvertToCamelCase(true, "_op_name", "_opName");240 testConvertToCamelCase(true, "__op_name", "_OpName");241 testConvertToCamelCase(true, "op__name", "Op_Name");242 testConvertToCamelCase(true, "", "");243 testConvertToCamelCase(true, "A", "A");244 testConvertToCamelCase(true, "_", "_");245 testConvertToCamelCase(true, "a", "A");246 testConvertToCamelCase(true, "OpName", "OpName");247 testConvertToCamelCase(true, "_OpName", "_OpName");248 testConvertToCamelCase(true, "Op_Name", "Op_Name");249 testConvertToCamelCase(true, "opName", "OpName");250}251 252constexpr uint64_t MaxUint64 = std::numeric_limits<uint64_t>::max();253constexpr int64_t MaxInt64 = std::numeric_limits<int64_t>::max();254constexpr int64_t MinInt64 = std::numeric_limits<int64_t>::min();255 256TEST(StringExtrasTest, UToStr) {257 EXPECT_EQ("0", utostr(0));258 EXPECT_EQ("0", utostr(0, /*isNeg=*/false));259 EXPECT_EQ("1", utostr(1));260 EXPECT_EQ("1", utostr(1, /*isNeg=*/false));261 EXPECT_EQ(std::to_string(MaxUint64), utostr(MaxUint64));262 EXPECT_EQ(std::to_string(MaxUint64), utostr(MaxUint64, /*isNeg=*/false));263 264 EXPECT_EQ("-0", utostr(0, /*isNeg=*/true));265 EXPECT_EQ("-1", utostr(1, /*isNeg=*/true));266 EXPECT_EQ("-" + std::to_string(MaxInt64), utostr(MaxInt64, /*isNeg=*/true));267 constexpr uint64_t MinusMinInt64 = -static_cast<uint64_t>(MinInt64);268 EXPECT_EQ("-" + std::to_string(MinusMinInt64),269 utostr(MinusMinInt64, /*isNeg=*/true));270 EXPECT_EQ("-" + std::to_string(MaxUint64), utostr(MaxUint64, /*isNeg=*/true));271}272 273TEST(StringExtrasTest, IToStr) {274 EXPECT_EQ("0", itostr(0));275 EXPECT_EQ("1", itostr(1));276 EXPECT_EQ("-1", itostr(-1));277 EXPECT_EQ(std::to_string(MinInt64), itostr(MinInt64));278 EXPECT_EQ(std::to_string(MaxInt64), itostr(MaxInt64));279}280 281TEST(StringExtrasTest, ListSeparator) {282 ListSeparator LS;283 StringRef S = LS;284 EXPECT_EQ(S, "");285 S = LS;286 EXPECT_EQ(S, ", ");287 288 ListSeparator LS2(" ");289 S = LS2;290 EXPECT_EQ(S, "");291 S = LS2;292 EXPECT_EQ(S, " ");293 294 ListSeparator LS3(",", "{");295 S = LS3;296 EXPECT_EQ(S, "{");297 S = LS3;298 EXPECT_EQ(S, ",");299}300 301TEST(StringExtrasTest, toStringAPInt) {302 bool isSigned;303 304 EXPECT_EQ(toString(APInt(8, 0), 2, true, true), "0b0");305 EXPECT_EQ(toString(APInt(8, 0), 8, true, true), "00");306 EXPECT_EQ(toString(APInt(8, 0), 10, true, true), "0");307 EXPECT_EQ(toString(APInt(8, 0), 16, true, true), "0x0");308 EXPECT_EQ(toString(APInt(8, 0), 36, true, false), "0");309 310 isSigned = false;311 EXPECT_EQ(toString(APInt(8, 255, isSigned), 2, isSigned, true), "0b11111111");312 EXPECT_EQ(toString(APInt(8, 255, isSigned), 8, isSigned, true), "0377");313 EXPECT_EQ(toString(APInt(8, 255, isSigned), 10, isSigned, true), "255");314 EXPECT_EQ(toString(APInt(8, 255, isSigned), 16, isSigned, true), "0xFF");315 EXPECT_EQ(toString(APInt(8, 255, isSigned), 36, isSigned, false), "73");316 317 isSigned = true;318 EXPECT_EQ(toString(APInt(8, -1, isSigned), 2, isSigned, true), "-0b1");319 EXPECT_EQ(toString(APInt(8, -1, isSigned), 8, isSigned, true), "-01");320 EXPECT_EQ(toString(APInt(8, -1, isSigned), 10, isSigned, true), "-1");321 EXPECT_EQ(toString(APInt(8, -1, isSigned), 16, isSigned, true), "-0x1");322 EXPECT_EQ(toString(APInt(8, -1, isSigned), 36, isSigned, false), "-1");323}324 325TEST(StringExtrasTest, toStringAPSInt) {326 bool isUnsigned;327 328 EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 2), "0");329 EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 8), "0");330 EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 10), "0");331 EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 16), "0");332 333 isUnsigned = true;334 EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 2), "11111111");335 EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 8), "377");336 EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 10), "255");337 EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 16), "FF");338 339 isUnsigned = false;340 EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 2), "-1");341 EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 8), "-1");342 EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 10), "-1");343 EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 16), "-1");344}345 346TEST(StringExtrasTest, splitStringRef) {347 auto Spl = split("foo<=>bar<=><=>baz", "<=>");348 auto It = Spl.begin();349 auto End = Spl.end();350 351 ASSERT_NE(It, End);352 EXPECT_EQ(*It, StringRef("foo"));353 ASSERT_NE(++It, End);354 EXPECT_EQ(*It, StringRef("bar"));355 ASSERT_NE(++It, End);356 EXPECT_EQ(*It, StringRef(""));357 ASSERT_NE(++It, End);358 EXPECT_EQ(*It, StringRef("baz"));359 ASSERT_EQ(++It, End);360}361 362TEST(StringExtrasTest, splitStringRefForLoop) {363 llvm::SmallVector<StringRef, 4> Result;364 for (StringRef x : split("foo<=>bar<=><=>baz", "<=>"))365 Result.push_back(x);366 EXPECT_THAT(Result, testing::ElementsAre("foo", "bar", "", "baz"));367}368 369TEST(StringExtrasTest, splitChar) {370 auto Spl = split("foo,bar,,baz", ',');371 auto It = Spl.begin();372 auto End = Spl.end();373 374 ASSERT_NE(It, End);375 EXPECT_EQ(*It, StringRef("foo"));376 ASSERT_NE(++It, End);377 EXPECT_EQ(*It, StringRef("bar"));378 ASSERT_NE(++It, End);379 EXPECT_EQ(*It, StringRef(""));380 ASSERT_NE(++It, End);381 EXPECT_EQ(*It, StringRef("baz"));382 ASSERT_EQ(++It, End);383}384 385TEST(StringExtrasTest, splitCharForLoop) {386 llvm::SmallVector<StringRef, 4> Result;387 for (StringRef x : split("foo,bar,,baz", ','))388 Result.push_back(x);389 EXPECT_THAT(Result, testing::ElementsAre("foo", "bar", "", "baz"));390}391 392TEST(StringExtrasTest, arrayToStringRef) {393 auto roundTripTestString = [](llvm::StringRef Str) {394 EXPECT_EQ(Str, toStringRef(arrayRefFromStringRef<uint8_t>(Str)));395 EXPECT_EQ(Str, toStringRef(arrayRefFromStringRef<char>(Str)));396 };397 roundTripTestString("");398 roundTripTestString("foo");399 roundTripTestString("\0\n");400 roundTripTestString("\xFF\xFE");401}402