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 <gtest/gtest.h>
13
14 using namespace angle;
15
16 namespace
17 {
18
19 // Basic SplitString tests
TEST(StringUtilsTest,SplitString_Basics)20 TEST(StringUtilsTest, SplitString_Basics)
21 {
22 std::vector<std::string> r;
23
24 r = SplitString(std::string(), ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL);
25 EXPECT_TRUE(r.empty());
26
27 // Empty separator list
28 r = SplitString("hello, world", "", KEEP_WHITESPACE, SPLIT_WANT_ALL);
29 ASSERT_EQ(1u, r.size());
30 EXPECT_EQ("hello, world", r[0]);
31
32 // Should split on any of the separators.
33 r = SplitString("::,,;;", ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL);
34 ASSERT_EQ(7u, r.size());
35 for (auto str : r)
36 ASSERT_TRUE(str.empty());
37
38 r = SplitString("red, green; blue:", ",:;", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
39 ASSERT_EQ(3u, r.size());
40 EXPECT_EQ("red", r[0]);
41 EXPECT_EQ("green", r[1]);
42 EXPECT_EQ("blue", r[2]);
43
44 // Want to split a string along whitespace sequences.
45 r = SplitString(" red green \tblue\n", " \t\n", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
46 ASSERT_EQ(3u, r.size());
47 EXPECT_EQ("red", r[0]);
48 EXPECT_EQ("green", r[1]);
49 EXPECT_EQ("blue", r[2]);
50
51 // Weird case of splitting on spaces but not trimming.
52 r = SplitString(" red ", " ", TRIM_WHITESPACE, SPLIT_WANT_ALL);
53 ASSERT_EQ(3u, r.size());
54 EXPECT_EQ("", r[0]); // Before the first space.
55 EXPECT_EQ("red", r[1]);
56 EXPECT_EQ("", r[2]); // After the last space.
57 }
58
59 // Check different whitespace and result types for SplitString
TEST(StringUtilsTest,SplitString_WhitespaceAndResultType)60 TEST(StringUtilsTest, SplitString_WhitespaceAndResultType)
61 {
62 std::vector<std::string> r;
63
64 // Empty input handling.
65 r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_ALL);
66 EXPECT_TRUE(r.empty());
67 r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY);
68 EXPECT_TRUE(r.empty());
69
70 // Input string is space and we're trimming.
71 r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
72 ASSERT_EQ(1u, r.size());
73 EXPECT_EQ("", r[0]);
74 r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
75 EXPECT_TRUE(r.empty());
76
77 // Test all 4 combinations of flags on ", ,".
78 r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_ALL);
79 ASSERT_EQ(3u, r.size());
80 EXPECT_EQ("", r[0]);
81 EXPECT_EQ(" ", r[1]);
82 EXPECT_EQ("", r[2]);
83 r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY);
84 ASSERT_EQ(1u, r.size());
85 ASSERT_EQ(" ", r[0]);
86 r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
87 ASSERT_EQ(3u, r.size());
88 EXPECT_EQ("", r[0]);
89 EXPECT_EQ("", r[1]);
90 EXPECT_EQ("", r[2]);
91 r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
92 ASSERT_TRUE(r.empty());
93 }
94
95 // Tests for TrimString
TEST(StringUtilsTest,TrimString)96 TEST(StringUtilsTest, TrimString)
97 {
98 // Basic tests
99 EXPECT_EQ("a", TrimString("a", kWhitespaceASCII));
100 EXPECT_EQ("a", TrimString(" a", kWhitespaceASCII));
101 EXPECT_EQ("a", TrimString("a ", kWhitespaceASCII));
102 EXPECT_EQ("a", TrimString(" a ", kWhitespaceASCII));
103
104 // Tests with empty strings
105 EXPECT_EQ("", TrimString("", kWhitespaceASCII));
106 EXPECT_EQ("", TrimString(" \n\r\t", kWhitespaceASCII));
107 EXPECT_EQ(" foo ", TrimString(" foo ", ""));
108
109 // Tests it doesn't removes characters in the middle
110 EXPECT_EQ("foo bar", TrimString(" foo bar ", kWhitespaceASCII));
111
112 // Test with non-whitespace trimChars
113 EXPECT_EQ(" ", TrimString("foo bar", "abcdefghijklmnopqrstuvwxyz"));
114 }
115
116 // Basic functionality tests for HexStringToUInt
TEST(StringUtilsTest,HexStringToUIntBasic)117 TEST(StringUtilsTest, HexStringToUIntBasic)
118 {
119 unsigned int uintValue;
120
121 std::string emptyString;
122 ASSERT_FALSE(HexStringToUInt(emptyString, &uintValue));
123
124 std::string testStringA("0xBADF00D");
125 ASSERT_TRUE(HexStringToUInt(testStringA, &uintValue));
126 EXPECT_EQ(0xBADF00Du, uintValue);
127
128 std::string testStringB("0xBADFOOD");
129 EXPECT_FALSE(HexStringToUInt(testStringB, &uintValue));
130
131 std::string testStringC("BADF00D");
132 EXPECT_TRUE(HexStringToUInt(testStringC, &uintValue));
133 EXPECT_EQ(0xBADF00Du, uintValue);
134
135 std::string testStringD("0x BADF00D");
136 EXPECT_FALSE(HexStringToUInt(testStringD, &uintValue));
137 }
138
139 // Note: ReadFileToString is harder to test
140
141 class BeginsWithTest : public testing::Test
142 {
143 public:
BeginsWithTest()144 BeginsWithTest() : mMode(TestMode::CHAR_ARRAY) {}
145
146 enum class TestMode
147 {
148 CHAR_ARRAY,
149 STRING_AND_CHAR_ARRAY,
150 STRING
151 };
152
setMode(TestMode mode)153 void setMode(TestMode mode) { mMode = mode; }
154
runBeginsWith(const char * str,const char * prefix)155 bool runBeginsWith(const char *str, const char *prefix)
156 {
157 if (mMode == TestMode::CHAR_ARRAY)
158 {
159 return BeginsWith(str, prefix);
160 }
161 if (mMode == TestMode::STRING_AND_CHAR_ARRAY)
162 {
163 return BeginsWith(std::string(str), prefix);
164 }
165 return BeginsWith(std::string(str), std::string(prefix));
166 }
167
runTest()168 void runTest()
169 {
170 ASSERT_FALSE(runBeginsWith("foo", "bar"));
171 ASSERT_FALSE(runBeginsWith("", "foo"));
172 ASSERT_FALSE(runBeginsWith("foo", "foobar"));
173
174 ASSERT_TRUE(runBeginsWith("foobar", "foo"));
175 ASSERT_TRUE(runBeginsWith("foobar", ""));
176 ASSERT_TRUE(runBeginsWith("foo", "foo"));
177 ASSERT_TRUE(runBeginsWith("", ""));
178 }
179
180 private:
181 TestMode mMode;
182 };
183
184 // Test that BeginsWith works correctly for const char * arguments.
TEST_F(BeginsWithTest,CharArrays)185 TEST_F(BeginsWithTest, CharArrays)
186 {
187 setMode(TestMode::CHAR_ARRAY);
188 runTest();
189 }
190
191 // Test that BeginsWith works correctly for std::string and const char * arguments.
TEST_F(BeginsWithTest,StringAndCharArray)192 TEST_F(BeginsWithTest, StringAndCharArray)
193 {
194 setMode(TestMode::STRING_AND_CHAR_ARRAY);
195 runTest();
196 }
197
198 // Test that BeginsWith works correctly for std::string arguments.
TEST_F(BeginsWithTest,Strings)199 TEST_F(BeginsWithTest, Strings)
200 {
201 setMode(TestMode::STRING);
202 runTest();
203 }
204
205 class EndsWithTest : public testing::Test
206 {
207 public:
EndsWithTest()208 EndsWithTest() : mMode(TestMode::CHAR_ARRAY) {}
209
210 enum class TestMode
211 {
212 CHAR_ARRAY,
213 STRING_AND_CHAR_ARRAY,
214 STRING
215 };
216
setMode(TestMode mode)217 void setMode(TestMode mode) { mMode = mode; }
218
runEndsWith(const char * str,const char * suffix)219 bool runEndsWith(const char *str, const char *suffix)
220 {
221 if (mMode == TestMode::CHAR_ARRAY)
222 {
223 return EndsWith(str, suffix);
224 }
225 if (mMode == TestMode::STRING_AND_CHAR_ARRAY)
226 {
227 return EndsWith(std::string(str), suffix);
228 }
229 return EndsWith(std::string(str), std::string(suffix));
230 }
231
runTest()232 void runTest()
233 {
234 ASSERT_FALSE(EndsWith("foo", "bar"));
235 ASSERT_FALSE(EndsWith("", "bar"));
236 ASSERT_FALSE(EndsWith("foo", "foobar"));
237
238 ASSERT_TRUE(EndsWith("foobar", "bar"));
239 ASSERT_TRUE(EndsWith("foobar", ""));
240 ASSERT_TRUE(EndsWith("bar", "bar"));
241 ASSERT_TRUE(EndsWith("", ""));
242 }
243
244 private:
245 TestMode mMode;
246 };
247
248 // Test that EndsWith works correctly for const char * arguments.
TEST_F(EndsWithTest,CharArrays)249 TEST_F(EndsWithTest, CharArrays)
250 {
251 setMode(TestMode::CHAR_ARRAY);
252 runTest();
253 }
254
255 // Test that EndsWith works correctly for std::string and const char * arguments.
TEST_F(EndsWithTest,StringAndCharArray)256 TEST_F(EndsWithTest, StringAndCharArray)
257 {
258 setMode(TestMode::STRING_AND_CHAR_ARRAY);
259 runTest();
260 }
261
262 // Test that EndsWith works correctly for std::string arguments.
TEST_F(EndsWithTest,Strings)263 TEST_F(EndsWithTest, Strings)
264 {
265 setMode(TestMode::STRING);
266 runTest();
267 }
268
269 } // anonymous namespace
270