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