xref: /aosp_15_r20/external/angle/src/common/string_utils_unittest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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