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