1 // 2 // Copyright 2015 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // string_utils_unittests: 7 // Unit tests for the string utils. 8 // 9 10 #include "string_utils.h" 11 12 #include <gmock/gmock.h> 13 #include <gtest/gtest.h> 14 15 using namespace angle; 16 17 namespace 18 { 19 20 // Basic SplitString tests TEST(StringUtilsTest,SplitStringBasics)21 TEST(StringUtilsTest, SplitStringBasics) 22 { 23 std::vector<std::string> r; 24 25 r = SplitString(std::string(), ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL); 26 EXPECT_TRUE(r.empty()); 27 28 // Empty separator list 29 r = SplitString("hello, world", "", KEEP_WHITESPACE, SPLIT_WANT_ALL); 30 ASSERT_EQ(1u, r.size()); 31 EXPECT_EQ("hello, world", r[0]); 32 33 // Should split on any of the separators. 34 r = SplitString("::,,;;", ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL); 35 ASSERT_EQ(7u, r.size()); 36 for (auto str : r) 37 ASSERT_TRUE(str.empty()); 38 39 r = SplitString("red, green; blue:", ",:;", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); 40 ASSERT_EQ(3u, r.size()); 41 EXPECT_EQ("red", r[0]); 42 EXPECT_EQ("green", r[1]); 43 EXPECT_EQ("blue", r[2]); 44 45 // Want to split a string along whitespace sequences. 46 r = SplitString(" red green \tblue\n", " \t\n", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); 47 ASSERT_EQ(3u, r.size()); 48 EXPECT_EQ("red", r[0]); 49 EXPECT_EQ("green", r[1]); 50 EXPECT_EQ("blue", r[2]); 51 52 // Weird case of splitting on spaces but not trimming. 53 r = SplitString(" red ", " ", TRIM_WHITESPACE, SPLIT_WANT_ALL); 54 ASSERT_EQ(3u, r.size()); 55 EXPECT_EQ("", r[0]); // Before the first space. 56 EXPECT_EQ("red", r[1]); 57 EXPECT_EQ("", r[2]); // After the last space. 58 } 59 60 // Check different whitespace and result types for SplitString TEST(StringUtilsTest,SplitStringWhitespaceAndResultType)61 TEST(StringUtilsTest, SplitStringWhitespaceAndResultType) 62 { 63 std::vector<std::string> r; 64 65 // Empty input handling. 66 r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_ALL); 67 EXPECT_TRUE(r.empty()); 68 r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); 69 EXPECT_TRUE(r.empty()); 70 71 // Input string is space and we're trimming. 72 r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL); 73 ASSERT_EQ(1u, r.size()); 74 EXPECT_EQ("", r[0]); 75 r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); 76 EXPECT_TRUE(r.empty()); 77 78 // Test all 4 combinations of flags on ", ,". 79 r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_ALL); 80 ASSERT_EQ(3u, r.size()); 81 EXPECT_EQ("", r[0]); 82 EXPECT_EQ(" ", r[1]); 83 EXPECT_EQ("", r[2]); 84 r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); 85 ASSERT_EQ(1u, r.size()); 86 ASSERT_EQ(" ", r[0]); 87 r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL); 88 ASSERT_EQ(3u, r.size()); 89 EXPECT_EQ("", r[0]); 90 EXPECT_EQ("", r[1]); 91 EXPECT_EQ("", r[2]); 92 r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); 93 ASSERT_TRUE(r.empty()); 94 } 95 96 // Tests for SplitStringAlongWhitespace TEST(StringUtilsTest,SplitStringAlongWhitespace)97 TEST(StringUtilsTest, SplitStringAlongWhitespace) 98 { 99 { 100 // No whitespace. 101 std::vector<std::string> r; 102 SplitStringAlongWhitespace("abcd", &r); 103 ASSERT_THAT(r, testing::ElementsAre("abcd")); 104 } 105 106 { 107 // Just whitespace. 108 std::vector<std::string> r; 109 SplitStringAlongWhitespace(" \t", &r); 110 ASSERT_THAT(r, testing::ElementsAre()); 111 } 112 113 { 114 // Consecutive whitespace of same type. 115 std::vector<std::string> r; 116 SplitStringAlongWhitespace("a b", &r); 117 ASSERT_THAT(r, testing::ElementsAre("a", "b")); 118 } 119 120 { 121 // Consecutive whitespace of different types. 122 std::vector<std::string> r; 123 SplitStringAlongWhitespace("ab \tcd", &r); 124 ASSERT_THAT(r, testing::ElementsAre("ab", "cd")); 125 } 126 127 { 128 // Non-empty output std::vector. 129 std::vector<std::string> r; 130 r.push_back("z"); 131 SplitStringAlongWhitespace("abc", &r); 132 ASSERT_THAT(r, testing::ElementsAre("z", "abc")); 133 } 134 } 135 136 // Tests for TrimString TEST(StringUtilsTest,TrimString)137 TEST(StringUtilsTest, TrimString) 138 { 139 // Basic tests 140 EXPECT_EQ("a", TrimString("a", kWhitespaceASCII)); 141 EXPECT_EQ("a", TrimString(" a", kWhitespaceASCII)); 142 EXPECT_EQ("a", TrimString("a ", kWhitespaceASCII)); 143 EXPECT_EQ("a", TrimString(" a ", kWhitespaceASCII)); 144 145 // Tests with empty strings 146 EXPECT_EQ("", TrimString("", kWhitespaceASCII)); 147 EXPECT_EQ("", TrimString(" \n\r\t", kWhitespaceASCII)); 148 EXPECT_EQ(" foo ", TrimString(" foo ", "")); 149 150 // Tests it doesn't removes characters in the middle 151 EXPECT_EQ("foo bar", TrimString(" foo bar ", kWhitespaceASCII)); 152 153 // Test with non-whitespace trimChars 154 EXPECT_EQ(" ", TrimString("foo bar", "abcdefghijklmnopqrstuvwxyz")); 155 } 156 157 // Basic functionality tests for HexStringToUInt TEST(StringUtilsTest,HexStringToUIntBasic)158 TEST(StringUtilsTest, HexStringToUIntBasic) 159 { 160 unsigned int uintValue; 161 162 std::string emptyString; 163 ASSERT_FALSE(HexStringToUInt(emptyString, &uintValue)); 164 165 std::string testStringA("0xBADF00D"); 166 ASSERT_TRUE(HexStringToUInt(testStringA, &uintValue)); 167 EXPECT_EQ(0xBADF00Du, uintValue); 168 169 std::string testStringB("0xBADFOOD"); 170 EXPECT_FALSE(HexStringToUInt(testStringB, &uintValue)); 171 172 std::string testStringC("BADF00D"); 173 EXPECT_TRUE(HexStringToUInt(testStringC, &uintValue)); 174 EXPECT_EQ(0xBADF00Du, uintValue); 175 176 std::string testStringD("0x BADF00D"); 177 EXPECT_FALSE(HexStringToUInt(testStringD, &uintValue)); 178 } 179 180 // Tests for ToCamelCase TEST(StringUtilsTest,ToCamelCase)181 TEST(StringUtilsTest, ToCamelCase) 182 { 183 // No underscore in input; expect identical output 184 EXPECT_EQ("", ToCamelCase("")); 185 EXPECT_EQ("a", ToCamelCase("a")); 186 EXPECT_EQ("AbCdEfG", ToCamelCase("AbCdEfG")); 187 EXPECT_EQ("aBcDeFg", ToCamelCase("aBcDeFg")); 188 189 // Underscore should be removed and the next character turned upper case 190 EXPECT_EQ("", ToCamelCase("_")); 191 EXPECT_EQ("aB", ToCamelCase("a_b")); 192 EXPECT_EQ("aB", ToCamelCase("a_b")); 193 EXPECT_EQ("camelCase", ToCamelCase("camel_case")); 194 EXPECT_EQ("abCDeBEfG", ToCamelCase("abCDe_bEfG")); 195 196 // Multiple underscores 197 EXPECT_EQ("aBCDEFG", ToCamelCase("a_b_c_d_e_f_g")); 198 EXPECT_EQ("abCdEfGh", ToCamelCase("ab_cd_ef_gh")); 199 EXPECT_EQ("aShortName", ToCamelCase("a_short_name")); 200 EXPECT_EQ("someShortWords", ToCamelCase("some_short_words")); 201 EXPECT_EQ("bunchOLetters", ToCamelCase("bunch_o_letters")); 202 EXPECT_EQ("whatEndsInE", ToCamelCase("what_ends_in_e")); 203 EXPECT_EQ("adjustSrcDstRegionForBlitFramebuffer", 204 ToCamelCase("adjust_src_dst_region_for_BlitFramebuffer")); 205 206 // Uppercase after underscore 207 EXPECT_EQ("abCDEFGh", ToCamelCase("ab_CD_eF_Gh")); 208 EXPECT_EQ("IWasThere", ToCamelCase("I_was_there")); 209 EXPECT_EQ("whereDidTHATComeFrom", ToCamelCase("where_did_THAT_come_from")); 210 211 // Digits 212 EXPECT_EQ("ab123c4deF5gHi6J", ToCamelCase("ab1_2_3c_4de_f5g_hi6_j")); 213 EXPECT_EQ("maxSize16KB", ToCamelCase("max_size_16KB")); 214 EXPECT_EQ("supportRGBA8", ToCamelCase("support_RGBA8")); 215 } 216 217 // Basic functionality for NamesMatchWithWildcard. TEST(StringUtilsTest,NamesMatchWithWildcard)218 TEST(StringUtilsTest, NamesMatchWithWildcard) 219 { 220 EXPECT_TRUE(NamesMatchWithWildcard("ASDF", "ASDF")); 221 EXPECT_TRUE(NamesMatchWithWildcard("A*", "ASDF")); 222 EXPECT_TRUE(NamesMatchWithWildcard("AS*", "ASDF")); 223 EXPECT_TRUE(NamesMatchWithWildcard("ASD*", "ASDF")); 224 EXPECT_TRUE(NamesMatchWithWildcard("ASDF*", "ASDF")); 225 226 EXPECT_TRUE(NamesMatchWithWildcard("*F", "ASDF")); 227 EXPECT_TRUE(NamesMatchWithWildcard("*DF", "ASDF")); 228 EXPECT_TRUE(NamesMatchWithWildcard("*SDF", "ASDF")); 229 EXPECT_TRUE(NamesMatchWithWildcard("*ASDF", "ASDF")); 230 231 EXPECT_TRUE(NamesMatchWithWildcard("AS**", "ASDF")); 232 EXPECT_TRUE(NamesMatchWithWildcard("AS***", "ASDF")); 233 EXPECT_TRUE(NamesMatchWithWildcard("**DF", "ASDF")); 234 EXPECT_TRUE(NamesMatchWithWildcard("***DF", "ASDF")); 235 236 EXPECT_TRUE(NamesMatchWithWildcard("A*F", "ASDF")); 237 EXPECT_TRUE(NamesMatchWithWildcard("A**F", "ASDF")); 238 EXPECT_TRUE(NamesMatchWithWildcard("*SD*", "ASDF")); 239 EXPECT_TRUE(NamesMatchWithWildcard("*S*D*", "ASDF")); 240 241 EXPECT_TRUE(NamesMatchWithWildcard("ASD*", "ASDF*")); 242 } 243 244 // Note: ReadFileToString is harder to test 245 246 class BeginsWithTest : public testing::Test 247 { 248 public: BeginsWithTest()249 BeginsWithTest() : mMode(TestMode::CHAR_ARRAY) {} 250 251 enum class TestMode 252 { 253 CHAR_ARRAY, 254 STRING_AND_CHAR_ARRAY, 255 STRING 256 }; 257 setMode(TestMode mode)258 void setMode(TestMode mode) { mMode = mode; } 259 runBeginsWith(const char * str,const char * prefix)260 bool runBeginsWith(const char *str, const char *prefix) 261 { 262 if (mMode == TestMode::CHAR_ARRAY) 263 { 264 return BeginsWith(str, prefix); 265 } 266 if (mMode == TestMode::STRING_AND_CHAR_ARRAY) 267 { 268 return BeginsWith(std::string(str), prefix); 269 } 270 return BeginsWith(std::string(str), std::string(prefix)); 271 } 272 runTest()273 void runTest() 274 { 275 ASSERT_FALSE(runBeginsWith("foo", "bar")); 276 ASSERT_FALSE(runBeginsWith("", "foo")); 277 ASSERT_FALSE(runBeginsWith("foo", "foobar")); 278 279 ASSERT_TRUE(runBeginsWith("foobar", "foo")); 280 ASSERT_TRUE(runBeginsWith("foobar", "")); 281 ASSERT_TRUE(runBeginsWith("foo", "foo")); 282 ASSERT_TRUE(runBeginsWith("", "")); 283 } 284 285 private: 286 TestMode mMode; 287 }; 288 289 // Test that BeginsWith works correctly for const char * arguments. TEST_F(BeginsWithTest,CharArrays)290 TEST_F(BeginsWithTest, CharArrays) 291 { 292 setMode(TestMode::CHAR_ARRAY); 293 runTest(); 294 } 295 296 // Test that BeginsWith works correctly for std::string and const char * arguments. TEST_F(BeginsWithTest,StringAndCharArray)297 TEST_F(BeginsWithTest, StringAndCharArray) 298 { 299 setMode(TestMode::STRING_AND_CHAR_ARRAY); 300 runTest(); 301 } 302 303 // Test that BeginsWith works correctly for std::string arguments. TEST_F(BeginsWithTest,Strings)304 TEST_F(BeginsWithTest, Strings) 305 { 306 setMode(TestMode::STRING); 307 runTest(); 308 } 309 310 class EndsWithTest : public testing::Test 311 { 312 public: EndsWithTest()313 EndsWithTest() : mMode(TestMode::CHAR_ARRAY) {} 314 315 enum class TestMode 316 { 317 CHAR_ARRAY, 318 STRING_AND_CHAR_ARRAY, 319 STRING 320 }; 321 setMode(TestMode mode)322 void setMode(TestMode mode) { mMode = mode; } 323 runEndsWith(const char * str,const char * suffix)324 bool runEndsWith(const char *str, const char *suffix) 325 { 326 if (mMode == TestMode::CHAR_ARRAY) 327 { 328 return EndsWith(str, suffix); 329 } 330 if (mMode == TestMode::STRING_AND_CHAR_ARRAY) 331 { 332 return EndsWith(std::string(str), suffix); 333 } 334 return EndsWith(std::string(str), std::string(suffix)); 335 } 336 runTest()337 void runTest() 338 { 339 ASSERT_FALSE(EndsWith("foo", "bar")); 340 ASSERT_FALSE(EndsWith("", "bar")); 341 ASSERT_FALSE(EndsWith("foo", "foobar")); 342 343 ASSERT_TRUE(EndsWith("foobar", "bar")); 344 ASSERT_TRUE(EndsWith("foobar", "")); 345 ASSERT_TRUE(EndsWith("bar", "bar")); 346 ASSERT_TRUE(EndsWith("", "")); 347 } 348 349 private: 350 TestMode mMode; 351 }; 352 353 // Test that EndsWith works correctly for const char * arguments. TEST_F(EndsWithTest,CharArrays)354 TEST_F(EndsWithTest, CharArrays) 355 { 356 setMode(TestMode::CHAR_ARRAY); 357 runTest(); 358 } 359 360 // Test that EndsWith works correctly for std::string and const char * arguments. TEST_F(EndsWithTest,StringAndCharArray)361 TEST_F(EndsWithTest, StringAndCharArray) 362 { 363 setMode(TestMode::STRING_AND_CHAR_ARRAY); 364 runTest(); 365 } 366 367 // Test that EndsWith works correctly for std::string arguments. TEST_F(EndsWithTest,Strings)368 TEST_F(EndsWithTest, Strings) 369 { 370 setMode(TestMode::STRING); 371 runTest(); 372 } 373 374 } // anonymous namespace 375