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