xref: /aosp_15_r20/external/angle/third_party/abseil-cpp/absl/strings/ascii_test.cc (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/strings/ascii.h"
16 
17 #include <algorithm>
18 #include <cctype>
19 #include <clocale>
20 #include <cstring>
21 #include <string>
22 
23 #include "gtest/gtest.h"
24 #include "absl/base/macros.h"
25 #include "absl/strings/string_view.h"
26 
27 namespace {
28 
TEST(AsciiIsFoo,All)29 TEST(AsciiIsFoo, All) {
30   for (int i = 0; i < 256; i++) {
31     const auto c = static_cast<unsigned char>(i);
32     if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
33       EXPECT_TRUE(absl::ascii_isalpha(c)) << ": failed on " << c;
34     else
35       EXPECT_TRUE(!absl::ascii_isalpha(c)) << ": failed on " << c;
36   }
37   for (int i = 0; i < 256; i++) {
38     const auto c = static_cast<unsigned char>(i);
39     if ((c >= '0' && c <= '9'))
40       EXPECT_TRUE(absl::ascii_isdigit(c)) << ": failed on " << c;
41     else
42       EXPECT_TRUE(!absl::ascii_isdigit(c)) << ": failed on " << c;
43   }
44   for (int i = 0; i < 256; i++) {
45     const auto c = static_cast<unsigned char>(i);
46     if (absl::ascii_isalpha(c) || absl::ascii_isdigit(c))
47       EXPECT_TRUE(absl::ascii_isalnum(c)) << ": failed on " << c;
48     else
49       EXPECT_TRUE(!absl::ascii_isalnum(c)) << ": failed on " << c;
50   }
51   for (int i = 0; i < 256; i++) {
52     const auto c = static_cast<unsigned char>(i);
53     if (i != '\0' && strchr(" \r\n\t\v\f", i))
54       EXPECT_TRUE(absl::ascii_isspace(c)) << ": failed on " << c;
55     else
56       EXPECT_TRUE(!absl::ascii_isspace(c)) << ": failed on " << c;
57   }
58   for (int i = 0; i < 256; i++) {
59     const auto c = static_cast<unsigned char>(i);
60     if (i >= 32 && i < 127)
61       EXPECT_TRUE(absl::ascii_isprint(c)) << ": failed on " << c;
62     else
63       EXPECT_TRUE(!absl::ascii_isprint(c)) << ": failed on " << c;
64   }
65   for (int i = 0; i < 256; i++) {
66     const auto c = static_cast<unsigned char>(i);
67     if (absl::ascii_isprint(c) && !absl::ascii_isspace(c) &&
68         !absl::ascii_isalnum(c)) {
69       EXPECT_TRUE(absl::ascii_ispunct(c)) << ": failed on " << c;
70     } else {
71       EXPECT_TRUE(!absl::ascii_ispunct(c)) << ": failed on " << c;
72     }
73   }
74   for (int i = 0; i < 256; i++) {
75     const auto c = static_cast<unsigned char>(i);
76     if (i == ' ' || i == '\t')
77       EXPECT_TRUE(absl::ascii_isblank(c)) << ": failed on " << c;
78     else
79       EXPECT_TRUE(!absl::ascii_isblank(c)) << ": failed on " << c;
80   }
81   for (int i = 0; i < 256; i++) {
82     const auto c = static_cast<unsigned char>(i);
83     if (i < 32 || i == 127)
84       EXPECT_TRUE(absl::ascii_iscntrl(c)) << ": failed on " << c;
85     else
86       EXPECT_TRUE(!absl::ascii_iscntrl(c)) << ": failed on " << c;
87   }
88   for (int i = 0; i < 256; i++) {
89     const auto c = static_cast<unsigned char>(i);
90     if (absl::ascii_isdigit(c) || (i >= 'A' && i <= 'F') ||
91         (i >= 'a' && i <= 'f')) {
92       EXPECT_TRUE(absl::ascii_isxdigit(c)) << ": failed on " << c;
93     } else {
94       EXPECT_TRUE(!absl::ascii_isxdigit(c)) << ": failed on " << c;
95     }
96   }
97   for (int i = 0; i < 256; i++) {
98     const auto c = static_cast<unsigned char>(i);
99     if (i > 32 && i < 127)
100       EXPECT_TRUE(absl::ascii_isgraph(c)) << ": failed on " << c;
101     else
102       EXPECT_TRUE(!absl::ascii_isgraph(c)) << ": failed on " << c;
103   }
104   for (int i = 0; i < 256; i++) {
105     const auto c = static_cast<unsigned char>(i);
106     if (i >= 'A' && i <= 'Z')
107       EXPECT_TRUE(absl::ascii_isupper(c)) << ": failed on " << c;
108     else
109       EXPECT_TRUE(!absl::ascii_isupper(c)) << ": failed on " << c;
110   }
111   for (int i = 0; i < 256; i++) {
112     const auto c = static_cast<unsigned char>(i);
113     if (i >= 'a' && i <= 'z')
114       EXPECT_TRUE(absl::ascii_islower(c)) << ": failed on " << c;
115     else
116       EXPECT_TRUE(!absl::ascii_islower(c)) << ": failed on " << c;
117   }
118   for (unsigned char c = 0; c < 128; c++) {
119     EXPECT_TRUE(absl::ascii_isascii(c)) << ": failed on " << c;
120   }
121   for (int i = 128; i < 256; i++) {
122     const auto c = static_cast<unsigned char>(i);
123     EXPECT_TRUE(!absl::ascii_isascii(c)) << ": failed on " << c;
124   }
125 }
126 
127 // Checks that absl::ascii_isfoo returns the same value as isfoo in the C
128 // locale.
TEST(AsciiIsFoo,SameAsIsFoo)129 TEST(AsciiIsFoo, SameAsIsFoo) {
130 #ifndef __ANDROID__
131   // temporarily change locale to C. It should already be C, but just for safety
132   const char* old_locale = setlocale(LC_CTYPE, "C");
133   ASSERT_TRUE(old_locale != nullptr);
134 #endif
135 
136   for (int i = 0; i < 256; i++) {
137     const auto c = static_cast<unsigned char>(i);
138     EXPECT_EQ(isalpha(c) != 0, absl::ascii_isalpha(c)) << c;
139     EXPECT_EQ(isdigit(c) != 0, absl::ascii_isdigit(c)) << c;
140     EXPECT_EQ(isalnum(c) != 0, absl::ascii_isalnum(c)) << c;
141     EXPECT_EQ(isspace(c) != 0, absl::ascii_isspace(c)) << c;
142     EXPECT_EQ(ispunct(c) != 0, absl::ascii_ispunct(c)) << c;
143     EXPECT_EQ(isblank(c) != 0, absl::ascii_isblank(c)) << c;
144     EXPECT_EQ(iscntrl(c) != 0, absl::ascii_iscntrl(c)) << c;
145     EXPECT_EQ(isxdigit(c) != 0, absl::ascii_isxdigit(c)) << c;
146     EXPECT_EQ(isprint(c) != 0, absl::ascii_isprint(c)) << c;
147     EXPECT_EQ(isgraph(c) != 0, absl::ascii_isgraph(c)) << c;
148     EXPECT_EQ(isupper(c) != 0, absl::ascii_isupper(c)) << c;
149     EXPECT_EQ(islower(c) != 0, absl::ascii_islower(c)) << c;
150     EXPECT_EQ(isascii(c) != 0, absl::ascii_isascii(c)) << c;
151   }
152 
153 #ifndef __ANDROID__
154   // restore the old locale.
155   ASSERT_TRUE(setlocale(LC_CTYPE, old_locale));
156 #endif
157 }
158 
TEST(AsciiToFoo,All)159 TEST(AsciiToFoo, All) {
160 #ifndef __ANDROID__
161   // temporarily change locale to C. It should already be C, but just for safety
162   const char* old_locale = setlocale(LC_CTYPE, "C");
163   ASSERT_TRUE(old_locale != nullptr);
164 #endif
165 
166   for (int i = 0; i < 256; i++) {
167     const auto c = static_cast<unsigned char>(i);
168     if (absl::ascii_islower(c))
169       EXPECT_EQ(absl::ascii_toupper(c), 'A' + (i - 'a')) << c;
170     else
171       EXPECT_EQ(absl::ascii_toupper(c), static_cast<char>(i)) << c;
172 
173     if (absl::ascii_isupper(c))
174       EXPECT_EQ(absl::ascii_tolower(c), 'a' + (i - 'A')) << c;
175     else
176       EXPECT_EQ(absl::ascii_tolower(c), static_cast<char>(i)) << c;
177 
178     // These CHECKs only hold in a C locale.
179     EXPECT_EQ(static_cast<char>(tolower(i)), absl::ascii_tolower(c)) << c;
180     EXPECT_EQ(static_cast<char>(toupper(i)), absl::ascii_toupper(c)) << c;
181   }
182 #ifndef __ANDROID__
183   // restore the old locale.
184   ASSERT_TRUE(setlocale(LC_CTYPE, old_locale));
185 #endif
186 }
187 
TEST(AsciiStrTo,Lower)188 TEST(AsciiStrTo, Lower) {
189   const char buf[] = "ABCDEF";
190   const std::string str("GHIJKL");
191   const std::string str2("MNOPQR");
192   const absl::string_view sp(str2);
193   const std::string long_str("ABCDEFGHIJKLMNOPQRSTUVWXYZ1!a");
194   std::string mutable_str("_`?@[{AMNOPQRSTUVWXYZ");
195   auto fun = []() -> std::string { return "PQRSTU"; };
196 
197   EXPECT_EQ("abcdef", absl::AsciiStrToLower(buf));
198   EXPECT_EQ("ghijkl", absl::AsciiStrToLower(str));
199   EXPECT_EQ("mnopqr", absl::AsciiStrToLower(sp));
200   EXPECT_EQ("abcdefghijklmnopqrstuvwxyz1!a", absl::AsciiStrToLower(long_str));
201   EXPECT_EQ("pqrstu", absl::AsciiStrToLower(fun()));
202 
203   // An empty `string_view` specifically exercises the case where a null data
204   // pointer is passed to internal functions.
205   EXPECT_EQ("", absl::AsciiStrToLower(absl::string_view()));
206 
207   absl::AsciiStrToLower(&mutable_str);
208   EXPECT_EQ("_`?@[{amnopqrstuvwxyz", mutable_str);
209 
210   char mutable_buf[] = "Mutable";
211   std::transform(mutable_buf, mutable_buf + strlen(mutable_buf),
212                  mutable_buf, absl::ascii_tolower);
213   EXPECT_STREQ("mutable", mutable_buf);
214 }
215 
TEST(AsciiStrTo,Upper)216 TEST(AsciiStrTo, Upper) {
217   const char buf[] = "abcdef";
218   const std::string str("ghijkl");
219   const std::string str2("_`?@[{amnopqrstuvwxyz");
220   const absl::string_view sp(str2);
221   const std::string long_str("abcdefghijklmnopqrstuvwxyz1!A");
222   auto fun = []() -> std::string { return "pqrstu"; };
223 
224   EXPECT_EQ("ABCDEF", absl::AsciiStrToUpper(buf));
225   EXPECT_EQ("GHIJKL", absl::AsciiStrToUpper(str));
226   EXPECT_EQ("_`?@[{AMNOPQRSTUVWXYZ", absl::AsciiStrToUpper(sp));
227   EXPECT_EQ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1!A", absl::AsciiStrToUpper(long_str));
228   EXPECT_EQ("PQRSTU", absl::AsciiStrToUpper(fun()));
229 
230   // An empty `string_view` specifically exercises the case where a null data
231   // pointer is passed to internal functions.
232   EXPECT_EQ("", absl::AsciiStrToUpper(absl::string_view()));
233 
234   char mutable_buf[] = "Mutable";
235   std::transform(mutable_buf, mutable_buf + strlen(mutable_buf),
236                  mutable_buf, absl::ascii_toupper);
237   EXPECT_STREQ("MUTABLE", mutable_buf);
238 }
239 
TEST(StripLeadingAsciiWhitespace,FromStringView)240 TEST(StripLeadingAsciiWhitespace, FromStringView) {
241   EXPECT_EQ(absl::string_view{},
242             absl::StripLeadingAsciiWhitespace(absl::string_view{}));
243   EXPECT_EQ("foo", absl::StripLeadingAsciiWhitespace({"foo"}));
244   EXPECT_EQ("foo", absl::StripLeadingAsciiWhitespace({"\t  \n\f\r\n\vfoo"}));
245   EXPECT_EQ("foo foo\n ",
246             absl::StripLeadingAsciiWhitespace({"\t  \n\f\r\n\vfoo foo\n "}));
247   EXPECT_EQ(absl::string_view{}, absl::StripLeadingAsciiWhitespace(
248                                      {"\t  \n\f\r\v\n\t  \n\f\r\v\n"}));
249 }
250 
TEST(StripLeadingAsciiWhitespace,InPlace)251 TEST(StripLeadingAsciiWhitespace, InPlace) {
252   std::string str;
253 
254   absl::StripLeadingAsciiWhitespace(&str);
255   EXPECT_EQ("", str);
256 
257   str = "foo";
258   absl::StripLeadingAsciiWhitespace(&str);
259   EXPECT_EQ("foo", str);
260 
261   str = "\t  \n\f\r\n\vfoo";
262   absl::StripLeadingAsciiWhitespace(&str);
263   EXPECT_EQ("foo", str);
264 
265   str = "\t  \n\f\r\n\vfoo foo\n ";
266   absl::StripLeadingAsciiWhitespace(&str);
267   EXPECT_EQ("foo foo\n ", str);
268 
269   str = "\t  \n\f\r\v\n\t  \n\f\r\v\n";
270   absl::StripLeadingAsciiWhitespace(&str);
271   EXPECT_EQ(absl::string_view{}, str);
272 }
273 
TEST(StripTrailingAsciiWhitespace,FromStringView)274 TEST(StripTrailingAsciiWhitespace, FromStringView) {
275   EXPECT_EQ(absl::string_view{},
276             absl::StripTrailingAsciiWhitespace(absl::string_view{}));
277   EXPECT_EQ("foo", absl::StripTrailingAsciiWhitespace({"foo"}));
278   EXPECT_EQ("foo", absl::StripTrailingAsciiWhitespace({"foo\t  \n\f\r\n\v"}));
279   EXPECT_EQ(" \nfoo foo",
280             absl::StripTrailingAsciiWhitespace({" \nfoo foo\t  \n\f\r\n\v"}));
281   EXPECT_EQ(absl::string_view{}, absl::StripTrailingAsciiWhitespace(
282                                      {"\t  \n\f\r\v\n\t  \n\f\r\v\n"}));
283 }
284 
TEST(StripTrailingAsciiWhitespace,InPlace)285 TEST(StripTrailingAsciiWhitespace, InPlace) {
286   std::string str;
287 
288   absl::StripTrailingAsciiWhitespace(&str);
289   EXPECT_EQ("", str);
290 
291   str = "foo";
292   absl::StripTrailingAsciiWhitespace(&str);
293   EXPECT_EQ("foo", str);
294 
295   str = "foo\t  \n\f\r\n\v";
296   absl::StripTrailingAsciiWhitespace(&str);
297   EXPECT_EQ("foo", str);
298 
299   str = " \nfoo foo\t  \n\f\r\n\v";
300   absl::StripTrailingAsciiWhitespace(&str);
301   EXPECT_EQ(" \nfoo foo", str);
302 
303   str = "\t  \n\f\r\v\n\t  \n\f\r\v\n";
304   absl::StripTrailingAsciiWhitespace(&str);
305   EXPECT_EQ(absl::string_view{}, str);
306 }
307 
TEST(StripAsciiWhitespace,FromStringView)308 TEST(StripAsciiWhitespace, FromStringView) {
309   EXPECT_EQ(absl::string_view{},
310             absl::StripAsciiWhitespace(absl::string_view{}));
311   EXPECT_EQ("foo", absl::StripAsciiWhitespace({"foo"}));
312   EXPECT_EQ("foo",
313             absl::StripAsciiWhitespace({"\t  \n\f\r\n\vfoo\t  \n\f\r\n\v"}));
314   EXPECT_EQ("foo foo", absl::StripAsciiWhitespace(
315                            {"\t  \n\f\r\n\vfoo foo\t  \n\f\r\n\v"}));
316   EXPECT_EQ(absl::string_view{},
317             absl::StripAsciiWhitespace({"\t  \n\f\r\v\n\t  \n\f\r\v\n"}));
318 }
319 
TEST(StripAsciiWhitespace,InPlace)320 TEST(StripAsciiWhitespace, InPlace) {
321   std::string str;
322 
323   absl::StripAsciiWhitespace(&str);
324   EXPECT_EQ("", str);
325 
326   str = "foo";
327   absl::StripAsciiWhitespace(&str);
328   EXPECT_EQ("foo", str);
329 
330   str = "\t  \n\f\r\n\vfoo\t  \n\f\r\n\v";
331   absl::StripAsciiWhitespace(&str);
332   EXPECT_EQ("foo", str);
333 
334   str = "\t  \n\f\r\n\vfoo foo\t  \n\f\r\n\v";
335   absl::StripAsciiWhitespace(&str);
336   EXPECT_EQ("foo foo", str);
337 
338   str = "\t  \n\f\r\v\n\t  \n\f\r\v\n";
339   absl::StripAsciiWhitespace(&str);
340   EXPECT_EQ(absl::string_view{}, str);
341 }
342 
TEST(RemoveExtraAsciiWhitespace,InPlace)343 TEST(RemoveExtraAsciiWhitespace, InPlace) {
344   const char* inputs[] = {"No extra space",
345                           "  Leading whitespace",
346                           "Trailing whitespace  ",
347                           "  Leading and trailing  ",
348                           " Whitespace \t  in\v   middle  ",
349                           "'Eeeeep!  \n Newlines!\n",
350                           "nospaces",
351                           "",
352                           "\n\t a\t\n\nb \t\n"};
353 
354   const char* outputs[] = {
355       "No extra space",
356       "Leading whitespace",
357       "Trailing whitespace",
358       "Leading and trailing",
359       "Whitespace in middle",
360       "'Eeeeep! Newlines!",
361       "nospaces",
362       "",
363       "a\nb",
364   };
365   const int NUM_TESTS = ABSL_ARRAYSIZE(inputs);
366 
367   for (int i = 0; i < NUM_TESTS; i++) {
368     std::string s(inputs[i]);
369     absl::RemoveExtraAsciiWhitespace(&s);
370     EXPECT_EQ(outputs[i], s);
371   }
372 }
373 
374 }  // namespace
375